Параллельно обрабатывать группу файлов, а затем вычислять последовательно с использованием slurm - PullRequest
1 голос
/ 14 мая 2019

Мне нужно преобразовать каждый файл в определенном каталоге, а затем скомпилировать результаты в одно вычисление в системе, используя slurm. Работа над каждым отдельным файлом занимает столько же времени, сколько и остальные коллективные вычисления. Поэтому я бы хотел, чтобы отдельные обращения происходили одновременно. Последовательно, это то, что мне нужно сделать:

main.sh

#!/bin/bash
#SBATCH --account=millironx
#SBATCH --time=1-00:00:00
#SBATCH --ntasks=32
#SBATCH --cpus-per-task=4

find . -maxdepth 1 -name "*.input.txt" \
  -exec ./convert-files.sh {} \;

./compile-results.sh *.output.txt

./compute.sh

echo "All Done!"

convert-files.sh

#!/bin/bash
# Simulate a time-intensive process
INPUT=${1%}
OUTPUT="${$INPUT/input.txt/output.txt}"
sleep 10
date > $OUTPUT

Пока эта система работает, я обычно обрабатываю пакеты из 30+ файлов, и время вычислений превышает ограничение по времени, установленное администратором при использовании только одного узла. Как я могу обрабатывать файлы параллельно, а затем компилировать и вычислять их после полной обработки?

Что я пробовал / считал

Добавление srun к find -exec

find . -maxdepth 1 -name "*.input.txt" \
  -exec srun -n1 -N1 --exclusive ./convert-files.sh {} \;

find -exec ожидает блокирования процессов , а srun блокирует , так что это делает то же самое, что и базовый код по времени.

Использование sbatch в скрипте отправки

find . -maxdepth 1 -name "*.input.txt" \
  -exec sbatch ./convert-files.sh {} \;

Это не ожидает завершения преобразований перед началом вычислений, и, следовательно, они терпят неудачу.

Использование GNU параллельно

find . -maxdepth 1 -name "*.input.txt" | \
  parallel ./convert-files.sh

OR

find . -maxdepth 1 -name "*.input.txt" | \
  parallel srun -n1 -N1 --exclusive ./convert-files.sh

параллель может «видеть» только количество процессоров на текущем узле, поэтому обрабатывает только четыре файла одновременно. Лучше, но все же не то, что я ищу.

Использование массивов заданий

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

Отправка заданий отдельно с использованием sbatch

На терминале:

$ find . -maxdepth 1 -name "*.input.txt" \
>  -exec sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
>  ./convert-files.sh {} \;

Пять часов спустя:

$ srun --account=millironx --time=30:00 --cpus-per-task=4 \
>   ./compile-results.sh *.output.txt & \
>   sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
>   ./compute.sh

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

Использование sbatch с зависимостью

На терминале:

$ find . -maxdepth 1 -name "*.input.txt" \
>  -exec sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
>  ./convert-files.sh {} \;
Submitted job xxxx01
Submitted job xxxx02
...
Submitted job xxxx45
$ sbatch --account=millironx --time=30:00 --cpus-per-task=4 \
>   --dependency=after:xxxx45 --job-name=compile_results \
>   ./compile-results.sh *.output.txt & \
>   sbatch --account=millironx --time=05:00:00 --cpus-per-task=4 \
>   --dependency=after:compile_results \
>   ./compute.sh

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


Кажется, это должно быть так легко сделать, но я пока не понял этого.

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Способ find . -maxdepth 1 -name "*.input.txt" | parallel srun -n1 -N1 --exclusive ./convert-files.sh, вероятно, тот, которому нужно следовать. Но, похоже, ./convert-files.sh ожидает имя файла в качестве аргумента, и вы пытаетесь протолкнуть его до stdin через канал. Вам нужно использовать xargs, и, поскольку xargs может работать параллельно, вам не нужна команда parallel.

Попробуйте:

find . -maxdepth 1 -name "*.input.txt" | xargs -L1 -P$SLURM_NTASKS srun -n1 -N1 --exclusive ./convert-files.sh

-L1 будет разделять результат find на строку и передавать его в convert.sh, вызывая максимум $SLURM_NTASKS процессов за раз, и «отправлять» каждый из них в ЦП на узлах, выделенных Slurm благодаря srun -n1 -N1 --exclusive.

1 голос
/ 14 мая 2019

Если ваши $SLURM_NODELIST содержат что-то похожее на node1,node2,node34, то это может сработать:

find ... | parallel -S $SLURM_NODELIST convert_files
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...