使用降雪包在R中使用C-in-R函数进行并行计算。 问题:Mac显示加载轮子并几乎冻结

我有一个包含C-within-R函数的R包,名为myFun。 我想在我的并行计算中称之为myFun。 这个myFun在我的Mac上运行良好,但是当它通过并行计算functionsfClusterApplyLB调用时,它显示出奇怪的行为:我的Mac显示加载轮子和R几乎冻结。 过了一会儿,R停止冻结,sfClusterApplyLB返回并行化的结果。 我真的想避免这种冻结状态,因为我甚至无法在冻结时向上/向下滚动R控制台!

为了说明这一点,我有一个小例子代码。

我有一个小的C代码,循环100次,每20秒打印一次迭代次数,每次迭代hibernate1秒:

# include  # include  # include  # include  # include  SEXP myC (SEXP j) { for (int i = 0; i < 100; i++) { R_FlushConsole(); R_ProcessEvents(); R_CheckUserInterrupt(); sleep(1); // sleep one second at each iteration. this sleep is // replaced by something in my code if (i%20==0) Rprintf("\v%d iterations are done...",i); } return (R_NilValue); } 

我创建了一个临时的R包“myRpack”,它包含了这个myC函数以及它的R包装函数myFun,它被定义为:

  myFun <- function(x) { .Call("myC", as.integer(x), "myRpack") } 

通过终端中的命令R CMD INSTALL myRpack将“myRpack”安装到我的Mac上。

这个函数myCfun独立运行时工作正常。 查看,

  library(myRpack) myFun(1) 

现在,我想使用降雪包并行计算这个myFun。 以下是用于此目的的并行计算的R代码:

  library("snowfall") sfInit(parallel=TRUE,cpus=3,type="SOCK") x <- 1 : 100 res.list <- sfClusterApplyLB(x,myFun) 

然后R冻结了!

PS我刚刚在执行C-in-Rfunction时遇到了这个问题(没有并行计算)。 我向Rcpp问了这个问题:Mac显示加载轮子几乎冻结 。 时间的解决方案是添加线条

  R_FlushConsole(); R_ProcessEvents(); R_CheckUserInterrupt(); 

在我的C文件中(我在我的代码中也做过)。 但是,这个解决方案并没有帮助并行计算环境……

我将不胜感激任何帮助。

PSS即使我将myC函数定义为:

 # include  # include  # include  # include  # include  SEXP myC (SEXP j) { const int input=INTEGER(j)[0]; Rprintf("\n input %d",input); for (int i = 0; i < 100; i++) { R_FlushConsole(); R_ProcessEvents(); R_CheckUserInterrupt(); sleep(1); // sleep one second at each iteration. this sleep is // replaced by something in my code if (i%20==0) Rprintf("\v%d iterations are done...",i); } return (R_NilValue); } 

问题出现了。

我遇到了同样的问题,偶然发现了一个可能会或可能不适用于您的情况的解决方法。

tl; dr:我意识到我正在运行的脚本(使用并行的低级C代码调用函数)将挂起在R GUI中,可以在终端中的R实例中正确执行(每个实例一次 – 后续source() ings会挂起)。


更多背景,对于遇到同样问题的其他人:我遇到它并行调用函数gbm.step()和dismo包。 我使用doParallel和foreach包来并行化它。 `gbm.step()函数是一个C函数,适合增强的回归树模型,当我并行运行时,它会冻结(经过检查,大部分CPU使用率是系统,而不是用户)。

我只是开始在小牛队遇到这个问题,所以我想知道它是否与Mavericks的压缩内存或类似东西有关。

(我的最终解决方法是开始在Linux服务器上运行此代码,因此请将其用于它的价值。)

在你的myCfunction中

SEXP myC(SEXP j){

不应该将“j”转换为某个C变量吗?