rrcpprcppparallelrcpparmadillo

Parallel Worker in namespace


This example is a follow up example from this earlier post. I am trying to move the Parallel Worker to its own cpp file and and declare it in the header file.

Calling 'mypackage' function within public worker

The two errors are as follows: 1) variable type 'ExampleInternal::PARALLEL_WORKER' is an abstract class

and in my non-reproducible example: 2) error: expected unqualified-id on the 'ExampleInternal::PARALLEL_WORKER{' line in the Parallel_worker.cpp file.

Right now the code looks like this:

ExampleInternal.h

#ifndef ExampleInternal_H
#define ExampleInternal_H

namespace ExampleInternal{

#include <RcppArmadillo.h>
#include <RcppParallel.h>

double myfunc3(arma::vec vec_in){

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

struct PARALLEL_WORKER : RcppParallel::Worker{};

}


#endif

Parallel_Worker.cpp

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

using namespace RcppParallel;
using namespace ExampleInternal;

namespace ExampleInternal{

ExampleInternal::PARALLEL_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);

    // Create a loop that runs through a selected section of the total Boot_reps
    for( int k = begin; k < end; k ++){
      engine.seed(k);
      arma::vec index = input;
      std::shuffle( index.begin(), index.end(), engine);

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

};

} //Close Namespace

Parallel_func.cpp

#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace ExampleInternal;

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

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

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

Solution

  • You need to do the split between the declaration and the definition of your struct correctly. The declaration in the header file contains the member variables and method signatures.

    namespace ExampleInternal{
    
    struct PARALLEL_WORKER : RcppParallel::Worker{
      const arma::vec &input;
      arma::vec &output;
    
      PARALLEL_WORKER(const arma::vec &input, arma::vec &output);
      void operator()(std::size_t begin, std::size_t end);
    
    };
    }
    

    In the cpp file you then define your methods:

    namespace ExampleInternal{
    
      PARALLEL_WORKER::PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}
    
      void PARALLEL_WORKER::operator()(std::size_t begin, std::size_t end){
    
        std::mt19937 engine(1);
    
        // Create a loop that runs through a selected section of the total Boot_reps
        for( std::size_t k = begin; k < end; k ++){
          engine.seed(k);
          arma::vec index = input;
          std::shuffle( index.begin(), index.end(), engine);
    
          output[k] = ExampleInternal::myfunc3(index);
        }
      }
    
    
    } //Close Namespace
    

    I had to do a few more changes to get everything compiled without warnings (the function defined in the header should be inline etc.) Full details at https://github.com/rstub/stackoverflow/tree/master/55082456. Note that some of the changes make only sense in the context of Rcpp Attributes outside of a package. BTW, since you don't provide test data, I have only verified the compilation, not proper operation.