| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# gaudirun.py

Go to the documentation of this file.

    00001 #!/usr/bin/env python
    00002
    00003 #---------------------------------------------------------------------
    00004 if __name__ == "__main__":
    00005     import os, sys
    00006     from optparse import OptionParser
    00007     parser = OptionParser(usage = "%prog [options] <opts_file> ...")
    00008     parser.add_option("-n","--dry-run", action="store_true",
    00009                       help="do not run the application, just parse option files")
    00010     parser.add_option("-p","--pickle-output", action="store", type="string",
    00011                       metavar = "FILE",
    00012                       help="DEPRECATED: use '--output file.pkl' instead. Write "
    00013                            "the parsed options as a pickle file (static option "
    00014                            "file)")
    00015     parser.add_option("-v","--verbose", action="store_true",
    00016                       help="print the parsed options")
    00017     parser.add_option("--old-opts", action="store_true",
    00018                       help="format printed options in old option files style")
    00019     parser.add_option("--all-opts", action="store_true",
    00020                       help="print all the option (even if equal to default)")
    00021     # GaudiPython Parallel Mode Option
    00022     #   Argument must be an integer in range [ -1, sys_cpus ]
    00023     #   -1   : All available cpus
    00024     #    0   : Serial Mode (traditional gaudirun)
    00025     #    n>0 : parallel with n cpus (n <= sys_cpus)
    00026     parser.add_option("--ncpus", action="store", type="int", default=0,
    00027                       help="start the application in parallel mode using NCPUS processes. "
    00028                            "0 => serial mode (default), -1 => use all CPUs")
    00029
    00030     def option_cb(option, opt, value, parser):
    00031         """Add the option line to a list together with its position in the
    00032         argument list.
    00033         """
    00034         parser.values.options.append((len(parser.largs), value))
    00035     parser.add_option("--option", action="callback", callback=option_cb,
    00036                       type = "string", nargs = 1,
    00037                       help="add a single line (Python) option to the configuration. "
    00038                            "All options lines are executed, one after the other, in "
    00039                            "the same context.")
    00040     parser.add_option("--no-conf-user-apply", action="store_true",
    00041                       help="disable the automatic application of configurable "
    00042                            "users (for backward compatibility)")
    00043     parser.add_option("-o", "--output", action = "store", type = "string",
    00044                       help ="dump the configuration to a file. The format of "
    00045                             "the options is determined by the extension of the "
    00046                             "file name: .pkl = pickle, .py = python, .opts = "
    00047                             "old style options. The python format cannot be "
    00048                             "used to run the application and it contains the "
    00049                             "same dictionary printed with -v")
    00050     parser.add_option("--post-option", action="append", type="string",
    00051                       dest="post_options",
    00052                       help="Python options to be executed after the ConfigurableUser "
    00053                            "are applied. "
    00054                            "All options lines are executed, one after the other, in "
    00055                            "the same context.")
    00056     parser.add_option("--debug", action="store_true",
    00057                       help="enable some debug print-out")
    00058     parser.add_option("--printsequence", action="store_true",
    00059                       help="print the sequence")
    00060     if not sys.platform.startswith("win"):
    00061         # These options can be used only on unix platforms
    00062         parser.add_option("-T", "--tcmalloc", action="store_true",
    00063                           help="Use the Google malloc replacement. The environment "
    00064                                "variable TCMALLOCLIB can be used to specify a different "
    00065                                "name for the library (the default is libtcmalloc.so)")
    00066         parser.add_option("--preload", action="append",
    00067                           help="Allow pre-loading of special libraries (e.g. Google "
    00068                                "profiling libraries).")
    00069     parser.set_defaults(options = [],
    00070                         tcmalloc = False,
    00071                         preload = [],
    00072                         ncpus = None)
    00073
    00074     opts, args = parser.parse_args()
    00075
    00076     # Check consistency of options
    00077
    00078     # Parallel Option ---------------------------------------------------------
    00079     from commands import getstatusoutput as gso
    00080     if opts.ncpus != None :
    00081         # try to find the max number of cpus in system (with builtin modules!)
    00082         stat, out = gso('cat /proc/cpuinfo | grep processor | wc -l')
    00083         if stat :
    00084             # command failed, set a default
    00085             sys_cpus = 8
    00086         else :
    00087             sys_cpus = int(out)
    00088         if opts.ncpus < -1 :
    00089             s = "Invalid value : --ncpus must be integer >= -1"
    00090             parser.error( s )
    00091         if opts.ncpus > sys_cpus :
    00092             s = "Invalid value : --ncpus : only %i cpus available"%(sys_cpus)
    00093             parser.error( s )
    00094         if opts.ncpus == 0 :
    00095             # revert to serial version, as if the option was not used.
    00096             opts.ncpus = None
    00097
    00098     # configure the logging
    00099     import logging
    00100     from GaudiKernel.ProcessJobOptions import InstallRootLoggingHandler
    00101
    00102     if opts.old_opts: prefix = "// "
    00103     else: prefix = "# "
    00104     level = logging.INFO
    00105     if opts.debug:
    00106         level = logging.DEBUG
    00107     InstallRootLoggingHandler(prefix, level = level)
    00108     root_logger = logging.getLogger()
    00109
    00110     # tcmalloc support
    00111     if opts.tcmalloc:
    00112         opts.preload.insert(0, os.environ.get("TCMALLOCLIB", "libtcmalloc.so"))
    00113     # allow preloading of libraries
    00114     if opts.preload:
    00115         preload = os.environ.get("LD_PRELOAD", "")
    00116         if preload:
    00117             preload = preload.replace(" ", ":").split(":")
    00118         else:
    00119             preload = []
    00120         for libname in set(preload).intersection(opts.preload):
    00121             logging.warning("Ignoring preload of library %s because it is "
    00122                             "already in LD_PRELOAD.", libname)
    00123         to_load = [libname
    00124                    for libname in opts.preload
    00125                    if libname not in set(preload)]
    00126         if to_load:
    00127             preload += to_load
    00128             preload = ":".join(preload)
    00129             os.environ["LD_PRELOAD"] = preload
    00130             logging.info("Restarting with LD_PRELOAD='%s'", preload)
    00131             # remove the --tcmalloc option from the arguments
    00132             # FIXME: the --preload arguments will issue a warning but it's tricky to remove them
    00133             args = [ a for a in sys.argv if a != '-T' and not '--tcmalloc'.startswith(a) ]
    00134             os.execv(sys.executable, [sys.executable] + args)
    00135
    00136     if opts.pickle_output:
    00137         if opts.output:
    00138             root_logger.error("Conflicting options: use only --pickle-output or --output")
    00139             sys.exit(1)
    00140         else:
    00141             root_logger.warning("--pickle-output is deprecated, use --output instead")
    00142             opts.output = opts.pickle_output
    00143
    00144     from Gaudi.Main import gaudimain
    00145     c = gaudimain()
    00146
    00147     # Prepare the "configuration script" to parse (like this it is easier than
    00148     # having a list with files and python commands, with an if statements that
    00149     # decides to do importOptions or exec)
    00150     options = [ "importOptions(%r)" % f for f in args ]
    00151     # The option lines are inserted into the list of commands using their
    00152     # position on the command line
    00153     optlines = list(opts.options)
    00154     optlines.reverse() # this allows to avoid to have to care about corrections of the positions
    00155     for pos, l in optlines:
    00156         options.insert(pos,l)
    00157
    00158     # prevent the usage of GaudiPython
    00159     class FakeModule(object):
    00160         def __init__(self, exception):
    00161             self.exception = exception
    00162         def __getattr__(self, *args, **kwargs):
    00163             raise self.exception
    00164     sys.modules["GaudiPython"] = FakeModule(RuntimeError("GaudiPython cannot be used in option files"))
    00165
    00166     # "execute" the configuration script generated (if any)
    00167     if options:
    00168         g = {}
    00169         l = {}
    00170         exec "from Gaudi.Configuration import *" in g, l
    00171         for o in options:
    00172             logging.debug(o)
    00173             exec o in g, l
    00174
    00175     import GaudiKernel.Proxy.Configurable
    00176     if opts.no_conf_user_apply:
    00177         logging.info("Disabling automatic apply of ConfigurableUser")
    00178         # pretend that they have been already applied
    00179         GaudiKernel.Proxy.Configurable._appliedConfigurableUsers_ = True
    00180
    00181     # This need to be done before dumping
    00182     from GaudiKernel.Proxy.Configurable import applyConfigurableUsers
    00183     applyConfigurableUsers()
    00184
    00185     # Options to be processed after applyConfigurableUsers
    00186     if opts.post_options:
    00187         g = {}
    00188         l = {}
    00189         exec "from Gaudi.Configuration import *" in g, l
    00190         for o in opts.post_options:
    00191             logging.debug(o)
    00192             exec o in g, l
    00193
    00194     if opts.verbose:
    00195         c.printconfig(opts.old_opts, opts.all_opts)
    00196     if opts.output:
    00197         c.writeconfig(opts.output, opts.all_opts)
    00198     if opts.printsequence:
    00199         c.printsequence()
    00200
    00201     # re-enable the GaudiPython module
    00202     del sys.modules["GaudiPython"]
    00203
    00204     if not opts.dry_run:
    00205         # Do the real processing
    00206         sys.exit(c.run(opts.ncpus))

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines