软件包中的RCPP omp_set_num_threads

时间:2019-02-15 19:09:10

标签: c++ rcpp

我用Rcpp和OpenMP编写了以下简单示例,当我从RStudio中获取cpp文件时,它们运行良好:

> rcpphello::my_matrix(10,10,5)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0    0    0    0    0    0    0    0     0
 [2,]    0    0    0    0    0    0    0    0    0     0
 [3,]    0    0    0    0    0    0    0    0    0     0
 [4,]    0    0    0    0    0    0    0    0    0     0
 [5,]    0    0    0    0    0    0    0    0    0     0
 [6,]    0    0    0    0    0    0    0    0    0     0
 [7,]    0    0    0    0    0    0    0    0    0     0
 [8,]    0    0    0    0    0    0    0    0    0     0
 [9,]    0    0    0    0    0    0    0    0    0     0
[10,]    0    0    0    0    0    0    0    0    0     0

但是,如果我创建一个包,相同的代码将无法正常工作:

First part (before @ )is good but unable to place

如果我从程序包中调用它,为什么相同的代码仅使用一个线程?如果有帮助,我将所有代码推送到this github repo

2 个答案:

答案 0 :(得分:5)

添加到src/Makevarssrc/Makevars.win

PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS)

这将启用-fopenmp标志。否则,您最终将不会在软件包中启用OpenMP。

注意:使用时:

// [[Rcpp::plugins(openmp)]]

-fopenmp一起运行时,这将sourceCpp()参数设置为 only 。此选项不会传输到程序包中。因此,我们必须在MakevarsMakevars.win中建立设置。

可以在此处找到一个简短示例:

https://github.com/r-pkg-examples/rcpp-and-openmp

不过,我需要清理一下。

答案 1 :(得分:1)

@coatless已经回答了这个问题。我想补充一点:不要在并行代码中使用R或Rcpp中的数据结构。不过,您可以使用RcppParallel

#include <Rcpp.h>
// [[Rcpp::plugins(openmp)]]
#include <omp.h>

// [[Rcpp::depends(RcppParallel)]]
#include <RcppParallel.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix my_matrix(int I, int J, int nthreads) {
  NumericMatrix A(I,J);
  // create a thread safe accessor for A
  RcppParallel::RMatrix<double> a(A);
  int tid;
  omp_set_num_threads(nthreads);
#pragma omp parallel for private(tid)
  for(int j = 0; j < J; j++) {
    for(int i = 0; i < I; i++) {
      tid = omp_get_thread_num();
      a(i, j) = tid ;
    }
  }

  return A;
}


/*** R
set.seed(42)
my_matrix(12,10,5)
*/

请注意,我还更改了对main列的访问权限,并删除了ij的附加声明。请注意,在parallel节内声明的变量是自动私有的。

如果您要使用R的RNG(因为您正在设置种子),则还有另一个“不要这样做”。看看sitmodqrng之类的可用于并行代码的RNG包。