我想并行化下面的 bash 脚本中的 for 循环。
我有两个 Matlab 脚本
1) 主.m
clear
rng default
P=2;
grid=randn(2,3);
jobs=1;
2) 调频
sgetasknum_grid=grid(jobs*(str2double(getenv('SGE_TASK_ID'))-1)+1: str2double(getenv('SGE_TASK_ID'))*jobs,:); %jobsx3
result=sgetasknum_grid+1;
filename = sprintf('result.%d.mat', ID);
save(filename, 'result')
exit
我想做的事:
我想运行 main.m;
然后,我想跑两次调频在平行下
一切都应该在节点上执行A
这是我的版本没有并行化
1)我将 main.m 和 fm 保存到名为 My_folder 的文件夹中
2)我如下创建 bash 文件 td.sh 并将其保存到文件夹 My_folder 中
#$ -S /bin/bash
#$ -l h_vmem=5G
#$ -l tmem=5G
#$ -l h_rt=480:0:0
#$ -cwd
#$ -j y
#$ -N try
date
hostname
export SGE_TASK_ID
for SGE_TASK_ID in {1..2}
do
#Output the Task ID
echo "Task ID is $SGE_TASK_ID"
/share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit"
done
3)我进入终端并输入ssh username@A
,然后cd /.../My_folder
,然后bash td.sh
为了并行化,本论坛很多答案都建议使用parallel
。我猜 bash 文件看起来像下面这样
#$ -S /bin/bash
#$ -l h_vmem=5G
#$ -l tmem=5G
#$ -l h_rt=480:0:0
#$ -cwd
#$ -j y
#$ -N try
date
hostname
export SGE_TASK_ID
SGE_TASK_ID={1..2}
echo "$SGE_TASK_ID" | parallel -P 2 /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit"
但是,这是我在终端上收到的错误
A.local
td.sh: line 16: parallel: command not found
据我了解,可能是parallel
机器中缺少“软件”。我可以安装它吗?如果可以,如何安装?或者应该由系统管理员安装?或者,您还有其他建议吗parallel
?
更新:尝试实现下面第二个答案的脚本
#!/bin/bash -l
#$ -S /bin/bash
#$ -l h_vmem=5G
#$ -l tmem=5G
#$ -l h_rt=480:0:0
#$ -cwd
#$ -j y
#$ -N try
date
hostname
export SGE_TASK_ID
SGE_TASK_ID={1..2}
echo -e SGE_TASK_ID | xargs -I {} -P 4 /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID={}; f; exit"
这是我收到的错误消息
Undefined function or variable 'SGE_TASK_ID'.
答案1
在循环中,在后台启动 Matlab 作业,然后等待它们在循环后完成:
for SGE_TASK_ID in 1 2; do
printf 'Task ID is %d\n' "$SGE_TASK_ID"
/share/.../matlab -nodisplay -nodesktop -nojvm -nosplash \
-r "main; ID=$SGE_TASK_ID; f; exit" &
done
wait
Matlab 作业将快速连续启动并同时运行。 afterwait
循环确保脚本在所有后台作业完成之前不会退出。
对于J
允许并行运行N
作业的作业:
SGE_TASK_ID=1
n=0
while [ "$SGE_TASK_ID" -le "$J" ]; do
if [ "$n" -eq "$N" ]; then
wait # waits for the N started jobs to finish
n=0
fi
printf 'Task ID is %d\n' "$SGE_TASK_ID"
/share/.../matlab -nodisplay -nodesktop -nojvm -nosplash \
-r "main; ID=$SGE_TASK_ID; f; exit" &
SGE_TASK_ID=$(( SGE_TASK_ID + 1 ))
n=$(( n + 1 ))
done
wait
另一种变化是等待单身的后台作业在循环的 - 语句内完成if
,wait -n
并且只需减n
一而不是将其设置为零。
答案2
稍微干净一点的解决方案;
echo -e "1\n2" | xargs -I {} -P $(nproc) /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID={}; f; exit"
如果您有超过 2 个任务