在R中使用C-within-R函数进行并行计算,使用snow包.问题:Mac显示正在加载轮子,并且几乎冻结



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

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

我有一个小C代码,它循环100次,同时每20秒打印一次迭代次数,每次迭代休眠1秒:

 # include <R.h>
 # include <Rinternals.h>
 # include <Rmath.h>
 # include <R_ext/Linpack.h>
 # include <unistd.h>
 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")
    }

"myRpack"是通过终端中的命令R CMD INSTALL myRpack安装到我的Mac上的。

此函数myCfun在独立运行时运行良好。看,

 library(myRpack)
 myFun(1)

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

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

然后R冻结!

第页。S.不久前,当我执行C-within-R函数(没有并行计算)时,我遇到了这个问题。我向Rcpp问了这个问题:Mac显示加载轮,几乎冻结。当时的解决方案是添加

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

在我的C文件中(我在代码中也这样做了)。然而,这种解决方案在并行计算环境中没有帮助。。。

如果有任何帮助,我将不胜感激。

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

# include <R.h>
# include <Rinternals.h>
# include <Rmath.h>
# include <R_ext/Linpack.h>
# include <unistd.h>
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()事件将挂起)。


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

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

(我的最终解决方案是在Linux服务器上开始运行这段代码,所以要考虑它的价值。)

在myC函数中

SEXP myC(SEXP j){

"j"不应该在某个地方转换成C变量吗?

最新更新