R 的并行包加载库的 RAM 使用过多

Hir*_*rek 5 parallel-processing r

在某些机器上,在所有内核上加载软件包会占用所有可用 RAM,从而导致错误 137 并且我的 R 会话被终止。在我的笔记本电脑 (Mac) 和 Linux 计算机上,它运行良好。在我想要运行它的 Linux 计算机上,它没有 32 核和 32 * 6GB RAM。系统管理员告诉我计算节点上的内存是有限的。然而,根据我在下面的编辑,我的记忆需求并没有超出任何想象。

我如何调试它并找出不同之处?我是这个parallel包的新手。

这是一个示例(假设该命令install.packages(c(“tidyverse”,”OpenMx”))已在 4.0.3 版的 R 中运行):

我还注意到,这似乎只适用于OpenMxmixtools包。我mixtools从 MWE 中排除,因为OpenMx足以产生问题。tidyverse单独工作正常。

我尝试过的一种解决方法是不在集群上加载包,而只是.libPaths("~/R/x86_64-pc-linux-gnu-library/4.0/")在 of 的主体中进行评估 exprclusterEvalQ并像OpenMx::vec在我的函数中一样使用命名空间命令,但这会产生相同的错误。所以我被卡住了,因为在三台机器中的两台上它运行良好,只是不在我应该使用的一台(计算节点)上。

.libPaths("~/R/x86_64-pc-linux-gnu-library/4.0/")
library(parallel)
num_cores <- detectCores()
cat("Number of cores found:") 
print(num_cores)
working_mice <- makeCluster(num_cores) 
clusterExport(working_mice, ls())
clusterEvalQ(working_mice, expr = {
  library("OpenMx")
  library("tidyverse")
  })
Run Code Online (Sandbox Code Playgroud)

通过简单地加载包,它似乎消耗了所有可用的 RAM,从而导致错误 137。这是一个问题,因为我需要在每个可用内核中加载库,它们的功能正在执行任务。

随后,我正在使用DEoptim但加载包足以产生错误。

编辑

我已经使用分析了代码profmem,发现示例代码中的部分需要大约 2MB 的内存,而我试图运行的整个脚本需要 94.75MB。然后,我还使用我的操作系统(Catalina)进行了检查,并捕获了屏幕截图中显示的以下过程。

这些数字都没有让我觉得过多,尤其是在每个 CPU 约 6GB 和 32 个内核的节点上。除非,我在这里遗漏了一些重要的东西。

内存信息

Jus*_*dis 2

首先我想说我不确定是什么原因导致了您出现这个问题。以下示例可以帮助您调试每个子进程使用了​​多少内存。

使用包mem_used中的pryr内容将帮助您跟踪 R 会话使用了多少 RAM。下面显示了在我的 8 核和 16 GB RAM 的本地计算机上执行此操作的结果。

library(parallel)
library(tidyr)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(ggplot2)
num_cores <- detectCores()
cat("Number of cores found:") 
#> Number of cores found:
print(num_cores)
#> [1] 8
working_mice <- makeCluster(num_cores) 
clusterExport(working_mice, ls())
clust_memory <- clusterEvalQ(working_mice, expr = {
  start <- pryr::mem_used()
  library("OpenMx")
  mid <- pryr::mem_used()
  library("tidyverse")
  end <- pryr::mem_used()
  data.frame(mem_state = factor(c("start","mid","end"), levels = c("start","mid","end")),
             mem_used = c(start, mid, end), stringsAsFactors = F)
})

to_GB <- function(x) paste(x/1e9, "GB")

tibble(
  clust_indx = seq_len(num_cores),
  mem = clust_memory
) %>%
  unnest(mem) %>% 
  ggplot(aes(mem_state, mem_used, group = clust_indx)) +
  geom_line(position = 'stack') +
  scale_y_continuous(labels = to_GB) #approximately
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,每个进程在我的机器上使用大约相同数量的 RAM ~ 160MG。根据pryr::mem_used(),每个步骤后每个核心使用的 RAM 量始终相同library

无论您在什么环境中工作,我都建议您仅在 10 个工作线程上执行此操作,看看它是否使用了合理的内存量。

我还向 top 确认htop,所有子进程仅使用大约 4.5 GB 的虚拟内存以及每个大约相似数量的 RAM。

我唯一能想到的可能是这个问题clusterExport(working_mice, ls())。仅当您不在新的 R 会话中执行此操作时,这才会成为问题。例如,如果您的全局环境中有 5 GB 的数据,则每个套接字都将获得一个副本。