並行處理並行處理

基礎包 parallel 允許通過分叉,套接字和隨機數生成進行平行計算。

檢測 localhost 上存在的核心數:

parallel::detectCores(all.tests = FALSE, logical = TRUE)

在 localhost 上建立核心叢集:

parallelCluster <- parallel::makeCluster(parallel::detectCores())

首先,必須建立適合並行化的函式。考慮 mtcars 資料集。通過為每個級別的 tihuan 建立單獨的迴歸模型,可以改善對 mpg 的迴歸。

data <- mtcars
yfactor <- 'cyl'
zlevels <- sort(unique(data[[yfactor]]))
datay <- data[,1]
dataz <- data[,2]
datax <- data[,3:11]

fitmodel <- function(zlevel, datax, datay, dataz) {
  glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}

建立一個可以迴圈遍歷 zlevels 所有可能迭代的函式。這仍然是序列的,但它是一個重要的步驟,因為它確定了將並行化的確切過程。

fitmodel <- function(zlevel, datax, datay, dataz) {
  glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}

for (zlevel in zlevels) {
  print("*****")
  print(zlevel)
  print(fitmodel(zlevel, datax, datay, dataz))
}

咖哩這個功能:

worker <- function(zlevel) {
    fitmodel(zlevel,datax, datay, dataz)
  }

使用 parallel 進行平行計算無法訪問全域性環境。幸運的是,每個功能都創造了 parallel 可以訪問的本地環境。建立包裝函式允許並行化。要應用的功能也需要放在環境中。

wrapper <- function(datax, datay, dataz) {
  # force evaluation of all paramters not supplied by parallelization apply
  force(datax)
  force(datay)
  force(dataz)
  # these variables are now in an enviroment accessible by parallel function
  
  # function to be applied also in the environment
  fitmodel <- function(zlevel, datax, datay, dataz) {
    glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
  }
  
  # calling in this environment iterating over single parameter zlevel
  worker <- function(zlevel) {
    fitmodel(zlevel,datax, datay, dataz)
  }
  return(worker) 
}

現在建立一個叢集並執行包裝器函式。

parallelcluster <- parallel::makeCluster(parallel::detectCores())
models <- parallel::parLapply(parallelcluster,zlevels,
                              wrapper(datax, datay, dataz))

完成後始終停止群集。

parallel::stopCluster(parallelcluster)

parallel 套裝包括整個 apply() 系列,字首為 par