Могу ли я использовать mpiexec для запуска одного и того же исполняемого файла с разными аргументами командной строки для исполняемого файла каждый раз?
Я новичок в распределенной операционной системе. И мне нужно потренироваться о нескольких моделях машинного обучения с суперкомпьютерами. Мне нужно запустить один и тот же сценарий обучения несколько раз, и для каждого запуска передать сценарий с другим аргументом командной строки. Могу ли я достичь этого с помощью mpiexec, чтобы я мог тренировать несколько моделей параллельно с разными входами?
Я нашел модель данных с одной программой и несколькими программами mpi, но я не знаю соответствующих команд.
Я хочу запустить следующую строку параллельно между вычислительными узлами в кластере.
python train.py arg > log.out # arg is the argument that differs for each node
Но, если я использую:
mpiexec train.py arg >log.out
он будет запускать train.py только с одним и тем же аргументом командной строки: arg несколько раз параллельно.
Может кто-нибудь указать правильный способ сделать это? Спасибо!
2 ответа
Один из способов добиться того, чего вы хотите - это создать скрипт верхнего уровня, mpi_train.py
используя mpi4py. В задании MPI каждый процесс имеет уникальный ранг и все выполняют один и тот же код, поэтому
from mpi4py import MPI
comm = MPI.COMM_WORLD
print("Hello! I'm rank " + str(comm.rank))
с
mpiexec -n 4 python mpi_train.py
дам
Hello! I'm rank 0
Hello! I'm rank 1
Hello! I'm rank 3
Hello! I'm rank 2
Различные ранги могут затем использоваться для чтения отдельного файла, в котором указаны аргументы. Так что у вас будет что-то вроде
#All code in train should be in functions or __name__ == "__main__"
import train
from mpi4py import MPI
def get_command_args_from_rank(rank):
#Some code here to get args from unique rank no.
comm = MPI.COMM_WORLD
args = get_command_args_from_rank(comm.rank)
#Assuming the args can be passed to a run function
out = train.run(args)
Обратите внимание, что вы должны явно указать выходные данные для каждого процесса, например,
with open("log.out"+str(comm.rank)) as f:
f.write(out)
в противном случае все отпечатки отправляются на стандартный вывод и перемешиваются, поскольку порядок различных процессов не гарантируется.
Спасибо за все комментарии и ответы. Вот что я сделал, чтобы получить окончательное решение:
Сначала у меня был скрипт bash для отправки задания в кластер в виде массива заданий, с $PBS_ARRAYID для передачи разных аргументов командной строки каждому заданию:
#PBS -N ondemand/sys/myjobs/default
#PBS -l walltime=24:10:00
#PBS -l file=1gb
#PBS -l nodes=1:ppn=1:gpus=1:default
#PBS -l mem=40MB
#PBS -j oe
#PBS -A PAS0108
#PBS -o Job_array.out
# Move to the directory where the job was submitted
# run the following cmd in shell to submit the job in an array
# qsub -t 1-6 myjob.sh
cd $PBS_O_WORKDIR
cd $TMPDIR
# $PBS_ARRAYID can be used as a variable
# copy data to local storage of the node
cp ~/code/2018_9_28_training_node_6_OSC/* $TMPDIR
cp -r ~/Datasets_1/Processed/PascalContext/ResNet_Output/ $TMPDIR
cp -r ~/Datasets_1/Processed/PascalContext/Truth/ $TMPDIR
cp -r ~/Datasets_1/Processed/PascalContext/Decision_Tree/ $TMPDIR
# currently in $TMPDIR, load modules
module load python/3.6 cuda
# using $PBS_ARRAYID as a variable to pass the corresponding node ID
python train_decision_tree_node.py $PBS_ARRAYID $TMPDIR > training_log_${PBS_ARRAYID}
# saving logs
cp training_log ${HOME}/logs/${PBS_ARRAYID}_node_log/
cp my_results $PBS_O_WORKDIR
Я отправляю приведенный выше скрипт с командной строкой:
qsub -t 1-6 myjob.sh
Но я получил ошибку от кластера, как-то локальный каталог $TMPDIR
не может быть распознан фактическим узлом в кластере, когда я запускаю скрипт.
Наконец, я использовал скрипт bash верхнего уровня для отправки каждого задания с другим аргументом командной строки в цикле while, и это сработало:
run_multiple_jobs.tcsh:
#!/usr/bin/env tcsh
set n = 1
while ( $n <= 5 )
echo "Submitting job for concept node $n"
qsub -v NODE=$n job.pbs
@ n++
end
jobs.pbs:
#PBS -A PAS0108
#PBS -N node_${NODE}
#PBS -l walltime=160:00:00
#PBS -l nodes=1:ppn=1:gpus=1
#PBS -l mem=5GB
#PBS -m ae
#PBS -j oe
# copy data
cp -r ~/Datasets/Processed/PascalContext/Decision_Tree $TMPDIR
cp -r ~/Datasets/Processed/PascalContext/Truth $TMPDIR
cp -r ~/Datasets/Processed/PascalContext/ResNet_Output $TMPDIR
# move to working directory
cd $PBS_O_WORKDIR
# run program
module load python/3.6 cuda/8.0.44
python train_decision_tree_node.py ${NODE} $TMPDIR $HOME
# run with run_multiple_jobs.tcsh script