Определите количество времени, выделенное для пакетного задания в SLURM - PullRequest
0 голосов
/ 16 марта 2019

Время выделения для пакетного задания можно указать в команде sbatch для slurm.Например, следующие запросы 1 день, 3 минуты и 10 секунд:

$ sbatch -t 1-0:3:10 test.sh

Мой сценарий должен знать, как долго он будет работать, чтобы он мог сохранить все свои данные перед завершением.Переменные среды, доступные для задания, перечисленные на справочной странице sbatch , не включают ограничение времени выделения.

Как определить это в скрипте?

Сейчас я прошу у администратора очередей ограничение по времени текущей работы:

#!/bin/sh
squeue -j $SLURM_JOB_ID -o "%l"

, что дает

TIME_LIMIT
1-00:04:00

Я анализирую вывод, используя следующее:

#!/bin/bash

TIMELIMIT=`squeue -j $SLURM_JOB_ID -o "%l" | tail -1`
echo Time limit $TIMELIMIT

if [[ $TIMELIMIT == *-* ]]; then
    IFS='-' read -ra DAYS_HOURS <<< $TIMELIMIT
    DAYS=${DAYS_HOURS[0]}
    PART_DAYS=${DAYS_HOURS[1]}
else
    DAYS=0
    PART_DAYS=$TIMELIMIT
fi
if [[ $HOURS == *:*:* ]]; then
    IFS=':' read -ra HMS <<< $PART_DAYS
    H=${HMS[0]}
    M=${HMS[1]}
    S=${HMS[2]}
else
    IFS=':' read -ra HMS <<< $PART_DAYS
    H=0
    M=${HMS[0]}
    S=${HMS[1]}
fi

SECONDS=`echo "((($DAYS*24+$H)*60+$M)*60+$S)" | bc`
echo Time limit: $SECONDS seconds

HOURS=`echo "scale=3;((($DAYS*24+$H)*60+$M)*60+$S)/3600." | bc`
echo Time limit: $HOURS hours

что дает

Time limit 1-00:04:00
Time limit: 86404 seconds
Time limit: 24.001 hours

Есть ли более чистый способ сделать это?

1 Ответ

1 голос
/ 16 марта 2019

Несколько вещей.

Если вы используете proctrack / cgroup, вы можете перехватить сигнал SIGTERM, который отправляется, когда истекает срок.Это дает вам настраиваемое количество времени для сохранения состояния;SIGKILL отправляется после секунд KillWait, настроенных в slurm.conf.Однако, это трудно сделать, если вы используете proctrack / linuxproc, потому что он отправляет SIGTERM всем процессам, а не только сценарию bash.Примерно так:

#!/bin/bash
function sigterm {
    echo "SIGTERM"
    #save state
}
trap sigterm TERM

srun work.sh &

# This loop only breaks when all subprocesses exit
until wait; do :; done

Это может быть сложно, если вы до сих пор никогда не улавливали сигналы в bash.С помощью proctrack / cgroup SIGTERM отправляется в основной процесс каждого шага задания и в пакетный скрипт.Так что выше, work.sh также должен перехватывать SIGTERM.Также выше, bash не перехватывает сигнал до тех пор, пока не завершатся подпроцессы, если вы не справитесь с ними;следовательно, '&' и цикл ожидания.

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

sbatch --export=ALL,TIMELIMIT=1-0:3:10 -t1-0:3:10 test.sh

Досадно, вы должны указать ограничение по времени дважды.

Запрос контроллера squeue не является ужасным решением.Однако в масштабе тысячи запросов к контроллеру могут повлиять на производительность.Обратите внимание, что вы можете использовать флаг --noheader, чтобы не печатать TIME_LIMIT каждый раз, вместо использования tail.

По сути, именно для этого и был разработан KillWait, поэтому вы должны рассмотреть возможность его использования, если по какой-то причине вы не можете.https://slurm.schedmd.com/slurm.conf.html

Лучшим ответом может быть использование опции --signal для sbatch.Это позволяет отправлять настраиваемый сигнал на задание за определенное время до истечения срока.

sbatch --signal=B:USR1@120 myscript.sh

Приведенный выше пример отправляет USR1 в пакетный скрипт примерно за 2 минуты до конца задания.Как отмечено в справочной странице, разрешение составляет 60 секунд, поэтому сигнал можно отправить на 60 секунд раньше.

...