15from tempfile 
import mkstemp
 
   20    Remove from the arguments the presence of the profiler and its output in 
   21    order to relaunch the script w/o infinite loops. 
   23    >>> getArgsWithoutProfilerInfo(['--profilerName', 'igprof', 'myopts.py']) 
   26    >>> getArgsWithoutProfilerInfo(['--profilerName=igprof', 'myopts.py']) 
   29    >>> getArgsWithoutProfilerInfo(['--profilerName', 'igprof', '--profilerExtraOptions', 'a b c', 'myopts.py']) 
   32    >>> getArgsWithoutProfilerInfo(['--profilerName', 'igprof', '--options', 'a b c', 'myopts.py']) 
   33    ['--options', 'a b c', 'myopts.py'] 
   39        if o.startswith(
"--profile"):
 
 
   48    """Adds  a list of libraries to LD_PRELOAD""" 
   49    preload = os.environ.get(
"LD_PRELOAD", 
"")
 
   51        preload = preload.replace(
" ", 
":").split(
":")
 
   55    for libname 
in set(preload).intersection(newpreload):
 
   57            "Ignoring preload of library %s because it is " "already in LD_PRELOAD.",
 
   61    to_load = [libname 
for libname 
in newpreload 
if libname 
not in set(preload)]
 
   65        preload = 
":".join(preload)
 
   66        os.environ[
"LD_PRELOAD"] = preload
 
   67        logging.info(
"Setting LD_PRELOAD='%s'", preload)
 
 
   74    Convert the given path to a real path if the pointed file exists, otherwise 
   77    path = os.path.normpath(os.path.expandvars(path))
 
   78    if os.path.exists(path):
 
   79        path = os.path.realpath(path)
 
 
   85_qmt_tmp_opt_files = []
 
   90    Given a .qmt file, return the command line arguments of the corresponding 
   93    from xml.etree 
import ElementTree 
as ET
 
   95    global _qmt_tmp_opt_files
 
   97    qmt = ET.parse(qmtfile)
 
   98    args = [a.text 
for a 
in qmt.findall(
"argument[@name='args']//text")]
 
   99    options = qmt.find(
"argument[@name='options']/text")
 
  102        options 
is not None and options.text 
is not None 
  105        from tempfile 
import NamedTemporaryFile
 
  108            r"from\s+Gaudi.Configuration\s+import\s+\*" 
  109            r"|from\s+Configurables\s+import",
 
  112            tmp_opts = NamedTemporaryFile(suffix=
".py")
 
  114            tmp_opts = NamedTemporaryFile(suffix=
".opts")
 
  115        tmp_opts.write(options.text.encode(
"ascii"))
 
  117        args.append(tmp_opts.name)
 
  118        _qmt_tmp_opt_files.append(tmp_opts)
 
  122    qmtfile = os.path.abspath(qmtfile)
 
  123    if "qmtest" in qmtfile.split(os.path.sep):
 
  126        while os.path.basename(testdir) != 
"qmtest":
 
  127            testdir = os.path.dirname(testdir)
 
  131    old_cwd = os.getcwd()
 
 
  140if __name__ == 
"__main__":
 
  142    if os.environ.get(
"LC_ALL") != 
"C":
 
  143        print(
'# setting LC_ALL to "C"')
 
  145        os.environ[
"LC_ALL"] = 
"C" 
  147    from optparse 
import OptionParser
 
  149    parser = OptionParser(usage=
"%prog [options] <opts_file|function_id> ...")
 
  154        help=
"do not run the application, just parse option files",
 
  162        help=
"DEPRECATED: use '--output file.pkl' instead. Write " 
  163        "the parsed options as a pickle file (static option " 
  167        "-v", 
"--verbose", action=
"store_true", help=
"print the parsed options" 
  172        help=
"format printed options in old option files style",
 
  177        help=
"print all the option (even if equal to default)",
 
  189        help=
