包内的 Rcpp omp_set_num_threads

     2023-02-21     113

关键词:

【中文标题】包内的 Rcpp omp_set_num_threads【英文标题】:Rcpp omp_set_num_threads within a package 【发布时间】:2019-02-15 19:09:09 【问题描述】:

我使用 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

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

【问题讨论】:

在我看来,标准的 OpenMP 环境变量设置控制着它。当然,还有帮助程序包RhpcBLASctl。哦,我看你有电话。那么@coatless 是完全正确的。 两个警告:不要使用来自Rcpp 的数据结构进行并行处理。不过可以使用来自RcppParallel 的那些。 R 对矩阵使用列主要布局。一般来说,最好在您的代码中遵循这一点。 @ralf-stubner 你能告诉我你对RcppParallel的答案吗?我刚开始学习这些东西,很高兴看到您的答案得到实施。 【参考方案1】:

添加到src/Makevarssrc/Makevars.win

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

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

注意:使用时:

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

当使用sourceCpp() 运行时,这设置-fopenmp 参数。此选项转移到包中。因此,我们必须在MakevarsMakevars.win中建立设置。

一个简短的例子可以在这里找到:

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

不过,我需要稍微清理一下。

【讨论】:

【参考方案2】:

@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)
*/

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

如果你想使用 R 的 RNG(因为你正在设置种子),还有另一个“不要那样做”。查看类似 sitmo 或 dqrng 的包,这些包可以用于并行代码的 RNG。

【讨论】:

非常感谢@ralf-stubner。如果函数声明了NumericMatrix A(I,J);,您能否解释一下RcppParallel::RMatrix&lt;double&gt; a(A); 行在做什么以及为什么要执行a(j, i)?如果我使用您的代码 R 调用 my_matrix(12,10,5) 会崩溃 @Ignacio 该行为A 创建了一个线程安全的访问器。有关更多信息,请参阅链接的 RcppParallel 文档。感谢您检查非方阵。那确实是头脑简单。切换到列主要访问权限的问题现已修复。

如何编译包内的两个程序?

】如何编译包内的两个程序?【英文标题】:HowtoCompilethetwoprocedureinsideofpackage?【发布时间】:2019-04-2810:42:09【问题描述】:我在包内创建了三个程序。现在要编译包里面仅有的两个程序。是否可能,如果是意味着如何?【问题... 查看详情

java中如何修改jar包内的properties文件!!修改修改jar包内

用jar包中的代码修改!!用rar打开双击properties文件修改后点击确定保存他会提示文件已经修改是否确认更新压缩文件参考技术A楼上正解 查看详情

Oracle:调用包内的存储过程

