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

nate russell russell.n2012 at gmail.com
Wed Oct 22 21:03:23 CEST 2014


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)
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20141022/2d371bfb/attachment-0001.html>


More information about the Rcpp-devel mailing list