36 votes

makePSOCKcluster se bloque sur win x64 après l'appel système

Je suis confronté à un difficile à déboguer problème avec makePSOCKcluster de la parallel paquet sur R x 64 de Windows. Il ne se fait pas sur R i386 sur Windows, ni sur aucun OSX ou Linux. Malheureusement, il ne se produit pas systématiquement non plus, seulement de temps en temps et tout à fait au hasard.

Ce qui se passe, c'est que l' makePSOCKcluster fonction du temps et de figer la R de la session, mais seulement si plus tôt dans la séance, certaines (arbitraire) system() des appels ont été effectués. La vidéo et le script ci-dessous illustrent le problème plus clairement.

Quelques trucs que j'ai essayé sans succès:

  • Désactiver l'antivirus/pare-feu.
  • Attendre quelques secondes entre l'appelant system et makePSOCKcluser.
  • À l'aide de différents appels système.

Comment aurais-je préciser cela? Ici, la vidéo et le script utilisé dans la vidéo est:

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);

2voto

Hack-R Points 1129

makePSOCKCluster, ou, plus généralement, makeCluster, peut accrocher pour n'importe quel nombre de raisons, lors de la création de la soi-disant worker processus, qui implique de commencer de nouvelles R sessions à l'aide de la Rscript de commande qui s'exécute le .slaveRSOCK fonction, ce qui permettra de créer une connexion de socket de retour à la maîtrise et ensuite exécuter le slaveLoop fonction où il sera finalement exécuter les tâches qui lui sont transmises par le maître. Wehen quelque chose se passe mal lors du démarrage d'un des processus de travail, le maître se bloque lors de l'exécution de socketConnection, en attente pour le travailleur de se connecter à elle, même si ce travailleur est mort ou n'a même jamais été créé avec succès.

À l'aide de la outfile argument est grand parce qu'il révèle souvent l'erreur qui provoque le processus de travail de mourir et donc le maître à accrocher. Mais si cela ne révèle rien, puis passez en mode manuel. En mode manuel, le maître des estampes de la commande de lancement de chaque travailleur au lieu de l'exécution de la commande elle-même. C'est plus de travail, mais il vous donne un contrôle complet, et vous pouvez même debug dans les travailleurs, si vous en avez besoin.

Voici un exemple:

> 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 

Ouvrir une nouvelle fenêtre de terminal (invite de commande, ou quoi que ce soit), et collez-le dans que Rscript de commande. Dès que vous avez exécuté, makePSOCKcluster doit retourner depuis que nous avons seulement demandé à un travailleur. Bien sûr, si quelque chose va mal, il ne reviendra pas, mais si vous avez de la chance, vous obtiendrez un message d'erreur dans votre fenêtre de terminal et vous aurez un indice important qui devrait conduire à une solution à votre problème. Si vous n'avez pas cette chance, la Rscript commande aussi accrocher, et vous aurez à plonger encore plus profond.

Pour déboguer le travailleur, vous n'avez pas exécuter l'affiche Rscript commande parce que vous avez besoin d'une session interactive. Au lieu de cela, vous démarrez une session R avec une commande telle que:

$ R --vanille --args MASTER=localhost PORT=10187 OUT=log.txt TIMEOUT=2592000 MÉTHODES=TRUE XDR=TRUE

Dans cette R de la session, vous pouvez mettre un point d'arrêt sur la .slaveRSOCK de la fonction et de l'exécuter:

> debug(parallel:::.slaveRSOCK)
> parallel:::.slaveRSOCK()

Maintenant, vous pouvez commencer à entrer dans le code, éventuellement définir des points d'arrêt sur le slaveLoop et makeSOCKmaster fonctions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X