解析以下函数:“def execute(reptrav, multiple=False, with_dbg=False, only_env=False,
follow_output=True, fpara=None, facmtps=1.,
runner=None, **kargs):
"""Run a Code_Aster execution in 'reptrav'.
Arguments :
multiple : False if only one execution is run (so stop if it fails),
True if several executions are run (don't stop when error occurs)
with_dbg : start debugger or not,
fpara : deprecated,
follow_output : print output to follow the execution,
kargs give "run, conf, prof, build" instances + exec name
Return a tuple (diag, tcpu, tsys, ttot, validbase).
"""
# 1. ----- initializations
run = kargs['run']
conf = kargs['conf']
prof = kargs['prof']
build = kargs['build']
exetmp = kargs['exe']
ctest = prof['parent'][0] == "astout"
waf_inst = build.support('waf')
waf_nosupv = build.support('nosuperv')
waf_noresu = build.support('noresu')
waf_orb = build.support('orbinitref')
use_numthreads = build.support('use_numthreads')
run.DBG("version supports: waf ({0}), nosuperv ({1}), "
"orbinitref ({2}), numthreads ({3})".format(waf_inst, waf_nosupv,
waf_orb, use_numthreads))
if not waf_inst:
exetmp = osp.join('.', osp.basename(exetmp))
tcpu = 0.
tsys = 0.
ttot = 0.
validbase = True
if runner is None:
runner = Runner()
runner.set_rep_trav(reptrav)
interact = ('interact' in prof.args or
prof.args.get('args', '').find('-interact') > -1)
hide_command = ("hide-command" in prof.args or
prof.args.get('args', '').find('--hide-command') > -1)
os.chdir(reptrav)
# 2. ----- list of command files
list_comm = glob('fort.1.*')
list_comm.sort()
if osp.exists('fort.1'):
list_comm.insert(0, 'fort.1')
if waf_nosupv:
for fcomm in list_comm:
add_import_commands(fcomm)
# 3. ----- arguments list
drep = { 'REPOUT' : 'rep_outils', 'REPMAT' : 'rep_mat', 'REPDEX' : 'rep_dex' }
cmd = []
if waf_nosupv:
if interact:
cmd.append('-i')
cmd.append('fort.1')
else:
if waf_inst:
cmd.append(osp.join(conf['SRCPY'][0], conf['ARGPYT'][0]))
else:
cmd.append(osp.join(conf['REPPY'][0], conf['ARGPYT'][0]))
cmd.extend(conf['ARGEXE'])
# warning: using --commandes will turn off backward compatibility
cmd.append('-commandes')
cmd.append('fort.1')
# cmd.append(_fmtoption('command', 'fort.1'))
# remove deprecated options
long_opts_rm = ['rep', 'mem', 'mxmemdy', 'memory_stat', 'memjeveux_stat',
'type_alloc', 'taille', 'partition',
'origine', 'eficas_path']
# for version < 12.6/13.2 that does not support --ORBInitRef=, ignore it
if not waf_orb:
long_opts_rm.append('ORBInitRef')
cmd_memtps = {}
for k, v in list(prof.args.items()):
if k == 'args':
cmd.append(prof.args[k])
elif k in long_opts_rm:
warn("this command line option is deprecated : --%s" % k,
DeprecationWarning, stacklevel=3)
elif k in ('memjeveux', 'tpmax'):
cmd_memtps[k] = v
elif v.strip() == '' and k in list(drep.values()):
run.Mess(_('empty value not allowed for "%s"') % k, '<A>_INVALID_PARAMETER')
else:
cmd.append(_fmtoption(k, v))
# add arguments to find the process (for as_actu/as_del)
if not 'astout' in prof['actions'] and not 'distribution' in prof['actions']:
cmd.append(_fmtoption('num_job', run['num_job']))
cmd.append(_fmtoption('mode', prof['mode'][0]))
# arguments which can be set in file 'config.txt'
for kconf, karg in list(drep.items()):
if conf[kconf][0] != '' and not karg in list(prof.args.keys()):
cmd.append(_fmtoption(karg, conf[kconf][0]))
ncpus = prof['ncpus'][0]
try:
ncpus = max(1, int(ncpus))
except ValueError:
ncpus = ''
if use_numthreads:
if ncpus == '':
ncpus = max([run[prof['mode'][0] + '_nbpmax'] // 2, 1])
cmd.append(_fmtoption('numthreads', ncpus))
elif ncpus == '':
ncpus = '1'
# 4. ----- add parameters from prof
if on_64bits():
facW = 8
else:
facW = 4
tps = 0
memj = 0
nbp = 0
try:
tps = int(float(prof.args['tpmax']))
except KeyError:
run.Mess(_('tpmax not provided in profile'), '<E>_INCORRECT_PARA')
except ValueError:
run.Mess(_('incorrect value for tpmax (%s) in profile') % \
prof.args['tpmax'], '<E>_INCORRECT_PARA')
try:
memj = float(prof.args['memjeveux'])
except KeyError:
run.Mess(_('memjeveux not provided in profile'), '<E>_INCORRECT_PARA')
except ValueError:
run.Mess(_('incorrect value for memjeveux (%s) in profile') % \
prof.args['memjeveux'], '<E>_INCORRECT_PARA')
try:
nbp = int(ncpus)
except ValueError:
run.Mess(_('incorrect value for ncpus (%s) in profile') % \
prof['ncpus'][0], '<E>_INCORRECT_PARA')
# 4.1. check for memory, time and procs limits
run.Mess(_('Parameters : memory %d MB - time limit %d s') % (memj*facW, tps))
check_limits(run, prof['mode'][0], tps, memj*facW, nbp, runner.nbnode(), runner.nbcpu())
# check for previous errors (parameters)
if not multiple:
run.CheckOK()
elif run.GetGrav(run.diag) > run.GetGrav('<A>'):
run.Mess(_('error in parameters : %s') % run.diag)
return run.diag, tcpu, tsys, ttot, validbase
# 5. ----- only environment, print command lines to execute
if only_env:
run.Mess(ufmt(_('Code_Aster environment prepared in %s'), reptrav), 'OK')
run.Mess(_('To start execution copy/paste following lines in a ksh/bash shell :'))
run.Mess(' cd %s' % reptrav, 'SILENT')
run.Mess(' . %s' % osp.join(confdir, 'profile.sh'), 'SILENT')
tmp_profile = "profile_tmp.sh"
with open(tmp_profile, 'w') as f:
f.write("""
export PYTHONPATH=$PYTHONPATH:.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
""")
# set per version environment
for f in conf.get_with_absolute_path('ENV_SH') + [tmp_profile]:
run.Mess(' . %s' % f, 'SILENT')
cmd.insert(0, exetmp)
# add memjeveux and tpmax
cmd.extend([_fmtoption(k, v) for k, v in list(cmd_memtps.items())])
cmdline = ' '.join(cmd)
# get pdb.py path
pdbpy_cmd = "import os, sys ; " \
"pdbpy = os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3], 'pdb.py')"
d = {}
exec(pdbpy_cmd, d)
pdbpy = d['pdbpy']
if runner.really(): #XXX and if not ? perhaps because of exit_code
cmdline = runner.get_exec_command(cmdline,
add_tee=False,
env=conf.get_with_absolute_path('ENV_SH'))
# print command lines
k = 0
for fcomm in list_comm:
k += 1
run.Mess(_("Command line %d :") % k)
run.Mess("cp %s fort.1" % fcomm, 'SILENT')
run.Mess(cmdline, 'SILENT')
# how to start the Python debugger
if not runner.really():
run.Mess(_('To start execution in the Python debugger you could type :'), 'SILENT')
pdb_cmd = cmdline.replace(exetmp,
'%s %s' % (exetmp, ' '.join(pdbpy.splitlines())))
run.Mess("cp %s fort.1" % fcomm, 'SILENT')
run.Mess(pdb_cmd, 'SILENT')
diag = 'OK'
# 6. ----- really execute
else:
# 6.1. content of reptrav
if not ctest:
run.Mess(ufmt(_('Content of %s before execution'), reptrav), 'TITLE')
out = run.Shell(cmd='ls -la')[1]
print(out)
if len(list_comm) == 0:
run.Mess(_('no .comm file found'), '<E>_NO_COMM_FILE')
# check for previous errors (copy datas)
if not multiple:
run.CheckOK()
elif run.GetGrav(run.diag) > run.GetGrav('<A>'):
run.Mess(_('error occurs during preparing data : %s') % run.diag)
return run.diag, tcpu, tsys, ttot, validbase
# 6.2. complete command line
cmd.append('--suivi_batch')
add_tee = False
if with_dbg:
# how to run the debugger
cmd_dbg = run.config.get('cmd_dbg', '')
if not cmd_dbg:
run.Mess(_('command line to run the debugger not defined'),
'<F>_DEBUG_ERROR')
if cmd_dbg.find('gdb') > -1:
ldbg = ['break main', ]
else:
ldbg = ['stop in main', ]
# add memjeveux and tpmax
update_cmd_memtps(cmd_memtps)
cmd.extend([_fmtoption(k, v) for k, v in list(cmd_memtps.items())])
pos_memtps = -1
cmd_args = ' '.join(cmd)
ldbg.append('run ' + cmd_args)
cmd = getdbgcmd(cmd_dbg, exetmp, '', ldbg, cmd_args)
else:
add_tee = True
cmd.insert(0, exetmp)
# position where insert memjeveux+tpmax
pos_memtps = len(cmd)
# keep for compatibility with version < 13.1
os.environ['OMP_NUM_THREADS'] = str(ncpus)
# unlimit coredump size
try:
corefilesize = int(prof['corefilesize'][0]) * 1024*1024
except ValueError:
corefilesize = 'unlimited'
run.SetLimit('core', corefilesize)
# 6.3. if multiple .comm files, keep previous bases
if len(list_comm) > 1:
run.Mess(_('%d command files') % len(list_comm))
validbase = False
BASE_PREC = osp.join(reptrav, 'BASE_PREC')
run.MkDir(BASE_PREC)
# 6.4. for each .comm file
diag = '?'
diag_ok = None
k = 0
for fcomm in list_comm:
k += 1
os.chdir(runner.reptrav())
run.Copy('fort.1', fcomm)
# start execution
tit = _('Code_Aster run')
run.timer.Start(tit)
# add memjeveux and tpmax at the right position
if os.name != 'nt' or not add_tee:
cmd_i = cmd[:]
else:
print("cmd", cmd)
cmd_i = [cm.replace(" ","\" \"") if not cm.startswith("--max_") else cm for cm in cmd]
update_cmd_memtps(cmd_memtps)
if pos_memtps > -1:
for key, value in list(cmd_memtps.items()):
cmd_i.insert(pos_memtps, _fmtoption(key, value))
if True or not ctest:
run.Mess(tit, 'TITLE')
run.Mess(_('Command line %d :') % k)
if not run['verbose']:
run.Mess(' '.join(cmd_i))
if waf_nosupv and not hide_command:
dash = "# " + "-" * 90
with open('fort.1', 'rb') as f:
content =[_("Content of the file to execute"),
dash,
to_unicode(f.read()),
dash]
run.Mess(os.linesep.join(content))
cmd_exec = runner.get_exec_command(' '.join(cmd_i),
add_tee=add_tee,
env=conf.get_with_absolute_path('ENV_SH'))
# go
iret, exec_output = run.Shell(cmd_exec, follow_output=follow_output, interact=interact)
if iret != 0:
cats = ['fort.6']
if not waf_noresu:
cats.extend(['fort.8', 'fort.9'])
for f in cats:
run.FileCat(text="""\n <I>_EXIT_CODE = %s""" % iret, dest=f)
if not follow_output and not ctest:
print(exec_output)
# mpirun does not include cpu/sys time of childrens, add it in timer
if exec_output:
runner.add_to_timer(exec_output, tit)
run.timer.Stop(tit)
if k < len(list_comm):
for b in glob('vola.*')+glob('loca.*'):
run.Delete(b, remove_dirs=False)
if len(list_comm) > 1:
ldiag = build.getDiag(cas_test=ctest)
diag_k = ldiag[0]
tcpu += ldiag[1]
tsys += ldiag[2]
ttot += ldiag[3]
run.FileCat('fort.6', 'fort_bis.6')
run.Delete('fort.6', remove_dirs=False)
if not waf_noresu:
run.FileCat('fort.8', 'fort_bis.8')
run.Delete('fort.8', remove_dirs=False)
run.FileCat('fort.9', 'fort_bis.9')
run.Delete('fort.9', remove_dirs=False)
if re.search('<[ESF]{1}>', diag_k):
# switch <F> to <E> if multiple .comm
if diag_k.find('<F>') > -1:
diag_k = diag_k.replace('<F>', '<E>')
# ...and try to restore previous bases
run.Mess(ufmt(_('restore bases from %s'), BASE_PREC))
lbas = glob(osp.join(BASE_PREC, 'glob.*')) + \
glob(osp.join(BASE_PREC, 'bhdf.*')) + \
glob(osp.join(BASE_PREC, 'pick.*'))
if len(lbas) > 0:
run.Copy(os.getcwd(), niverr='INFO', verbose=follow_output, *lbas)
else:
run.Mess(_('no glob/bhdf base to restore'), '<A>_ALARM')
run.Mess(_('execution aborted (comm file #%d)') % k, diag_k)
diag = diag_k
break
else:
# save bases in BASE_PREC if next execution fails
validbase = True
if k < len(list_comm):
if not ctest:
run.Mess(ufmt(_('save bases into %s'), BASE_PREC))
lbas = glob('glob.*') + \
glob('bhdf.*') + \
glob('pick.*')
run.Copy(BASE_PREC, niverr='INFO', verbose=follow_output, *lbas)
run.Mess(_('execution ended (comm file #%d)') % k, diag_k)
# at least one is ok/alarm ? keep the "worse good" status!
if run.GetGrav(diag_k) in (0, 1):
diag_ok = diag_ok or 'OK'
if run.GetGrav(diag_ok) < run.GetGrav(diag_k):
diag_ok = diag_k
# the worst diagnostic
if run.GetGrav(diag) < run.GetGrav(diag_k):
diag = diag_k
# 6.5. global diagnostic
if len(list_comm) > 1:
run.Rename('fort_bis.6', 'fort.6')
run.Rename('fort_bis.8', 'fort.8')
run.Rename('fort_bis.9', 'fort.9')
else:
diag, tcpu, tsys, ttot = build.getDiag(cas_test=ctest)[:4]
validbase = run.GetGrav(diag) <= run.GetGrav('<S>')
if ctest and run.GetGrav(diag) < 0:
diag = '<F>_' + diag
if ctest and diag == 'NO_TEST_RESU' and diag_ok:
diag = diag_ok
run.ReinitDiag(diag)
# expected diagnostic ?
if prof['expected_diag'][0]:
expect = prof['expected_diag'][0]
if run.GetGrav(diag) >= run.GetGrav('<E>'):
diag = '<F>_ERROR'
if run.GetGrav(diag) == run.GetGrav(expect):
run.Mess(_('Diagnostic is as expected.'))
diag = 'OK'
else:
run.Mess(_("Diagnostic is not as expected (got '%s').") % diag)
diag = 'NOOK_TEST_RESU'
run.ReinitDiag(diag)
run.Mess(_('Code_Aster run ended, diagnostic : %s') % diag)
# 6.6. post-mortem analysis of the core file
if not with_dbg:
cmd_dbg = run.config.get('cmd_post', '')
lcor = glob('core*')
if cmd_dbg and lcor:
run.Mess(_('Code_Aster run created a coredump'),
'<E>_CORE_FILE')
if not multiple:
# take the first one if several core files
core = lcor[0]
run.Mess(ufmt(_('core file name : %s'), core))
cmd = getdbgcmd(cmd_dbg, exetmp, core,
('where', 'quit'), '')
tit = _('Coredump analysis')
run.Mess(tit, 'TITLE')
run.timer.Start(tit)
iret, output = run.Shell(' '.join(cmd),
alt_comment='coredump analysis...', verbose=True)
if iret == 0 and not ctest:
print(output)
run.timer.Stop(tit)
if not ctest:
# 6.7. content of reptrav
run.Mess(ufmt(_('Content of %s after execution'), os.getcwd()), 'TITLE')
out = run.Shell(cmd='ls -la . REPE_OUT')[1]
print(out)
# 6.8. print some informations
run.Mess(_('Size of bases'), 'TITLE')
lf = glob('vola.*')
lf.extend(glob('loca.*'))
lf.extend(glob('glob.*'))
lf.extend(glob('bhdf.*'))
lf.extend(glob('pick.*'))
for f in lf:
run.Mess(_('size of %s : %12d bytes') % (f, os.stat(f).st_size))
return diag, tcpu, tsys, ttot, validbase
def _fmtoption(key, value=None):
"""Format an option"""
key = key.lstrip('-')
if value is None or (type(value) is str and not value.strip()):
fmt = '--{0}'.format(key)
else:
fmt = '--{0}={1}'.format(key, value)
return fmt
”