Parallel processing Rcpp导致SEGFULT RcppArmadillo不存在
我目前正在尝试并行化现有的分层MCMC采样方案。我的大部分(现在是顺序的)源代码都是用RcppArmadillo编写的,所以我也希望使用这个并行化框架 在开始并行化我的代码之前,我读了几篇关于Rcpp/Openmp的博客文章。在大多数博客文章(例如)中,作者警告线程安全、R/Rcpp数据结构和Openmp的问题。到目前为止,我读过的所有帖子的底线是,R和Rcpp不是线程安全的,不要从omp并行pragma中调用它们 因此,当从R调用时,以下Rcpp示例会导致segfault:Parallel processing Rcpp导致SEGFULT RcppArmadillo不存在,parallel-processing,openmp,rcpp,armadillo,Parallel Processing,Openmp,Rcpp,Armadillo,我目前正在尝试并行化现有的分层MCMC采样方案。我的大部分(现在是顺序的)源代码都是用RcppArmadillo编写的,所以我也希望使用这个并行化框架 在开始并行化我的代码之前,我读了几篇关于Rcpp/Openmp的博客文章。在大多数博客文章(例如)中,作者警告线程安全、R/Rcpp数据结构和Openmp的问题。到目前为止,我读过的所有帖子的底线是,R和Rcpp不是线程安全的,不要从omp并行pragma中调用它们 因此,当从R调用时,以下Rcpp示例会导致segfault: #include
#include <Rcpp.h>
#include <omp.h>
using namespace Rcpp;
double rcpp_rootsum_j(Rcpp::NumericVector x)
{
Rcpp::NumericVector ret = sqrt(x);
return sum(ret);
}
// [[Rcpp::export]]
Rcpp::NumericVector rcpp_rootsum(Rcpp::NumericMatrix x, int cores = 2)
{
omp_set_num_threads(cores);
const int nr = x.nrow();
const int nc = x.ncol();
Rcpp::NumericVector ret(nc);
#pragma omp parallel for shared(x, ret)
for (int j=0; j<nc; j++)
ret[j] = rcpp_rootsum_j(x.column(j));
return ret;
}
有趣的是,语义等价的代码不会导致segfault
在研究过程中我注意到的第二件事是,前面提到的语句(R和Rcpp不是线程安全的,不要从omp并行pragma中调用它们)似乎并不总是正确的。例如,下一个示例中的调用不会导致segfault,尽管我们正在读取和写入Rcpp数据结构
#include <Rcpp.h>
#include <omp.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix rcpp_sweep_(Rcpp::NumericMatrix x, Rcpp::NumericVector vec)
{
Rcpp::NumericMatrix ret(x.nrow(), x.ncol());
#pragma omp parallel for default(shared)
for (int j=0; j<x.ncol(); j++)
{
#pragma omp simd
for (int i=0; i<x.nrow(); i++)
ret(i, j) = x(i, j) - vec(i);
}
return ret;
}
在我看来,第一个和第二个例子显然干扰了我在第一点和第二点所作的假设。例三也让我头疼,因为对我来说,这就像是一个打电话给R
我的最新问题
RVector
和RMatrix
资源:
RVector
和RMatrix
资源:
<> P>和您最大的资源可能是GITHUB的一些有针对性的搜索,包括R、C++和OpenMP的代码。它将引导您找到许多工作示例。感谢您的快速回复!也许我的问题措辞含糊不清:我不想把这种行为归咎于Rcpp,而且我知道有很多R-packages可以使用openmp代码。我的问题很简单:我只是不明白为什么称arma::col(I)或Rcpp::(I,j)而不是Rcpp::.colm(I)是安全的。不幸的是,引用的资料中没有一个明确提到这个问题;GitHub上的评论也是如此[search:Rcpp&Openmp]。错误的假设:仅仅因为第二种方法没有立即失效并不能证明它是合理的或推荐的。通过我们选择的(有效的)方法,RcppArmadillo对象仍然使用R内存。所以,请去阅读我提供的参考资料。再次感谢您的时间!周末,我更仔细地研究了您向我指出的Rcpp图库中的OpenMP示例。由于一些例子让我更加困惑,我已经编辑了我的原始问题。如果你有一个新问题,最好用一个简短的可复制的例子提出一个新的、有重点的问题。这不是一个按需教程网站。我已经给你们指出了很多工作示例。好的,明白了。我将创建一个新问题@德克:我知道你的例子是有效的(!)我只是不知道为什么,我不能
#include <Rcpp.h>
#include <omp.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix rcpp_sweep_(Rcpp::NumericMatrix x, Rcpp::NumericVector vec)
{
Rcpp::NumericMatrix ret(x.nrow(), x.ncol());
#pragma omp parallel for default(shared)
for (int j=0; j<x.ncol(); j++)
{
#pragma omp simd
for (int i=0; i<x.nrow(); i++)
ret(i, j) = x(i, j) - vec(i);
}
return ret;
}
arma::mat temp_row_sub = temp_mat.rows(x-2, x+2);
interMatrix(_, i) = MAT_COV(_, index_asset); // 3rd code example 3rd method
thread_sum += R::dlnorm(i+j, 0.0, 1.0, 0); // subsection OpenMP support