foreach 执行:无法分配内存,而 RAM 仍然可用
foreach execution: cannot allocate memory, while RAM still available
在我几周前的最后一次 R 更新之前(我现在使用的是 4.1.0 (2021-05-18)),我 运行 在我的 19 个内核上并行执行以下代码(我有一台 Windows 机器,共有 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 控制(本质上,是生成分布的 Monte Carlo 模拟次数)。
尽管如此,根据设计,某些内核将不得不使用比其他内核更大的矩阵(由于影响每个内核的 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 版本是 64 位。如果不是,如果我没记错的话,RAM 分配限制为 4Gb。在 64 位 R 中,分配受可用内存限制。
在 RStudio 中:
工具 > 全局选项 > 常规 > R 版本
过去我的机器(24 核,128 Gb RAM,64 位)在看似随机的时间出于未知原因默认为 32 位 R 时遇到过问题。在全局选项中,我必须手动将 R 版本更改为 64 位以确保它不再发生。
在我几周前的最后一次 R 更新之前(我现在使用的是 4.1.0 (2021-05-18)),我 运行 在我的 19 个内核上并行执行以下代码(我有一台 Windows 机器,共有 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 控制(本质上,是生成分布的 Monte Carlo 模拟次数)。
尽管如此,根据设计,某些内核将不得不使用比其他内核更大的矩阵(由于影响每个内核的 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 版本是 64 位。如果不是,如果我没记错的话,RAM 分配限制为 4Gb。在 64 位 R 中,分配受可用内存限制。
在 RStudio 中: 工具 > 全局选项 > 常规 > R 版本
过去我的机器(24 核,128 Gb RAM,64 位)在看似随机的时间出于未知原因默认为 32 位 R 时遇到过问题。在全局选项中,我必须手动将 R 版本更改为 64 位以确保它不再发生。