Я пытаюсь использовать GNU параллельно для проведения серии экспериментов с использованием MATLAB на нашем суперкомпьютере, который использует SLURM. У меня есть текстовый файл, содержащий комбинации из 4 параметров, которые считываются и передаются в функцию MATLAB. Этот текстовый файл называется gnu_parameters.txt и имеет 4 столбца, разделенных одним пробелом.
fs_method data_name use_vars 1
fs_method1 data_name use_vars 1
fs_method3 data_name use_vars 1
где параметры в столбцах 1–3 следует считывать как строку, а параметр 4 — число.
Я хочу запускать каждую комбинацию параметров параллельно, чтобы ускорить процесс. Мой сценарий SLURM приведен ниже, но когда я говорю GNU-parallel, куда поместить каждый параметр, используя обозначение {1} {2} {3} {4}, я получаю сообщение об ошибке, что MATLAB не распознает переменную fs_method. Просмотр журнала говорит мне, что ошибка означает, что MATLAB не читает как строку. Чтобы это исправить, я попробовал добавить одинарные кавычки в сценарий SLURM следующим образом:
#!/bin/bash -l
#SBATCH --time=4-00:00:00
#SBATCH --ntasks=1
#SBATCH --mem=1200g
#SBATCH --tmp=500g
#SBATCH --cpus-per-task=115
#SBATCH --mail-type=FAIL,END
#SBATCH --mail-user=myemail
#SBATCH -p groupPartition
cd $WRK_DIR
module load matlab
module load parallel
export JOBS_PER_NODE=$(( $SLURM_CPUS_ON_NODE / $SLURM_CPUS_PER_TASK ))
echo $JOBS_PER_NODE
cat gnu_parameters.txt | parallel --jobs $JOBS_PER_NODE --joblog tasklog.log --progress --colsep ' ' 'matlab -nodisplay -r "run_holdout_parallel('{1}', '{2}', '{3}', {4});exit" '
Ниже приведены выдержки из файла журнала, файла ошибок и выходного файла.
Бревно
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
1 : 1719498346.300 14.911 0 298 0 0 matlab -nodisplay -r "run_holdout_parallel(fs_method, data_name, use_vars, 1);exit"
2 : 1719498361.751 14.387 0 298 0 0 matlab -nodisplay -r "run_holdout_parallel(fs_method1, data_name, use_vars, 1);exit"
3 : 1719498376.666 14.385 0 298 0 0 matlab -nodisplay -r "run_holdout_parallel(fs_method3, data_name, use_vars, 1);exit"
Файл ошибок
local:1/0/100%/0.0s sh: /dev/tty: No such device or address
local:1/0/100%/0.0s sh: /dev/tty: No such device or address
local:1/0/100%/0.0s {Unrecognized function or variable 'fs_method'.
}
local:0/1/100%/15.0s
Выходной файл
< M A T L A B (R) >
Copyright 1984-2023 The MathWorks, Inc.
R2023b Update 7 (23.2.0.2515942) 64-bit (glnxa64)
January 30, 2024
To get started, type doc.
For product information, visit www.mathworks.com.
< M A T L A B (R) >
Copyright 1984-2023 The MathWorks, Inc.
R2023b Update 7 (23.2.0.2515942) 64-bit (glnxa64)
January 30, 2024
To get started, type doc.
For product information, visit www.mathworks.com.
Но это возвращает ту же ошибку. Как я могу передать эти параметры в виде строк в MATLAB? Есть ли лучший способ провести эти эксперименты параллельно, чем тот метод, который я использую?
@CrisLuengo Да, я отредактировал свой вопрос, включив их.
Ага, понятно. Возможно, вам придется избежать кавычек. run_holdout_parallel(\'{1}\',
@CrisLuengo Хорошая мысль. Я попробовал это и получил синтаксическую ошибку /var/spool/slurmd/job19168324/slurm_script: line 16: syntax error near unexpected token `)'` . Я думаю, что проблема в синтаксисе этих кавычек. Я не эксперт в bash :/
Да, кавычки в bash я всегда делаю методом проб и ошибок, я их правда не понимаю. Я думаю, что часть {1} должна быть за пределами одинарных кавычек. Но вам нужны одинарные кавычки для передачи в MATLAB. Так может быть что-то вроде run_holdout_parallel(\''{1}'\',?
В настоящее время в журнале вы видите, что выполняется команда matlab -nodisplay -r "run_holdout_parallel(fs_method, data_name, use_vars, 1);exit". Вам нужно настроить bash-скрипт так, чтобы это стало matlab -nodisplay -r "run_holdout_parallel('fs_method', 'data_name', 'use_vars', 1);exit". Иногда кавычки необходимо экранировать дважды (\\\'), если они проходят два этапа интерпретации bash. Не спрашивай...
Очевидно, вы не можете избежать одинарных кавычек. Вот обходной путь: stackoverflow.com/a/1250279/7328782 -- Так что, я думаю, будет run_holdout_parallel('"'"{1}"'"',.
@CrisLuengo казалось, что это сработало, но в файле журнала ничего не отображается. Может быть, просто нужно время...





Проблема в том, как экранируются кавычки. Способ, который работает для меня, это
'matlab -nodisplay -r "run_holdout_parallel(\\\"{1}\\\", \\\"{2}\\\", \\\"{3}\\\", {4});exit" '
Почему-то воспользовавшись ответом в комментариях
'matlab -nodisplay -r "run_holdout_parallel('"'"{1}"'"', '"'"{2}"'"', '"'"{3}"'"', {4});exit" '
работал нормально, но команды не выполнялись.
Несколько советов, которые не дают прямого ответа на ваш вопрос, но могут быть полезны для более эффективного выполнения вашей работы.
parfor, чтобы масштабировать свою работу до вашего кластера.parpool('local') на узле, выделенном вам SLURM.matlab -r для подобных вещей.Я ненавижу цитировать. man parallel говорит:
Вывод: если это сбивает с толку, подумайте о том, чтобы избежать необходимости иметь дело с кавычками, написав небольшой скрипт или функцию (не забудьте экспортировать -f функцию) и использовать параллельный вызов GNU.
Итак, в вашем случае создайте функцию:
run_holdout() {
echo This should run_holdout_parallel on $1 $2 $3 $4
matlab -nodisplay -r "run_holdout_parallel(\"$1\", \"$2\", \"$3\", $4);exit"
}
Когда вы можете запустить это в командной строке:
$ run_holdout fs_method3 data_name use_vars 1
и это работает, затем распараллелите с:
$ export -f run_holdout
$ ... | parallel run_holdout {1} {2} {3} {4}
Спасибо, это очень хорошо работает и легче читается!
Можете ли вы поделиться соответствующим разделом журнала и/или выводом консоли?