2015-12-01 2 views
3

В настоящее время я работаю с некоторыми большими наборами данных, поэтому распараллеливание рабочих процессов - единственный путь.Параллельное вычисление: загрузка пакетов в каждый поток только один раз

нужно загрузить несколько пакетов для каждого потока один раз в начале (то есть:. for(this.thread in threads) { #load some packages }

К сожалению, я не знаю, как это сделать

Следующий код иллюстрирует мою проблему. , где я пытаюсь использовать оператор трубы из magrittr в %dopar%:.

library(parallel) 
library(doParallel) 
library(foreach) 
library(magrittr) 


# Generate some random data and function : 
# ----------------------------------------- 

randomData = runif(10^3) 
randomFunction = function(x) {x * (2^x) } 

randomData[1] %>% randomFunction #Works 



# And now ... The parallel part : 
# -------------------------------- 

myCluster = makeCluster(6) 
registerDoParallel(myCluster) 


# Test that the do par is up and running: 
foreach(i = randomData) %dopar% { i } 


# Use magrittr pipe operator: 
# Error in { : task 1 failed - "could not find function "%>%"" 
foreach(i = randomData) %dopar% { i %>% randomFunction } 


# Load the library at each loop: (ie: length(data) times !) 
# Other than unnecessarily loading the library (length(data) - numberOfThreads) times, 
# it works nicely 
foreach(i = randomData) %dopar% { library(magrittr); i %>% randomFunction } 


# Now try without re-loading: 
# Tararaa - (ie: Works nicely) 
foreach(i = randomData) %dopar% { i %>% randomFunction } 

.

Любые идеи?

+0

@ VeerendraGadekar, я создал некоторые случайные данные в приведенном выше скрипте. Моя проблема заключается в том, что * not * не работает в параллельных циклах. Я пытаюсь избежать загрузки пакетов n раз, где n = длина моих больших данных. Надеюсь, что это еще раз пояснит. –

+3

Два вызова библиотеки() примерно так же дорогостоящие, как один (R проверяет, загружена ли библиотека, и если это так ничего не делает), так что не нужно потеть. Пойдите с вашим решением «это прекрасно работает». –

+0

Спасибо за ваш комментарий @VeerendraGadekar. На самом деле, моя проблема не связана конкретно с magrittr или с оператором труб, а с концепцией в целом. Например, я использую некоторые функции интерполяции из некоторых пакетов. Я использую magrittr здесь только для иллюстрации. –

ответ

4

Пакет doParallel наследует некоторые удобные функции низкого уровня от parallel, включая clusterCall, который выполняет функцию один раз на каждом узле.

У меня была точно такая же проблема и решить ее, выполнив:

library(doParallel) 
myCluster = makeCluster(6) 
registerDoParallel(myCluster) 
clusterCall(myCluster, function() library(magrittr)) 

Вы также можете использовать аргумент .packages:

foreach(i = randomData, .packages = "magrittr") %dopar% {require("magrittr"); i %>% randomFunction } 
+0

Отлично! Не знал об этом! Спасибо @ mkemp6! –

-1

Вы можете попробовать это:

foreach(i = randomData,.packages=c("magrittr")) %dopar% { 
    i %>% randomFunction 
} 
Смежные вопросы