- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我目前正在尝试并行化现有的分层 MCMC 采样方案。我的大部分(现在是连续的)源代码都是用 RcppArmadillo 编写的,所以我也想坚持使用这个并行化框架。
在开始并行化我的代码之前,我阅读了几篇关于 Rcpp/Openmp 的博客文章。在这些博客文章的大部分(例如 Drew Schmidt, wrathematics)中,作者警告线程安全、R/Rcpp 数据结构和 Openmp 问题。到目前为止我读过的所有帖子的底线是,R 和 Rcpp 不是线程安全的,不要从 omp parallel pragma 中调用它们。
因此,当从 R 调用时,以下 Rcpp 示例会导致段错误:
#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;
}
正如 Drew 在他的博客文章中所解释的那样,段错误的发生是由于“隐藏”副本,Rcpp 在调用 ret[j] = rcpp_rootsum_j(x.column(j));
时创建的。 .
因为我对 RcppArmadillo 在并行化情况下的行为感兴趣,所以我转换了 Drew 的示例:
//[[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <omp.h>
double rcpp_rootsum_j_arma(arma::vec x)
{
arma::vec ret = arma::sqrt(x);
return arma::accu(ret);
}
// [[Rcpp::export]]
arma::vec rcpp_rootsum_arma(arma::mat x, int cores = 2)
{
omp_set_num_threads(cores);
const int nr = x.n_rows;
const int nc = x.n_cols;
arma::vec ret(nc);
#pragma omp parallel for shared(x, ret)
for (int j=0; j<nc; j++)
ret(j) = rcpp_rootsum_j_arma(x.col(j));
return ret;
}
有趣的是,语义上等效的代码不会导致段错误。
我在研究过程中注意到的第二件事是,上述声明(R 和 Rcpp 不是线程安全的,不要从 omp parallel pragma 中调用它们)似乎并不总是坚持是真的。例如,下一个示例中的调用不会导致段错误,尽管我们正在读取和写入 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;
}
我的问题
arma::mat.col(i)
) 还是调用方法不安全 (Rcpp::NumericMatrix.column(i)
)?我是否必须每次都阅读框架的源代码?
我的 RcppArmadillo 示例没有失败可能纯属巧合。请参阅下面的 Dirks 评论。
编辑 1
在他的回答和他的两条评论中,Dirk 强烈建议更仔细地研究 Rcpp Gallery 中的示例。
这是我的初步假设:
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
在我看来,第一个和第二个示例明显干扰了我在第一点和第二点中所做的假设。示例三也让我头疼,因为对我来说它看起来像是对 R 的调用......
我更新的问题
除了 RcppGallery 和 GitHub 之外,还有关于如何更好地了解 Rcpp 和 OpenMP 交互的任何建议吗?
最佳答案
Before starting with parallelizing my code I have read a couple of blog posts on Rcpp/Openmp. In the majority of these blog posts (e.g. Drew Schmidt, wrathematics) the authors warn about the issue of thread safety, R/Rcpp data structures and Openmp. The bottom line of all posts I have read so far is, R and Rcpp are not thread safe, don't call them from within an omp parallel pragma.
这是 R 本身不是线程安全的一个众所周知的限制。这意味着您无法回调或触发 R 事件——除非您小心,否则 Rcpp 可能会发生这种情况。更简单地说:约束与 Rcpp 无关,它只是意味着你不能盲目地通过 Rcpp 进入 OpenMP。但如果你小心的话,你可以。
我们在 CRAN、Rcpp Gallery 和扩展包(如 RcppParallel)上的许多包中都有 无数成功的 OpenMP 和相关工具示例。
您似乎非常有选择性选择阅读有关该主题的内容,并且最终得出的结果介于错误和误导之间。我建议你转向 Rcpp Gallery 上的几个例子。它处理 OpenMP/RcppParallel,因为它们处理的是这个问题。或者,如果您赶时间:在 RcppParallel 文档中查找 RVector
和 RMatrix
。
资源:
您最大的资源可能是在 GitHub 上进行一些有针对性的搜索,以查找涉及 R、C++ 和 OpenMP 的代码。它将引导您找到大量工作示例。
关于parallel-processing - Rcpp 导致段错误 RcppArmadillo 不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56416828/
考虑以下 R 代码, ## ----------- R version ----------- caller using namespace arma ; using n
RcppArmadillo 是我尝试安装的一些软件包的依赖项。我在编译 RcppArmadillo 版本 0.10.1.0.0 时收到此错误(这是 R 在发现 RcppArmadillo 是一个 de
我正在研究 a package ,它使用来自 RcppArmadillo 的随机数。该软件包运行 MCMC 算法,为了获得精确的再现性,用户应该能够设置随机数种子。执行此操作时,似乎用于从 Gamma
我是 Rcpp 的新手,正在尝试基于 for() 中的负索引执行计算- 使用 RcppArmadillo 循环。 我已经发现 RcppArmadillo 中的负索引不是那么简单,但是可以通过应该保留的
我正在尝试使用 RcppArmadillo 定义一个可以处理稀疏和密集矩阵输入的模板函数。我得到了一个非常简单的案例,将一个密集或稀疏矩阵发送到 C++,然后返回到 R 以像这样工作: library
我试图找到一个非常大的稀疏矩阵的特征值。我正在使用 RcppArmadillo 的 eig_gen 函数,它不是专门用于稀疏矩阵的,但只要计算是以单精度完成的,我就可以接受。所以我的 cpp 代码是:
我在我的 Rcpp 代码中使用 RcppArmadillo::sample,它在下面有这种奇怪的行为。 fun_good 按预期工作,从 x vector 中采样 1 个元素。然而,fun_bad 不
问题是我有一个变量 arma::mat prob_vec并想要相当于 rmultinom(1, 1, prob_vec) 的东西在 R。 我找到了 rmultinom RcppArmadillo 提供
这是一个用于绘制 N 的 C++ 函数均值为零和标准差的独立正态偏差s // [[Rcpp::depends(RcppArmadillo)]] #include using namespace Rc
我有以下 Rcpp/RcppArmadillo 函数,它计算矩阵中的相关距离 #include using namespace Rcpp; // [[Rcpp::export]] arma::mat
开始有 R 经验,但完全是 C++ 新手,我用 RcppArmadillo 编写了一些函数,并且对它的可用性和速度非常热情。我现在想使用函数 RcppArmadillo.package.skeleto
我在编译这个简单的 c++ 时遇到了一些麻烦代码使用 Rcpp和 RcppArmadillo包裹。以下面的简单示例将矩阵的每一列乘以数值标量: code (m); for(int i = 0; i :
问候和称呼, 我正在尝试使用字段对象类型而不是列表数据类型来避免必须发出复制命令。我试图这样做是为了减少与从列表中删除一个矩阵相关的时间,该矩阵由 Armadillo 的数据结构中已经定义的矩阵进行操
我正在尝试使用 RcppArmadillo 通过完全旋转来实现 LU 分解。幸运的是我有 this可以执行我想要的操作的 Matlab 代码,但我在将其转换为 Armadillo 时遇到了一些挑战。
将 log1p() 应用于整个 arma::vec 的合适方法是什么?似乎有 log() 和 exp() 的矢量化版本,但没有 log1p()。我发现 NumericVector 有语法糖,所以我最终
以下玩具示例为 parallelFor工作正常( f2 是 f1 的并行版本): // [[Rcpp::depends(RcppParallel)]] // [[Rcpp::depends(RcppA
我在编译 RcppArmadillo 时遇到问题。这是我尝试安装软件包时的结果: > install.packages("RcppArmadillo") Installing package(s)
我试图了解用 RcppArmadillo 编写的函数与使用 Armadillo 库在独立 C++ 程序中编写的函数之间的性能差异。例如,考虑以下简单函数,该函数使用传统教科书公式计算线性模型的系数。
真的很困惑为什么使用 RcppArmadillo 的 QR 输出与 R 的 QR 输出不同; Armadillo 文档也没有给出明确的答案。本质上,当我给 R 一个矩阵 Y 是 n * q (比如 1
我需要使用名为 dgebal 的 Fortran 例程(文档 here )在我的 Rcpparmadillo 代码中。我已经包含了以下标题: # include # include 但是,当我尝试
我是一名优秀的程序员,十分优秀!