2013-05-15 2 views
2

Можно ли запускать biglm в параллельном режиме? Я пытался использовать doMC, а затем встраивать biglm в цикл foreach, но, похоже, все ядра будут работать над одним и тем же фрагментом данных одновременно. Как я могу распараллелить это?Как использовать biglm с doMC и foreach

library(doMC) 
RegisterDoMC(4) 

require(ffbase) 
sample <- read.table.ffdf(file="sample_output.csv", FUN = "read.csv", na.strings = "") 
library(biglm) 
model<-list() 
biglmupdate<-function(dataset,start,end) { 
if (start==1) { 
    model <<- biglm(a~b+c, data=dataset[start:end,]) 
} 
else { 
    model <<- update(model,dataset[start:end,]) 
} 
} 

chunks <- floor(dim(sample)[1]/220000)+1 
start<-0; end<-0; 
foreach (i = 1: chunks) %dopar% { 
    start = end +1; end =ifelse (i == chunks, dim(sample)[1], start+220000); 
    print(paste("chunk ",i," ",start,":",end," started at:", Sys.time())); 
    biglmupdate(dataset = sample, start, end); 
    print(paste("chunk ",i,"ended at:", Sys.time())); 
} 
+0

Обновление QR-декомпозиции выполняется в коде C & fortran пакета biglm и в настоящее время является последовательным (см. Biglm ::: update.biglm & biglm ::: update.bigqr). Вы можете попросить автора билльма посмотреть, видит ли он возможность разрешать несекретные обновления QR и оценку сэндвича. – jwijffels

ответ

0

Я не очень хорошо знаком с biglm пакетом, но это не кажется, что он может быть легко выполняться параллельно, так как он работает по последовательности обновлений для модели объекта. Петли такого рода принципиально последовательны. Например, вы не можете распараллелить:

i <- 0 
for (i in 1:10) { 
    i <- i + 1 
} 

, имея десять различных процессов каждый добавить 1 к i. Цикл зависит от последовательных обновлений до i. Из того, что я вижу, то же самое можно сказать и о функции biglm.

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

n <- nrow(sample) 
m <- 220000 
foreach(start=seq(1,n,by=m), end=seq(m,n,by=m) %dopar% { 
    # ... 
} 

Значения start и end все предварительно вычисленное, и поэтому нет никаких проблем выполнения цикла параллельно. Я подозреваю, что это решает проблему, которая привела к вашему комментарию, что все ядра работают над одним и тем же фрагментом данных. К сожалению, это не затрагивает фундаментальную проблему параллельного выполнения biglm.

Проблема с model заключается в том, что вы пытаетесь обновить одну из переменных типа от параллельных процессов. При использовании foreach вы должны думать о возврате значения с каждой итерации цикла и обработки их с помощью функции .combine. Наличие тела, изменяющего переменную вне цикла, почти всегда терпит неудачу.

+0

Спасибо, Стив. Я согласен с теми проблемами, которые вы обнаружили. Я поговорил с автором бильярда, и он предложил объединить QR-матрицу от отдельных процессов, которые я пытаюсь расследовать и буду отчитываться. – user1030532