如何控制R使用的CPU数量?

时间:2017-12-14 11:08:52

标签: r

我使用the R package crossmatch本身依赖于其他一些R软件包(survival,nbpMatching,MASS),而这些软件包又会导入更多依赖项。 交叉匹配包对(可能)大矩阵实施统计测试,我需要经常计算(在MCMC算法中)。我编写了以下包装器,在计算实际测试之前计算一些预处理步骤(这是最后一行中的crossmatchtest()):

# wrapper function to directly call the crossmatch test with a single matrix
# first column of the matrix must be a binary group indicator, following columns are observations
# code is modified from the documentation of the crossmatch package
crossmatchdata <- function(dat) {

  # the grouping variable should be in the first column
  z = dat[,1]
  X = subset(dat, select = -1)

  ## Rank based Mahalanobis distance between each pair:
  # X <- as.matrix(X)
  n <- dim(X)[1]
  k <- dim(X)[2]

  for (j in 1:k) {
    X[, j] <- rank(X[, j])
  }

  cv <- cov(X)
  vuntied <- var(1:n)
  rat <- sqrt(vuntied / diag(cv))

  cv <- diag(rat) %*% cv %*% diag(rat)
  out <- matrix(NA, n, n)

  icov <- ginv(cv)
  for (i in 1:n) {
    out[i, ] <- mahalanobis(X, X[i, ], icov, inverted = TRUE)
  }

  dis <- out

  ## The cross-match test:
  return(crossmatchtest(z, dis))
}

我注意到如果矩阵相当小,这个测试只会使用一个CPU:

library(MASS)
library(crossmatch)
source("theCodeFromAbove.R")
# create a dummy matrix
m = cbind(c(rep(0, 100), rep(1, 100)))
m = cbind(m, (matrix(runif(100), ncol=10, nrow=20, byrow=T)))
while(TRUE) { crossmatchdata(m) }

通过htop监控。但是,如果我增加这个矩阵,R将使用尽可能多的内核(至少它看起来像这样):

# create a dummy matrix
m = cbind(c(rep(0, 1000), rep(1, 1000)))
m = cbind(m, (matrix(runif(100000), ncol=1000, nrow=2000, byrow=T)))
while(TRUE) { crossmatchdata(m) }

我对这种并行化很不错,但我希望能够手动控制R进程正在使用的核心数量。我试过options(mc.cores = 4)但没有成功。

我可以设置其他变量吗?或者找到负责使用多个核心的软件包的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

让我们看一下依赖项:

library(miniCRAN)
tags <- "crossmatch"
dg <- makeDepGraph(tags, enhances = FALSE, suggests = FALSE)
set.seed(1)
plot(dg, legendPosition = c(-1, 1), vertex.size = 20)

resulting plot of dependencies

这是很多依赖项。乍一看,那里没有用于R级并行化的包。这使得包通过编译代码使用并行化的可能性。一个这样的包是data.table(可能还有其他包),尝试使用setDTthreads(1)关闭并行化。

当然,您可能还将R链接到优化的BLAS。如果是这种情况,那么并行化最有可能发生在矩阵代数中。

<强>更新

@Dirk Eddelbuettel just pointed outRhpcBLASctlOpenMPController允许控制BLAS或OpenMP使用的核心数。

由kartoffelsalat编辑

以下是Ubuntu 16.04下问题中的问题。它在macOS下不起作用(包OpenMPController也没有)。

library(RhpcBLASctl)
blas_set_num_threads(3)