c++ - 包内的 Rcpp omp_set_num_threads
问题描述
我使用 Rcpp 和 OpenMP 编写了以下简单示例,当我从 RStudio 获取 cpp 文件时,它可以正常工作:
#include <Rcpp.h>
#include <omp.h>
// [[Rcpp::plugins(openmp)]]
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix my_matrix(int I, int J, int nthreads) {
NumericMatrix A(I,J);
int i,j,tid;
omp_set_num_threads(nthreads);
#pragma omp parallel for private(i, j, tid)
for(int i = 0; i < I; i++) {
for(int j = 0; j < J; j++) {
tid = omp_get_thread_num();
A(i,j) = tid ;
}
}
return A;
}
/*** R
set.seed(42)
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,] 1 1 1 1 1 1 1 1 1 1
[4,] 1 1 1 1 1 1 1 1 1 1
[5,] 2 2 2 2 2 2 2 2 2 2
[6,] 2 2 2 2 2 2 2 2 2 2
[7,] 3 3 3 3 3 3 3 3 3 3
[8,] 3 3 3 3 3 3 3 3 3 3
[9,] 4 4 4 4 4 4 4 4 4 4
[10,] 4 4 4 4 4 4 4 4 4 4
但是,如果我创建一个包,相同的代码将无法按预期工作:
> 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
如果我从包中调用相同的代码,为什么只使用一个线程?如果有帮助,我将所有代码推送到这个 github repo
解决方案
添加到src/Makevars
和src/Makevars.win
:
PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS)
这将启用-fopenmp
标志。否则,您最终不会在您的包中启用 OpenMP。
注意:使用时:
// [[Rcpp::plugins(openmp)]]
这仅在使用 运行时设置-fopenmp
参数。此选项不会转移到包中。因此,我们必须在和中建立设置。sourceCpp()
Makevars
Makevars.win
可以在这里找到一个简短的示例:
https://github.com/r-pkg-examples/rcpp-and-openmp
不过,我需要稍微清理一下。
推荐阅读
- python - 在python中更有效地按字母顺序对列表进行排序而不使用排序方法
- vue.js - 绑定到采用字符串文字参数的方法
- kdb - 为什么我不能在更新语句中添加条件?
- git - 远程分支、远程跟踪分支和本地跟踪分支如何设置相互对应?
- google-maps - Flutter google_maps_flutter 包阻塞 alertDialog
- node.js - 长 URL GET 请求的 Express.js 服务器 400 错误请求错误
- php - PHP 显示带偏移量的日期时间
- javascript - 为什么我的调度不起作用?反应还原
- azure-cosmosdb - 通过 CosmosDB 更改源使用多个使用者
- javascript - 如何在实时数据库中创建 id