Ejemplo n.º 1
0
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))
Ejemplo n.º 2
0
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)