[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