16

我正在尝试使用该parallel包,发现makeCluster无法完成。我已将问题追溯到以下行newPSOCKnode

con <- socketConnection("localhost", port = port, server = TRUE, 
    blocking = TRUE, open = "a+b", timeout = timeout)

该命令停止(假设默认超时值很大)。我怀疑这是由于我们的工作计算机上制定了一些“过分热心的 IT 规则”,但欢迎任何有关如何追踪(和修复)问题根源的建议。这是 Windows7-64,“企业”,R 3.0.1。

更多信息:在调试会话中,我设置timeout < - 10了 ,但它仍然挂起 - 好像socketConnection被困在某个甚至无法检查超时值的地方。

这是我与 Richie Cotton 的数据同时进行的转储:

Browse[3]> ls.str()
arg :  chr "parallel:::.slaveRSOCK()"
cmd :  chr "\"C:/Users/carl.witthoft/Documents/R/R-3.0.1/bin/x64/Rscript\" -e \"parallel:::.slaveRSOCK()\" MASTER=localhost PORT=11017 OUT="| __truncated__
env :  chr "MASTER=localhost PORT=11017 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE"
machine :  chr "localhost"
manual :  logi FALSE
master :  chr "localhost"
methods :  logi TRUE
options : <environment: 0x000000000ccac6a0> 
outfile :  chr "/dev/null"
port :  int 11017
rank :  int 1
renice :  int NA
rscript :  chr "\"C:/Users/carl.witthoft/Documents/R/R-3.0.1/bin/x64/Rscript\""
timeout :  num 2592000
useXDR :  logi TRUE

所以除了不同的端口号,我认为一切都匹配。

下一个技巧:我打开一个 shell 并运行netsh advfirewall firewall add rule name="Open Port 11017" dir=in action=allow protocol=TCP localport=11017 并得到“OK”响应。我跑了netstat -a -n ,发现以下行:

TCP 0.0.0.0:11017 0.0.0.0:0 LISTENING

但是跑步makePSOCKcluster 仍然挂在同一个地方。

NEXT:我尝试R从命令行运行(通过 cygwin bash),我得到的错误消息是Error in loadhistory(file) : no history mechanism available Execution halted,然后 -C 将我返回到 R-prompt。

4

3 回答 3

9

您所描述的是 PSOCK 集群的经典问题:makeClusterhangs。它可能因多种原因挂起,因为它必须创建所有进程,称为“工作”进程,这些进程将执行“集群”的实际工作,并且涉及使用 Rscript 命令启动新的 R 会话,该命令将执行.slaveRSOCK函数,它将创建一个返回到主节点的套接字连接,然后执行该slaveLoop函数,最终将执行主节点发送给它的任务。如果启动任何工作进程出现任何问题(相信我:很多都可能出错),主进程将在执行时挂起socketConnection,等待工作进程连接到它,即使该工作进程可能已经死亡或从未成功创建.

对于许多失败场景,使用该outfile参数非常有用,因为它经常揭示导致工作进程死亡从而导致主进程挂起的错误。但如果这没有显示任何内容,我会进入手动模式。在手动模式下,master 打印命令来启动每个 worker,而不是执行命令本身。它需要更多的工作,但它可以让您完全控制,如果需要,您甚至可以调试工作人员。

这是一个例子:

> library(parallel)
> cl <- makePSOCKcluster(1, manual=TRUE, outfile='log.txt')
Manually start worker on localhost with
   '/usr/lib/R/bin/Rscript' -e 'parallel:::.slaveRSOCK()' MASTER=localhost
PORT=10187 OUT=log.txt TIMEOUT=2592000 METHODS=TRUE XDR=TRUE 

此时,您的 R 会话已挂起,因为它正在执行socketConnection,正如您所描述的那样。现在您的工作是打开一个新的终端窗口(命令提示符或其他),然后粘贴该 Rscript 命令。一旦你执行了它,makePSOCKcluster应该返回,因为我们只请求了一个工人。当然,如果出现问题,它不会返回,但如果你幸运的话,你会在终端窗口中收到一条错误消息,并且你会有一个重要的线索,希望能解决你的问题. 如果你不那么幸运,Rscript 命令也会挂起,你将不得不更深入地研究。

要调试工作程序,您不需要执行显示的 Rscript 命令,因为您需要一个交互式会话。相反,您可以使用以下命令启动 R 会话:

$ R --vanilla --args MASTER=localhost PORT=10187 OUT=log.txt TIMEOUT=2592000 METHODS=TRUE XDR=TRUE

在那个 R 会话中,您可以在函数上放置一个断点.slaveRSOCK,然后执行它:

> debug(parallel:::.slaveRSOCK)
> parallel:::.slaveRSOCK()

现在您可以开始单步执行代码,可能在slaveLoopandmakeSOCKmaster函数上设置断点。在您的情况下,我假设它会在尝试创建套接字连接时挂起,在这种情况下,您的问题的标题将是合适的。

有关此类问题的更多信息,请参阅我对类似问题的回答。

更新

现在这个特殊问题已经解决了,我可以添加两个调试makePSOCKcluster问题的技巧:

  • 检查您的 .Rprofile 中的任何内容是否仅在交互模式下有效
  • 在 Windows 上,使用 Rterm 命令而不是 Rgui,这样您就更有可能看到错误消息和使用outfile=''.
于 2013-10-08T22:42:59.767 回答
3

测试1:明显的命令有效吗?

library(parallel)    
cluster <- makePSOCKcluster("localhost")    
parSapply(cluster, 1:5, sqrt)
stopCluster(cluster)

测试2:你的端口被阻塞了吗?

根据?makeCluster,默认端口是10187。请与您的网络管理员联系以查看该端口是否已打开。

测试 3:传入的变量socketConnection看起来是否正确?

如果我这样做debugonce(parallel:::newPSOCKnode),然后在调用 to 之前单步执行socketConnection,则工作区如下所示:

ls.str()
arg :  chr "parallel:::.slaveRSOCK()"
## cmd :  chr "\"C:/PROGRA~1/R/R-215~1.2/bin/x64/Rscript\" -e \"parallel:::.slaveRSOCK()\" MASTER=localhost PORT=10187 OUT=/dev/null TIMEOUT=2"| __truncated__
## env :  chr "MASTER=localhost PORT=10187 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE"
## machine :  chr "localhost"
## manual :  logi FALSE
## master :  chr "localhost"
## methods :  logi TRUE
## options : <environment: 0x0000000010bf2518> 
## outfile :  chr "/dev/null"
## port :  num 10187
## rank :  int 1
## renice :  int NA
## rscript :  chr "\"C:/PROGRA~1/R/R-215~1.2/bin/x64/Rscript\""
## timeout :  num 2592000
## useXDR :  logi TRUE

你得到同样的东西吗?

于 2013-10-08T14:29:56.030 回答
2

好吧,我不觉得自己像个彻头彻尾的白痴。

我回到“软件调试的三个 R”(重试、重新启动、重新加载),在重新启动我的系统并成功启动手动工作人员后,我尝试创建一个集群,manual=FALSE 并在那里立即取得了成功。

编辑:我应该明确指出,将我.Rprofile的 fromloadhistory()更改if(interactive() ) loadhistory()为对成功使用这些cluster功能至关重要。

我非常感谢 Richie 和 Steve 提出的所有有用的意见和建议。我当然已经“在幕后”学到了很多东西,所以至少对我来说这种体验是非常积极的。

(所以我不知道是什么 WindowsOS 的东西或中断的电话阻碍了,但一切都很好,结果很好)

于 2013-10-09T12:20:16.057 回答