】Oracle:调用包内的存储过程【英文标题】:Oracle:Callstoredprocedureinsidethepackage【发布时间】:2012-10-1302:58:09【问题描述】:我对甲骨文了解不多。我使用PL/SQLDeveloper。我有以下包裹:createorreplacepackagePKG1asprocedureINIT(nRNinnumber,nREC_T... 查看详情

Oracle12:调用包内的过程

】Oracle12:调用包内的过程【英文标题】:Oracle12:callingaprocedureinsideaPackage【发布时间】:2018-02-1310:05:32【问题描述】:我有一个DBMS_JOB作业声明如下BEGINDBMS_SCHEDULER.CREATE_JOB(job_name=>\'GET_ENAGAS_INVOICES_JOB\',job_type=>\'PLSQL_BLOCK\',job_a 查看详情

springboot的jar包内的配置文件与jar包外配置文件的加载顺序

一结论关于jar包外的application.yml和jar包内的application.yml的加载顺序。1.jar包外的application-prod.yml配置文件加载顺序小于jar包内的application.yml的加载顺序。2.jar包外的application.yml的配置文件的加载顺序大于jar包内的application.yml的加载... 查看详情

Python -m 切换运行包内的模块

】Python-m切换运行包内的模块【英文标题】:Python-mswitchtorunmoduleinsidepackage【发布时间】:2020-02-2222:37:00【问题描述】:我正在阅读这个article。我想知道为什么文章中的以下陈述是正确的?因为我可以使用解决方案1-即-python-mpackA... 查看详情

是否可以使用反射遍历包内的所有类? [复制]

】是否可以使用反射遍历包内的所有类?[复制]【英文标题】:IspossibleiterateoverallclassesinsideapackagewithReflection?[duplicate]【发布时间】:2012-04-1111:51:40【问题描述】:我有一个有一些价值的字符串。我想遍历调用特定方法的包中的... 查看详情

包内的 Meteor Ionic Angular App - 如何链接到模板?

】包内的MeteorIonicAngularApp-如何链接到模板?【英文标题】:MeteorIonicAngularAppinsideaPackage-Howdoyoulinktothetemplate?【发布时间】:2016-01-2817:45:02【问题描述】:我们正在开发我们的流星应用程序的移动部分作为一个包。由于我们有移动... 查看详情

如何在 vue 中触发 npm 包内的方法?

】如何在vue中触发npm包内的方法?【英文标题】:Howtotriggeramethodinsidenpmpackageinvue?【发布时间】:2021-04-2106:47:59【问题描述】:我是Vuejs的新手,我正在使用vue-countup-v2npm包我安装它,然后将它导入我的Vue组件中,当我加载页面时... 查看详情

配置 logback 以禁止从包内的所有类进行日志记录

】配置logback以禁止从包内的所有类进行日志记录【英文标题】:Configuringlogbacktosuppressloggingfromallclassesinsideapackage【发布时间】:2014-07-2709:04:45【问题描述】:我有这个完美工作的logback.xml用于控制台,它记录了所有调试级别的语... 查看详情

如何在 PL/SQL 中使用包内的过程

】如何在PL/SQL中使用包内的过程【英文标题】:HowtouseprocedurewithinpackageinPL/SQL【发布时间】:2020-10-2110:27:09【问题描述】:如何创建一个包含过程的包?程序将指定和激励作为输入,并通过添加给定指定的激励来更新员工工资。... 查看详情

springboot项目以jar包运行时,读取jar包内的静态文件(代码片段)

springboot项目以jar包运行时,读取jar包内的静态文件javaimportjava.io.IOException;importorg.springframework.core.io.Resource;importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;importorg 查看详情

springboot项目以jar包运行时,读取jar包内的静态文件(代码片段)

springboot项目以jar包运行时,读取jar包内的静态文件javaimportjava.io.IOException;importorg.springframework.core.io.Resource;importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;importorg 查看详情

linux修改jar包内的配置文件(代码片段)

已知配置文件名称为bootstrap.yml,查询jar包中的配置文件位置[root@Charlie~]#jar-tvfservice-zuul.jar|grepbootstrap.yml6048SunMar2000:50:38CST2022BOOT-INF/classes/config/bootstrap.yml提取配置文件到当前目录[root@Charlie~]# 查看详情

包内的 TPopupMenu 子类化会在安装后破坏 IDE 的弹出菜单处理

】包内的TPopupMenu子类化会在安装后破坏IDE的弹出菜单处理【英文标题】:TPopupMenusubclassinginsideapackagebreaksIDE\'spopupmenushandlingafterinstalling【发布时间】:2022-01-1416:42:37【问题描述】:我正在制作一个组件,我需要在其中处理TPopupMen... 查看详情

zip压缩文件unzip查看zip压缩包内的内容

  [[email protected]tmp]#zip-rnew.zip./* adding:gitlab_key_file20161001-2668-1eu44mv(deflated15%) adding:RackMultipart20161001-8364-1ldbh6x(stored0%) adding:yum.log(store 查看详情

如何从包内的两个不同文件夹中导入一个模块,该模块导入另一个模块

】如何从包内的两个不同文件夹中导入一个模块,该模块导入另一个模块【英文标题】:Howtoimportamodule,whichimportsanothermodule,fromtwodifferentfoldersinsideapackage【发布时间】:2021-04-2009:39:11【问题描述】:假设我有一个具有以下结构的py... 查看详情

spring项目jar包内的配置文件和项目的配置文件有重复项

参考技术A1、首先是web项目,可以配置web.xml。2、其次spring.profiles.activedev。3、最后使用不同的profile启动,就会加载不同的bean和不同的配置。 查看详情