2014-06-20 7 views
13

Ho provato a fare funzionare il seguente codice su una macchina Unix con 20 CPU, utilizzando R foreach, parallel, doParallel, e party pacchetti (il mio obiettivo è quello di avere la funzione party/varimp lavorando su diversi CPU in parallelo):Errore in unserialize (socklist [[n]]): errore di lettura dal collegamento su Unix

parallel_compute_varimp <- function (object, mincriterion = 0, conditional = FALSE, threshold = 0.2, 
    nperm = 1, OOB = TRUE, pre1.0_0 = conditional) 
{ 
    response <- [email protected] 
    input <- [email protected]@get("input") 
    xnames <- colnames(input) 
    inp <- initVariableFrame(input, trafo = NULL) 
    y <- [email protected]@variables[[1]] 
    error <- function(x, oob) mean((levels(y)[sapply(x, which.max)] != y)[oob]) 

    w <- [email protected] 
    perror <- matrix(0, nrow = nperm * length([email protected]), ncol = length(xnames)) 
    colnames(perror) <- xnames 

    data = foreach(b = 1:length([email protected]), .packages = c("party","stats"), .combine = rbind) %dopar% 
    { 
     try({ 
      tree <- [email protected][[b]] 
      oob <- [email protected][[b]] == 0 

      p <- .Call("R_predict", tree, inp, mincriterion, -1L, PACKAGE = "party") 

      eoob <- error(p, oob) 

      for (j in unique(varIDs(tree))) { 
       for (per in 1:nperm) { 
        if (conditional || pre1.0_0) { 
         tmp <- inp 
         ccl <- create_cond_list(conditional, threshold, xnames[j], input) 
         if (is.null(ccl)) { 
         perm <- sample(which(oob)) 
         } 
         else { 
         perm <- conditional_perm(ccl, xnames, input, tree, oob) 
         } 
         [email protected][[j]][which(oob)] <- [email protected][[j]][perm] 
         p <- .Call("R_predict", tree, tmp, mincriterion, -1L, PACKAGE = "party") 
        } 
        else { 
         p <- .Call("R_predict", tree, inp, mincriterion, as.integer(j), PACKAGE = "party") 
        } 
        perror[b, j] <- (error(p, oob) - eoob) 
       } 
      } 

      ######## 
      # return data to the %dopar% loop data variable 
      perror[b, ] 
      ######## 

     }) # END OF TRY 
    } # END OF LOOP WITH PARALLEL COMPUTING 

    perror = data 
    perror <- as.data.frame(perror) 
    return(MeanDecreaseAccuracy = colMeans(perror)) 
} 

environment(parallel_compute_varimp) <- asNamespace('party') 


cl <- makeCluster(detectCores()) 
registerDoParallel(cl, cores = detectCores()) 
<...> 
system.time(data.cforest.varimp <- parallel_compute_varimp(data.cforest, conditional = TRUE)) 

ma sto ottenendo un errore:

> system.time(data.cforest.varimp <- parallel_compute_varimp(data.cforest, conditional = TRUE)) 
Error in unserialize(socklist[[n]]) : error reading from connection 
Timing stopped at: 58.302 13.197 709.307 

il codice è stato lavorare con un set di dati più piccola di 4 CPU.

io sono a corto di idee. Qualcuno può suggerire un modo per raggiungere il mio obiettivo di correre funzione varimp pacchetto partito su CPU parallelo?

+0

Hai capire questo problema? – Zach

+0

Io non la penso così. Ho dimenticato tutto comunque :) – tucson

risposta

16

L'errore:

Error in unserialize(socklist[[n]]) : error reading from connection 

significa che il processo maestro ottenuto un errore quando si chiama unserialize a leggere dalla connessione socket a uno degli operai. Questo probabilmente significa che il corrispondente lavoratore è morto, lasciando cadere così la sua estremità della connessione socket. Sfortunatamente, potrebbe essere morto per un numero qualsiasi di ragioni, molte delle quali sono molto specifiche del sistema.

di solito si può capire perché l'operaio è morto utilizzando il makeCluster "OUTFILE" opzione in modo che il messaggio di errore generato dal lavoratore non si butta via. Io di solito consiglia di utilizzare outfile="" come descritto in this answer. Nota che l'opzione "outfile" funziona allo stesso modo sia nei pacchetti neve che in quelli paralleli.

Si potrebbe anche verificare che il ciclo foreach funziona correttamente quando eseguito in modo sequenziale registrando il backend sequenziale:

registerDoSEQ() 

Se siete fortunati, il ciclo foreach avrà esito negativo quando viene eseguito in sequenza, dal momento che di solito è più facile capire cosa sta andando storto.

Problemi correlati