【问题标题】:Using Rcpp functions inside of R's par*apply functions from the parallel package在并行包中的 R 的 par*apply 函数中使用 Rcpp 函数
【发布时间】:2016-07-22 04:50:37
【问题描述】:

我试图了解在并行化环境中调用 Rcpp::sourceCpp() 背后发生了什么。最近,这在问题中得到了部分解决:Using Rcpp function in parLapply on Windows

在这篇文章中,德克说,

“您需要在每个生成的进程中运行 sourceCpp() 调用,否则将它们获取您的代码。”

这是对提问者使用将 Rcpp 函数分发给工作进程的回应。提问者通过以下方式发送 Rcpp 函数:

clusterExport(cl = cl, varlist = "payoff")

我很困惑为什么这不起作用。我的想法是,这就是 clusterExport() 的目标。

【问题讨论】:

    标签: r parallel-processing rcpp


    【解决方案1】:

    这里的问题是,由于二进制文件如何链接到 R 的进程,编译后的代码不能“导出”到生成的进程而不嵌入到包中。

    传统上,clusterExport() 语句允许将 R 特定代码分发给工作人员。

    通过在 Rcpp 函数上使用 clusterExport(),您只会收到 R 声明,而不是 底层共享库。也就是说,Attributes.R 中给出的R CMD SHLIB 不与工人共享/导出给工人。因此,当随后调用 worker 上的 Rcpp 函数时,R 找不到正确的共享库。

    取上一题的函数:

    Rcpp::cppFunction("NumericVector payoff( double strike, NumericVector data) {
        return pmax(data - strike, 0);
    }")
    

    注意:我使用的是cppFunction() 而不是sourceCpp(),但结果是等效,因为cppFunction() calls sourceCpp() to create the function

    输入函数名:

    payoff
    

    使用共享库指针生成 R 声明。

    function (strike, data) 
    .Primitive(".Call")(<pointer: 0x1015ec130>, strike, data)
    

    此共享库仅在编译该函数的进程上可用。

    因此,为什么将编译后的代码嵌入包中然后分发包总是理想的选择。

    【讨论】:

    • 那么,如果我将我的一个 .cpp 文件添加到一个包中,并使用 clusterEvalQ 将其导出给工作人员,它应该可以解决我的问题吗?
    • 是的,因为包处理编译代码的包装。
    • 感谢您解决这个问题。我开始四处寻找用单个文件制作包的简单方法。你有推荐的资源吗?
    • 我接受了答案,并尝试投票,但我没有足够的声誉。感谢您的帮助!
    • 在我的教程幻灯片中有大量使用单个文件制作包的示例。从Rcpp.package.skeleton() 开始,最好安装 pkgKitten,或者使用 RStudio 内置的包骨架生成器(并选择“Package w/Rcpp”)。因为每次使用 devtools 创建包时,$DEITY 都会杀死一只小猫。只是在开玩笑。否则很好的答案和(非常重要的)点。赞成。
    猜你喜欢
    • 2014-07-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 2020-10-01
    • 1970-01-01
    • 2022-03-28
    相关资源
    最近更新 更多