[Rcpp-devel] dyn.load error with particular functor
nate russell
russell.n2012 at gmail.com
Wed Oct 22 21:59:07 CEST 2014
Matt and Bill,
Thank you both for your input. I was under the impression that
std::transform would be calling a new trackIdx(c1,c2) object for each step
along the input vectors, and therefore a static data member would be needed
to ensure that the count was being accumulated properly (my knowledge of
C++ is pretty basic, as you might have picked up on). I took your
suggestions about using a non-static data member, though, and it worked
correctly. Thanks again for the help guys.
Nate
On Wed, Oct 22, 2014 at 3:32 PM, Matthew Wright <mattw at trdlnk.com> wrote:
> Hi Nate,
>
> No problem.
>
> So the reason it's persisting across method calls is because you made it a
> static, which means there's just one instance of that data across the
> entire program. In your usage, it doesn't look like you need it to be
> static. You could just make it an instance variable and you'd probably get
> what you want, so you'd just remove the static keyword and don't initialize
> it outside the struct definition.
>
> In terms of why you initialize statics this way, this stack overflow
> question might prove helpful, I always found it a bit confusing:
> http://stackoverflow.com/questions/185844/initializing-private-static-members
>
> Matt
>
>
> On Wed, Oct 22, 2014 at 2:03 PM, nate russell <russell.n2012 at gmail.com>
> wrote:
>
>> Just for the sake of completeness, I noticed that the value of
>> trackIdx::tracker was persisting (and therefore continuing to be
>> incremented) between function calls with mc_index, so in addition to your
>> first suggestion, I added a member function to reset the value to zero, and
>> everything seems to be working smoothly. Once again, thank you for your
>> help.
>>
>> Nathan Russell
>>
>>
>>
>> #include <Rcpp.h>
>> #include <vector>
>> #include <string>
>> #include <algorithm>
>> // [[Rcpp::plugins(cpp11)]]
>>
>> class trackIdx {
>> public:
>> trackIdx(const std::string& s1_, const std::string& s2_)
>> : s1(s1_),s2(s2_) {}
>> int operator() (std::string x1, std::string x2) {
>> tracker++;
>> return (s1==x1 && s2==x2 ? (tracker-1) : -10);
>> }
>> void reset() { tracker = 0; }
>> private:
>> std::string s1;
>> std::string s2;
>> static int tracker;
>> };
>>
>> int trackIdx::tracker = 0;
>>
>> // [[Rcpp::export]]
>> std::vector<int> mc_index(const Rcpp::DataFrame& df,
>> const std::string& c1,
>> const std::string& c2)
>> {
>> std::vector<std::string> vc1 = df["C1"];
>> std::vector<std::string> vc2 = df["C2"];
>> int N = df.nrows();
>>
>> std::vector<int> vcount;
>> vcount.resize( N );
>>
>> trackIdx track(c1,c2);
>>
>> std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),track);
>> vcount.erase(
>> std::remove_if(vcount.begin(),vcount.end(),
>> [](int i) -> bool {
>> return (i<0);
>> }),
>> vcount.end());
>>
>> track.reset();
>> return vcount;
>> }
>>
>>
>>
>> On Wed, Oct 22, 2014 at 2:29 PM, nate russell <russell.n2012 at gmail.com>
>> wrote:
>>
>>> Matthew,
>>>
>>> Thank you for such a quick response; both of those suggestions worked
>>> perfectly. Out of curiosity, is there any reason to use one of these
>>> implementations over the other - or are they essentially equivalent?
>>>
>>> Regards,
>>> Nathan Russell
>>>
>>> On Wed, Oct 22, 2014 at 2:10 PM, Matthew Wright <mattw at trdlnk.com>
>>> wrote:
>>>
>>>> Nate,
>>>>
>>>> The problem here is how you are have implemented your static member of
>>>> trackIdx. You only declared it.
>>>>
>>>> I'd suggest one of two alternatives:
>>>>
>>>> // add this below the struct declaration.
>>>> int trackIdx::tracker = 0;
>>>>
>>>> Or, just create it in the function where you actually use it instead of
>>>> making it a member.
>>>> int operator() (std::string x1, std::string x2) {
>>>> static int tracker;
>>>> tracker++;
>>>> return ((s1==x1 && s2==x2) ? (tracker-1) : -1);
>>>> }
>>>>
>>>>
>>>>
>>>> On Wed, Oct 22, 2014 at 12:39 PM, nate russell <russell.n2012 at gmail.com
>>>> > wrote:
>>>>
>>>>> Hello,
>>>>>
>>>>> I am running into the "Error in dyn.load [...] unable to load shared
>>>>> object ['/tmp/...'] undefined symbol [_...]" error; however it is only
>>>>> happening with one particular Rcpp function, which I find puzzling. Here is
>>>>> my .cpp file containing two functions - I can compile the first one without
>>>>> any issue (in its own file), but the second brings about the noted error
>>>>> message:
>>>>>
>>>>>
>>>>> #include <Rcpp.h>
>>>>> #include <vector>
>>>>> #include <string>
>>>>> #include <algorithm>
>>>>> // [[Rcpp::plugins(cpp11)]]
>>>>>
>>>>> /*
>>>>> * Works fine.
>>>>> */
>>>>>
>>>>> struct checkTwo {
>>>>> public:
>>>>> checkTwo(const std::string& s1_, const std::string& s2_)
>>>>> : s1(s1_), s2(s2_) {}
>>>>> int operator() (std::string x1, std::string x2) {
>>>>> return (s1==x1 && s2==x2 ? 1 : 0);
>>>>> }
>>>>> private:
>>>>> std::string s1;
>>>>> std::string s2;
>>>>> };
>>>>>
>>>>> // [[Rcpp::export]]
>>>>> int count_if_if(const Rcpp::DataFrame& df,
>>>>> const std::string& c1,
>>>>> const std::string& c2)
>>>>> {
>>>>> std::vector<std::string> vc1 = df["C1"];
>>>>> std::vector<std::string> vc2 = df["C2"];
>>>>> int N = df.nrows();
>>>>>
>>>>> std::vector<int> vcount;
>>>>> vcount.resize( N );
>>>>>
>>>>>
>>>>> std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),checkTwo(c1,c2));
>>>>> int total = std::accumulate(vcount.begin(),vcount.end(),0);
>>>>>
>>>>> return total;
>>>>> }
>>>>>
>>>>> /*
>>>>> * Does not compile.
>>>>> */
>>>>>
>>>>> struct trackIdx {
>>>>> public:
>>>>> trackIdx(const std::string& s1_, const std::string& s2_)
>>>>> : s1(s1_),s2(s2_) {}
>>>>> int operator() (std::string x1, std::string x2) {
>>>>> tracker++;
>>>>> return ((s1==x1 && s2==x2) ? (tracker-1) : -1);
>>>>> }
>>>>> private:
>>>>> std::string s1;
>>>>> std::string s2;
>>>>> static int tracker;
>>>>> };
>>>>>
>>>>> // [[Rcpp::export]]
>>>>> std::vector<int> mc_index(const Rcpp::DataFrame& df,
>>>>> const std::string& c1,
>>>>> const std::string& c2)
>>>>> {
>>>>> std::vector<std::string> vc1 = df["C1"];
>>>>> std::vector<std::string> vc2 = df["C2"];
>>>>> int N = df.nrows();
>>>>>
>>>>> std::vector<int> vcount;
>>>>> vcount.resize( N );
>>>>>
>>>>> std::vector<int> result;
>>>>> result.resize( N );
>>>>>
>>>>>
>>>>> std::transform(vc1.begin(),vc1.end(),vc2.begin(),vcount.begin(),trackIdx(c1,c2));
>>>>> std::copy_if(vcount.begin(),vcount.end(),result.begin(),
>>>>> [](int i) -> bool {
>>>>> return !(i<0);
>>>>> });
>>>>>
>>>>> return result;
>>>>> }
>>>>>
>>>>>
>>>>> The above functions (only "count_if_if" at the moment) can be tested
>>>>> like this:
>>>>>
>>>>> Df <- data.frame(
>>>>> C1=rep(LETTERS[1:4],each=15),
>>>>> C2=as.character(rep(rep(1:3,each=5),4)),
>>>>> C3=rep(rep(1:3,each=5),4),
>>>>> stringsAsFactors=FALSE)
>>>>> ##
>>>>> count_if_if(Df,"B","3")
>>>>> ##
>>>>> # mc_index(Df,"B","3")
>>>>>
>>>>>
>>>>>
>>>>> The exact error message I am getting is:
>>>>>
>>>>> Error in
>>>>> dyn.load("/tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so") :
>>>>> unable to load shared object
>>>>> '/tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so':
>>>>> /tmp/Rtmpw7VSkV/sourcecpp_27046ca49cd4/sourceCpp_67600.so: undefined
>>>>> symbol: _ZN8trackIdx7trackerE
>>>>>
>>>>>
>>>>> and judging by the last bit, "undefined symbol:
>>>>> _ZN8trackIdx7trackerE", it looks like my "trackIdx" function object is the
>>>>> source of the problem.
>>>>>
>>>>> I have tested this on two different platforms -
>>>>>
>>>>> my network server running CentOS 7:
>>>>>
>>>>> R version 3.1.1
>>>>> Platform: x86_64-redhat-linux-gnu (64-bit)
>>>>> Rcpp_0.11.3
>>>>>
>>>>>
>>>>> and my laptop running Ubuntu 14.04:
>>>>>
>>>>> R version 3.0.2
>>>>> Platform: x86_64-pc-linux-gnu (64-bit)
>>>>> Rcpp_0.11.2
>>>>>
>>>>>
>>>>> Both of these machines use a reasonably up-to-date version of g++ that
>>>>> supports c++11 (although I don't think this has anything to do with the
>>>>> issue). I have never had any problems compiling Rcpp functions on either of
>>>>> these platforms, yet the second function object & Rcpp function above
>>>>> produce the same error on each machine. If anyone can explain what is going
>>>>> wrong and/or suggest how to correct the problem with the above code I would
>>>>> appreciate it very much.
>>>>>
>>>>> Thank you,
>>>>> Nathan Russell
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Rcpp-devel mailing list
>>>>> Rcpp-devel at lists.r-forge.r-project.org
>>>>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> -------------------------
>>>> Matt Wright
>>>> 312-264-2987 (p)
>>>> 312-479-6821 (m)
>>>>
>>>
>>>
>>
>
>
> --
> -------------------------
> Matt Wright
> 312-264-2987 (p)
> 312-479-6821 (m)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20141022/940b8986/attachment-0001.html>
More information about the Rcpp-devel
mailing list