2011-01-22 22 views
16

Estoy intentando utilizar foreach para hacer computación multinúcleo en R.no pudo encontrar la función dentro del bucle foreach

A <-function(....) { 
    foreach(i=1:10) %dopar% { 
    B() 
    } 
} 

entonces la función A en la consola llaman. El problema es que estoy llamando a una función Posdef dentro de B que está definida en otro archivo de script que yo procedo. Tuve que poner Posdef en la lista de argumentos exportación de foreach: .export=c("Posdef"). Sin embargo, aparece el siguiente error:

Error in { : task 3 failed - "could not find function "Posdef"" 

¿Por qué R no puede encontrar esta función definida?

+1

recomendaría la búsqueda de información en relación con el ámbito dinámico con R. No es en absoluto intuitivo y encontrará una gran cantidad de preguntas en detalle para que las personas que tienen problemas al definir una función dentro de una función. –

+0

Agradeceríamos un ejemplo reproducible. Además, ¿has probado las nevadas para el multicorchar? Encuentro que es más intuitivo y fácil de adaptar (modificación de funciones de aplicación). –

+0

mismo problema, no se encontró ninguna respuesta simple por el momento. Me las arreglé para hacerlo funcionar llamando a 4 núcleos foreach (j = 1: N, .combine = rbind, .packages = c (VECTOR DE PAQUETES NECESARIO PARA LLAMAR TODAS SUS FUNCIONES))% dopar% fun (j). Mejora la velocidad, pero no se divide por 4 (solo por 2) No estoy seguro de lo que hago, así que no replique esto ... – RockScience

Respuesta

7

La respuesta corta es que se trataba de un error en backends paralelas como doSNOW , doParallel y doMPI, pero desde entonces se ha solucionado.

La respuesta un poco más larga es que foreach exporta funciones a los trabajadores que usan un entorno especial de "exportación", no el entorno global. Eso solía causar problemas para las funciones que se crearon en el entorno global, porque el entorno de "exportación" no estaba en su alcance, a pesar de que ahora se definían en el mismo entorno de "exportación". Por lo tanto, no pudieron ver ninguna otra función o variable definida en el entorno de "exportación", como "Posdef" en su caso.

Los doSNOW, doParallel y doMPI backends ahora cambian el medio ambiente asociados de lo global con el medio ambiente "exportación" de las funciones exportadas a través de ".export", y parece haber resuelto estos problemas.

11

Para que pueda reproducir este, para los curiosos:

require(doSNOW) 
registerDoSNOW(makeCluster(5, type="SOCK")) 
getDoParWorkers() 
getDoParName() 
getDoParVersion() 

fib <- function(n) { 
    if (n <= 1) { return(1) } 
    return(fib(n-1) + fib(n-2)) 
} 

my.matrix <- matrix(runif(2500, 10, 50), nrow=50) 

calcLotsaFibs <- function() { 
    result <- foreach(row.num=1:nrow(my.matrix), .export=c("fib", "my.matrix")) %dopar% { 
    return(Vectorize(fib)(my.matrix[row.num,])) 
    } 
    return(result) 
} 

lotsa.fibs <- calcLotsaFibs() 

he podido conseguir evitar esto poniendo la función en otro archivo y cargar ese archivo en el cuerpo del foreach. También podría mover la definición de la función al cuerpo del foreach mismo.

[EDIT - Me habían sugerido previamente que quizás .export no funciona correctamente con los nombres de función, pero se corrigió a continuación.]

+1

".export" puede tomar nombres de funciones. Este es un ejemplo interesante, sin embargo, ya que creo que el problema es que el error ocurre cuando 'fib' hace una llamada recursiva a sí mismo, ya que' fib' no está en su propio ámbito, como explico en mi respuesta. –

+0

¿Quiere decir que podría funcionar si envolvemos la función personalizada en un paquete R? – agenis

0

solución rápida para un problema con foreach% dopar% es volver a instalar estos paquetes:

install.packages("doSNOW") 

install.packages("doParallel") 

install.packages("doMPI") 

trabajó en mi caso.

Cuestiones relacionadas