5 from tempfile
import mkstemp
9 Remove from the arguments the presence of the profiler and its output in
10 order to relaunch the script w/o infinite loops.
12 >>> getArgsWithoutoProfilerInfo(['--profilerName', 'igprof', 'myopts.py'])
15 >>> getArgsWithoutoProfilerInfo(['--profilerName=igprof', 'myopts.py'])
18 >>> getArgsWithoutoProfilerInfo(['--profilerName', 'igprof', '--profilerExtraOptions', 'a b c', 'myopts.py'])
21 >>> getArgsWithoutoProfilerInfo(['--profilerName', 'igprof', '--options', 'a b c', 'myopts.py'])
22 ['--options', 'a b c', 'myopts.py']
28 if o.startswith(
'--profile'):
36 ''' Adds a list of libraries to LD_PRELOAD '''
37 preload = os.environ.get(
"LD_PRELOAD",
"")
39 preload = preload.replace(
" ",
":").split(
":")
43 for libname
in set(preload).intersection(newpreload):
44 logging.warning(
"Ignoring preload of library %s because it is "
45 "already in LD_PRELOAD.", libname)
48 for libname
in newpreload
49 if libname
not in set(preload)]
53 preload =
":".join(preload)
54 os.environ[
"LD_PRELOAD"] = preload
55 logging.info(
"Setting LD_PRELOAD='%s'", preload)
61 Convert the given path to a real path if the pointed file exists, otherwise
64 path = os.path.normpath(os.path.expandvars(path))
65 if os.path.exists(path):
66 path = os.path.realpath(path)
70 _qmt_tmp_opt_files = []
73 Given a .qmt file, return the command line arguments of the corresponding
76 from xml.etree
import ElementTree
as ET
77 global _qmt_tmp_opt_files
79 qmt = ET.parse(qmtfile)
80 args = [a.text
for a
in qmt.findall(
"argument[@name='args']//text")]
81 options = qmt.find(
"argument[@name='options']/text")
83 if options
is not None:
84 from tempfile
import NamedTemporaryFile
86 if re.search(
r"from\s+Gaudi.Configuration\s+import\s+\*"
87 r"|from\s+Configurables\s+import", options.text):
88 tmp_opts = NamedTemporaryFile(suffix=
'.py')
90 tmp_opts = NamedTemporaryFile(suffix=
'.opts')
91 tmp_opts.write(options.text)
93 args.append(tmp_opts.name)
94 _qmt_tmp_opt_files.append(tmp_opts)
98 qmtfile = os.path.abspath(qmtfile)
99 if 'qmtest' in qmtfile.split(os.path.sep):
102 while os.path.basename(testdir) !=
'qmtest':
103 testdir = os.path.dirname(testdir)
107 old_cwd = os.getcwd()
109 args =
map(rationalizepath, args)
115 if __name__ ==
"__main__":
117 if os.environ.get(
'LC_ALL') !=
'C':
118 print '# setting LC_ALL to "C"'
119 os.environ[
'LC_ALL'] =
'C'
121 from optparse
import OptionParser
122 parser = OptionParser(usage =
"%prog [options] <opts_file> ...")
123 parser.add_option(
"-n",
"--dry-run", action=
"store_true",
124 help=
"do not run the application, just parse option files")
125 parser.add_option(
"-p",
"--pickle-output", action=
"store", type=
"string",
127 help=
"DEPRECATED: use '--output file.pkl' instead. Write "
128 "the parsed options as a pickle file (static option "
130 parser.add_option(
"-v",
"--verbose", action=
"store_true",
131 help=
"print the parsed options")
132 parser.add_option(
"--old-opts", action=
"store_true",
133 help=
"format printed options in old option files style")
134 parser.add_option(
"--all-opts", action=
"store_true",
135 help=
"print all the option (even if equal to default)")
141 parser.add_option(
"--ncpus", action=
"store", type=
"int", default=0,
142 help=
"start the application in parallel mode using NCPUS processes. "
143 "0 => serial mode (default), -1 => use all CPUs")
146 """Add the option line to a list together with its position in the
149 parser.values.options.append((len(parser.largs), value))
150 parser.add_option(
"--option", action=
"callback", callback=option_cb,
151 type =
"string", nargs = 1,
152 help=
"add a single line (Python) option to the configuration. "
153 "All options lines are executed, one after the other, in "
155 parser.add_option(
"--no-conf-user-apply", action=
"store_true",
156 help=
"disable the automatic application of configurable "
157 "users (for backward compatibility)")
158 parser.add_option(
"--old-conf-user-apply", action=
"store_true",
159 help=
"use the old logic when applying ConfigurableUsers "
160 "(with bug #103803) [default]")
161 parser.add_option(
"--new-conf-user-apply", action=
"store_false",
162 dest=
"old_conf_user_apply",
163 help=
"use the new (correct) logic when applying "
164 "ConfigurableUsers (fixed bug #103803), can be "
165 "turned on also with the environment variable "
166 "GAUDI_FIXED_APPLY_CONF")
167 parser.add_option(
"-o",
"--output", action =
"store", type =
"string",
168 help =
"dump the configuration to a file. The format of "
169 "the options is determined by the extension of the "
170 "file name: .pkl = pickle, .py = python, .opts = "
171 "old style options. The python format cannot be "
172 "used to run the application and it contains the "
173 "same dictionary printed with -v")
174 parser.add_option(
"--post-option", action=
"append", type=
"string",
176 help=
"Python options to be executed after the ConfigurableUser "
178 "All options lines are executed, one after the other, in "
180 parser.add_option(
"--debug", action=
"store_true",
181 help=
"enable some debug print-out")
182 parser.add_option(
"--gdb", action=
"store_true",
184 parser.add_option(
"--printsequence", action=
"store_true",
185 help=
"print the sequence")
186 if not sys.platform.startswith(
"win"):
188 parser.add_option(
"-T",
"--tcmalloc", action=
"store_true",
189 help=
"Use the Google malloc replacement. The environment "
190 "variable TCMALLOCLIB can be used to specify a different "
191 "name for the library (the default is libtcmalloc.so)")
192 parser.add_option(
"--preload", action=
"append",
193 help=
"Allow pre-loading of special libraries (e.g. Google "
194 "profiling libraries).")
197 parser.add_option(
"--profilerName", type=
"string",
198 help=
"Select one profiler among: igprofPerf, igprofMem and valgrind<toolname>")
201 parser.add_option(
"--profilerOutput", type=
"string",
202 help=
"Specify the name of the output file for the profiler output")
205 parser.add_option(
"--profilerExtraOptions", type=
"string",
206 help=
"Specify additional options for the profiler. The '--' string should be expressed as '__' (--my-opt becomes __my-opt)")
208 parser.add_option(
'--use-temp-opts', action=
'store_true',
209 help=
'when this option is enabled, the options are parsed'
210 ' and stored in a temporary file, then the job is '
211 'restarted using that file as input (to save '
213 parser.add_option(
"--run-info-file", type=
"string",
214 help=
"Save gaudi process information to the file specified (in JSON format)")
216 parser.set_defaults(options = [],
220 profilerExtraOptions =
'',
224 old_conf_user_apply=
'GAUDI_FIXED_APPLY_CONF' not in os.environ,
225 run_info_file =
None)
229 for a
in sys.argv[1:]:
230 if a.endswith(
'.qmt')
and os.path.exists(a):
234 if argv != sys.argv[1:]:
235 print '# Running', sys.argv[0],
'with arguments', argv
237 opts, args = parser.parse_args(args=argv)
243 from multiprocessing
import cpu_count
244 sys_cpus = cpu_count()
245 if opts.ncpus > sys_cpus:
246 s =
"Invalid value : --ncpus : only %i cpus available" % sys_cpus
248 elif opts.ncpus < -1 :
249 s =
"Invalid value : --ncpus must be integer >= -1"
260 if opts.old_opts: prefix =
"// "
264 level = logging.DEBUG
266 root_logger = logging.getLogger()
270 opts.preload.insert(0, os.environ.get(
"TCMALLOCLIB",
"libtcmalloc.so"))
273 preload = os.environ.get(
"LD_PRELOAD",
"")
275 preload = preload.replace(
" ",
":").split(
":")
278 for libname
in set(preload).intersection(opts.preload):
279 logging.warning(
"Ignoring preload of library %s because it is "
280 "already in LD_PRELOAD.", libname)
282 for libname
in opts.preload
283 if libname
not in set(preload)]
286 preload =
":".join(preload)
287 os.environ[
"LD_PRELOAD"] = preload
288 logging.info(
"Restarting with LD_PRELOAD='%s'", preload)
291 args = [ a
for a
in sys.argv
if a !=
'-T' and not '--tcmalloc'.startswith(a) ]
292 os.execv(sys.executable, [sys.executable] + args)
295 if opts.profilerName:
296 profilerName = opts.profilerName
297 profilerExecName =
""
298 profilerOutput = opts.profilerOutput
or (profilerName +
".output")
303 igprofPerfOptions =
"-d -pp -z -o igprof.pp.gz".split()
306 if profilerName ==
"igprof":
307 if not opts.profilerOutput:
308 profilerOutput +=
".profile.gz"
309 profilerOptions =
"-d -z -o %s" % profilerOutput
310 profilerExecName =
"igprof"
312 elif profilerName ==
"igprofPerf":
313 if not opts.profilerOutput:
314 profilerOutput +=
".pp.gz"
315 profilerOptions =
"-d -pp -z -o %s" % profilerOutput
316 profilerExecName =
"igprof"
318 elif profilerName ==
"igprofMem":
319 if not opts.profilerOutput:
320 profilerOutput +=
".mp.gz"
321 profilerOptions =
"-d -mp -z -o %s" % profilerOutput
322 profilerExecName =
"igprof"
324 elif "valgrind" in profilerName:
326 if not opts.profilerOutput:
327 profilerOutput +=
".log"
328 toolname = profilerName.replace(
'valgrind',
'')
329 outoption =
"--log-file"
330 if toolname
in (
"massif",
"callgrind",
"cachegrind"):
331 outoption =
"--%s-out-file" % toolname
332 profilerOptions =
"--tool=%s %s=%s" % (toolname, outoption, profilerOutput)
333 profilerExecName =
"valgrind"
335 elif profilerName ==
"jemalloc":
336 opts.preload.insert(0, os.environ.get(
"JEMALLOCLIB",
"libjemalloc.so"))
337 os.environ[
'MALLOC_CONF'] =
"prof:true,prof_leak:true"
339 root_logger.warning(
"Profiler %s not recognized!" % profilerName)
342 if opts.profilerExtraOptions!=
"":
343 profilerExtraOptions = opts.profilerExtraOptions
344 profilerExtraOptions = profilerExtraOptions.replace(
"__",
"--")
345 profilerOptions +=
" %s" % profilerExtraOptions
349 import distutils.spawn
350 profilerPath = distutils.spawn.find_executable(profilerExecName)
352 root_logger.error(
"Cannot locate profiler %s" % profilerExecName)
355 root_logger.info(
"------ Profiling options are on ------ \n"\
357 " o Options: '%s'.\n"\
358 " o Output: %s" % (profilerExecName
or profilerName, profilerOptions, profilerOutput))
368 profilerOptions +=
" python"
371 arglist = [profilerPath] + profilerOptions.split() + args
372 arglist = [ a
for a
in arglist
if a!=
'' ]
376 os.execv(profilerPath, arglist)
378 arglist = [a
for a
in sys.argv
if not a.startswith(
"--profiler")]
379 os.execv(sys.executable, [sys.executable] + arglist)
383 if opts.pickle_output:
385 root_logger.error(
"Conflicting options: use only --pickle-output or --output")
388 root_logger.warning(
"--pickle-output is deprecated, use --output instead")
389 opts.output = opts.pickle_output
397 options = [
"importOptions(%r)" % f
for f
in args ]
400 optlines = list(opts.options)
402 for pos, l
in optlines:
403 options.insert(pos,l)
411 sys.modules[
"GaudiPython"] =
FakeModule(RuntimeError(
"GaudiPython cannot be used in option files"))
415 if 'GAUDI_TEMP_OPTS_FILE' in os.environ:
416 options = [
'importOptions(%r)' % os.environ[
'GAUDI_TEMP_OPTS_FILE']]
423 exec
"from Gaudi.Configuration import *" in g, l
429 if opts.no_conf_user_apply:
430 logging.info(
"Disabling automatic apply of ConfigurableUser")
432 GaudiKernel.Proxy.Configurable._appliedConfigurableUsers_ =
True
435 if opts.old_conf_user_apply:
442 if opts.post_options:
445 exec
"from Gaudi.Configuration import *" in g, l
446 for o
in opts.post_options:
450 if 'GAUDI_TEMP_OPTS_FILE' in os.environ:
451 os.remove(os.environ[
'GAUDI_TEMP_OPTS_FILE'])
452 opts.use_temp_opts =
False
454 if opts.verbose
and not opts.use_temp_opts:
455 c.printconfig(opts.old_opts, opts.all_opts)
457 c.writeconfig(opts.output, opts.all_opts)
459 if opts.use_temp_opts:
460 fd, tmpfile = mkstemp(
'.opts')
462 c.writeconfig(tmpfile, opts.all_opts)
463 os.environ[
'GAUDI_TEMP_OPTS_FILE'] = tmpfile
464 logging.info(
'Restarting from pre-parsed options')
465 os.execv(sys.executable, [sys.executable] + sys.argv)
467 c.printsequence = opts.printsequence
468 if opts.printsequence:
470 logging.warning(
"--printsequence not supported with --ncpus: ignored")
472 logging.warning(
"--printsequence not supported with --dry-run: ignored")
475 del sys.modules[
"GaudiPython"]
479 retcode = c.run(opts.gdb,opts.ncpus)
483 if opts.run_info_file:
486 run_info[
"pid"] = os.getpid()
487 run_info[
"retcode"] = retcode
488 if os.path.exists(
'/proc/self/exe'):
490 run_info[
"exe"] = os.readlink(
'/proc/self/exe')
492 logging.info(
"Saving run info to: %s" % opts.run_info_file)
493 with open(opts.run_info_file,
"w")
as f:
494 json.dump(run_info, f)
def InstallRootLoggingHandler
def applyConfigurableUsers()
def __init__(self, exception)
def option_cb(option, opt, value, parser)
def getArgsFromQmt(qmtfile)
struct GAUDI_API map
Parametrisation class for map-like implementation.
def rationalizepath(path)
def getArgsWithoutoProfilerInfo(args)
def __getattr__(self, args, kwargs)
def setLibraryPreload(newpreload)