Rcpp 会导致段错误 RcppArmadillo 不会

2023-12-01

我目前正在尝试并行化现有的分层 MCMC 采样方案。我的大部分(现在是顺序的)源代码都是用 RcppArmadillo 编写的,所以我也想坚持使用这个并行化框架。

在开始并行化我的代码之前,我阅读了几篇关于 Rcpp/Openmp 的博客文章。在大多数这些博客文章中(例如德鲁·施密特,wrathematics)作者对线程安全、R/Rcpp 数据结构和 Openmp 问题发出警告。到目前为止我读过的所有帖子的底线是,R 和 Rcpp 不是线程安全的,不要从 omp 并行编译指示中调用它们。

因此,当从 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 并行编译指示中调用它们)似乎并不总是成立。例如,下一个示例中的调用不会导致段错误,尽管我们正在读取和写入 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;
}

我的问题

  1. 为什么第一个示例中的代码会导致段错误,而示例二和示例三中的代码却不会? 罢工>
  2. 我怎么知道调用方法是否安全(arma::mat.col(i))或者如果调用方法不安全(Rcpp::NumericMatrix.column(i))?我每次都必须阅读框架的源代码吗?
  3. 关于如何避免这些“不透明”情况(如示例一)的任何建议?

在开始并行化我的代码之前,我阅读了几篇关于 Rcpp/Openmp 的博客文章。在大多数这些博客文章(例如 Drew Schmidt、wrathematics)中,作者对线程安全、R/Rcpp 数据结构和 Openmp 问题提出警告。到目前为止我读过的所有帖子的底线是,R 和 Rcpp 不是线程安全的,不要从 omp 并行编译指示中调用它们。

这是 R 本身不是线程安全的一个众所周知的限制。这意味着您无法回调或触发 R 事件——除非您小心,否则 Rcpp 可能会发生这种情况。更简单地说:该约束与 Rcpp 无关,它只是意味着您不能通过 Rcpp 盲目地进入 OpenMP。但如果你小心的话,你可以做到。

We have 无数示例successOpenMP 和相关工具均位于 CRAN、Rcpp Gallery 上的众多软件包中以及通过 RcppParallel 等扩展包。

你似乎已经非常有选择性在你选择阅读的关于这个主题的内容中,你最终得到了一些介于错误和误导之间的东西。我建议你看看上面的几个例子RCPP画廊它处理 OpenMP / RcppParallel 因为它们处理这个问题。或者,如果您赶时间:请向上查找RVector and RMatrix在 RcppParallel 文档中。

资源:

  • RcppGallery 上有 6 个关于 OpenMP 的帖子
  • Rcpp并行站点
  • Rcpp并行CRAN包

您最大的资源可能是在 GitHub 上有针对性地搜索涉及 R、C++ 和 OpenMP 的代码。它将引导您看到许多工作示例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rcpp 会导致段错误 RcppArmadillo 不会 的相关文章

  • 如何在Python中使用多处理来加速循环执行

    我有两个清单 列表 A 包含 500 个单词 列表 B 包含 10000 个单词 我正在尝试为列表 A 找到与 B 相关的相似单词 我正在使用 Spacy 的相似函数 我面临的问题是计算需要很长时间 我是多处理使用的新手 因此请求帮助 如何
  • 并发:C++11 内存模型中的原子性和易失性

    全局变量在 2 个不同内核上的 2 个并发运行的线程之间共享 线程对变量进行写入和读取 对于原子变量 一个线程可以读取过时的值吗 每个核心可能在其缓存中具有共享变量的值 并且当一个线程写入缓存中的其副本时 不同核心上的另一个线程可能会从其自
  • dmvnorm MVN 密度 - RcppArmadillo 实现比 R 包慢,包括一些 Fortran

    The solution现已上线RCPP画廊 http gallery rcpp org articles dmvnorm arma 我从 RcppArmadillo 中的 mvtnorm 包重新实现了 dmvnorm 我有点喜欢犰狳 但我
  • mclapply 调用应该嵌套吗?

    正在筑巢parallel mclapply是个好主意吗 require parallel ans lt mclapply 1 3 function x mclapply 1 3 function y y x unlist ans Outpu
  • 同时调用多个 API,并在相应请求处理完成后立即更新 UI Android

    我需要跑6个API同时调用并且需要在相应的请求完成时更新每个用户界面 目前我正在使用kotlin 协程并行执行使用以下代码 suspend fun getAllData List
  • 在 RcppArmadillo 中将列向量乘以数值标量

    我在编译这个简单的程序时遇到一些麻烦c 代码使用Rcpp和RcppArmadillo包裹 采用以下简单示例 将矩阵的每一列乘以数值标量 code lt arma mat out Rcpp as
  • 超标量和 VLIW

    我想问一些关于ILP的问题 超标量处理器是标量处理器和矢量处理器的混合体 那么我可以说矢量处理器的架构遵循超标量吗 同时处理多个指令不会使体系结构超标量 因为流水线 多处理器或多核体系结构也可以实现这一点 这意味着什么 我读过 超标量 CP
  • 英特尔融核上的 MKL 性能

    我有一个例程 对小矩阵 50 100 x 1000 个元素 执行一些 MKL 调用以拟合模型 然后我调用不同的模型 在伪代码中 double doModelFit int model while done cblas dgemm cblas
  • 与 GridSearchCV 的并行错误,与其他方法一起工作正常

    我使用 GridSearchCV 时遇到以下问题 它在使用时给我一个并行错误n jobs gt 1 同时n jobs gt 1与 RadonmForestClassifier 等单一模型配合良好 下面是一个显示错误的简单工作示例 train
  • 如何使用 Rcpp 将 C 结构从 C 库公开到 R

    我正在尝试将 C 结构从 C 库公开到 R 中 例如 struct A int flag 库提供 API 来构造和销毁是很常见的A A initA void freeA A a 感谢RCPP MODULE 很容易暴露它而不考虑析构函数 in
  • 如何用OpenCV解决图像处理相机IO延迟

    我有一个 OpenCV 程序 其工作原理如下 VideoCapture cap 0 Mat frame while true cap gt gt frame myprocess frame 问题是如果myprocess耗时较长 超过相机的I
  • Python:并行修改数组的简单方法

    这个问题可能听起来很简单 但作为 Python 并行化的新手 我肯定会遇到困难 我处理了 OpenMP for C 中的并行化问题 这要容易得多 我需要做的是并行修改矩阵的条目 就是这样 问题是 我无法使用简单的 joblib 库来做到这一
  • mclapply 用户时间大于已用时间

    我正在尝试使用mclapply的功能parallel封装在R 该函数通过计算对数似然距离将值分配给序列矩阵 这是一个 CPU 密集型操作 所结果的system time价值观令人困惑 gt system time mclapply work
  • Parallel.ForEach - 优雅取消

    关于等待任务完成和线程同步的主题 我目前有一个迭代 我已将其包含在 Parallel ForEach 中 在下面的示例中 我在评论中提出了一些关于如何最好地处理循环的优雅终止的问题 NET 4 0 private void myFuncti
  • OpenMP 超线程导致性能不佳:如何将线程绑定到核心

    我正在开发大型密集矩阵乘法代码 当我分析代码时 它有时会达到我的四核系统的峰值失败率的 75 而其他时候则达到约 36 代码执行之间的效率不会改变 它要么从 75 开始 并继续保持该效率 要么从 36 开始 并继续保持该效率 我已将问题追溯
  • 为每个 mpi 进程分配不同数量的 openmp 线程

    假设我有一个在 384 个 MPI 进程 24 个计算节点 每个计算节点有 16 个核心 上运行的代码 并使用以下简单脚本将我的作业提交到作业队列 bin bash PBS S bin bash PBS l nodes 24 ppn 16
  • 具有多个参数和返回值的两个并行函数

    我有两个独立的功能 每一个都需要相当长的时间来执行 def function1 arg do some stuff here return result1 def function2 arg1 arg2 arg3 do some stuff
  • Eclipse PTP:在本地计算机上运行并行(MPI)应用程序?

    必须如何配置 eclipse PTP 才能在本地计算机上使用 OpenMPI 运行 MPI 应用程序 使用 添加资源管理器 我可以选择 OpenMPI 并在 连接名称 中切换到本地主机 但仍然要求我提供一些用户名和密码 这是正确的方法吗 D
  • Haskell 五个独特的 Wordle 单词

    为了好玩 我正在尝试解决 Matt Parker 在他的 Haskell 频道 Standup Maths in Haskell 频道的链接视频中谈到的与 Wordle 相关的问题 基本上 找到 5 个没有任何共同字母的 5 个字母单词 因
  • NumericVector 和 vector 之间有性能差异吗?

    假设有人使用NumericVector和其他用途vector

