00001 import sys, os
00002 from time import time
00003 from Gaudi import Configuration
00004 import logging
00005
00006 log = logging.getLogger(__name__)
00007
00008 class gaudimain(object) :
00009
00010 mainLoop = None
00011
00012 def __init__(self) :
00013 from Configurables import ApplicationMgr
00014 appMgr = ApplicationMgr()
00015 if "GAUDIAPPNAME" in os.environ:
00016 appMgr.AppName = str(os.environ["GAUDIAPPNAME"])
00017 if "GAUDIAPPVERSION" in os.environ:
00018 appMgr.AppVersion = str(os.environ["GAUDIAPPVERSION"])
00019 self.log = logging.getLogger(__name__)
00020 self.printsequence = False
00021
00022 def setupParallelLogging( self ) :
00023
00024
00025
00026
00027 import multiprocessing
00028
00029 from time import ctime
00030 datetime = ctime()
00031 datetime = datetime.replace(' ', '_')
00032 outfile = open( 'gaudirun-%s.log'%(datetime), 'w' )
00033
00034 streamhandler = logging.StreamHandler(strm=outfile)
00035 console = logging.StreamHandler()
00036
00037 formatter = logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" )
00038
00039 streamhandler.setFormatter(formatter)
00040 console.setFormatter(formatter)
00041
00042
00043
00044 self.log = multiprocessing.log_to_stderr()
00045 self.log.setLevel( logging.INFO )
00046 self.log.name = 'Gaudi/Main.py Logger'
00047 self.log.handlers = []
00048
00049 self.log.addHandler(streamhandler)
00050 self.log.addHandler(console)
00051 self.log.removeHandler(console)
00052
00053 self.log.setLevel = logging.INFO
00054
00055
00056 def generatePyOutput(self, all = False):
00057 from pprint import pformat
00058 conf_dict = Configuration.configurationDict(all)
00059 return pformat(conf_dict)
00060
00061 def generateOptsOutput(self, all = False):
00062 from pprint import pformat
00063 conf_dict = Configuration.configurationDict(all)
00064 out = []
00065 names = conf_dict.keys()
00066 names.sort()
00067 for n in names:
00068 props = conf_dict[n].keys()
00069 props.sort()
00070 for p in props:
00071 out.append('%s.%s = %s;' % (n,p, repr(conf_dict[n][p])))
00072 return "\n".join(out)
00073
00074 def _writepickle(self, filename) :
00075
00076 import pickle
00077 output = open(filename, 'wb')
00078
00079 from GaudiKernel.Proxy.Configurable import getNeededConfigurables
00080 to_dump = {}
00081 for n in getNeededConfigurables():
00082 to_dump[n] = Configuration.allConfigurables[n]
00083 pickle.dump(to_dump, output, -1)
00084 output.close()
00085
00086 def printconfig(self, old_format = False, all = False) :
00087 msg = 'Dumping all configurables and properties'
00088 if not all:
00089 msg += ' (different from default)'
00090 log.info(msg)
00091 conf_dict = Configuration.configurationDict(all)
00092 if old_format:
00093 print self.generateOptsOutput(all)
00094 else:
00095 print self.generatePyOutput(all)
00096
00097 def writeconfig(self, filename, all = False):
00098 write = { ".pkl" : lambda filename, all: self._writepickle(filename),
00099 ".py" : lambda filename, all: open(filename,"w").write(self.generatePyOutput(all) + "\n"),
00100 ".opts": lambda filename, all: open(filename,"w").write(self.generateOptsOutput(all) + "\n"),
00101 }
00102 from os.path import splitext
00103 ext = splitext(filename)[1]
00104 if ext in write:
00105 write[ext](filename, all)
00106 else:
00107 log.error("Unknown file type '%s'. Must be any of %r.", ext, write.keys())
00108 sys.exit(1)
00109
00110 def _printsequence(self):
00111 if not self.printsequence:
00112
00113 return
00114
00115 def printAlgo( algName, appMgr, prefix = ' ') :
00116 print prefix + algName
00117 alg = appMgr.algorithm( algName.split( "/" )[ -1 ] )
00118 prop = alg.properties()
00119 if prop.has_key( "Members" ) :
00120 subs = prop[ "Members" ].value()
00121 for i in subs : printAlgo( i.strip( '"' ), appMgr, prefix + " " )
00122 elif prop.has_key( "DetectorList" ) :
00123 subs = prop[ "DetectorList" ].value()
00124 for i in subs : printAlgo( algName.split( "/" )[ -1 ] + i.strip( '"' ) + "Seq", appMgr, prefix + " ")
00125
00126 mp = self.g.properties()
00127 print "\n ****************************** Algorithm Sequence **************************** \n"
00128 for i in mp["TopAlg"].value(): printAlgo( i, self.g )
00129 print "\n ****************************************************************************** \n"
00130
00131
00132
00133 def run(self, ncpus = None):
00134 if not ncpus:
00135
00136 result = self.runSerial()
00137 else:
00138
00139 result = self.runParallel(ncpus)
00140 return result
00141
00142
00143 def runSerial(self) :
00144
00145 import GaudiPython
00146 self.log.debug('-'*80)
00147 self.log.debug('%s: running in serial mode', __name__)
00148 self.log.debug('-'*80)
00149 sysStart = time()
00150 self.g = GaudiPython.AppMgr()
00151 self._printsequence()
00152 runner = self.mainLoop or (lambda app, nevt: app.run(nevt))
00153 statuscode = runner(self.g, self.g.EvtMax)
00154 if hasattr(statuscode, "isSuccess"):
00155 success = statuscode.isSuccess()
00156 else:
00157 success = statuscode
00158 success = self.g.exit().isSuccess() and success
00159 if not success and self.g.ReturnCode == 0:
00160
00161 self.g.ReturnCode = 1
00162 sysTime = time()-sysStart
00163 self.log.debug('-'*80)
00164 self.log.debug('%s: serial system finished, time taken: %5.4fs', __name__, sysTime)
00165 self.log.debug('-'*80)
00166 return self.g.ReturnCode
00167
00168 def runParallel(self, ncpus) :
00169 if self.mainLoop:
00170 self.log.fatal("Cannot use custom main loop in multi-process mode, check your options")
00171 return 1
00172 self.setupParallelLogging( )
00173 from Gaudi.Configuration import Configurable
00174 import GaudiMP.GMPBase as gpp
00175 c = Configurable.allConfigurables
00176 self.log.info('-'*80)
00177 self.log.info('%s: Parallel Mode : %i '%(__name__, ncpus))
00178 from commands import getstatusoutput as gso
00179 metadataCommands = [ 'uname -a',
00180 'echo $CMTCONFIG',
00181 'echo $GAUDIAPPNAME',
00182 'echo $GAUDIAPPVERSION']
00183 for comm in metadataCommands :
00184 s, o = gso( comm )
00185 if s :
00186 o = "Undetermined"
00187 string = '%s: %30s : %s '%(__name__, comm, o)
00188 self.log.info( string )
00189 try :
00190 events = str(c['ApplicationMgr'].EvtMax)
00191 except :
00192 events = "Undetermined"
00193 self.log.info('%s: Events Specified : %s '%(__name__,events))
00194 self.log.info('-'*80)
00195
00196 Parall = gpp.Coord( ncpus, c, self.log )
00197 sysStart = time()
00198 sc = Parall.Go()
00199 self.log.info('MAIN.PY : received %s from Coordinator'%(sc))
00200 if sc.isFailure() :
00201 return 1
00202 sysTime = time()-sysStart
00203 self.log.name = 'Gaudi/Main.py Logger'
00204 self.log.info('-'*80)
00205 self.log.info('%s: parallel system finished, time taken: %5.4fs', __name__, sysTime)
00206 self.log.info('-'*80)
00207 return 0