如何使用lapply复现mclapply生成的完全相同随机数
问题说明
以下R并行代码可正常运行:
library(parallel) RNGkind("L'Ecuyer-CMRG") set.seed(100) mclapply(1:4, function(i) rnorm(1))
该代码并行运行的随机数输出符合预期,但如果直接把mclapply替换为串行版本的lapply,生成的随机数结果会发生变化,无法和并行运行的结果保持一致,需要找到串行模式下复现并行结果的方案。
解决方案
结果不一致的核心原因是:当使用L'Ecuyer-CMRG随机数生成器时,mclapply默认预调度模式下不会使用全局环境的连续随机数序列,而是会为每一个任务分支提前分配独立的随机数子流。要在串行模式下完全复现结果,只需要手动复刻这一子流分配逻辑即可,代码如下:
library(parallel) RNGkind("L'Ecuyer-CMRG") set.seed(100) result <- list() # 记录set.seed之后的初始随机数种子状态 current_rng_seed <- .Random.seed for (idx in 1:4) { # 为当前任务加载对应子流的种子 .Random.seed <- current_rng_seed result[[idx]] <- rnorm(1) # 推进到下一个任务对应的子流种子,和mclapply内部逻辑完全对齐 current_rng_seed <- nextRNGStream(current_rng_seed) } print(result)
运行上述串行代码得到的随机数结果,和原mclapply并行代码的输出完全一致。
提示:上述复现逻辑仅对
mclapply默认参数mc.preschedule=TRUE生效,如果设置了mc.preschedule=FALSE,子流分配规则会发生变化,需要对应调整种子推进逻辑。
内容的提问来源于stack exchange,提问作者Mike Zhang
相关产品推荐
相关产品推荐

