Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用foreach和doSNOW并行调用外部程序:如何导入结果?_R_Foreach_Parallel Processing_Pbs_Snow - Fatal编程技术网

使用foreach和doSNOW并行调用外部程序:如何导入结果?

使用foreach和doSNOW并行调用外部程序:如何导入结果?,r,foreach,parallel-processing,pbs,snow,R,Foreach,Parallel Processing,Pbs,Snow,我使用R在一个具有多个节点和多个核心的集群上并行调用一个外部程序。外部程序需要三个输入数据文件并生成一个输出文件(所有文件都存储在同一子文件夹中)。 为了并行运行程序(或者说以并行方式调用它),我最初使用了foreach函数和doParallel库。只要我在一个节点上使用多个内核,这就可以正常工作 但是,我希望使用具有多个核心的多个节点。因此,我相应地修改了代码,将doSNOW库与foreach结合使用(我尝试了Rmpi和doMPI,但我没有在这些库的多个节点上运行代码)。 我觉得这很好用。E外

我使用R在一个具有多个节点和多个核心的集群上并行调用一个外部程序。外部程序需要三个输入数据文件并生成一个输出文件(所有文件都存储在同一子文件夹中)。 为了并行运行程序(或者说以并行方式调用它),我最初使用了
foreach
函数和
doParallel
库。只要我在一个节点上使用多个内核,这就可以正常工作

但是,我希望使用具有多个核心的多个节点。因此,我相应地修改了代码,将
doSNOW
库与
foreach
结合使用(我尝试了
Rmpi
doMPI
,但我没有在这些库的多个节点上运行代码)。 我觉得这很好用。E外部程序现在确实在多个节点(具有多个核心)上运行,集群日志文件显示,它产生了所需的结果。然而,我现在面临的问题是,外部程序不再将结果/输出文件存储在主节点/工作目录的指定子文件夹中(当我使用
doParallel
时,它是这样做的)。这使得我无法将结果导入R

事实上,如果我检查相关文件夹的内容,它不包含任何输出文件,尽管日志文件清楚地显示外部程序成功运行。我猜它们存储在不同的节点(?)。 我必须对我的
foreach
功能或设置集群的方式进行哪些修改,才能将这些文件保存在主节点/工作目录中指定的子文件夹中?

下面是一些示例R代码,以展示我正在做的事情:

# #Set working directory in non-interactive mode
setwd(system("pwd", intern = T))


# #Load some libraries
library(foreach)
library(parallel)
library(doParallel)


# ####Parallel tasks####
# #Create doSNOW cluster for parallel tasks
library(doSNOW)
nCoresPerNode <- as.numeric(Sys.getenv("PBS_NUM_PPN"))
nodeNames <- system("cat $PBS_NODEFILE | uniq", intern=TRUE)
machines <- rep(nodeNames, each = nCoresPerNode)
cl <- makeCluster(machines, type = "SOCK")
registerDoSNOW(cl)

# #How many workers are we using?
getDoParWorkers()

#####DUMMY CODE#####
# #The following 3 lines of code are just dummy code: 
# #The idea is to create input files for the external program "myprogram"
external_Command_Script.cmd # #command file necessary for external program "myprogram" to run
startdata # #some input data for "myprogram"
enddata # #additional input data for "myprogram"
####DUMMY CODE######


# #Write necessary command and data files for external program: THIS WORKS!
for(i in 1:100)){
  write(external_Command_Script.cmd[[i]], file=paste("./mysubfolder/external_Command_Script.",i,".cmd", sep=""))
  write.table(startdata, file=paste("./mysubfolder/","startdata.",i,".txt", sep=""), col.names = FALSE, quote=FALSE)
  write.table(enddata, file=paste("./mysubfolder/","enddata.",i,".txt", sep=""), col.names = FALSE, quote=FALSE)
}


# #Run external program "myprogram" in parallel: THIS WORKS!
foreach(i = 1:100)) %dopar% {
    system(paste('(cd ./mysubfolder && ',"myprogram",' ' ,"enddata.",i,".txt ", "startdata.",i,".txt", sep="",' < external_Command_Script.',i,'.cmd)'))
}



# #Import results of external program: THIS DOES NOT WORK WHEN RUN ON MULTIPLE NODES!
results <- list()
for(i in 1:100)){
    results[[i]] = read.table(paste("./mysubfolder/","enddata.txt.",i,".log.txt", sep=""), sep = "\t",  quote="\"", header = TRUE)
}

# #The import does NOT work as the files created by the external program are NOT stored on the master node/in the
# #subfolder of the working directory!
# #Instead I get the following error message:
# #sh: line 0: cd: ./mysubfolder: No such file or directory
# #Error in { : task 6 failed - "cannot open the connection"

问题已解决:
我犯了一个错误:外部程序实际上没有运行-我误解了日志文件。外部程序无法运行的原因是找不到子文件夹(包含必要的输入数据)。集群似乎默认为用户目录,而不是pbs提交脚本中指定的工作目录。这种行为与使用doParallel创建的集群不同,后者确实可以识别工作目录。因此,只需在R脚本中添加工作目录和子文件夹的相对路径即可解决此问题,即。e
/workingdirectory/mysubfolder/
而不仅仅是
/mysubfolder/
。或者,也可以使用文件夹的完整路径

我建议你们检查一下包装。它提供了与来自R的TORQUE/PBS交互的方法

如果您可以暂时使用它的前身,我还建议您尝试一下,当您了解它是如何工作的时候,再看看doforeach适配器的未来。这将允许您使用future.BatchJobs包。doFuture、future.BatchJobs和BatchJobs的组合允许您在R中完成所有工作,您不必担心创建临时R脚本等(免责声明:我是这两个脚本的作者)

示例:安装后的外观:

## Tell foreach to use futures
library("doFuture")
registerDoFuture()

## Tell futures to use TORQUE / PBS with help from BatchJobs
library("future.BatchJobs")
plan(batchjobs_torque)
然后你使用:

res <- foreach(i = 1:100) %dopar% {
  my_function(pathname[i], arg1, arg2)
}

res-FYI,使用TORQUE/PBS,您可以使用
qsub
选项
-d
指定工作目录,例如
qsub-d$(pwd)foo.PBS
将导致在当前工作目录中启动
foo.PBS
。非常感谢!我要看一看!
res <- foreach(i = 1:100) %dopar% {
  my_function(pathname[i], arg1, arg2)
}