随机推荐

  • 如何在 Python 中定义具有默认参数值和可选参数的函数?

    我想定义一个可以省略输入参数或具有默认值的函数 我有这个功能 def nearxy x y x0 y0 z distance for i in range 0 len x distance append abs math sqrt x i
  • 如何阻止 div 内并排的 3 个图像换行到下一行?

    我无法弄清楚这一点 我希望 3 个图像并排放置在 930px 宽的 div 中 因此 当您进入响应式设计模式 或横向拖动屏幕浏览器以使其变小时 所有 3 个图像将并排保留在 div 内 而不会换行到下一行 但会自动开始调整大小以适应调整大小
  • 如何阻止 MySQL 复制返回数组中每列的条目?

    我的 MySQL 查询返回包含重复条目的数组 编号键和标记键 其中包含相同的数据 这可能是标准的 但似乎很浪费 并且如果我打印值可能会导致问题 我的意思是 显然这不是一个大问题 但我只是好奇我是否能阻止它 看来没有必要 例如 Array 0
  • Unix fork() 系统调用什么时候运行?

    void child int pid printf Child PID d n pid exit 0 void parent int pid printf Parent PID d n pid exit 0 void init printf
  • 从不同字节中提取并组合位 c c++

    我已经声明了一个字节数组 uint8 t memory 123 我已经填写了 memory 0 0xFF memory 1 0x00 memory 2 0xFF memory 3 0x00 memory 4 0xFF 现在我收到用户对特定位
  • HttpRequest 和 POST

    我不断收到以下错误消息之一 The remote server returned an error 400 Bad Request OR System Net ProtocolViolationException You must writ
  • 如何在启动时启动应用程序[关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 这个问题似乎不是关于主要由程序员使用的特定编程问题 软件算法或软件工具 如果您认为该问题与主题相关另一个 Stack Exchange 站点 您可以发表评论来解释问题可以在哪里得到解
  • 为了副作用而导入 ES6 模块的可接受做法?

    我喜欢保持代码模块化 因此我将此类代码放在单独的文件中 overrides extra js import Ember from ember Ember RSVP configure onerror function error expor
  • 在 Node 中仅获取 GET 请求的标头

    我需要得到Content Length and Content Type的标题large带有 Node js 的文件 不幸的是 我正在处理的服务器不允许HEAD请求 并且文件太大 无法生成完整的GET要求 我正在寻找类似这样的 python
  • 视觉工作室更新 2013 1,2,3,4,5

    只是想问一下 Visual Studio 2013 的更新 4 是否还包括更新 1 2 3 4 因为它是侧面唯一可用的东西 所以我无法下载 1 2 3 的更新 而且大小确实很大 包含大约 5 GB 的数据 是的 更新是累积的 安装 Upda
  • 仅在一列中交替行 - CSS

    如何仅在表格的一列中为交替行着色 代码是什么 正如 afranz409 所说 理想的解决方案是创建一个类 然而 这可以通过 CSS 特定解决方案来完成 浏览器功能有限 没有 IE 浏览器 table tr nth child 2n gt t
  • Python 将文件和目录从一个文件夹移动到另一个文件夹

    我想将一个目录中的 python 文件和目录移动到另一个具有覆盖能力的目录 我从以下代码开始 moving files from progs path tempfolder progs for dirs files in os listdi
  • 当浏览器调整大小时 CSS 媒体查询?

    我认为当用户调整浏览器大小时 CSS 媒体查询不起作用 用户必须刷新页面才能使媒体查询生效 我怎样才能用 JS 更新媒体查询 目前我使用 JS 来检测调整大小添加时的窗口大小addClass 您不需要 JS 即可让 MediaQueries
  • Matlab 灰度归一化

    我是 matlab 和图像处理的新手 在规范化方面遇到一些问题 但我不确定为什么 在我的代码中 我将图像作为黑白图像存储在 lim3 中 然后 minvalue min min min lim3 maxvalue max max max l
  • 如何在javascript中删除“:”之前的字符串部分?

    如果我有一个字符串Abc Lorem ipsum sit amet 如何使用 JavaScript jQuery 删除前面的字符串 包括 例如上面的字符串将变成 Lorem ipsum sit amet 这里不需要 jQuery 常规 Ja
  • Cstring 到 BYTE 的转换

    我正在使用 Visual Studio c 想要将 Cstring 转换为 Byte 我已经编写了这段代码 但它在第二行给了我错误 数据 未定义 CString data T OK LPBYTE pByte new BYTE data Ge
  • 无法替换字符串中的字符

    我试图遍历一个字符数组 并将字符串中的该字符替换为另一个数组中的并行字符 private String replace String input char first a e o s char second 3 0 String myCop
  • 如何在C#中拦截调试信息(Debugview风格)?

    出于测试目的 我计划组装一个小应用程序 该应用程序将侦听来自应用程序的特定事件并在此时与其交互 鉴于我们正处于测试过程中不可能更改应用程序代码的阶段 从我的角度来看 理想的做法是监听应用程序的调试跟踪 有点像 debugview 所做的那样
  • TinyMCE 文本编辑器未加载我的文本

    我在我的页面中使用 TinyMCE 但它没有加载所需的 Html 文本 我使用以下代码在 Javascript 中动态创建了此文本 但在使用 TinyMCE 文本编辑器后 该文本未加载到 TinyMCE 文本编辑器中 mytextAreaI
  • Rcpp 会导致段错误 RcppArmadillo 不会

    我目前正在尝试并行化现有的分层 MCMC 采样方案 我的大部分 现在是顺序的 源代码都是用 RcppArmadillo 编写的 所以我也想坚持使用这个并行化框架 在开始并行化我的代码之前 我阅读了几篇关于 Rcpp Openmp 的博客文章