수색…


비고

원격 기계의 병렬 처리는 각 기계에 라이브러리를 다운로드해야합니다. package::function() 호출을 선호합니다. 몇몇 패키지는 기본적으로 caret , plsplyr 포함하여 병렬 처리가 내장되어 있습니다.

Microsoft R Open (Revolution R)은 본질적으로 많은 공통 기능을 병렬화하는 멀티 스레드 BLAS / LAPACK 라이브러리를 사용합니다.

foreach 패키지로 병렬 처리

foreach 패키지는 병렬 처리 기능을 R에 제공합니다. 그러나 멀티 코어 CPU를 사용하기 전에 멀티 코어 클러스터를 할당해야합니다. doSNOW 패키지는 한 가지 가능성이 있습니다.

foreach 루프의 간단한 사용은 제곱근과 1에서 100000까지의 모든 숫자의 제곱의 합을 계산하는 것입니다.

library(foreach)
library(doSNOW)

cl <- makeCluster(5, type = "SOCK")
registerDoSNOW(cl)

f <- foreach(i = 1:100000, .combine = c, .inorder = F) %dopar% {
    k <- i ** 2 + sqrt(i)
    k
} 

foreach 의 출력 구조는 .combine 인수에 의해 제어됩니다. 기본 출력 구조는 목록입니다. 위의 코드에서 c 는 벡터를 반환하는 데 사용됩니다. "+" 와 같은 계산 함수 (또는 연산자)는 계산을 수행하고 추가로 처리 된 객체를 반환하는 데 사용될 수도 있습니다.

foreach-loop의 결과가 마지막 호출임을 언급하는 것이 중요합니다. 따라서이 예제에서는 k 가 결과에 더해진다.

매개 변수 세부
.콤바인 기능을 결합하십시오. 루프의 결과를 결합하는 방법을 결정합니다. 가능한 값은 c , cbind , rbind , "+" , "*" ...입니다.
.inorder TRUE 이면 반복 가능한 순서 (여기에서 i )에 따라 결과가 정렬됩니다. FALSE 이면 결과가 정렬되지 않습니다. 이것은 계산 시간에 영향을 미칠 수 있습니다.
패키지 base , 예를 들어 mass , randomForest 또는 그 밖의 다른 패키지가 제공하는 함수의 경우 이러한 패키지에 c("mass", "randomForest") 를 제공해야합니다.

병렬 패키지로 병렬 처리

기본 패키지 parallel 은 분기, 소켓 및 난수 생성을 통한 병렬 계산을 허용합니다.

localhost에있는 코어의 수를 감지합니다.

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

localhost에 코어 클러스터를 만듭니다.

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

첫째, 병렬화에 적합한 함수가 생성되어야한다. mtcars 데이터 세트를 고려하십시오. cyl 각 레벨에 대해 개별 회귀 모델을 작성하면 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 패키지는 par 시작하는 전체 apply() 패밀리를 포함합니다.

난수 생성

병렬화의 주요 문제점은 RNG를 시드로 사용한다는 점입니다. 숫자에 의한 임의의 숫자는 세션 시작 또는 가장 최근의 set.seed() 에서의 작업 수에 의해 반복됩니다. 병렬 프로세스는 동일한 함수에서 발생하므로 동일한 시드를 사용하여 동일한 결과를 초래할 수 있습니다! 전화가 다른 코어에서 연속적으로 실행되므로 이점이 없습니다.

일련의 시드를 생성하여 각 병렬 프로세스로 보내야합니다. 이것은 일부 패키지 ( parallel , snow 등)에서 자동으로 수행되지만 다른 패키지에서는 명시 적으로 처리해야합니다.

s <- seed
for (i in 1:numofcores) {
    s <- nextRNGStream(s)
    # send s to worker i as .Random.seed
}

종자는 또한 재현성을 위해 설정할 수 있습니다.

clusterSetRNGStream(cl = parallelcluster, iseed)

mcparallelDo

mcparallelDo 패키지는 Unix (Linux 및 MacOSX 등) 운영 체제에서 R 코드를 비동기 적으로 평가할 수 있도록합니다. 패키지의 기본 철학은 코딩보다는 탐색 데이터 분석의 필요성과 일치합니다. 비동기 코딩의 경우 future 패키지를 고려하십시오.

데이터 작성

data(ToothGrowth)

포크에서 분석을 수행하려면 mcparallelDo를 트리거하십시오.

mcparallelDo({glm(len ~ supp * dose, data=ToothGrowth)},"interactionPredictorModel")

다른 일을하십시오.

binaryPredictorModel <- glm(len ~ supp, data=ToothGrowth)
gaussianPredictorModel <- glm(len ~ dose, data=ToothGrowth)

mcparallelDo의 결과는 targetEnvironment (예 : .GlobalEnv)에서 메시지가 완료되면 반환됩니다 (기본적으로).

summary(interactionPredictorModel)

다른 예

# Example of not returning a value until we return to the top level
for (i in 1:10) {
  if (i == 1) {
    mcparallelDo({2+2}, targetValue = "output")
  }
  if (exists("output")) print(i)
}

# Example of getting a value without returning to the top level
for (i in 1:10) {
  if (i == 1) {
    mcparallelDo({2+2}, targetValue = "output")
  }
  mcparallelDoCheck()
  if (exists("output")) print(i)
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow