【发布时间】:2021-09-13 18:45:05
【问题描述】:
在几周前我的最后一次 R 更新之前(我现在使用的是 4.1.0 (2021-05-18)),我在我的 19 个内核上并行运行以下代码(我有一台带有总共 24 个虚拟内核和 128 GB RAM 的共享内存)
nport.total.all <- c(seq(10,100,10),seq(200,1000,100))
n.portfolios <- length(nport.total.all)
nsim <- 100000
ncores <- length(nport.total.all)
nruns <- 20
data.VaR.L <- matrix(data = 0,nrow = nruns, ncol = ncores)
data.VaR.E.L.Y <- matrix(data = 0,nrow = nruns, ncol = ncores)
data.VaR.Analytical <- matrix(data = 0,nrow = nruns, ncol = ncores)
library(doParallel)
library(foreach)
library(iterators)
cl <- makePSOCKcluster(names = ncores)
registerDoParallel(cl)
getDoParWorkers()
start_time <- Sys.time()
paralleltest <- foreach(core = 1:ncores) %dopar% {
nport.total <- nport.total.all[core]
alpha.LGD <- 2
beta.LGD <- 3
E.LGD <- (alpha.LGD / (alpha.LGD + beta.LGD))
Var.LGD <- (alpha.LGD * beta.LGD) / ( (alpha.LGD+beta.LGD)^2 *(alpha.LGD + beta.LGD + 1) )
EAD <- rep(x = 1000, times = nport.total)
w.i <- EAD/sum(EAD)
min.PD <- 0.0005
max.PD <- 0.018
mean.PD <- (min.PD + max.PD) / 2
PD <- rep(x = mean.PD, times = nport.total)
c <- qnorm(PD)
Rho.PD <- 0.12 * ( (1-exp(-50*PD)) / (1-exp(-50)) ) + 0.24 * ( 1 - ( (1-exp(-50*PD)) / (1-exp(-50)) ) )
alpha <- 0.999
for (run in 1:nruns) {
# /!\ EMPIRICAL PART /!\ DISTRIBUTION OF L
Y <- matrix(data = rnorm(nsim), nrow = nport.total, ncol = nsim, byrow = TRUE)
Z.Default <- matrix(data = rnorm(nsim * nport.total), nrow = nport.total, ncol = nsim, byrow = FALSE)
LGD.Basel <- matrix(data = rbeta(n = (nsim * nport.total), shape1 = alpha.LGD, shape2 = beta.LGD, ncp = 0), nrow = nport.total, ncol = nsim)
X.Default <- sqrt(Rho.PD) * Y + sqrt(1 - (Rho.PD)) * Z.Default
rm(Z.Default)
gc()
Default <- 1 * (X.Default < c)
Basel.Rel.Loss <- w.i * LGD.Basel * Default
Basel.Port.Rel.Loss <- apply(Basel.Rel.Loss, 2, sum)
Ecdf.Basel.Port.Rel.Loss <- ecdf(Basel.Port.Rel.Loss)
VaR.Rel.Port.Basel <- as.numeric(quantile(x = Ecdf.Basel.Port.Rel.Loss, prob = alpha))
rm(Default,Basel.Rel.Loss,LGD.Basel)
gc()
##########################################################################################################################################################################
# /!\ EMPIRICAL PART /!\ DISTRIBUTION OF E[L|Y]
PD.Conditional <- pnorm( (qnorm(PD) - sqrt(Rho.PD) * Y) / sqrt(1-Rho.PD) )
Basel.E.cond.portfolio.loss.i <- w.i * E.LGD * PD.Conditional
Basel.E.cond.portfolio.loss <- apply(Basel.E.cond.portfolio.loss.i, 2, sum)
Ecdf.Basel.E.cond.portfolio.loss <- ecdf(Basel.E.cond.portfolio.loss)
VaR.Basel.E.cond.portfolio.loss <- as.numeric(quantile(x = Ecdf.Basel.E.cond.portfolio.loss, prob = alpha))
rm(PD.Conditional,Basel.E.cond.portfolio.loss.i)
gc()
##########################################################################################################################################################################
# /!\ ANALYTICAL FORMULAS /!\
VaR.Ana.Quantile.Basel_i <- w.i * E.LGD * pnorm((qnorm(PD)-sqrt(Rho.PD)*qnorm(1-alpha)) / sqrt(1-Rho.PD))
VaR.Ana.Quantile.Basel <- sum(VaR.Ana.Quantile.Basel_i)
##########################################################################################################################################################################
# SAVE THE GENERATED VAR
data.VaR.L[run,core] <- VaR.Rel.Port.Basel
data.VaR.E.L.Y[run,core] <- VaR.Basel.E.cond.portfolio.loss
data.VaR.Analytical[run,core] <- VaR.Ana.Quantile.Basel
rm(Y)
gc()
}
return(list(data.VaR.L,data.VaR.E.L.Y,data.VaR.Analytical))
}
end_time <- Sys.time()
time.sim <- end_time - start_time
stopCluster(cl)
并行化策略如下:
- 要求 19 个内核。
- 在这 19 个内核中的每一个上都运行许多顺序操作。这些顺序操作的大小由变量 nsim(本质上是生成分布的蒙特卡罗模拟次数)控制。
尽管如此,根据设计,某些内核必须使用比其他内核更大的矩阵(由于影响每个内核的 nport.total 值不同)。后者在早期的模拟中从未真正成为问题,它只是意味着要“完成自身”,整个过程将不得不等待“最后的核心”。
在我上次更新 R 之前,我能够增加/减少 nsim 值,这要归功于我的 RAM 可用性。但是,如果没有以下错误消息之一(取决于我介绍的 nsim),我目前无法增加 nsim:
Error in { : task 17 failed - "cannot allocate vector of size 610.4 Mb"
我很难理解 R 引擎下发生了什么/可能发生了什么变化...当我通过任务管理器检查我的计算机资源使用情况时,我仍然有很多可用的 RAM:
直觉上是这样
- R 不再被允许/无法访问整个 RAM。
- 我并行化的每个 CPU 都不允许访问整个 RAM(因此存在 CPU 无法共享整个 RAM 的问题)。
有人遇到过类似的问题吗?
【问题讨论】:
-
检查你的内存构成,它是你的内存使用时间线下方的一个栏。我曾经有一个类似的问题。内存使用有点误导。它有时不考虑应用程序的保留内存。试着执行你的计算并观察酒吧。你可能会发现突然有一个新的类别占据了所有的内存。这些是 R-Subprocesses 保留内存,但不使用它。因此,您的 Ram 可能比您想象的更承受压力。
标签: r foreach parallel-processing out-of-memory doparallel