我使用foreach包使用HPC并行运行蒙特卡罗模拟。我没有问题foreach返回我想要的结果,但我想知道是否可以定期保存工作区。我问的原因是我必须指定一个挂号时间(之后作业被终止),因此我冒险1.设置壁挂时间太低并在foreach循环完成之前丢失所有内容并保存输出或2.设置保守上班时间和浪费我的配额。理想情况下,我希望能够定期保存输出,在这种情况下,如果作业终止,我仍然有数据。
例如:
results <- foreach (ii = 1:100, .combine = rbind) %dopar% {
res1 <- ii^2
res2 <- matrix(sample(1:9,9,replace = F),nrow = 3, ncol = 3)
if (ii %% 10 == 0){
save.image("temp_save.RData")
}
results <- list(res1,res2)
}
save.image("final_save.RData")
> load("~/final_save.RData")
> results
[,1] [,2]
result.1 1 Integer,9
result.2 4 Integer,9
result.3 9 Integer,9
result.4 16 Integer,9
...
但是'temp_save'是空的,可能是因为'结果'只在foreach循环结束后生成。在foreach循环完成之前,有没有办法访问和保存这些数据?谢谢你的帮助。
答案 0 :(得分:0)
我遇到了与此非常相似的问题,并使用评论中提到的 save()
方法解决了该问题。具体来说,我喜欢在处理大型数据集时间歇性地“保存”我的进度,这样我就不会在出现问题时浪费计算资源(例如,walltime 用完)。我个人发现 save.image()
在复杂代码中使用时非常不可靠,尤其是在 HPC 环境中。我的代码太长,无法在此处复制,但这是通用(未经测试)方法:
# Set up the parallel backend
library(doParallel)
library(foreach)
cl <- parallel::makeCluster(4)
doParallel::registerDoParallel(cl)
# Set up a scratch directory for your intermediate files
intermediate_directory <- 'INTER_DIR'
if (!dir.exists(intermediate_directory) {
dir.create(intermediate_directory)
}
# Run your parallel loop
foreach(i = 1:100, .export = ls(environment())) %dopar% {
# Create a unique filename for each interation of the parallel loop
each_filename <- paste0('RESULT_', as.character(i), '.rda')
each_filepath <- file.path(intermediate_directory, each_filename)
# If the file exists, skip to the next iteration
if (file.exists(each_filepath)) {
next
}
# Otherwise, run your code
each_result <- jitter(i, factor = 10)
# Save the result individually
save(each_result, file = each_filepath)
# OR, save the contents of an environment:
save(list = ls(environment()), file = each_filepath)
}
循环结束后,结果可以重新加载到列表形式中,这也是 foreach
无论如何都应该返回的。类似的东西:
fls <- list.files(intermediate_directory, pattern = '.rda')
result_list <- lapply(fls, function(x) get(eval(load(x)))