0

This question is really a follow up to this previous question, Calling 'mypackage' function within public worker. And I suspect there is some deeper understanding to be had by asking it.

The error is

unable to load shared object" in "ParallelExample.so'

What I am trying to do is internally call a Cpp function in an R-package. To do this I have written and added a header file to the src directory, and defined a namespace in this header. The compiling error occurs with the code below:

That said, I have come upon two solutions for this problem.

  1. Define the function in the header file instead of only declaring it.
  2. Leave the namespace out of the header file.

From, the cpp research I have done on this topic, it seems doable and common (to declare a function in a namespace in a header file) outside of Rcpp. Which, makes me wonder if this is just a problem with the mac compiler or a feature of Rcpp.

First, cpp file:

#include <RcppArmadillo.h>
#include "ExampleInternal.h"
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){

  int Len = arma::size(vec_in)[0];
  return (vec_in[0] +vec_in[1])/Len;
}

Second, Cpp:

#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
#include <random>

using namespace RcppParallel;

struct PARALLEL_WORKER : public Worker{

  const arma::vec &input;
  arma::vec &output;

  PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}

  void operator()(std::size_t begin, std::size_t end){


    std::mt19937 engine(1);

    for( int k = begin; k < end; k ++){
      engine.seed(k);
      arma::vec index = input;
      std::shuffle( index.begin(), index.end(), engine);

      output[k] = ExampleInternal::myfunc(index);
  }
}

};

// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){

  arma::vec input = arma::regspace(0, 500);
  arma::vec output(Len_in);

  PARALLEL_WORKER  parallel_woker(input, output);
  parallelFor( 0, Len_in, parallel_woker);
  return output;
}

And finally an internal header file, also within the src directory:

#ifndef EXAMPLEINTERNAL_H
#define EXAMPLEINTERNAL_H

#include <RcppArmadillo.h>
#include <Rcpp.h>

namespace ExampleInternal{

double myfunc(arma::vec vec_in);

}

#endif
O'Neil
  • 3,790
  • 4
  • 16
  • 30
skatz
  • 115
  • 7
  • Unable to load ParallelExample.so sounds like a runtime linking problem rather than a design problem. Is there such a fill? Is the directory for file on the LD_LIBRARY_PATH? – Matthew Fisher Aug 28 '18 at 02:37
  • Thats what I have the R package named, so it is generated by the build process. – skatz Aug 28 '18 at 03:02
  • and you can actually see the shared library (.so) file? The .so is on the LD_LIBRARY_PATH? If not then it won't be visible to the runtime linker. If you have an actual executable try the 'ldd' command, it will give a message about missing shared libraries. – Matthew Fisher Aug 28 '18 at 03:05
  • the '.so' file shows up in the 'src' directory – skatz Aug 28 '18 at 03:25

1 Answers1

2

You declare and call a function ExampleInternal::myfunc but then define a function myfunc in the global namespace. That does not match and I am quite sure that the rest of the error message you are not showing indicates that ExampleInternal::myfunc was not found in the so file.

Solution: Use the same namespace while defining the function:

#include <RcppArmadillo.h>
#include "ExampleInternal.h"
namespace ExampleInternal {

double myfunc(arma::vec vec_in){

  int Len = arma::size(vec_in)[0];
  return (vec_in[0] +vec_in[1])/Len;
}

}

I have also removed the annotation to export the function. BTW, don't include both RcppAramdillo.h and Rcpp.h.

Ralf Stubner
  • 26,263
  • 3
  • 40
  • 75