замена `srun` - PullRequest
       21

замена `srun`

0 голосов
/ 16 января 2019

Я пытаюсь создать функцию, которая заменяет команду SLURM srun. Потребность в этой функции-обертке заключается в том, что я хочу кодифицировать скрипт, используя srun, когда он запускается под управлением SLURM, но все еще может запускать скрипт без SLURM.

Пока у меня есть эта функция:

srun_wrap() {
    if [ -z "$SLURM_JOB_ID" ]
    then
        # Not running under SLURM so start the code without srun
        "${@:2}"
    else
        # A SLURM job ID found, so use srun
        srun ${@:1:1} "${@:2}"
    fi
}

Это позволяет мне преобразовать строку как

srun --job-name listing ls

на строку типа

srun_wrapper "--job-name listing" ls

Совсем близко к раскрытию, но пока нет.

Рациональное это:

  • Проверьте переменную $SLURM_JOB_ID для некоторого значения
    • Если в переменной нет значения, это означает, что мы не находимся под SLURM, и мы должны запустить команду без srun. Расширение скобки игнорирует первый аргумент (srun параметры) и запускает остальную часть командной строки.
    • Если есть какое-то значение, это означает, что мы находимся в распределении SLURM, поэтому используйте srun. Командная строка состоит из srun, первый параметр без кавычек , позволяющий srun правильно идентифицировать параметры и, наконец, настоящая командная строка, правильно заключенная в кавычки.

У этого подхода есть два недостатка:

  1. Параметры srun в расширении скобок должны быть заключены в кавычки, иначе они не правильно обработан srun.
  2. Параметры srun при вызове должны передаваться в кавычках, чтобы их можно было рассматривать как один параметр.
  3. Я вынужден всегда передавать параметр обертке, даже пустой. srun ls будет переведено в srun_wrapper "" ls.

Есть идеи, как преодолеть эти три недостатка? Как заключить в скобки расширение, как избежать цитирования параметров srun и как избежать необходимости пустого параметра?

1 Ответ

0 голосов
/ 24 февраля 2019

Это то, что я придумал. Мастер оболочки мог бы, вероятно, сделать лучше. Это решает все ваши недостатки?

У этого есть новые недостатки, над которыми я работаю. Флаги не могут иметь пробелов. Поэтому вы должны использовать их так: srun_wrap --ntasks=2 ls или srun_wrap -n2 ls.

Вызовы echo и вызов функции в конце предназначены только для отладки.

#!/bin/bash

function srun_wrap {
        i=1
        for var in "$@"; do
                # args starting with '-' up to the first that doesn't are srun
                # flags. The rest of the args are the command
                if [[ $var == -* ]]; then
                        flags=( "${flags[@]}" "$var" )
                else
                        cmd="${@:$i}"
                        break
                fi
                i=$((i+1))
        done
        echo "flags = $flags"
        echo "cmd = $cmd"

        if [ "x$SLURM_JOB_ID" != "x" ]; then
                # run in slurm
                eval "srun ${flags[@]} ${cmd[@]}"
        else
                # run outside slurm
                eval "${cmd[@]}"
        fi
}

srun_wrap "$@"

Чтобы обойти проблему флагов, вы можете определить флаг самостоятельно (например, --cmd или что-то в этом роде), который отделяет флаги srun от исполняемого файла.

srun_wrap --ntasks 2 --exclusive --cmd ls -alh

Или вы можете быть более явным, например sbatch, и создать флаг --wrap=<command>, который вы анализируете сами. Вы должны были бы процитировать это, хотя.

srun_wrap --ntasks 2 --exclusive --wrap="ls -alh"

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

...