问题
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;
}
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/55082456/parallel-worker-in-namespace