class AsterCalcul(BaseCalcul): """This class read user's profile and (if needed) call as_run through or not a terminal, or just write a btc file... """ _supported_services = ( 'study', 'parametric_study', 'testcase', 'meshtool', 'stanley', 'convbase', 'distribution', 'exectool', 'multiple', ) def __init__(self, run, filename=None, prof=None, pid=None, differ_init=False): """Initializations """ BaseCalcul.__init__(self) assert filename or prof, 'none of (filename, prof) provided!' self.run = run if pid is None: self.pid = self.run['num_job'] else: self.pid = pid self.studyid = self.pid if prof is not None: self.prof = prof else: # ----- profile filename fprof = get_tmpname(self.run, self.run['tmp_user'], basename='profil_astk') self.run.ToDelete(fprof) kret = self.run.Copy(fprof, filename, niverr='<F>_PROFILE_COPY') self.prof = AsterProfil(fprof, self.run) if self.prof['nomjob'][0] == '': self.prof['nomjob'] = 'unnamed' # attributes self.dict_info = None self.as_exec_ref = self.run.get('as_exec_ref') self.diag = '?' self.__initialized = False if not differ_init: self.finalize_init() def finalize_init(self): """Finalize initialization. Allow to adapt prof object before customization.""" # decode service called self.decode_special_service() # add memory self.add_memory() # allow customization of calcul object if self.run['schema_calcul']: schem = get_plugin(self.run['schema_calcul']) self.run.DBG("calling plugin : %s" % self.run['schema_calcul']) self.prof = schem(self) self.__initialized = True def decode_special_service(self): """Return the profile modified for the "special" service. """ self.serv, self.prof = apply_special_service(self.prof, self.run) if self.serv == '': if self.prof['parent'][0] == 'parametric': self.serv = 'parametric_study' elif self.prof['parent'][0] == 'astout': self.serv = 'testcase' else: self.serv = 'study' self.prof['service'] = self.serv self.run.DBG("service name : %s" % self.serv) if self.serv not in self._supported_services: self.error(_(u'Unknown service : %s') % self.serv) def add_memory(self): """Add an amount of memory (MB) to the export parameters""" if self.serv in ('parametric_study', ): return conf = build_config_from_export(self.run, self.prof) self.run.DBG("memory to add: %s" % conf['ADDMEM'][0]) try: addmem = float(conf['ADDMEM'][0]) except ValueError: addmem = 0. if not addmem: return memory = float(self.prof['memjob'][0] or 0.) / 1024. + addmem self.prof.set_param_memory(memory) self.run.DBG("new memory parameters: memjob=%s memjeveux=%s" % \ (self.prof['memjob'][0], self.prof.args['memjeveux'])) def build_dict_info(self, opts): """Build a dictionnary grouping all parameters. """ sep = "-----------------------------------------------" self.mode = self.prof['mode'][0] if not self.mode or self.run.get(self.mode) not in YES_VALUES: self.mode = self.prof['mode'] = "interactif" if self.mode == 'batch': self.scheduler = BatchSystemFactory(self.run, self.prof) node = self.prof['noeud'][0] or self.prof['serveur'][0] self.dict_info = { 'sep': sep, 'export': self.prof.get_filename(), 'mcli': self.prof['mclient'][0], 'ucli': self.prof['uclient'][0], 'serv': self.prof['serveur'][0], 'user': self.prof['username'][0], 'mode': self.mode, 'node': node, 'plt': self.run['plate-forme'], 'vers': self.prof.get_version_path(), 'tpsjob': self.prof['tpsjob'][0], 'vmem': float(self.prof['memjob'][0] or 0.) / 1024., 'ncpus': self.prof['ncpus'][0] or 'auto', 'mpi_nbnoeud': self.prof['mpi_nbnoeud'][0], 'mpi_nbcpu': self.prof['mpi_nbcpu'][0], 'dbg': self.prof['debug'][0], 'prof_content': self.prof.get_content(), 'nomjob': self.prof['nomjob'][0], 'nomjob_': self.flash('', ''), 'nomjob_p': self.flash('export', '$num_job'), 'as_run_cmd': " ".join(self.run.get_as_run_cmd(with_args=False)), 'who': self.run.system.getuser_host()[0], 'opts': opts, 'remote_args': " ".join(self.run.get_as_run_args()), } if self.prof['srv_dbg'][0] in YES_VALUES: self.dict_info['opts'] += ' --debug' if self.prof['srv_verb'][0] in YES_VALUES: self.dict_info['opts'] += ' --verbose' # rep_trav from profile or config(_nodename) / keep consistancy with job.py rep_trav = self.prof['rep_trav'][0] if rep_trav == '': rep_trav = get_nodepara(node, 'rep_trav', self.run['rep_trav']) self.dict_info['rep_trav'] = rep_trav # set message using previous content self.dict_info['message'] = self.message() def message(self): """Format information message. """ # No "' in ASTK_MESSAGE ! ASTK_MESSAGE = [] # check client and server versions serv_vers = self.run.__version__ try: client_vers = self.prof['origine'][0].split()[1] except Exception, msg: self.run.DBG('Error : unexpected "origine" value :', self.prof['origine'][0]) client_vers = '' if client_vers == '': ASTK_MESSAGE.append(msg_cli_version % serv_vers) elif serv_vers != client_vers: ASTK_MESSAGE.append(msg_pb_version % (serv_vers, client_vers)) ASTK_MESSAGE.append(msg_info % self.dict_info) if self.prof['classe'][0]: ASTK_MESSAGE.append(msg_classe % self.prof['classe'][0]) if self.prof['depart'][0]: ASTK_MESSAGE.append(msg_depart % self.prof['depart'][0]) ASTK_MESSAGE.append(self.dict_info['sep']) if self.prof['consbtc'][0] not in NO_VALUES: msg = "generated" else: msg = "provided by user" ASTK_MESSAGE.append(msg_consbtc % msg) ASTK_MESSAGE.append(self.dict_info['sep']) ASTK_MESSAGE.append(msg_vers % (serv_vers, client_vers)) return convert(os.linesep.join(ASTK_MESSAGE))
def RunAster(run, *args): """Allow to run Code_Aster with or without compiling additional source files, check a development, run a list of test cases... """ run.print_timer = True prev = os.getcwdu() # ----- check argument if len(args) != 1: run.parser.error( _(u"'--%s' requires one argument") % run.current_action) # 1. ----- initializations jn = run['num_job'] fprof = get_tmpname(run, run['tmp_user'], basename='profil_astk') run.ToDelete(fprof) # 1.1. ----- check argument type # 1.1.1. ----- use profile from args if isinstance(args[0], AsterProfil): prof = args[0].copy() prof.WriteExportTo(fprof) forig = fprof else: # 1.1.2. ----- read profile from args forig = args[0] kret = run.Copy(fprof, forig, niverr='<F>_PROFILE_COPY') prof = AsterProfil(fprof, run) if not run.IsRemote(forig): export_fname = run.PathOnly(get_absolute_path(forig)) prof.absolutize_filename(export_fname) if not prof['mode'][0] in ('batch', 'interactif'): run.Mess(_(u"Unknown mode (%s), use 'interactif' instead") % \ repr(prof['mode'][0]), 'UNEXPECTED_VALUE') prof['mode'] = ['interactif'] run.DBG("Input export : %s" % fprof, prof) # 1.2. get AsterConfig and AsterBuild objects REPREF = prof.get_version_path() conf = build_config_from_export(run, prof) build = AsterBuild(run, conf) DbgPara = { 'debug': { 'exe': conf['BIN_DBG'][0], 'suff': conf['BINOBJ_DBG'][0], 'libast': conf['BINLIB_DBG'][0], 'libfer': conf['BINLIBF_DBG'][0] }, 'nodebug': { 'exe': conf['BIN_NODBG'][0], 'suff': conf['BINOBJ_NODBG'][0], 'libast': conf['BINLIB_NODBG'][0], 'libfer': conf['BINLIBF_NODBG'][0] }, } # 1.3. set environment depending on version for f in conf.get_with_absolute_path('ENV_SH'): run.AddToEnv(f) # 1.4. set runner parameters klass = Runner # allow to customize of the execution objects if run.get('schema_execute'): schem = get_plugin(run['schema_execute']) run.DBG("calling plugin : %s" % run['schema_execute']) klass = schem(prof) runner = klass(conf.get_defines()) iret = runner.set_cpuinfo(prof['mpi_nbnoeud'][0], prof['mpi_nbcpu'][0]) if iret == 1: run.Mess( ufmt( _(u"%s is not a MPI version of Code_Aster. " "The number of nodes/processors must be equal to 1."), REPREF), "<F>_INVALID_PARAMETER") elif iret != 0: run.Mess(_(u"incorrect value for mpi_nbnoeud (%s) or mpi_nbcpu (%s)") \ % (prof['mpi_nbnoeud'][0], prof['mpi_nbcpu'][0]), '<F>_INVALID_PARAMETER') # 1.5. rep_trav from profile or from run[...] reptrav = runner.set_rep_trav(prof['rep_trav'][0], prof['mode'][0]) # write reptrav in the export prof['rep_trav'] = reptrav prof.WriteExportTo(prof.get_filename()) #XXX overrides the original export if forig != prof.get_filename(): run.Copy(forig, prof.get_filename(), niverr='<A>_ALARM') # add reptrav to LD_LIBRARY_PATH (to find dynamic libs provided by user) old = os.environ.get("LD_LIBRARY_PATH", "") os.environ["LD_LIBRARY_PATH"] = (reptrav + os.pathsep + old).strip( os.pathsep) # do not reinitialize rep_trav if if prof['prep_env'][0] not in NO_VALUES: run.MkDir(reptrav, chmod=0700) if prof['detr_rep_trav'][0] not in NO_VALUES: run.ToDelete(reptrav) # 1.6. copy profile in rep_trav kret = run.Copy(osp.join(reptrav, jn + '.export'), fprof) # ... and config file as ./config.txt conf.WriteConfigTo(osp.join(reptrav, 'config.txt')) # 1.7. debug/nodebug dbg = prof['debug'][0] if dbg == '': dbg = 'nodebug' # 1.8. default values exetmp = osp.join(REPREF, DbgPara[dbg]['exe']) cmdetmp = osp.join(REPREF, conf['BINCMDE'][0]) eletmp = osp.join(REPREF, conf['BINELE'][0]) # 2. ----- read profile values # it's valid because exec, cmde and ele must appear only once # these values will be overidden if they are available in reptrav # after an occurence of 'make_...' if prof.Get('DR', 'exec'): exetmp = prof.Get('DR', 'exec')[0]['path'] if prof.Get('DR', 'cmde'): cmdetmp = prof.Get('DR', 'cmde')[0]['path'] if prof.Get('DR', 'ele'): eletmp = prof.Get('DR', 'ele')[0]['path'] # order of actions : list_actions = [ 'make_exec', 'make_cmde', 'make_ele', 'make_etude', 'make_dbg', 'make_env', 'astout', 'distribution', 'multiple', 'exec_crs', 'exec_crp' ] # 3. ==> Let's go ! # 3.0. check if we know what to do for act in prof['actions']: if act == '': run.Mess(_(u'nothing to do'), 'OK') elif not act in list_actions: run.Mess(_(u'unknown action : %s') % act, '<A>_ALARM') # check if the version allows developments if conf['DEVEL'][0] in NO_VALUES and \ ( 'make_exec' in prof['actions'] or \ 'make_cmde' in prof['actions'] or \ 'make_ele' in prof['actions'] ): run.Mess( _(u'The configuration of this version does not allow ' 'user developments.'), '<F>_ERROR') # # 3.1. ----- make_exec # iret = 0 if 'make_exec' in prof['actions']: run.DBG(u'Start make_exec action') exetmp = osp.join(reptrav, 'aster.exe') tit = _(u'Compilation of source files') run.Mess(tit, 'TITLE') run.timer.Start(tit) repact = osp.join(reptrav, 'make_exec') repobj = osp.join(repact, 'repobj') run.MkDir(repact) lf = [] for typ in ('c', 'f', 'f90'): for rep in [l['path'] for l in prof.Get('D', typ=typ)]: jret, lbi = build.Compil(typ.upper(), rep, repobj, dbg, rep_trav=repact, error_if_empty=True, numthread='auto') iret = max(iret, jret) lf.extend(lbi) # liste des fichiers surchargés vers = get_aster_version(REPREF) vers = '.'.join(vers[:3]) fsurch = osp.join(repact, 'surchg.f') listsurcharge(vers, fsurch, lf) jret, lbi = build.Compil('F', fsurch, repobj, dbg, repact) run.timer.Stop(tit) run.CheckOK() tit = _(u'Build executable') run.Mess(tit, 'TITLE') run.timer.Start(tit) libaster = osp.join(REPREF, DbgPara[dbg]['libast']) libferm = osp.join(REPREF, DbgPara[dbg]['libfer']) # for backward compatibility if run.IsDir(libaster): libaster = osp.join(libaster, 'lib_aster.lib') if run.IsDir(libferm): libferm = osp.join(libferm, 'ferm.lib') lobj = glob(osp.join(repobj, '*.o')) # build an archive if there are more than NNN object files if len(lobj) > 500: run.timer.Stop(tit) tit2 = _(u'Add object files to library') run.timer.Start(tit2) libtmp = osp.join(repobj, 'libsurch.a') run.Copy(libtmp, libaster) kret = build.Archive(repobj, libtmp, force=True) lobj = [] libaster = libtmp run.timer.Stop(tit2) run.timer.Start(tit) kret = build.Link(exetmp, lobj, libaster, libferm, repact) run.timer.Stop(tit) run.CheckOK() tit = _(u'Copying results') run.timer.Start(tit, num=999) if prof.Get('R', typ='exec'): exe = prof.Get('R', typ='exec')[0] run.Delete(exe['path'], remove_dirs=False) iret = run.MkDir(osp.dirname(exe['path'])) iret = run.Copy(exe['path'], exetmp) exedata = prof.Get('D', typ='exec') if exedata and exedata[0]['path'] != exe['path']: exetmp = exedata[0]['path'] run.timer.Stop(tit) run.Mess(_(u'Code_Aster executable successfully created'), 'OK') # # 3.2. ----- make_cmde # if 'make_cmde' in prof['actions']: run.DBG(u'Start make_cmde action') tit = _(u"Compilation of commands catalogue") cmdetmp = osp.join(reptrav, 'cata_commande') run.timer.Start(tit) repact = osp.join(reptrav, 'make_cmde') run.MkDir(repact) kargs = { 'exe': exetmp, 'cmde': cmdetmp, } kargs['capy'] = [l['path'] for l in prof.Get('D', typ='capy')] lfun = prof.Get('D', typ='unig') if lfun: kargs['unigest'] = build.GetUnigest(lfun[0]['path']) if prof.Get('D', typ='py'): kargs['py'] = [l['path'] for l in prof.Get('D', typ='py')] jret = build.CompilCapy(REPREF, repact, **kargs) #i18n=True, run.timer.Stop(tit) run.CheckOK() tit = _(u'Copying results') run.timer.Start(tit) if prof.Get('R', typ='cmde'): cmde = prof.Get('R', typ='cmde')[0] iret = run.MkDir(cmde['path']) iret = run.Copy(cmde['path'], osp.join(cmdetmp, 'cata*.py*')) run.timer.Stop(tit) # # 3.3. ----- make_ele # if 'make_ele' in prof['actions']: run.DBG(u'Start make_ele action') tit = _(u"Compilation of elements") eletmp = osp.join(reptrav, 'elem.1') run.timer.Start(tit) repact = osp.join(reptrav, 'make_ele') run.MkDir(repact) kargs = { 'exe': exetmp, 'cmde': cmdetmp, 'ele': eletmp, } kargs['cata'] = [l['path'] for l in prof.Get('D', typ='cata')] lfun = prof.Get('D', typ='unig') if lfun: kargs['unigest'] = build.GetUnigest(lfun[0]['path']) if prof.Get('D', typ='py'): kargs['py'] = [l['path'] for l in prof.Get('D', typ='py')] jret = build.CompilEle(REPREF, repact, **kargs) run.timer.Stop(tit) run.CheckOK() tit = _(u'Copying results') run.timer.Start(tit) if prof.Get('R', typ='ele'): ele = prof.Get('R', typ='ele')[0] iret = run.MkDir(osp.dirname(ele['path'])) iret = run.Copy(ele['path'], eletmp) run.timer.Stop(tit) # # 3.4. ----- make_env / make_etude / make_dbg # if 'make_env' in prof['actions'] or 'make_etude' in prof['actions'] or \ 'make_dbg' in prof['actions']: run.DBG(u'Start make_etude/make_env/make_dbg action') os.chdir(reptrav) run.Mess(_(u'Code_Aster execution'), 'TITLE') # 3.4.1. prepare reptrav to run Code_Aster (proc# = 0) only_env = 'make_env' in prof['actions'] kargs = { 'exe': exetmp, 'cmde': cmdetmp, 'ele': eletmp, 'lang': prof['lang'][0], 'only_env': only_env, } lfun = prof.Get('D', typ='unig') if lfun: kargs['unigest'] = build.GetUnigest(lfun[0]['path']) if prof.Get('D', typ='py'): kargs['py'] = [l['path'] for l in prof.Get('D', typ='py')] tit = _(u'Preparation of environment') run.timer.Start(tit) run.Mess(ufmt(_(u'prepare environment in %s'), reptrav)) if prof['prep_env'][0] != 'no': build.PrepEnv(REPREF, reptrav, dbg=dbg, **kargs) else: run.Mess(_(u'... skipped (%s = no) !') % 'prep_env', 'SILENT') run.timer.Stop(tit) # 3.4.2. copy datas (raise <E> errors if failed) tit = _(u'Copying datas') run.Mess(tit, 'TITLE') run.timer.Start(tit) if prof['copy_data'][0] not in NO_VALUES: copyfiles(run, 'DATA', prof) else: run.Mess(_(u'... skipped (%s = no) !') % 'copy_data', 'SILENT') print3(os.getcwdu()) run.timer.Stop(tit) # 3.4.3. execution diag, tcpu, tsys, ttot, copybase = execute(reptrav, multiple=False, with_dbg='make_dbg' in prof['actions'], only_env=only_env, runner=runner, run=run, conf=conf, prof=prof, build=build, exe=exetmp) if not 'make_env' in prof['actions']: # 3.4.4. copy results tit = _(u'Copying results') run.Mess(tit, 'TITLE') run.timer.Start(tit) if prof['copy_result'][0] not in NO_VALUES: emit_alarm = prof['copy_result_alarm'][0] not in NO_VALUES copyfiles(run, 'RESU', prof, copybase, emit_alarm) else: run.Mess( _(u'... skipped (%s = no) !') % 'copy_result', 'SILENT') run.timer.Stop(tit) run.Mess(_(u'Code_Aster run ended'), diag) # 3.4.5. add .resu/.erre to output for testcases ctest = prof['parent'][0] == "astout" if ctest: run.Mess(_(u'Content of RESU file'), 'TITLE') run.FileCat('fort.8', magic.get_stdout()) run.Mess(_(u'Content of ERROR file'), 'TITLE') run.FileCat('fort.9', magic.get_stdout()) # 3.4.6. notify the user if prof['notify'][0]: content = _( '[Code_Aster] job %(job)s on %(server)s ended: %(diag)s') content = content % { 'job': prof.get_jobname(), 'diag': diag, 'server': prof['serveur'][0], } dest = ','.join(prof['notify']) run.SendMail(dest=dest, text=content, subject=content.splitlines()[0]) run.Mess(_(u'Email notification sent to %s') % dest) run.CheckOK() os.chdir(prev) # 3.5. ----- astout if 'astout' in prof['actions']: run.DBG(u'Start astout action') kargs = { 'exe': exetmp, 'cmde': cmdetmp, 'ele': eletmp, 'numthread': prof['numthread'][0], } os.chdir(reptrav) RunAstout(run, conf, prof, runner=runner, **kargs) os.chdir(prev) # 3.6. ----- distribution if 'distribution' in prof['actions']: run.DBG(u'Start distribution action') kargs = { 'exe': exetmp, 'cmde': cmdetmp, 'ele': eletmp, 'numthread': prof['numthread'][0], } Parametric(run, prof, runner=runner, **kargs) # 3.7. ----- multiple if 'multiple' in prof['actions']: run.DBG(u'Start multiple action') Multiple(run, prof, runner=runner, numthread=prof['numthread'][0]) # 4. ----- clean up if 'make_env' in prof['actions'] and prof['detr_rep_trav'][ 0] not in NO_VALUES: run.DoNotDelete(reptrav)