在公共工作者中调用"mypackage"功能 [英] Calling 'mypackage' function within public worker

查看:211
本文介绍了在公共工作者中调用"mypackage"功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我遇到的问题是线程安全问题.正如我现在所拥有的代码,将使用"seThreadOptions(1)"执行.我的问题是克服这一问题的最佳做法.

I know the problem I have is a thread-safety issue. As the code I have now will execute with 'seThreadOptions(1)'. My question is what would be a good practice to overcome this.

我知道这一点:带有Rcpp的线程安全函数指针和RcppParallel通过std :: shared_ptr 将以某种方式发挥作用.而且我也一直在考虑/试着将内部功能作为并行工作者的结构的一部分.实际上,我在调用两个内部函数,我希望一个是可变的,另一个是恒定的,这使我认为我将需要两个解决方案.

I know this: Threadsafe function pointer with Rcpp and RcppParallel via std::shared_ptr Will come into play somehow. And I have also been thinking/playing around with making the internal function part of the structure for the parallel worker. Realistically, I am calling two internal functions and I would like one to be variable and the other to be constant, this tends me to think that i will need 2 solutions.

错误是rstudio中的R会话崩溃. 这里需要注意的两件事: 1.如果我"setThreadOptions(1)"可以正常运行. 2.如果我将"myfunc"移动到主cpp文件中并简单地进行调用"myfunc",则此操作也很好.

The error is that the R session, in rstudio, crashes. Two things of note here: 1. if I 'setThreadOptions(1)' this runs fine. 2. if I move 'myfunc' into the main cpp file and make the call simply 'myfunc' this also runs fine.

这是一个详细的示例:

第一个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:

Makevars, as I am using a 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.这是在平行上下文中绝对不能做的事情.我看到两种可能性:

When you call ParallelExample::myfunc, you are calling a function defined in inst/include/ParallelExample_RcppExport.h, which uses the R API. This is something one must not do in a parallel context. I see two possibilities:

  1. myfunc转换为仅标头并将其包含在int/include/ParallelExample.h中.
  2. 如果第二个cpp文件位于同一软件包中,则将myfunc的适当声明放入src/first.h,将该文件同时包含在src/first.cppsrc/second.cpp中,然后调用myfunc而不是ParallelExample::myfunc .毕竟,如果只想在同一个程序包中调用函数,就不必在R中注册一个函数.使用R注册是用于从外部调用的功能.
  1. Convert myfunc to header-only and include it in int/include/ParallelExample.h.
  2. If the second cpp file is within the same package, put a suitable declaration for myfunc into src/first.h, include that file in both src/first.cpp and src/second.cpp, and call myfunc instead of ParallelExample::myfunc. After all, it is not necessary to register a function with R if you only want to call it within the same package. Registring with R is for functions that are called from the outside.

这篇关于在公共工作者中调用"mypackage"功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