【问题标题】:Saving within a foreach loop (R package)?在 foreach 循环(R 包)中保存?
【发布时间】:2015-02-10 07:06:26
【问题描述】:

我正在使用 foreach 包使用 HPC 并行运行蒙特卡罗模拟。我对 foreach 返回我想要的结果没有任何问题,但我想知道是否可以定期保存工作区。我问的原因是我必须指定一个壁挂时间(在此之后作业终止),所以我冒险 1. 设置壁挂时间太低并在 foreach 循环完成并保存我的输出之前丢失所有内容或 2. 设置一个保守的walltime 和浪费我的配额。理想情况下,我希望能够定期保存我的输出,在这种情况下,如果作业终止,我仍然有数据。

例如:

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'是空的,大概是因为'results'只有在foreach循环完成后才生成。在 foreach 循环完成之前,有什么方法可以访问和保存这些数据?感谢您的帮助。

【问题讨论】:

  • 你可以将 res1 和 res2 转储到文件中,这样就够了吗?
  • 您使用的是什么后端? doParallel?
  • @Steve 我使用 doMC 作为后端。
  • @Laurik 如果可能的话,我宁愿保存而不是写,但感谢您的建议 - 如果我不能使用保存,这绝对是一个选择。
  • @yidryi 是的,但您也可以 save() 特定变量而不是整个图像。也许值得一试?

标签: r parallel-processing parallel-foreach


【解决方案1】:

我有一个与这个非常相似的问题,并使用 cmets 中提到的save() 方法解决了它。具体来说,我喜欢在处理大型数据集时间歇性地“保存”我的进度,这样我就不会在出现问题时浪费计算资源(例如,墙上时间用完)。我个人发现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)))

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 2016-02-07
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多