【问题标题】:How can I evaluate a C function from a dynamic library in an R package?如何从 R 包中的动态库评估 C 函数?
【发布时间】:2018-10-29 21:47:45
【问题描述】:

我正在尝试在 R 包中实现并行计算,该包使用 .C 函数从 R 调用 C。集群的节点似乎无法访问动态库。我做了一个并行套接字集群,像这样:

cl <- makeCluster(2)

我想使用 R 包并行中的 clusterEvalQ 在集群中的每个节点上评估我的 R 包中名为 valgrad 的 C 函数。但是,我的代码正在产生错误。我编译了我的包,但是当我运行时

out <- clusterEvalQ(cl, cresults <- .C(C_valgrad, …))

其中 表示C 函数valgrad 中的参数。我收到此错误:

Error in checkForRemoteErrors(lapply(cl, recvResult)) : 
  2 nodes produced errors; first error: object 'C_valgrad' not found

我怀疑clusterEvalQ 访问动态库的能力存在问题。我试图通过使用

将 glmm 包加载到集群中来解决这个问题
clusterEvalQ(cl, library(glmm))

但这并没有解决问题。

我可以使用 foreach R 包中的 foreach 函数在每个集群上评估 valgrad,如下所示:

out <- foreach(1:no_cores) %dopar% {.C(C_valgrad, …)}

no_cores 是集群中的节点数。但是,此函数不允许在集群上的任何后续计算中访问valgrad 的任何评估结果。

我该怎么做

(1) 使valgrad 的评估结果可用于集群上的后续计算或

(2) 使用clusterEvalQ 评估valgrad

【问题讨论】:

  • "我可以使用 foreach 函数评估每个集群上的 valgrad ..." - 原因可能是因为您在 Unix/macOS 上并使用 registerDoParallel(ncores),这会创建 分叉进程。使用cl &lt;- makeCluster(ncores, type = "FORK") 可能同样有效。也就是说,这里的 foreach 或其后端应该没有什么神奇之处。 Rui B 的回答说明了问题所在。

标签: r parallel-processing rparallel


【解决方案1】:

您必须加载外部库。但这不是通过library 调用完成的,而是通过dyn.load 完成的。
如果您使用多个操作系统,以下两个函数很有用,它们使用内置变量.Platform$dynlib.ext
还要注意卸载功能。如果您开发 C 函数库,您将需要它。如果您在测试之前更改了 C 函数,则必须卸载动态库,然后(新版本)重新加载。

请参阅编写 R 扩展,将文件 R-exts.pdf 放在 doc 文件夹的第 5 节或CRAN 上。

dynLoad <- function(dynlib){
    dynlib <- paste(dynlib, .Platform$dynlib.ext, sep = "")
    dyn.load(dynlib)
}

dynUnload <- function(dynlib){
    dynlib <- paste(dynlib, .Platform$dynlib.ext, sep = "")
    dyn.unload(dynlib)
}

【讨论】:

  • 如果我构建包这对我还有帮助吗? 编写 R 扩展 声明 .C 提供“一个已编译代码的接口,该接口已在构建时或通过 dyn.load 链接到 R 中”
猜你喜欢
  • 2021-02-09
  • 2015-04-22
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多