"start the application in parallel mode using NCPUS processes. " 
  190        "0 => serial mode (default), -1 => use all CPUs",
 
  194        """Add the option line to a list together with its position in the 
  197        parser.values.options.append((len(parser.largs), value))
 
 
  205        help=
"add a single line (Python) option to the configuration. " 
  206        "All options lines are executed, one after the other, in " 
  210        "--no-conf-user-apply",
 
  212        help=
"disable the automatic application of configurable " 
  213        "users (for backward compatibility)",
 
  216        "--old-conf-user-apply",
 
  218        help=
"use the old logic when applying ConfigurableUsers " 
  219        "(with bug #103803) [default]",
 
  222        "--new-conf-user-apply",
 
  223        action=
"store_false",
 
  224        dest=
"old_conf_user_apply",
 
  225        help=
"use the new (correct) logic when applying " 
  226        "ConfigurableUsers (fixed bug #103803), can be " 
  227        "turned on also with the environment variable " 
  228        "GAUDI_FIXED_APPLY_CONF",
 
  235        help=
"dump the configuration to a file. The format of " 
  236        "the options is determined by the extension of the " 
  237        "file name: .pkl = pickle, .py = python, .opts = " 
  238        "old style options. The python format cannot be " 
  239        "used to run the application and it contains the " 
  240        "same dictionary printed with -v",
 
  247        help=
"Python options to be executed after the ConfigurableUser " 
  249        "All options lines are executed, one after the other, in " 
  253        "--debug", action=
"store_true", help=
"enable some debug print-out" 
  255    parser.add_option(
"--gdb", action=
"store_true", help=
"attach gdb")
 
  256    parser.add_option(
"--printsequence", action=
"store_true", help=
"print the sequence")
 
  257    if not sys.platform.startswith(
"win"):
 
  263            help=
"Use the Google malloc replacement. The environment " 
  264            "variable TCMALLOCLIB can be used to specify a different " 
  265            "name for the library (the default is libtcmalloc.so)",
 
  270            help=
"Allow pre-loading of special libraries (e.g. Google " 
  271            "profiling libraries).",
 
  277            help=
"Select one profiler among: igprofPerf, igprofMem and valgrind<toolname>",
 
  284            help=
"Specify the name of the output file for the profiler output",
 
  289            "--profilerExtraOptions",
 
  291            help=
"Specify additional options for the profiler. The '--' string should be expressed as '__' (--my-opt becomes __my-opt)",
 
  297        help=
"when this option is enabled, the options are parsed" 
  298        " and stored in a temporary file, then the job is " 
  299        "restarted using that file as input (to save " 
  305        help=
"Save gaudi process information to the file specified (in JSON format)",
 
  309        help=
"name of the Gaudi::Application to use [default: %default]",
 
  317        profilerExtraOptions=
"",
 
  321        old_conf_user_apply=
"GAUDI_FIXED_APPLY_CONF" not in os.environ,
 
  323        application=
"Gaudi::Application",
 
  328    for a 
in sys.argv[1:]:
 
  329        if a.endswith(
".qmt") 
and os.path.exists(a):
 
  333    if argv != sys.argv[1:]:
 
  334        print(
"# Running", sys.argv[0], 
"with arguments", argv)
 
  336    opts, args = parser.parse_args(args=argv)
 
  342        from multiprocessing 
import cpu_count
 
  344        sys_cpus = cpu_count()
 
  345        if opts.ncpus > sys_cpus:
 
  346            s = 
"Invalid value : --ncpus : only %i cpus available" % sys_cpus
 
  348        elif opts.ncpus < -1:
 
  349            s = 
"Invalid value : --ncpus must be integer >= -1" 
  366        level = logging.DEBUG
 
  367    InstallRootLoggingHandler(prefix, level=level, with_time=opts.debug)
 
  368    root_logger = logging.getLogger()
 
  371    sanitizers = os.environ.get(
"PRELOAD_SANITIZER_LIB", 
"")
 
  372    preload = os.environ.get(
"LD_PRELOAD", 
"")
 
  374        os.environ[
"PRELOAD_SANITIZER_LIB"] = 
"" 
  375        if preload 
and sanitizers != preload:
 
  377                "Ignoring PRELOAD_SANITIZER_LIB (={}) as LD_PRELOAD (={}) is " 
  378                "different and takes precedence.".
format(sanitizers, preload)
 
  381            for sanitizer 
in reversed(sanitizers.split(
":")):
 
  382                if sanitizer 
not in preload:
 
  383                    opts.preload.insert(0, sanitizer)
 
  384            if opts.profilerName == 
"jemalloc":
 
  385                logging.warning(
"jemalloc disabled when using a sanitizer")
 
  386                opts.profilerName = 
None 
  392            logging.warning(
"tcmalloc preload disabled when using a sanitizer")
 
  394            opts.preload.insert(0, os.environ.get(
"TCMALLOCLIB", 
"libtcmalloc.so"))
 
  398        preload = os.environ.get(
"LD_PRELOAD", 
"")
 
  400            preload = preload.replace(
" ", 
":").split(
":")
 
  403        for libname 
in set(preload).intersection(opts.preload):
 
  405                "Ignoring preload of library %s because it is " 
  406                "already in LD_PRELOAD.",
 
  409        to_load = [libname 
for libname 
in opts.preload 
if libname 
not in set(preload)]
 
  412            preload = 
":".join(preload)
 
  413            os.environ[
"LD_PRELOAD"] = preload
 
  414            logging.info(
"Restarting with LD_PRELOAD='%s'", preload)
 
  417            args = [a 
for a 
in sys.argv 
if a != 
"-T" and not "--tcmalloc".startswith(a)]
 
  418            os.execv(sys.executable, [sys.executable] + args)
 
  421    if opts.profilerName:
 
  422        profilerName = opts.profilerName
 
  423        profilerExecName = 
"" 
  424        profilerOutput = opts.profilerOutput 
or (profilerName + 
".output")
 
  429        igprofPerfOptions = 
"-d -pp -z -o igprof.pp.gz".split()
 
  432        if profilerName == 
"igprof":
 
  433            if not opts.profilerOutput:
 
  434                profilerOutput += 
".profile.gz" 
  435            profilerOptions = 
"-d -z -o %s" % profilerOutput
 
  436            profilerExecName = 
"igprof" 
  438        elif profilerName == 
"igprofPerf":
 
  439            if not opts.profilerOutput:
 
  440                profilerOutput += 
".pp.gz" 
  441            profilerOptions = 
"-d -pp -z -o %s" % profilerOutput
 
  442            profilerExecName = 
"igprof" 
  444        elif profilerName == 
"igprofMem":
 
  445            if not opts.profilerOutput:
 
  446                profilerOutput += 
".mp.gz" 
  447            profilerOptions = 
"-d -mp -z -o %s" % profilerOutput
 
  448            profilerExecName = 
"igprof" 
  450        elif "valgrind" in profilerName:
 
  452            if not opts.profilerOutput:
 
  453                profilerOutput += 
".log" 
  454            toolname = profilerName.replace(
"valgrind", 
"")
 
  455            outoption = 
"--log-file" 
  456            if toolname 
in (
"massif", 
"callgrind", 
"cachegrind"):
 
  457                outoption = 
"--%s-out-file" % toolname
 
  458            profilerOptions = 
"--tool=%s %s=%s" % (toolname, outoption, profilerOutput)
 
  459            profilerExecName = 
"valgrind" 
  461        elif profilerName == 
"jemalloc":
 
  462            opts.preload.insert(0, os.environ.get(
"JEMALLOCLIB", 
"libjemalloc.so"))
 
  463            os.environ[
"MALLOC_CONF"] = 
"prof:true,prof_leak:true" 
  465            root_logger.warning(
"Profiler %s not recognized!" % profilerName)
 
  468        if opts.profilerExtraOptions != 
"":
 
  469            profilerExtraOptions = opts.profilerExtraOptions
 
  470            profilerExtraOptions = profilerExtraOptions.replace(
"__", 
"--")
 
  471            profilerOptions += 
" %s" % profilerExtraOptions
 
  475            import distutils.spawn
 
  477            profilerPath = distutils.spawn.find_executable(profilerExecName)
 
  479                root_logger.error(
"Cannot locate profiler %s" % profilerExecName)
 
  483            "------ Profiling options are on ------ \n" 
  485            " o Options: '%s'.\n" 
  487            % (profilerExecName 
or profilerName, profilerOptions, profilerOutput)
 
  498            profilerOptions += 
" python" 
  501            arglist = [profilerPath] + profilerOptions.split() + args
 
  502            arglist = [a 
for a 
in arglist 
if a != 
""]
 
  506            os.execv(profilerPath, arglist)
 
  508            arglist = [a 
for a 
in sys.argv 
if not a.startswith(
"--profiler")]
 
  509            os.execv(sys.executable, [sys.executable] + arglist)
 
  513    if opts.pickle_output:
 
  516                "Conflicting options: use only --pickle-output or --output" 
  520            root_logger.warning(
"--pickle-output is deprecated, use --output instead")
 
  521            opts.output = opts.pickle_output
 
  529        Helper class to be able to process option files or options 
  530        callables as they come along in the arguments. 
  534            self.
config = {} 
if initial_config 
is None else initial_config
 
 
  537            from GaudiConfig2 
import CALLABLE_FORMAT, invokeConfig, mergeConfigs
 
  541            arg = os.path.expandvars(arg)
 
  543            if CALLABLE_FORMAT.match(arg):
 
  544                self.
config = mergeConfigs(self.
config, invokeConfig(arg))
 
 
  553    options = [
"process({!r})".
format(arg) 
for arg 
in args]
 
  556    optlines = list(opts.options)
 
  559    for pos, l 
in optlines:
 
  560        options.insert(pos, l)
 
  571        RuntimeError(
"GaudiPython cannot be used in option files")
 
  576    if "GAUDI_TEMP_OPTS_FILE" in os.environ:
 
  577        options = [
"process({!r})".
format(os.environ[
"GAUDI_TEMP_OPTS_FILE"])]
 
  582        g = {
"process": process}
 
  584        exec(
"from Gaudi.Configuration import *", g, l)
 
  589    import GaudiKernel.Proxy.Configurable
 
  591    if opts.no_conf_user_apply:
 
  592        logging.info(
"Disabling automatic apply of ConfigurableUser")
 
  594        GaudiKernel.Proxy.Configurable._appliedConfigurableUsers_ = 
True 
  597    if opts.old_conf_user_apply:
 
  598        from GaudiKernel.Proxy.Configurable 
import (
 
  599            applyConfigurableUsers_old 
as applyConfigurableUsers,
 
  602        from GaudiKernel.Proxy.Configurable 
import applyConfigurableUsers
 
  603    applyConfigurableUsers()
 
  606    if opts.post_options:
 
  607        g = {
"process": process}
 
  609        exec(
"from Gaudi.Configuration import *", g, l)
 
  610        for o 
in opts.post_options:
 
  614    if "GAUDI_TEMP_OPTS_FILE" in os.environ:
 
  615        os.remove(os.environ[
"GAUDI_TEMP_OPTS_FILE"])
 
  616        opts.use_temp_opts = 
False 
  620    from GaudiConfig2 
import Configurable, mergeConfigs
 
  622    Configurable.instances = mergeConfigs(Configurable.instances, process.config)
 
  624    if opts.verbose 
and not opts.use_temp_opts:
 
  625        c.printconfig(opts.old_opts, opts.all_opts)
 
  627        c.writeconfig(opts.output, opts.all_opts)
 
  629    if opts.use_temp_opts:
 
  630        fd, tmpfile = mkstemp(
".opts")
 
  632        c.writeconfig(tmpfile, opts.all_opts)
 
  633        os.environ[
"GAUDI_TEMP_OPTS_FILE"] = tmpfile
 
  634        logging.info(
"Restarting from pre-parsed options")
 
  635        os.execv(sys.executable, [sys.executable] + sys.argv)
 
  637    c.printsequence = opts.printsequence
 
  638    if opts.printsequence:
 
  640            logging.warning(
"--printsequence not supported with --ncpus: ignored")
 
  642            logging.warning(
"--printsequence not supported with --dry-run: ignored")
 
  644    c.application = opts.application
 
  647    del sys.modules[
"GaudiPython"]
 
  651        retcode = c.run(opts.gdb, opts.ncpus)
 
  655        if opts.run_info_file:
 
  660            run_info[
"pid"] = os.getpid()
 
  661            run_info[
"retcode"] = retcode
 
  662            if os.path.exists(
"/proc/self/exe"):
 
  664                run_info[
"exe"] = os.readlink(
"/proc/self/exe")
 
  666            logging.info(
"Saving run info to: %s" % opts.run_info_file)
 
  667            with open(opts.run_info_file, 
"w") 
as f:
 
  668                json.dump(run_info, f)
 
 
 
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
__init__(self, initial_config=None)
__getattr__(self, *args, **kwargs)
__init__(self, exception)
option_cb(option, opt, value, parser)
setLibraryPreload(newpreload)
getArgsWithoutProfilerInfo(args)