windows - org - r cran linux
makePSOCKcluster se cuelga en win x64 después de llamar al sistema (1)
Estoy experimentando un problema difícil de depurar con makePSOCKcluster
desde el paquete parallel
en R x64 en Windows. No ocurre en R i386 en Windows, ni en ningún OSX o Linux. Desafortunadamente, tampoco ocurre de manera constante, solo ocasionalmente y de forma bastante aleatoria.
Lo que ocurre es que la función makePSOCKcluster
y congela la sesión R, pero solo si anteriormente en la sesión se realizaron algunas llamadas al system()
arbitrarias). El video y el script a continuación ilustran el problema más claramente.
Algunas cosas que intenté sin éxito:
- Deshabilitar antivirus / firewalls.
- Esperando un par de segundos entre llamar al
system
ymakePSOCKcluser
. - Usando diferentes llamadas al sistema.
¿Cómo podría estrechar aún más esto? Aquí el video y el script utilizado en el video es:
cmd_exists <- function(command){
iswin <- identical(.Platform$OS.type, "windows");
if(iswin){
test <- suppressWarnings(try(system(command, intern=TRUE, ignore.stdout=TRUE, ignore.stderr=TRUE, show.output.on.console=FALSE), silent=TRUE));
} else {
test <- suppressWarnings(try(system(command, intern=TRUE, ignore.stdout=TRUE, ignore.stderr=TRUE), silent=TRUE));
}
!is(test, "try-error")
}
options(hasgit = cmd_exists("git --version"));
options(haspandoc = cmd_exists("pandoc --version"));
options(hastex = cmd_exists("texi2dvi --version"));
cluster <- parallel::makePSOCKcluster(1);
makePSOCKCluster
, o más generalmente makeCluster
, puede colgarse por cualquier cantidad de razones al crear los llamados procesos de worker
, lo que implica comenzar nuevas sesiones R utilizando el comando Rscript que ejecutará la función .slaveRSOCK, que creará una conexión de socket de nuevo a la master y luego ejecute la función slaveLoop donde finalmente ejecutará las tareas que le envíe el maestro. Cuando algo va mal al iniciar cualquiera de los procesos de trabajo, el maestro se bloquea mientras se ejecuta socketConnection, esperando que el trabajador se conecte aunque el trabajador haya muerto o nunca se haya creado correctamente.
Usar el argumento de archivo de salida es excelente porque a menudo revela el error que causa la muerte del proceso de trabajo y, por lo tanto, la ejecución del maestro. Pero si eso no revela nada, entonces ve al modo manual. En el modo manual, el maestro imprime el comando para iniciar cada trabajador en lugar de ejecutar el comando. Es más trabajo, pero te da un control total, e incluso puedes depurar a los trabajadores si es necesario.
Aquí hay un ejemplo:
> library(parallel)
> cl <- makePSOCKcluster(1, manual=TRUE, outfile=''log.txt'')
Manually start worker on localhost with
''/usr/lib/R/bin/Rscript'' -e ''parallel:::.slaveRSOCK()'' MASTER=localhost
PORT=10187 OUT=log.txt TIMEOUT=2592000 METHODS=TRUE XDR=TRUE
Luego abra una nueva ventana de terminal (símbolo del sistema, o lo que sea), y pegue ese comando Rscript. Tan pronto como lo haya ejecutado, makePSOCKcluster debería regresar ya que solo solicitamos un trabajador. Por supuesto, si algo sale mal, no volverá, pero si tienes suerte, recibirás un mensaje de error en la ventana de tu terminal y tendrás una pista importante que con suerte conducirá a una solución a tu problema. . Si no tienes tanta suerte, el comando Rscript también se bloqueará, y tendrás que sumergirte aún más profundo.
Para depurar al trabajador, no ejecuta el comando Rscript que se muestra porque necesita una sesión interactiva. En cambio, comienza una sesión R con un comando como:
$ R --vanilla --args MASTER = localhost PORT = 10187 OUT = log.txt TIMEOUT = 2592000 MÉTODOS = VERDADERO XDR = VERDADERO
En esa sesión R, puede poner un punto de interrupción en la función .slaveRSOCK y luego ejecutarlo:
> debug(parallel:::.slaveRSOCK)
> parallel:::.slaveRSOCK()
Ahora puede comenzar a recorrer el código, posiblemente estableciendo puntos de corte en las funciones de esclavo y makeSOCKmaster.