之前关于并行方法的博文:
此外还有 MP I并行方法。本篇讲的是使用 sh 脚本文件实现并行(无数据依赖的情况),即:循环提交多个串行任务,分别分布在多个核上,最后把运行结果集中在某个输出文件中。这个方法的原理比较简单(和手动并行的原理相同),因此无需大范围修改程序,同时并行程度也比较高。
说明:该方法需要您对 sh 脚本十分熟悉,尤其是通过使用 sed 命令进行文本内容的修改。对于sh脚本不熟悉的同学,推荐阅读这篇:使用Python脚本文件实现半手动的并行计算。
运行:sh task.sh,提交多个pbs任务(这里分成了7个任务提交)。
task.sh文件:
#!/bin/sh
for ((job_index=0; job_index<7; job_index++))
do
cp a.py a${job_index}.py
sed -i "s/job_index = -1/job_index = ${job_index}/" a${job_index}.py
cp a.sh a${job_index}.sh
sed -i "s/python a.py/python a${job_index}.py/" a${job_index}.sh
qsub a${job_index}.sh
done
需要说明的是:另存一份 .py 文件是完全必要的,因为如果在运行时修改 .py 内容,很可能会导致结果产生变化。此外,上面的 task.sh 代码对 a.sh 文件也另存了一份,然后再qsub提交。
a.sh文件:
#!/bin/sh
#PBS -N task
#PBS -l nodes=1:ppn=1
python a.py
a.py文件:
import numpy as np
# 设置
cpus = 7 # 使用的CPU个数(等于提交任务的个数)
parameter_array_all = np.arange(0, 10, 0.1) # 需要计算的参数
# 通过.sh脚本文件修改的任务指标。job_index从0开始,最大值为cpus-1
job_index = -1
# 预处理
len_of_parameter_all = len(parameter_array_all) # 需要计算参数的个数
if len_of_parameter_all%cpus == 0:
len_parameter = int(len_of_parameter_all/cpus) # 一个CPU/任务需要计算参数的个数
parameter_array = parameter_array_all[job_index*len_parameter:(job_index+1)*len_parameter]
else:
len_parameter = int(len_of_parameter_all/(cpus-1)) # 一个CPU/任务需要计算参数的个数
if job_index != cpus-1:
parameter_array = parameter_array_all[job_index*len_parameter:(job_index+1)*len_parameter]
else:
parameter_array = parameter_array_all[job_index*len_parameter:len_of_parameter_all]
# 任务
with open('a'+str(job_index)+'.txt', 'w') as f:
for parameter in parameter_array:
result = parameter**2
f.write(str(parameter)+' '+str(result)+'\n')
运行结束后,可以通过以下 Python 代码对 .txt 文件进行合并。
combine.py文件:
f = open('combine.txt', 'w')
for job_index in range(7):
with open('a'+str(job_index)+'.txt', 'r') as f0:
text = f0.read()
f.write(text)
f.close()
参考资料:
[1] Linux下shell脚本:bash的介绍和使用(详细)
[2] shell脚本--sed的用法
[3] sed -i命令详解
【说明:本站主要是个人的一些笔记和代码分享,内容可能会不定期修改。为了使全网显示的始终是最新版本,这里的文章未经同意请勿转载。引用请注明出处:https://www.guanjihuan.com】