我正在使用
the R package crossmatch,它本身依赖于其他一些R包(生存,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进程正在使用的核心数量.我尝试了选项(mc.cores = 4)但没有成功.
我可以设置其他变量吗?或者找到负责使用多个核心的软件包的最佳方法是什么?
最佳答案 我们来看看依赖项:
library(miniCRAN)
tags <- "crossmatch"
dg <- makeDepGraph(tags, enhances = FALSE, suggests = FALSE)
set.seed(1)
plot(dg, legendPosition = c(-1, 1), vertex.size = 20)
这是很多依赖.乍一看,那里没有用于R级并行化的包.这使得包通过编译代码使用并行化的可能性.一个这样的包是data.table(可能还有其他包),尝试使用setDTthreads(1)关闭并行化.
当然,您可能还将R链接到优化的BLAS.如果是这种情况,那么并行化最有可能发生在矩阵代数中.
更新:
包装RhpcBLASctl和OpenMPController的@Dirk Eddelbuettel just pointed out允许控制BLAS或OpenMP使用的核心数量.
由kartoffelsalat编辑:
以下是Ubuntu 16.04下问题中的问题.它在macOS下不起作用(包OpenMPController也没有).
library(RhpcBLASctl)
blas_set_num_threads(3)