简体   繁体   中英

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;
}

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.

Just as a follow up. To move myfunc3 to a separate .cpp file required me to include the RcppParallel header to the myfunc3.cpp file. I also didn't have to add the 'inline'.

myfunc3.cpp

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

using namespace arma;

namespace ExampleInternal{

double myfunc3(arma::vec vec_in){

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

} // Close namespace

and the ExampleInternal.h

#ifndef ExampleInternal_H
#define ExampleInternal_H

namespace ExampleInternal{

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

double myfunc3(arma::vec vec_in);

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);
};

}

#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM