| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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()
150 self.g = GaudiPython.AppMgr()
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