如何使用 devtools 在另一个包中使用并行包?

Posted

技术标签:

【中文标题】如何使用 devtools 在另一个包中使用并行包?【英文标题】:How to use the parallel package inside another package, using devtools? 【发布时间】:2014-09-01 12:25:24 【问题描述】:

在 R 终端中运行以下代码时:

library(parallel)
func <- function(a,b,c) a+b+c

testfun <- function() 
    cl <- makeCluster(detectCores(), outfile="parlog.txt")    
    res <- clusterMap(cl, func, 1:10, 11:20, MoreArgs = list(c=1))
    print(res)
    stopCluster(cl)


testfun()

...它工作得很好。但是,当我将这两个函数定义复制到自己的包中时,添加一行#' @import parallel,在R 终端上执行dev_tools::load_all("mypackage"),然后调用testfun(),我得到一个

Error in unserialize(node$con) (from myfile.r#7) :
error reading from connection

其中#7 是包含对clusterMap 的调用的行。

所以完全相同的代码可以在终端上运行,但不能在包中运行。

如果我查看parlog.txt,我会看到以下内容:

starting worker pid=7204 on localhost:11725 at 13:17:50.784
starting worker pid=4416 on localhost:11725 at 13:17:51.820
starting worker pid=10540 on localhost:11725 at 13:17:52.836
starting worker pid=9028 on localhost:11725 at 13:17:53.849
Error: (converted from warning) namespace 'mypackage' is not available and has been replaced
by .GlobalEnv when processing object ''
Error: (converted from warning) namespace 'mypackage' is not available and has been replaced
by .GlobalEnv when processing object ''
Error: (converted from warning) namespace 'mypackage' is not available and has been replaced
by .GlobalEnv when processing object ''
Error: (converted from warning) namespace 'mypackage' is not available and has been replaced
by .GlobalEnv when processing object ''

这个问题的根源是什么,我该如何解决?

请注意,我正在使用一个完全新鲜的裸包进行此操作。 (由devtools::create 创建。)因此不会与现有的、可能具有破坏性的代码进行交互。

【问题讨论】:

【参考方案1】:

在写这个问题的时候,我实际上找到了答案,并准备在这里分享。

这里的问题是包devtoolsparallel的组合。

显然,出于某种原因,parallel 需要将包 mypackage 安装到某个本地库中,即使您不需要在工作程序中显式加载它(例如,使用 @ 987654326@或类似的东西)!

我使用的是通常的devtools 工作流程,这意味着我一直在dev_mode() 工作。然而,这导致我的包被安装在一些特殊的开发模式文件夹中(我不知道它在内部是如何工作的)。调用 parallel 的工作进程不会搜索这些,因为它们不在 dev_mode 中。

所以这是我的“解决方法”:

## turn off dev mode
dev_mode() 
## install the package into a 'real' library
install("mypackage") 
library(mypackage)
## ... and now the following works:
mypackage:::testfun()

Hadley just pointed out 正确,另一种解决方法是添加一行

clusterEvalQ(cl, dev_mode())

在集群创建之后。这样一来,就可以使用 dev_mode。

【讨论】:

男孩...如果 devtools 得到修复,这样就不会发生这种情况,我真的很喜欢,因为现在很多包都使用并行包中的功能,而且很多人会喜欢在他们的包中无缝使用这些包,而不必这样做。

以上是关于如何使用 devtools 在另一个包中使用并行包?的主要内容,如果未能解决你的问题,请参考以下文章

如何调试我创建的 NuGet 包中的代码

在 --save-dev 包中使用时,生产包如何工作?

R sys.child 中的 system.time 和并行包为 0

如何在 NPM 包中使用 webpack 动态导入?

制作框架并被他人使用后如何避免警告

是否可以在另一个过程中打开包中的游标?