在 public 工作人员中调用 'mypackage' 函数
Calling 'mypackage' function within public worker
我知道我遇到的问题是线程安全问题。因为我现在的代码将使用 'seThreadOptions(1)' 执行。我的问题是什么是克服这个问题的好做法。
我知道: 会以某种方式发挥作用。我也一直在 thinking/playing 使内部函数成为并行工作程序结构的一部分。实际上,我正在调用两个内部函数,我希望一个是可变的,另一个是常量,这让我倾向于认为我需要 2 个解决方案。
错误是rstudio中的R会话崩溃。
这里需要注意两点:
1. 如果我 'setThreadOptions(1)' 这运行正常。
2. 如果我将 'myfunc' 移动到主 cpp 文件中并简单地进行调用 'myfunc' 这也可以正常运行。
这里有一个详细的例子:
第一个 cpp 文件:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(cpp)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
二、cpp文件:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(ParallelExample)]]
#include "RcppArmadillo.h"
#include "RcppParallel.h"
#include "ParallelExample.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace std;
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);
// 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] = ParallelExample::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;
}
Makevars,因为我使用的是 macintosh:
CXX_STD = CXX11
PKG_CXXFLAGS += -I../inst/include
和命名空间:
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)
importFrom(RcppParallel,RcppParallelLibs)
useDynLib(ParallelExample, .registration = TRUE)
export(Parallelfunc)
当您调用 ParallelExample::myfunc
时,您正在调用 inst/include/ParallelExample_RcppExport.h
中定义的函数,该函数使用 R API。这是不能在并行上下文中做的事情。我看到两种可能性:
- 将
myfunc
转换为 header-only 并将其包含在 int/include/ParallelExample.h
中。
- 如果第二个 cpp 文件在同一个包中,将
myfunc
的适当声明放入 src/first.h
,将该文件包含在 src/first.cpp
和 src/second.cpp
中,并调用 myfunc
而不是 ParallelExample::myfunc
。毕竟,如果您只想在同一个包中调用一个函数,则没有必要向 R 注册一个函数。向 R 注册是为了从外部调用的函数。
在某些方面,这有点违背了 Rcpp 的内置接口 cpp 功能的目的。
首先cpp保存为'ExampleInternal.h':
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
namespace ExampleInternal
{
double myfunc3(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
}
第二个:
#include "ParallelExample.h"
#include "ExampleInternal.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace ExampleInternal;
using namespace std;
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);
// 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);
}
}
};
// [[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;
}
我知道我遇到的问题是线程安全问题。因为我现在的代码将使用 'seThreadOptions(1)' 执行。我的问题是什么是克服这个问题的好做法。
我知道:
错误是rstudio中的R会话崩溃。 这里需要注意两点: 1. 如果我 'setThreadOptions(1)' 这运行正常。 2. 如果我将 'myfunc' 移动到主 cpp 文件中并简单地进行调用 'myfunc' 这也可以正常运行。
这里有一个详细的例子:
第一个 cpp 文件:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::interfaces(cpp)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
二、cpp文件:
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(ParallelExample)]]
#include "RcppArmadillo.h"
#include "RcppParallel.h"
#include "ParallelExample.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace std;
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);
// 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] = ParallelExample::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;
}
Makevars,因为我使用的是 macintosh:
CXX_STD = CXX11
PKG_CXXFLAGS += -I../inst/include
和命名空间:
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)
importFrom(RcppParallel,RcppParallelLibs)
useDynLib(ParallelExample, .registration = TRUE)
export(Parallelfunc)
当您调用 ParallelExample::myfunc
时,您正在调用 inst/include/ParallelExample_RcppExport.h
中定义的函数,该函数使用 R API。这是不能在并行上下文中做的事情。我看到两种可能性:
- 将
myfunc
转换为 header-only 并将其包含在int/include/ParallelExample.h
中。 - 如果第二个 cpp 文件在同一个包中,将
myfunc
的适当声明放入src/first.h
,将该文件包含在src/first.cpp
和src/second.cpp
中,并调用myfunc
而不是ParallelExample::myfunc
。毕竟,如果您只想在同一个包中调用一个函数,则没有必要向 R 注册一个函数。向 R 注册是为了从外部调用的函数。
在某些方面,这有点违背了 Rcpp 的内置接口 cpp 功能的目的。
首先cpp保存为'ExampleInternal.h':
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]
#include "RcppArmadillo.h"
using namespace arma;
using namespace std;
namespace ExampleInternal
{
double myfunc3(arma::vec vec_in){
int Len = arma::size(vec_in)[0];
return (vec_in[0] +vec_in[1])/Len;
}
}
第二个:
#include "ParallelExample.h"
#include "ExampleInternal.h"
#include <random>
#include <memory>
#include <math.h>
using namespace Rcpp;
using namespace arma;
using namespace RcppParallel;
using namespace ExampleInternal;
using namespace std;
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);
// 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);
}
}
};
// [[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;
}