sbatch дублирование задач по узлам вместо распределения задач по узлам в SLURM

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

Вот сильно упрощенная версия пакетного скрипта, который я использую, который дублирует проблему:

---my_job_splitter.sh---
#!/bin/env bash

#SBATCH --job-name Test
#SBATCH --output=%x_%j_%t.csv
#SBATCH --error=log.err
#SBATCH --mail-type=END,FAIL
#SBATCH --nodes=4

#Read the command line input
if [ "$#" -ge 4 ]; then
    numtasks=${1}
    inptrangestart=${2}
    inptrangeend=${3}
    inptrangenum=${4}
fi

#Calculate the size of the chunks to break the range into
chunksize=$((inptrangenum/numtasks))

#Run a separate instance my_program to process each smaller chunk of the input range
for ((ii=0;ii<numtasks;ii++)); do
    stp=`echo "scale=4;($inptrangeend-$inptrangestart)/($inptrangenum-1)" | bc`
    a=`echo "$chunksize*$stp*$ii" | bc`
    b=`echo "$a+($chunksize-1)*$stp" | bc`
    srun my_program.sh $a $b $chunksize &
done

wait

Для наглядности my_program — это просто bash-скрипт, который берет входной диапазон и записывает его в stdout в виде строки csv:

---my_program.sh---
#!/bin/env bash
echo "$1,$2,$3"

Если бы все делало то, что я хочу, то если я запускаю команду sbatch my_job_splitter 32 0 1000 4000, выходной файл должен быть CSV-файлом с 32 записями, каждая с 1/32 диапазона 0:1000, но вместо этого я получаю CSV-файл с 96 записями, и каждая фрагмент диапазона дублируется 3 раза. Я думаю, что понимаю, что происходит - каждый раз, когда я запускаю srun, он видит, что я выделил 3 узла, и предполагает, что мне нужна 1 задача на узел, и поэтому он просто дублирует задачу, пока не назначит 1 задачу каждому узлу - но я не знаю, как это исправить, или это вообще глупый способ сделать это.

Другие вещи, которые я пробовал:

  • Использование флага --exclusive для srun: это просто заставляет srun использовать только один узел и игнорировать другие выделенные узлы.
  • Не использовать srun вообще: похоже, это имеет тот же эффект, что и использование srun --exclusive.

person Beezum    schedule 24.10.2019    source источник
comment
Попробуйте указать srun использовать только один узел (--nodes 1), хотя мне удобнее сообщить SLURM, сколько задач мне нужно, и позволить ему выделить количество узлов, которое он считает подходящим.   -  person Poshi    schedule 24.10.2019
comment
Это также приводит к тому, что он использует только один узел из 4 выделенных. Как и при использовании --ntasks 1, даже когда я также указываю --cpus-per-task 1. Если я укажу только --cpus-per-task 1, то задача будет дублироваться на всех процессорах и на всех узлах.   -  person Beezum    schedule 25.10.2019
comment
Я полагаю, что очевидное решение состоит в том, чтобы просто записать все разделенные входные данные в пронумерованные временные текстовые файлы и использовать массив заданий, но это так уродливо, особенно когда я разбиваю его на 80 или 90. отдельные куски.   -  person Beezum    schedule 25.10.2019
comment
Ну, использование одного узла из 4 — это ожидаемый результат, верно? Вы хотите, чтобы ваш my_program.sh работал на одном узле, верно? С другой стороны, вы можете использовать массив заданий без необходимости создавать промежуточные файлы, о которых вы говорите: просто вычисляйте их информацию на лету.   -  person Poshi    schedule 25.10.2019
comment
Да, я хочу, чтобы любой конкретный экземпляр my_program.sh запускался только один раз на одном узле, но если я выделил, скажем, узлы 1, 2, 3 и 4 для общего задания, а пакетный скрипт выполняется на узле 1, то все экземпляры my_program.sh запускаются на узле 1, а узлы 2, 3 и 4 ничего не делают; или узлы 2, 3 и 4 каждый запускают повторяющиеся экземпляры с дублирующими входными данными тех, которые работают на узле 1. Кажется, нет никакого способа сообщить планировщику, чтобы он поместил 1/4 экземпляров my_program.sh на узел 1, 1/4 из них на узле 2 и т.д.   -  person Beezum    schedule 25.10.2019
comment
Если вы скажете srun запустить задачу в одном узле, остальные будут простаивать, но как только второй srun снова прибудет и будет искать свободный узел, вторая задача будет запущена в одном из трех свободных узлов. То же самое для последующих задач.   -  person Poshi    schedule 26.10.2019
comment
Так что я до сих пор не уверен, что происходит, потому что если у меня есть строка в my_program.sh, которая печатает значение $SLURM_NODEID, все экземпляры по-прежнему печатают один и тот же узел, но если я открою средство просмотра состояния для кластера, оно покажет все выделенных процессоров, даже на разных узлах, как сильно используемых. Так что, похоже, теперь он, по крайней мере, делает то, что я хочу. Я опубликую варианты, которые я использовал в качестве ответа. Спасибо за вашу помощь @Poshi   -  person Beezum    schedule 31.10.2019


Ответы (1)


Итак, в итоге я использовал srun в пакетном сценарии со следующими параметрами:

srun --exclusive --cpus-per-task=1 --ntasks=1 my_program.sh $a $b $chunksize &

Похоже, что все отдельные задачи распределяются по всем выделенным узлам без дублирования.

person Beezum    schedule 31.10.2019