Soumettre des travaux à un noeud esclave à partir d'un script R?
Pour obtenir de l' myscript.R
pour exécuter sur un noeud d'esclave cluster en utilisant un planificateur de tâches (spécifiquement, PBS)
actuellement, je soumets un script R à un noeud esclave en utilisant la commande suivante
qsub -S /bin/bash -p -1 -cwd -pe mpich 1 -j y -o output.log ./myscript.R
y a-t-il des fonctions en R qui me permettraient d'exécuter myscript.R sur le noeud de tête et envoyer des tâches individuelles aux noeuds esclaves? Quelque chose comme:
foreach(i=c('file1.csv', 'file2.csv', pbsoptions = list()) %do% read.csv(i)
mise à jour: la solution alternative à la commande qsub est de supprimer #/usr/bin/Rscript
à partir de la première ligne de myscript.R
et l'appeler directement, comme souligné par @Josh
qsub -S /usr/bin/Rscript -p -1 -cwd -pe mpich 1 -j y -o output.log myscript.R
4 réponses
si vous voulez soumettre des travaux à partir d'un script R, je vous suggère de regarder le paquet "BatchJobs". Voici une citation du fichier de DESCRIPTION:
fournit des variantes de carte, de réduction et de filtrage pour générer des emplois sur les systèmes de calcul par lots comme PBS/Torque, LSF, SLURM et Sun Grid Engine.
BatchJobs semble être plus sophistiqué que les précédents, offres similaires, tels que Rsge et Rlsf. Il y a des fonctions pour enregistrer, soumettre, et récupérer les résultats d'emplois. Voici un exemple simple:
library(BatchJobs)
reg <- makeRegistry(id='test')
batchMap(reg, sqrt, x=1:10)
submitJobs(reg)
y <- loadResults(reg)
vous devez configurer BatchJobs pour utiliser votre système de mise en file d'attente. L'argument "ressource" de submitJobs peut être utilisé pour demander des ressources appropriées pour les emplois.
cette approche est très utile si votre cluster ne permet pas les jobs de très longue durée, ou si elle restreint sévèrement le nombre de jobs de longue durée. BatchJobs vous permet de contourner ces restrictions en fractionnant votre travail en plusieurs emplois tout en cachant la plupart du travail associé à faire cela manuellement.
la Documentation et les exemples sont disponibles à le site web du projet.
pour la plupart de nos travaux, nous exécutons plusieurs sessions R en parallèle en utilisant qsub (à la place).
Si c'est pour de multiples fichiers j'ai l'habitude de faire:
while read infile rest
do
qsub -v infile=$infile call_r.sh
done < list_of_infiles.txt
call_r.sh:
...
R --vanilla -f analyse_file.R $infile
...
analyse_file.R:
args <- commandArgs()
infile=args[5]
outfile=paste(infile,".out",sep="")...
puis je combine toute la sortie après...
le paquet R Rsge permet la soumission de travaux aux clusters gérés par SGE. Il sauve essentiellement l'environnement requis au disque, construit des scripts de soumission de travail, les exécute via qsub et puis rassemble les résultats et les renvoie à vous.
parce qu'il enveloppe fondamentalement les appels à qsub, il devrait fonctionner avec PBS aussi (bien que puisque je ne connais pas PBS, Je ne peux pas le garantir). Vous pouvez modifier la commande qsub et les options utilisées en modifiant les options globales associées à Rsge (préfixé sge. dans options()
sortie)
Sa n'est plus à CRAN, mais il est disponibles à partir de github: https://github.com/bodepd/Rsge, bien qu'il ne ressemble pas à son plus maintenue.
pour l'utiliser, Utilisez l'une des fonctions d'Application type fournies avec le paquet: sge.appliquer , sge.parRapply, sge.parCapply, sge.parLapply et sge.parSapply, qui sont des équivalents parallèles à appliquer, rapply, rapply(t (x),...), lapply et sapply respectivement. En plus de la norme paramètres passés aux fonctions non-parallèles quelques autres paramètres sont nécessaires:
njobs: Number of parallel jobs to use
global.savelist: Character vector giving the names of variables
from the global environment that should be imported.
function.savelist: Character vector giving the variables to save from
the local environment.
packages: List of library packages to be loaded by each worker process
before computation is started.
les deux paramètres savelist et les paramètres packages spécifient essentiellement quelles variables, fonctions et packages doivent être chargés dans les nouvelles instances de R tournant sur les machines cluster avant que votre code ne soit exécuté. Les différentes composantes de X (soit listent des éléments ou des données.frame rows/columns) sont divisés entre les différentes tâches njobs et soumis comme un tableau de tâches à SGE. Chacun node lance une instance de R charge les variables, les fonctions et les paquets spécifiés, exécute le code, sauvegarde et sauvegarde les résultats dans un fichier tmp. L'instance de contrôle R vérifie quand les travaux sont terminés, charge les données des fichiers tmp et réunit les résultats pour obtenir les résultats finaux.
par exemple, calculer une statistique sur un échantillon aléatoire d'une liste de gènes:
library(Rsge)
library(some.bioc.library)
gene.list <- read.delim(“gene.list.tsv”)
compute.sample <- function(gene.list) {
gene.list.sample <- sample(1000, gene.list)
statistic <- some.slow.bioc.function(gene.list.sample)
return (statistic)
}
results <- sge.parSapply(1:10000, function(x) compute.sample,
njobs = 100,
global.savelist = c(“gene.list”),
function.savelist(“compute.sample”),
packages = c(“some.bioc.library”))
si vous aimez envoyer des tâches à des noeuds esclaves alors que vous suivez un script sur le noeud tête, je crois que vos options sont les suivantes:
- pré-affecter tous les noeuds esclaves et eux et les garder en attente quand ils ne sont pas nécessaires (comme je l'ai suggéré dans ma première réponse).
- Lancez de nouveaux travaux lorsque les noeuds esclaves sont nécessaires et demandez-leur de sauvegarder leurs résultats sur le disque. Mettre le processus principal en attente jusqu'à ce que les esclaves ont terminé leurs tâches et puis rassembler leurs les fichiers de sortie.
L'Option 2 est certainement possible mais prendra beaucoup plus de temps à implémenter (Je l'ai fait moi-même plusieurs fois). la réponse de @pallevillesen est à peu près exacte.
réponse originale, avec question mal interprétée
Je n'ai jamais travaillé avec PBS moi-même, mais il semble que vous pouvez l'utiliser pour soumettre des jobs MPI. Vous pourriez avoir besoin de charger un module MPI avant d'exécuter le script R, ayant un script shell le long de ces lignes envoyées à qsub
.
#!/bin/bash
#PBS -N my_job
#PBS -l cput=10:00:00,ncpus=4,mem=2gb
module load openmpi
module load R
R -f myscript.R
vous devriez alors pouvoir utiliser doSNOW
pour exécuter votre foraech
boucle en parallèle.
n.slaves <- 4
library(doSNOW)
cl <- makeMPIcluster(n.slaves)
registerDoSNOW(cl)
foreach(i=c('file1.csv', 'file2.csv'), pbsoptions = list()) %dopar% read.csv(i)