All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Main.py
Go to the documentation of this file.
1 import sys, os
2 from time import time
3 from Gaudi import Configuration
4 import logging
5 
6 log = logging.getLogger(__name__)
7 
8 class gaudimain(object) :
9  # main loop implementation, None stands for the default
10  mainLoop = None
11 
12  def __init__(self) :
13  from Configurables import ApplicationMgr
14  appMgr = ApplicationMgr()
15  if "GAUDIAPPNAME" in os.environ:
16  appMgr.AppName = str(os.environ["GAUDIAPPNAME"])
17  if "GAUDIAPPVERSION" in os.environ:
18  appMgr.AppVersion = str(os.environ["GAUDIAPPVERSION"])
19  self.log = logging.getLogger(__name__)
20  self.printsequence = False
21 
22  def setupParallelLogging( self ) :
23  # ---------------------------------------------------
24  # set up Logging
25  # ----------------
26  # from multiprocessing import enableLogging, getLogger
27  import multiprocessing
28  # preliminaries for handlers/output files, etc.
29  from time import ctime
30  datetime = ctime()
31  datetime = datetime.replace(' ', '_')
32  outfile = open( 'gaudirun-%s.log'%(datetime), 'w' )
33  # two handlers, one for a log file, one for terminal
34  streamhandler = logging.StreamHandler(strm=outfile)
35  console = logging.StreamHandler()
36  # create formatter : the params in parentheses are variable names available via logging
37  formatter = logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" )
38  # add formatter to Handler
39  streamhandler.setFormatter(formatter)
40  console.setFormatter(formatter)
41  # now, configure the logger
42  # enableLogging( level=0 )
43  # self.log = getLogger()
44  self.log = multiprocessing.log_to_stderr()
45  self.log.setLevel( logging.INFO )
46  self.log.name = 'Gaudi/Main.py Logger'
47  self.log.handlers = []
48  # add handlers to logger : one for output to a file, one for console output
49  self.log.addHandler(streamhandler)
50  self.log.addHandler(console)
51  self.log.removeHandler(console)
52  # set level!!
53  self.log.setLevel = logging.INFO
54  # ---------------------------------------------------
55 
56  def generatePyOutput(self, all = False):
57  from pprint import pformat
58  conf_dict = Configuration.configurationDict(all)
59  return pformat(conf_dict)
60 
61  def generateOptsOutput(self, all = False):
62  from pprint import pformat
63  conf_dict = Configuration.configurationDict(all)
64  out = []
65  names = conf_dict.keys()
66  names.sort()
67  for n in names:
68  props = conf_dict[n].keys()
69  props.sort()
70  for p in props:
71  out.append('%s.%s = %s;' % (n,p, repr(conf_dict[n][p])))
72  return "\n".join(out)
73 
74  def _writepickle(self, filename) :
75  #--- Lets take the first file input file as the name of the pickle file
76  import pickle
77  output = open(filename, 'wb')
78  # Dump only the the configurables that make sense to dump (not User ones)
79  from GaudiKernel.Proxy.Configurable import getNeededConfigurables
80  to_dump = {}
81  for n in getNeededConfigurables():
82  to_dump[n] = Configuration.allConfigurables[n]
83  pickle.dump(to_dump, output, -1)
84  output.close()
85 
86  def printconfig(self, old_format = False, all = False) :
87  msg = 'Dumping all configurables and properties'
88  if not all:
89  msg += ' (different from default)'
90  log.info(msg)
91  conf_dict = Configuration.configurationDict(all)
92  if old_format:
93  print self.generateOptsOutput(all)
94  else:
95  print self.generatePyOutput(all)
96 
97  def writeconfig(self, filename, all = False):
98  write = { ".pkl" : lambda filename, all: self._writepickle(filename),
99  ".py" : lambda filename, all: open(filename,"w").write(self.generatePyOutput(all) + "\n"),
100  ".opts": lambda filename, all: open(filename,"w").write(self.generateOptsOutput(all) + "\n"),
101  }
102  from os.path import splitext
103  ext = splitext(filename)[1]
104  if ext in write:
105  write[ext](filename, all)
106  else:
107  log.error("Unknown file type '%s'. Must be any of %r.", ext, write.keys())
108  sys.exit(1)
109 
110  def _printsequence(self):
111  if not self.printsequence:
112  # No printing requested
113  return
114 
115  def printAlgo( algName, appMgr, prefix = ' ') :
116  print prefix + algName
117  alg = appMgr.algorithm( algName.split( "/" )[ -1 ] )
118  prop = alg.properties()
119  if prop.has_key( "Members" ) :
120  subs = prop[ "Members" ].value()
121  for i in subs : printAlgo( i.strip( '"' ), appMgr, prefix + " " )
122  elif prop.has_key( "DetectorList" ) :
123  subs = prop[ "DetectorList" ].value()
124  for i in subs : printAlgo( algName.split( "/" )[ -1 ] + i.strip( '"' ) + "Seq", appMgr, prefix + " ")
125 
126  mp = self.g.properties()
127  print "\n ****************************** Algorithm Sequence **************************** \n"
128  for i in mp["TopAlg"].value(): printAlgo( i, self.g )
129  print "\n ****************************************************************************** \n"
130 
131  ## Instantiate and run the application.
132  # Depending on the number of CPUs (ncpus) specified, it start
133  def run(self, ncpus = None):
134  if not ncpus:
135  # Standard sequential mode
136  result = self.runSerial()
137  else:
138  # Otherwise, run with the specified number of cpus
139  result = self.runParallel(ncpus)
140  return result
141 
142 
143  def runSerial(self) :
144  #--- Instantiate the ApplicationMgr------------------------------
145  import GaudiPython
146  self.log.debug('-'*80)
147  self.log.debug('%s: running in serial mode', __name__)
148  self.log.debug('-'*80)
149  sysStart = time()
151  self._printsequence()
152  runner = self.mainLoop or (lambda app, nevt: app.run(nevt))
153  try:
154  statuscode = runner(self.g, self.g.EvtMax)
155  except SystemError:
156  # It may not be 100% correct, but usually it means a segfault in C++
157  self.g.ReturnCode = 128 + 11
158  statuscode = False
159  except:
160  # for other exceptions, just set a generic error code
161  self.g.ReturnCode = 1
162  statuscode = False
163  if hasattr(statuscode, "isSuccess"):
164  success = statuscode.isSuccess()
165  else:
166  success = statuscode
167  success = self.g.exit().isSuccess() and success
168  if not success and self.g.ReturnCode == 0:
169  # ensure that the return code is correctly set
170  self.g.ReturnCode = 1
171  sysTime = time()-sysStart
172  self.log.debug('-'*80)
173  self.log.debug('%s: serial system finished, time taken: %5.4fs', __name__, sysTime)
174  self.log.debug('-'*80)
175  return self.g.ReturnCode
176 
177  def runParallel(self, ncpus) :
178  if self.mainLoop:
179  self.log.fatal("Cannot use custom main loop in multi-process mode, check your options")
180  return 1
181  self.setupParallelLogging( )
182  from Gaudi.Configuration import Configurable
183  import GaudiMP.GMPBase as gpp
184  c = Configurable.allConfigurables
185  self.log.info('-'*80)
186  self.log.info('%s: Parallel Mode : %i '%(__name__, ncpus))
187  from commands import getstatusoutput as gso
188  metadataCommands = [ 'uname -a',
189  'echo $CMTCONFIG',
190  'echo $GAUDIAPPNAME',
191  'echo $GAUDIAPPVERSION']
192  for comm in metadataCommands :
193  s, o = gso( comm )
194  if s :
195  o = "Undetermined"
196  string = '%s: %30s : %s '%(__name__, comm, o)
197  self.log.info( string )
198  try :
199  events = str(c['ApplicationMgr'].EvtMax)
200  except :
201  events = "Undetermined"
202  self.log.info('%s: Events Specified : %s '%(__name__,events))
203  self.log.info('-'*80)
204  # Parall = gpp.Coordinator(ncpus, shared, c, self.log)
205  Parall = gpp.Coord( ncpus, c, self.log )
206  sysStart = time()
207  sc = Parall.Go()
208  self.log.info('MAIN.PY : received %s from Coordinator'%(sc))
209  if sc.isFailure() :
210  return 1
211  sysTime = time()-sysStart
212  self.log.name = 'Gaudi/Main.py Logger'
213  self.log.info('-'*80)
214  self.log.info('%s: parallel system finished, time taken: %5.4fs', __name__, sysTime)
215  self.log.info('-'*80)
216  return 0
def generateOptsOutput
Definition: Main.py:61
def setupParallelLogging
Definition: Main.py:22
The Application Manager class.
def generatePyOutput
Definition: Main.py:56
def run
Instantiate and run the application.
Definition: Main.py:133