我有一个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变量吗?