R 并行化错误反序列化(socklisk[[n]])

Cel*_*ste 5 parallel-processing r

简而言之,我试图使用 Snow 和 adply 在日期上并行化我的整个脚本,但不断出现以下错误。

\n\n
Error in unserialize(socklist[[n]]) : error reading from connection\nIn addition: Warning messages:\n1: <anonymous>: ... may be used in an incorrect context: \xe2\x80\x98.fun(piece, ...)\xe2\x80\x99\n\n2: <anonymous>: ... may be used in an incorrect context: \xe2\x80\x98.fun(piece, ...)\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n\n

我通过以下方式设置了并行化过程:

\n\n
Cores = detectCores(all.tests = FALSE, logical = TRUE)\ncl = makeCluster(Cores, type="SOCK")\nregisterDoSNOW(cl)\nclusterExport(cl, c("Var1","Var2","Var3","Var4"), envir = environment())\n\n\nexposureDaily <- adply(.data = dateSeries,.margins = 1,.fun = MainCalcFunction,\n                       .expand = TRUE, Var1, Var2, Var3, \n                       Var4,.parallel = TRUE)\n\nstopCluster(cl)\n
Run Code Online (Sandbox Code Playgroud)\n\n

哪里dateSeries可能看起来像

\n\n
> dateSeries\n  marketDate\n1 2016-04-22\n2 2016-04-26\n
Run Code Online (Sandbox Code Playgroud)\n\n

MainCalcFunction是一个很长的脚本,其中包含多个我自己的函数。由于脚本的复制时间太长,因此不切实际,并且假设的小函数会达不到目的,因为我已经将这种方法与其他较小的函数一起使用。我可以说,MainCalcFunction我在其中调用了所有库、必要的函数和一个包含除上面导出的变量之外的所有其他变量的文件,这样我就不必导出一长串库和其他对象。

\n\n

MainCalcFunction可以使用但不使用并行化在 2 个日期上成功运行adply,这告诉我,导致并行化失败的不是代码中的错误。

\n\n

最初,我(根据经验)认为日期并行化失败了,因为代码中还有另一个利用并行化的函数,但是我随后重建了整个代码以确保不存在这样的函数。

\n\n

我用细齿梳子仔细地翻阅了脚本,看看是否有任何地方我不小心没有导出我需要的东西,而我却找不到任何东西。

\n\n

关于可能导致代码失败的一些想法是:

\n\n
    \n
  • fOptions和中各种期权估值函数的使用rquantlib
  • \n
  • 使用类型sock
  • \n
\n\n

我知道这个问题已经被问过,还有这个问题,虽然第一个问题对我有帮助,但它还没有帮助解决问题。(注意:这可能是因为我没有正确使用它,主要用于loginfo("text")跟踪代码的位置。可能有一种方法可以更改它,以便我记录警告和/或错误消息?)

\n\n

如果我可以提供任何其他信息来帮助解决此问题,请告诉我。如果有人可以提供一些指导,我将非常感激,因为代码运行一天需要近 40 分钟,而我需要运行它近一年,因此并行化至关重要!

\n\n

编辑

\n\n

我尝试通过利用 outfile 选项来实现上面第一个问题中的建议。鉴于我使用的是 Windows,我通过在导出关键对象并运行之前添加以下几行来完成此操作MainCalcFunction

\n\n
reportLogName <- paste("logout_parallel.txt", sep="")\naddHandler(writeToFile,  \n           file = paste(Save_directory,reportLogName, sep="" ),\n           level=\'DEBUG\')\nwith(getLogger(), names(handlers))\n\nloginfo(paste("Starting log file", getwd()))\n\nmc<-detectCores()\ncl<-makeCluster(mc, outfile="")  \nregisterDoParallel(cl)\n
Run Code Online (Sandbox Code Playgroud)\n\n

同样,在 的开头MainCalcFunction,在获取了我的库和函数之后,我包含了以下内容以打印到文件:

\n\n
reportLogName <- paste(testDate,"_logout.txt", sep="")\n    addHandler(writeToFile,  \n               file = paste(Save_directory,reportLogName, sep="" ),\n               level=\'DEBUG\')\n    with(getLogger(), names(handlers))\n\n    loginfo(paste("Starting test function ",getwd(), sep = ""))\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后,在该MainCalcFunction函数中,我loginfo("text")在关键时刻放置了语句,以通知我代码所在的位置。

\n\n

这导致代码由于上述错误而失败后,一些文本文件仍然可用。但是,这些文本文件除了错误发生的时间点外,没有提供有关错误原因的更多信息。尽管在最后的位置tryCatch嵌入了一条语句,但在任何错误实例上我都添加了该行MainCalcFunctionlogerror(e)

\n

Cel*_*ste 7

我发布这个答案是为了将来帮助其他遇到类似问题的人。

本质上,该错误unserialize(socklist[[n]])并没有告诉您太多信息,因此要解决它,只需缩小问题范围。

  • 首先,绝对确保代码在多个日期上非并行运行且没有错误
  • 确保并行设置正确。有一些明显的初始错误,许多其他问题都会对此做出回应,例如,代码内隐藏的并行化意味着并行化发生了两次。
  • 一旦确定代码没有问题并且并行化设置正确,就开始缩小范围。该问题很可能(除非上面遗漏了某些内容)代码中的某些内容在串行运行时不是问题,但在并行运行时却成为问题。缩小范围的最简单方法是设置outfile = "Log.txt"您使用的 make cluster 函数,例如cl<-makeCluster(cores-1, outfile="Log.txt"). 然后在函数中添加尽可能多的 print("Point in code") 注释,以缩小问题发生的位置。

就我而言,问题出在线路上jj = closeAllConnections()。该行在非并行中工作正常,但在并行时会破坏代码。我怀疑这与关闭所有连接(包括并行化所需的套接字连接)的功能有关。