[Rcpp-devel] dyn.load error with particular functor

William Dunlap wdunlap at tibco.com
Wed Oct 22 21:29:28 CEST 2014


Why don't you make track non-static instead?
Bill Dunlap
TIBCO Software
wdunlap tibco.com


On Wed, Oct 22, 2014 at 12: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)
>>
>>
>
>
> _______________________________________________
> 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


More information about the Rcpp-devel mailing list