2017-02-05 2 views
2

Je cours une fonction en parallèle. Afin d'obtenir des mises à jour sur l'état d'avancement du travail, j'aimerais qu'un travailleur, mais un seul, fasse rapport périodiquement sur ses progrès. Ma pensée naturelle pour ce faire serait d'avoir la fonction que les travailleurs exécutent vérifier le nom du travailleur, et seulement donner la mise à jour de statut si le nom correspond à une valeur particulière. Mais, je ne peux pas trouver un moyen fiable de le déterminer à l'avance. Dans Julia par exemple, il existe une fonction simple myid() qui donnera l'ID d'un travailleur (c'est-à-dire 1, 2, etc.). Je cherche quelque chose d'équivalent en R. Le meilleur que j'ai trouvé jusqu'ici est d'avoir chaque travailleur appelez Sys.getpid(). Mais, je ne connais pas un moyen fiable d'écrire mon script pour savoir à l'avance quel serait l'un des pids assignés à un travailleur. Le script de fonctionnalités de base que je suis à la recherche d'écrire ressemble le ci-dessous, à l'exception que je suis à la recherche de l'équivalent de R à la fonction myid():R - Obtenir le nom du travailleur lorsqu'il est exécuté en parallèle

library(parallel) 

Test_Fun = function(a){ 
    for (idx in 1:10){ 
     Sys.sleep(1) 
     if (myid() == 1){ 
      print(idx) 
     } 
    } 
} 

mclapply(1:4, Test_Fun, mc.cores = 4) 

Répondre

1

Le paquet parallel ne fournit pas une fonction d'identification des travailleurs à partir de R 3.3.2. Il n'y a pas non plus de mécanisme prévu pour initialiser les travailleurs avant qu'ils commencent à exécuter des tâches.

Je vous suggère de transmettre un argument d'ID de tâche supplémentaire à la fonction de travail en utilisant la fonction mcmapply. Si le nombre de tâches est égal au nombre de travailleurs, l'ID de tâche peut être utilisé comme ID de travailleur. Par exemple:

library(parallel) 
Test_Fun = function(a, taskid){ 
    for (idx in 1:10){ 
     Sys.sleep(1) 
     if (taskid == 1){ 
      print(idx) 
     } 
    } 
} 
mcmapply(Test_Fun, 1:4, 1:4, mc.cores = 4) 

Mais s'il y a plus de tâches que les travailleurs, vous ne verrez que les messages de progression pour la première tâche. Vous pouvez contourner ce problème en initialisant chacun des travailleurs lorsqu'ils exécutent leur première tâche:

WORKERID <- NA # indicates worker is uninitialized 
Test_Fun = function(a, taskid){ 
    if (is.na(WORKERID)) WORKERID <<- taskid 
    for (idx in 1:10){ 
     Sys.sleep(1) 
     if (WORKERID == 1){ 
      print(idx) 
     } 
    } 
} 
cores <- 4 
mcmapply(Test_Fun, 1:8, 1:cores, mc.cores = cores) 

Notez que cela suppose que mc.preschedule est TRUE, qui est la valeur par défaut. Si mc.preschedule est FALSE et que le nombre de tâches est supérieur au nombre de travailleurs, la situation est beaucoup plus dynamique car chaque tâche est exécutée par un processus de travail différent et les travailleurs ne s'exécutent pas tous simultanément.