Отправить задания в подчиненный node из R script? - программирование

Отправить задания в подчиненный node из R script?

Чтобы получить myscript.R для запуска на подчиненном кластере node с помощью планировщика заданий (в частности, PBS)

В настоящее время я передаю R script ведомому node, используя следующую команду

qsub -S /bin/bash -p -1 -cwd -pe mpich 1 -j y -o output.log ./myscript.R

Существуют ли функции в R, которые позволят мне запускать myscript.R на голове node и отправлять отдельные задачи на подчиненные узлы? Что-то вроде:

foreach(i=c('file1.csv', 'file2.csv', pbsoptions = list()) %do% read.csv(i)

Обновление: альтернативное решение для команды qsub - удалить #/usr/bin/Rscript из первой строки myscript.R и вызвать ее напрямую, как указано @Josh

qsub -S /usr/bin/Rscript -p -1 -cwd -pe mpich 1 -j y -o output.log myscript.R
4b9b3361

Ответ 1

Если вы хотите отправить задания из R script, я предлагаю вам посмотреть пакет "BatchJobs". Вот цитата из файла DESCRIPTION:

Предоставляет варианты "Карта", "Уменьшить" и "Фильтровать" для создания заданий в таких вычислительных системах, как PBS/Torque, LSF, SLURM и Sun Grid Engine.

BatchJobs выглядит более сложным, чем предыдущие аналогичные пакеты, такие как Rsge и Rlsf. Существуют функции для регистрации, отправки и получения результатов заданий. Вот простой пример:

library(BatchJobs)
reg <- makeRegistry(id='test')
batchMap(reg, sqrt, x=1:10)
submitJobs(reg)
y <- loadResults(reg)

Вам нужно настроить BatchJobs для использования вашей системы периодического обслуживания. Аргумент ресурса submitJobs может использоваться для запроса соответствующих ресурсов для заданий.

Этот подход очень полезен, если ваш кластер не позволяет выполнять очень длительные рабочие задания или сильно ограничивает количество длительно работающих заданий. BatchJobs позволяет обойти эти ограничения, разбив вашу работу на несколько заданий, скрывая большую часть работы, связанной с этим, вручную.

Документация и примеры доступны на веб-сайте проекта.

Ответ 2

Для большей части нашей работы мы запускаем несколько сеансов R параллельно, используя qsub (вместо этого).

Если это для нескольких файлов, которые я обычно делаю:

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="")...

Затем я объединяю все выходные данные...

Ответ 3

R-пакет Rsge позволяет отправлять задания в управляемые кластеры SGE. Он в основном сохраняет требуемую среду на диске, строит сценарии отправки задания, выполняет их через qsub, а затем сопоставляет результаты и возвращает их вам.

Поскольку он в основном обертывает вызовы qsub, он также должен работать с PBS (хотя, поскольку я не знаю PBS, я не могу этого гарантировать). Вы можете изменить команду qsub и параметры, используемые для изменения глобальных параметров, связанных с Rsge (prefixed sge. В выводе options())

Его больше нет в CRAN, но он доступен из github: https://github.com/bodepd/Rsge, хотя он не похож на его поддерживаемый Больше.

Чтобы использовать его, используйте одну из применяемых функций типа, поставляемых с пакетом: sge.apply, sge.parRapply, sge.parCapply, sge.parLapply и sge.parSapply, которые являются параллельными эквивалентами для применения, рэплом, rapply (t (x),...), соответственно. В дополнение к стандартным параметрам, переданным непараллельным функциям, требуется еще пара параметров:

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.

Два параметра savelist и параметры пакетов в основном определяют, какие переменные, функции и пакеты должны быть загружены в новые экземпляры R, запущенные на машинах кластера, прежде чем ваш код будет выполнен. Различные компоненты X (элементы списка или строки/столбцы data.frame) делятся между njob разными заданиями и передаются в качестве массива заданий в SGE. Каждый node запускает экземпляр R, который загружает указанные переменные, функции и пакеты, выполняет код, сохраняет и сохраняет результаты в файле tmp. Контролирующий экземпляр R проверяет, когда задания завершены, загружает данные из файлов tmp и объединяет результаты для получения окончательных результатов.

Например, вычисление статистики по случайной выборке списка генов:

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

Ответ 4

Если вам нравится отправлять задания на подчиненные узлы, когда вы идете вместе с script на голове node, я считаю, что ваши параметры следующие:

  • Предварительно назначьте все подчиненные узлы и их и сохраните их в режиме ожидания, когда они не понадобятся (как я предложил в своем первом ответе).
  • Запуск новых заданий, когда нужны подчиненные узлы, и сохранить их результаты на диске. Переведите основной процесс на удержание, пока подчиненные не выполнили свои задачи, а затем не соберите выходные файлы.

Вариант 2 определенно возможен, но потребуется намного больше времени для выполнения (я сам делал это несколько раз). Ответ на @pallevillesen в значительной степени зависит от.

Оригинальный ответ, с вопросом о непонятном вопросе

Я никогда не работал с PBS самостоятельно, но, похоже, вы можете использовать его для отправки заданий MPI. Возможно, вам придется загрузить модуль MPI перед выполнением R script, имея оболочку script вдоль этих строк, отправленных на 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

Затем вы можете использовать doSNOW для параллельного выполнения цикла foraech.

n.slaves <- 4

library(doSNOW)
cl <- makeMPIcluster(n.slaves)
registerDoSNOW(cl)

foreach(i=c('file1.csv', 'file2.csv'), pbsoptions = list()) %dopar% read.csv(i)