此致
我为这篇漫长的帖子道歉:
我的问题: 如何修改errFunction
中的* * *,runABQfile
函数(subprocess.call
)和下面是bash script
,以便我可以在群集中运行PSO优化?
背景:我正在使用Python编写的粒子群优化(PSO)和使用VUMAT(用户素材)的ABAQUS校准模型。 python脚本为每次迭代更新输入文件 N 不同的ABAQUS模型(对应于 N 不同的实验),并应运行每个 N 模型,直到实验和模型之间的全局误差最小化。我在没有管理员权限的群集中运行此优化。
假设我有一个有效的主脚本 main.py ,可以在调用函数 PSO之前导入必要的模块,启动变量,读取实验数据.py 使用
XOpt, FOpt = pso(errFunction, lb, ub, f_ieqcons=mycons, args=args)
要最小化的目标函数errFunction
是使用runABQfile
函数运行所有 N 模型,并将每次迭代的全局错误返回到PSO函数。我的代码结构的简要视图如下所示(我遗漏了不相关的部分)。
def errFunction(param2Calibrate,otherProps,InputFiles,experimentData,otherArgs):
maxNpts = otherArgs[0]
nAnalysis = otherArgs[1]
# Run Each Abaqus Simulation
inpFile = [0] * nAnalysis
abqDisp = [[0 for x in range(maxNpts)] for y in range(nAnalysis)]
abqForce = [[0 for x in range(maxNpts)] for y in range(nAnalysis)]
iexpForce = [[0 for x in range(maxNpts)] for y in range(nAnalysis)]
# ***********************************#
# - Update and Run Each Input File - #
for r in range(nParallelLoops):
for k in range( r*nAnalysis/nParallelLoops, (r+1)*nAnalysis/nParallelLoops ):
# - Write and Run Abaqus INP file - #
inpFile[k] = writeABQfile(param2Calibrate,otherProps[k],InputFiles[k])
runABQfile(inpFile[k])
# - Extract from Abaqus ODB - #
abqDisp_, abqForce_ = extraction(inpFile[k])
abqDisp[k][0:len(abqDisp_)] = abqDisp_
abqForce[k][0:len(abqForce_)] = abqForce_
# ***********************************#
# - Interpolate Experimental Results to Match Abaqus - #
for k in range(0,nAnalysis):
iexpForce_ = interpolate(experimentData[k],abqDisp[:][k])
iexpForce[k][0:len(abqDisp_)]= iexpForce_
# - Get Error - #
for k in range(0,nAnalysis):
Err[k] = Error(iexpForce[:][k],abqDisp[:][k],abqForce[:][k])
return Err
runABQfile
设置如下,其中2个进程将在serie中运行:
def runABQfile(inpFile):
import subprocess
import os
# - Run Abaqus - #
ABQexe = '/opt/abaqus/6.14-1/code/bin/abq6141'
prcStr1 = (ABQexe+' '+'job='+inpFile+' input='+inpFile+' \
user=$HOME/mPDFvumatNED.f scratch=/scratch/$USER/$SLURM_JOBID \
cpus=12 parallel=domain domains=12 mp_mode=mpi memory=60000mb \
interactive double=both')
prcStr2 = (ABQexe+' '+'cae noGUI='+inpFile+'_CAE.py')
process = subprocess.call(prcStr1,stdin=None,stdout=None,stderr=None,shell=True)
process = subprocess.call(prcStr2,shell=True)
问题似乎在哪里:我可以访问最多2个节点,每个作业24个cpus(受ABAQUS许可证限制)。如果我要运行单个分析,我将使用SLURM将作业排队,并使用以下脚本。
#!/bin/bash
#SBATCH --job-name="abaqus"
#SBATCH --output="abaqus.%j.%N.out"
#SBATCH --partition=debug
#SBATCH --nodes=2
#SBATCH --export=ALL
#SBATCH --ntasks-per-node=24
#SBATCH -L abaqus:25
#SBATCH -t 00:30:00
#Get the env file setup
scontrol show hostname > file-list1
scontrol show hostlist > file-list2
HOST1=`sed -n '1p' file-list1`
HOST2=`sed -n '2p' file-list1`
cat abq_v6.env |sed -e "s/host1/$HOST1/g" > ttt1.env
cat ttt1.env | sed -e "s/host2/$HOST2/g" > abaqus_v6.env
rm ttt*env
#Run the executable remotely
sed "s/DUMMY/$SLURM_JOBID/g" s4b.sh.orig > s4b.sh
chmod u+x s4b.sh
export EXHOST=`/bin/hostname`
ssh $EXHOST $SLURM_SUBMIT_DIR/s4b.sh
s4b.sh.orig
看起来像这样:
#!/bin/bash -l
cd /share/apps/examples/ABAQUS/s4b_multinode
module purge
module load abaqus/6.14-1
export EXE=abq6141
$EXE job=s4b scratch=/scratch/$USER/DUMMY cpus=48 -verbose 3 \
standard_parallel=all mp_mode=mpi memory=120000mb interactive
此脚本设置是提交一个ABAQUS作业的唯一方法,该作业在该群集上的多个节点上运行,因为ABAQUS环境文件和SLURM存在问题(我猜想mp_host_list没有正确分配或者超额订阅,但是老实说,我不明白可能会发生什么。
我在调用runABQfile
之后修改了我的subprocess.call
函数以使用bash结构:
prcStr1 = ('sed "s/DUMMY/$SLURM_JOBID/g" s4b.sh.orig > s4b0.sh; \
sed "s/MODEL/inpFile/g" s4b0.sh > s4b1.sh; \
chmod u+x s4b1.sh; \
export EXHOST=`/bin/hostname`; \
ssh $EXHOST $SLURM_SUBMIT_DIR/s4b1.sh' )
process = subprocess.call(prcStr1,stdin=None,stdout=None,stderr=None,shell=True)
但优化永远不会开始,并在修改第一个脚本后立即退出。
现在问题又是如何修改errFunction
中的* * *,runABQfile
函数( subprocess.call )之间的循环,以及bash脚本,以便我可以运行此优化? ...我想每个ABAQUS模型至少使用12个处理器,可能同时运行4个作业。请记住,在进入下一次迭代之前,所有 N 模型都需要运行和完成。
我将感谢你们提供的任何帮助。
此致
D P。