CMS 3D CMS Logo

Classes | Public Member Functions | Public Attributes | Private Attributes

cmsPerfSuite::PerfSuite Class Reference

List of all members.

Classes

class  PerfTest
class  simpleGenReportThread

Public Member Functions

def __init__
def benchmarks
 Run cmsScimark benchmarks a number of times.
def cprootfile
 Copy root file from another candle's directory ! Again this is messy.
def displayErrors
 Display G4 cerr errors and CMSExceptions in the logfile.
def getDate
def mkCandleDir
 Make directory for a particular candle and profiler.
def optionParse
def printDate
def printFlush
 Print and flush a string (for output to a log file)
def runcmd
 Run a command and return the exit status.
def runCmdSet
 Run a list of commands using system ! We should rewrite this not to use system (most cases it is unnecessary)
def runCmsInput
 Wrapper for cmsRelvalreportInput.
def runCmsReport
 This function is a wrapper around cmsRelvalreport.
def runPerfSuite
 Runs benchmarking, cpu spinlocks on spare cores and profiles selected candles.
def simpleGenReport
 Prepares the profiling directory and runs all the selected profiles (if this is not a unit test)
def testCmsDriver
 Test cmsDriver.py (parses the simcandles file, removing duplicate lines, and runs the cmsDriver part)
def valFilterReport
 Filter lines in the valgrind report that match GEN,SIM.

Public Attributes

 AuxiliaryScripts
 cmssw_arch
 cmssw_version
 Commands
 ERRORS
 HEPSPEC06
 host
 logh
 PerfTestTotalTimer
 FIXME: We may want to introduce a switch here or agree on a different default (currently 10 cmsScimark and 10 cmsScimarkLarge)
 Scripts
 user

Private Attributes

 _CASTOR_DIR
 _debug
 Developer options.
 _dryrun
 _noexec
 _unittest
 _verbose
 Check logfile option.

Detailed Description

Definition at line 60 of file cmsPerfSuite.py.


Constructor & Destructor Documentation

def cmsPerfSuite::PerfSuite::__init__ (   self)

Definition at line 61 of file cmsPerfSuite.py.

00062                       :
00063         
00064         self.ERRORS = 0
00065         self._CASTOR_DIR = "/castor/cern.ch/cms/store/relval/performance/"
00066         self._dryrun   = False
00067         self._debug    = False
00068         self._unittest = False
00069         self._noexec   = False
00070         self._verbose  = True
00071         self.logh = sys.stdout
00072     
00073         #Get some environment variables to use
00074         try:
00075             self.cmssw_arch   = os.environ["SCRAM_ARCH"]
00076             self.cmssw_version= os.environ["CMSSW_VERSION"]
00077             self.host         = os.environ["HOST"]
00078             self.user              = os.environ["USER"]
00079         except KeyError:
00080             self.logh.write('Error: An environment variable either SCRAM_ARCH, CMSSW_VERSION, HOST or USER is not available.\n')
00081             self.logh.write('       Please run eval `scramv1 runtime -csh` to set your environment variables\n')
00082             self.logh.flush()
00083             sys.exit()
00084            
00085         #Scripts used by the suite:
00086         self.Scripts         =["cmsDriver.py","cmsRelvalreport.py","cmsRelvalreportInput.py","cmsScimark2"]
00087         self.AuxiliaryScripts=["cmsScimarkLaunch.csh","cmsScimarkParser.py","cmsScimarkStop.py"]
00088 
        

Member Function Documentation

def cmsPerfSuite::PerfSuite::benchmarks (   self,
  cpu,
  pfdir,
  name,
  bencher,
  large = False 
)

Run cmsScimark benchmarks a number of times.

Definition at line 678 of file cmsPerfSuite.py.

00679                                                            :
00680         cmd = self.Commands[cpu][3]
00681         redirect = ""
00682         if large:
00683             redirect = " -large >>"    
00684         else:
00685             redirect = " >>"
00686     
00687         for i in range(bencher):
00688            #Check first for the existence of the file so that we can append:
00689            if not os.path.exists(os.path.join(pfdir,os.path.basename(name))):
00690               #Equivalent of touch to make sure the file exist to be able to append to it.
00691               open(os.path.join(pfdir,os.path.basename(name)))
00692               
00693            command= cmd + redirect + os.path.join(pfdir,os.path.basename(name))        
00694            self.printFlush(command + " [%s/%s]" % (i+1,bencher))
00695            self.runcmd(command)
00696            self.logh.flush()
    
def cmsPerfSuite::PerfSuite::cprootfile (   self,
  dir,
  candle,
  NumOfEvents,
  cmsdriverOptions = "" 
)

Copy root file from another candle's directory ! Again this is messy.

Definition at line 599 of file cmsPerfSuite.py.

00600                                                                    :
00601         cmds = ("cd %s" % dir,
00602                 "cp -pR ../%s_IgProf/%s_GEN,SIM.root ."  % (candle,CandFname[candle]))
00603         
00604         if self.runCmdSet(cmds):
00605             self.logh.write("Since there was no ../%s_IgProf/%s_GEN,SIM.root file it will be generated first\n"%(candle,CandFname[candle]))
00606 
00607             cmd = "cd %s ; cmsDriver.py %s -s GEN,SIM -n %s --fileout %s_GEN,SIM.root %s>& %s_GEN_SIM_for_valgrind.log" % (dir,KeywordToCfi[candle],str(NumOfEvents),candle,cmsdriverOptions,candle)
00608 
00609             self.printFlush(cmd)
00610             #Obsolete popen4-> subprocess.Popen
00611             #cmdout=os.popen3(cmd)[2].read()
00612             cmdout=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
00613             if cmdout:
00614                 self.printFlush(cmdout)
00615             return cmdout
            
def cmsPerfSuite::PerfSuite::displayErrors (   self,
  file 
)

Display G4 cerr errors and CMSExceptions in the logfile.

Definition at line 619 of file cmsPerfSuite.py.

00620                                 :
00621         try:
00622             for line in open(file,"r"):
00623                 if "cerr" in line or "CMSException" in line:
00624                     self.logh.write("ERROR: %s\n" % line)
00625                     self.ERRORS += 1
00626         except OSError, detail:
00627             self.logh.write("WARNING: %s\n" % detail)
00628             self.ERRORS += 1        
00629         except IOError, detail:
00630             self.logh.write("WARNING: %s\n" % detail)
00631             self.ERRORS += 1
        
def cmsPerfSuite::PerfSuite::getDate (   self)

Definition at line 579 of file cmsPerfSuite.py.

00580                      :
00581         return time.ctime()
    
def cmsPerfSuite::PerfSuite::mkCandleDir (   self,
  pfdir,
  candle,
  profiler 
)

Make directory for a particular candle and profiler.

! This is really unnecessary code and should be replaced with a os.mkdir() call

Definition at line 588 of file cmsPerfSuite.py.

00589                                                :
00590         adir = os.path.join(pfdir,"%s_%s" % (candle,profiler))
00591         self.runcmd( "mkdir -p %s" % adir )
00592         if self._verbose:
00593             self.printDate()
00594         return adir
    
def cmsPerfSuite::PerfSuite::optionParse (   self,
  argslist = None 
)

Definition at line 146 of file cmsPerfSuite.py.

00147                                        :
00148         parser = opt.OptionParser(usage='''./cmsPerfSuite.py [options]
00149            
00150     Examples:
00151     
00152     cmsPerfSuite.py --step GEN-HLT -t 5 -i 2 -c 1 -m 5 --RunTimeSize MinBias,TTbar --RunIgProf TTbar --RunCallgrind TTbar --RunMemcheck TTbar --RunDigiPileUp TTbar --PUInputFile /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root --cmsdriver="--eventcontent FEVTDEBUGHLT --conditions FrontierConditions_GlobalTag,IDEAL_V9::All"
00153     (this will run the suite with 5 events for TimeSize tests on MinBias and TTbar, 2 for IgProf tests on TTbar only, 1 for Callgrind tests on TTbar only, 5 for Memcheck on MinBias and TTbar, it will also run DIGI PILEUP for all TTbar tests defined, i.e. 5 TimeSize, 2 IgProf, 1 Callgrind, 5 Memcheck. The file /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root will be copied locally as INPUT_PILEUP_EVENTS.root and it will be used as the input file for the MixingModule pile up events. All these tests will be done for the step GEN-HLT, i.e. GEN,SIM,DIGI,L1,DIGI2RAW,HLT at once)
00154     OR
00155     cmsPerfSuite.py --step GEN-HLT -t 5 -i 2 -c 1 -m 5 --RunTimeSize MinBias,TTbar --RunIgProf TTbar --RunCallgrind TTbar --RunMemcheck TTbar --RunTimeSizePU TTbar --PUInputFile /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root
00156     (this will run the suite with 5 events for TimeSize tests on MinBias and TTbar, 2 for IgProf tests on TTbar only, 1 for Callgrind tests on TTbar only, 5 for Memcheck on MinBias and TTbar, it will also run DIGI PILEUP on TTbar but only for 5 TimeSize events. All these tests will be done for the step GEN-HLT, i.e. GEN,SIM,DIGI,L1,DIGI2RAW,HLT at once)
00157     OR
00158     cmsPerfSuite.py --step GEN-HLT -t 5 -i 2 -c 1 -m 5 --RunTimeSize MinBias,TTbar --RunIgProf TTbar --RunCallgrind TTbar --RunMemcheck TTbar --RunTimeSizePU TTbar --PUInputFile /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root --cmsdriver="--eventcontent RAWSIM --conditions FrontierConditions_GlobalTag,IDEAL_V9::All"
00159     (this will run the suite with 5 events for TimeSize tests on MinBias and TTbar, 2 for IgProf tests on TTbar only, 1 for Callgrind tests on TTbar only, 5 for Memcheck on MinBias and TTbar, it will also run DIGI PILEUP on TTbar but only for 5 TimeSize events. All these tests will be done for the step GEN-HLT, i.e. GEN,SIM,DIGI,L1,DIGI2RAW,HLT at once. It will also add the options "--eventcontent RAWSIM --conditions FrontierConditions_GlobalTag,IDEAL_V9::All" to all cmsDriver.py commands executed by the suite. In addition it will run only 2 cmsDriver.py "steps": "GEN,SIM" and "DIGI". Note the syntax GEN-SIM for combined cmsDriver.py steps)
00160     
00161     Legal entries for individual candles (--RunTimeSize, --RunIgProf, --RunCallgrind, --RunMemcheck options):
00162     %s
00163     ''' % ("\n".join(Candles)))
00164     
00165         parser.set_defaults(TimeSizeEvents   = 0        ,
00166                             IgProfEvents     = 0          ,
00167                             CallgrindEvents  = 0          ,
00168                             MemcheckEvents   = 0          ,
00169                             cmsScimark       = 10         ,
00170                             cmsScimarkLarge  = 10         ,  
00171                             cmsdriverOptions = "--eventcontent FEVTDEBUGHLT", # Decided to avoid using the automatic parsing of cmsDriver_highstats_hlt.txt: cmsRelValCmd.get_cmsDriverOptions(), #Get these options automatically now!
00172                             #"Release Integrators" will create another file relative to the performance suite and the operators will fetch from that file the --cmsdriver option... for now just set the eventcontent since that is needed in order for things to run at all now...
00173                             stepOptions      = ""         ,
00174                             profilers        = ""         ,
00175                             outputdir        = ""         ,
00176                             logfile          = os.path.join(os.getcwd(),"cmsPerfSuite.log"),
00177                             runonspare       = True       ,
00178                             bypasshlt        = False      ,
00179                             quicktest        = False      ,
00180                             unittest         = False      ,
00181                             noexec           = False      ,
00182                             dryrun           = False      ,
00183                             verbose          = True       ,
00184                             previousrel      = ""         ,
00185                             castordir        = self._CASTOR_DIR,
00186                             cores            = cmsCpuInfo.get_NumOfCores(), #Get Number of cpu cores on the machine from /proc/cpuinfo
00187                             cpu              = "1"        , #Cpu core on which the suite is run:
00188                             RunTimeSize      = ""         ,
00189                             RunIgProf        = ""         ,
00190                             RunCallgrind     = ""         ,
00191                             RunMemcheck      = ""         ,
00192                             RunDigiPileUP    = ""         ,
00193                             RunTimeSizePU    = ""         ,
00194                             RunIgProfPU      = ""         ,
00195                             RunCallgrindPU   = ""         ,
00196                             RunMemcheckPU    = ""         ,
00197                             PUInputFile      = ""         ,
00198                             userInputFile    = ""         )
00199         parser.add_option('-q', '--quiet'      , action="store_false", dest='verbose'   ,
00200             help = 'Output less information'                  )
00201         parser.add_option('-b', '--bypass-hlt' , action="store_true" , dest='bypasshlt' ,
00202             help = 'Bypass HLT root file as input to RAW2DIGI')
00203         parser.add_option('-n', '--notrunspare', action="store_false", dest='runonspare',
00204             help = 'Do not run cmsScimark on spare cores')        
00205         parser.add_option('-t', '--timesize'  , type='int'   , dest='TimeSizeEvents'  , metavar='<#EVENTS>'   ,
00206             help = 'specify the number of events for the TimeSize tests'                   )
00207         parser.add_option('-i', '--igprof'    , type='int'   , dest='IgProfEvents'    , metavar='<#EVENTS>'   ,
00208             help = 'specify the number of events for the IgProf tests'                     )
00209         parser.add_option('-c', '--callgrind'  , type='int'   , dest='CallgrindEvents'  , metavar='<#EVENTS>'   ,
00210             help = 'specify the number of events for the Callgrind tests'                   )
00211         parser.add_option('-m', '--memcheck'  , type='int'   , dest='MemcheckEvents'  , metavar='<#EVENTS>'   ,
00212             help = 'specify the number of events for the Memcheck tests'                   )
00213         parser.add_option('--cmsScimark'      , type='int'   , dest='cmsScimark'      , metavar=''            ,
00214             help = 'specify the number of times the cmsScimark benchmark is run before and after the performance suite on cpu1')
00215         parser.add_option('--cmsScimarkLarge' , type='int'   , dest='cmsScimarkLarge' , metavar=''            ,
00216             help = 'specify the number of times the cmsScimarkLarge benchmark is run before and after the performance suite on cpu1')
00217         parser.add_option('--cores'           , type='int', dest='cores'              , metavar='<CORES>'     ,
00218             help = 'specify the number of cores of the machine (can be used with 0 to stop cmsScimark from running on the other cores)')        
00219         parser.add_option('--cmsdriver' , type='string', dest='cmsdriverOptions', metavar='<OPTION_STR>',
00220             help = 'specify special options to use with the cmsDriver.py commands (designed for integration build use')        
00221         parser.add_option('-a', '--archive'   , type='string', dest='castordir'       , metavar='<DIR>'       ,
00222             help = 'specify the wanted CASTOR directory where to store the results tarball')
00223         parser.add_option('-L', '--logfile'   , type='string', dest='logfile'         , metavar='<FILE>'      ,
00224             help = 'file to store log output of the script')                
00225         parser.add_option('-o', '--output'    , type='string', dest='outputdir'       , metavar='<DIR>'       ,
00226             help = 'specify the directory where to store the output of the script')        
00227         parser.add_option('-r', '--prevrel'   , type='string', dest='previousrel'     , metavar='<DIR>'       ,
00228             help = 'Top level dir of previous release for regression analysis')        
00229         parser.add_option('--step'            , type='string', dest='stepOptions'     , metavar='<STEPS>'     ,
00230             help = 'specify the processing steps intended (instead of the default ones)' )
00231         parser.add_option('--cpu'             , type='string', dest='cpu'             , metavar='<CPU>'       ,
00232             help = 'specify the core on which to run the performance suite')
00233 
00234         #Adding new options to put everything configurable at command line:
00235         parser.add_option('--RunTimeSize'             , type='string', dest='RunTimeSize' , metavar='<CANDLES>'       ,
00236             help = 'specify on which candles to run the TimeSize tests')
00237         parser.add_option('--RunIgProf'             , type='string', dest='RunIgProf' , metavar='<CANDLES>'       ,
00238             help = 'specify on which candles to run the IgProf tests')
00239         parser.add_option('--RunCallgrind'             , type='string', dest='RunCallgrind' , metavar='<CANDLES>'       ,
00240             help = 'specify on which candles to run the Callgrind tests')
00241         parser.add_option('--RunMemcheck'             , type='string', dest='RunMemcheck' , metavar='<CANDLES>'       ,
00242             help = 'specify on which candles to run the Memcheck tests')
00243         parser.add_option('--RunDigiPileUp'             , type='string', dest='RunDigiPileUp' , metavar='<CANDLES>'       ,
00244             help = 'specify the candle on which to run DIGI PILE UP and repeat all the tests set to run on that candle with PILE UP')
00245         parser.add_option('--PUInputFile'             , type='string', dest='PUInputFile' , metavar='<FILE>'       ,
00246             help = 'specify the root file to pick the pile-up events from')
00247         parser.add_option('--RunTimeSizePU'             , type='string', dest='RunTimeSizePU' , metavar='<CANDLES>'       ,
00248             help = 'specify on which candles to run the TimeSize tests with PILE UP')
00249         parser.add_option('--RunIgProfPU'             , type='string', dest='RunIgProfPU' , metavar='<CANDLES>'       ,
00250             help = 'specify on which candles to run the IgProf tests with PILE UP')
00251         parser.add_option('--RunCallgrindPU'             , type='string', dest='RunCallgrindPU' , metavar='<CANDLES>'       ,
00252             help = 'specify on which candles to run the Callgrind tests with PILE UP')
00253         parser.add_option('--RunMemcheckPU'             , type='string', dest='RunMemcheckPU' , metavar='<CANDLES>'       ,
00254             help = 'specify on which candles to run the Memcheck tests with PILE UP')
00255 
00256         #Adding a filein option to use pre-processed RAW file for RECO and HLT:
00257         parser.add_option('--filein'             , type='string', dest='userInputFile' , metavar='<FILE>', #default="",
00258             help = 'specify input RAW root file for HLT and RAW2DIGI-RECO (list the files in the same order as the candles for the tests)')
00259 
00260         #Adding an option to handle additional (to the default user) email addresses to the email notification list (that sends the cmsPerfSuite.log once the performance suite is done running):
00261         parser.add_option('--mail', type='string', dest='MailLogRecipients', metavar='<EMAIL ADDRESS>', default=self.user, help='specify valid email address(es) name@domain in order to receive notification at the end of the performance suite running with the cmsPerfSuite.log file')
00262 
00263         #Adding option to turn off tarball creation at the end of the execution of the performance suite:
00264         parser.add_option('--no_tarball', action="store_false", dest='tarball', default=True, help='Turn off automatic tarball creation at the end of the performance suite execution')
00265                 
00266         #####################
00267         #    
00268         # Developer options
00269         #
00270     
00271         devel  = opt.OptionGroup(parser, "Developer Options",
00272                                          "Caution: use these options at your own risk."
00273                                          "It is believed that some of them bite.\n")
00274     
00275         devel.add_option('-p', '--profile'  , type="str" , dest='profilers', metavar="<PROFILERS>" ,
00276             help = 'Profile codes to use for cmsRelvalInput' )
00277         devel.add_option('-f', '--false-run', action="store_true", dest='dryrun'   ,
00278             help = 'Dry run'                                                                                           )            
00279         devel.add_option('-d', '--debug'    , action='store_true', dest='debug'    ,
00280             help = 'Debug'                                                                                             )
00281         devel.add_option('--quicktest'      , action="store_true", dest='quicktest',
00282             help = 'Quick overwrite all the defaults to small numbers so that we can run a quick test of our chosing.' )  
00283         devel.add_option('--test'           , action="store_true", dest='unittest' ,
00284             help = 'Perform a simple test, overrides other options. Overrides verbosity and sets it to false.'         )            
00285         devel.add_option('--no_exec'           , action="store_true", dest='noexec' ,
00286             help = 'Run the suite without executing the cmsRelvalreport.py commands in the various directories. This is a useful debugging tool.'         )
00287         parser.add_option_group(devel)
00288         (options, args) = parser.parse_args(argslist)
00289     
00290     
00291         self._debug           = options.debug
00292         self._unittest        = options.unittest
00293         self._noexec          = options.noexec
00294         self._verbose         = options.verbose
00295         self._dryrun          = options.dryrun    
00296         castordir        = options.castordir
00297         TimeSizeEvents   = options.TimeSizeEvents
00298         IgProfEvents     = options.IgProfEvents
00299         CallgrindEvents  = options.CallgrindEvents
00300         MemcheckEvents   = options.MemcheckEvents
00301         cmsScimark       = options.cmsScimark
00302         cmsScimarkLarge  = options.cmsScimarkLarge
00303         cmsdriverOptions = options.cmsdriverOptions
00304         stepOptions      = options.stepOptions
00305         quicktest        = options.quicktest
00306         #candleoption     = options.candleOptions
00307         runonspare       = options.runonspare
00308         profilers        = options.profilers.strip()
00309         cpu              = options.cpu.strip()
00310         bypasshlt        = options.bypasshlt
00311         cores            = options.cores
00312         logfile          = options.logfile
00313         prevrel          = options.previousrel
00314         outputdir        = options.outputdir
00315         RunTimeSize      = options.RunTimeSize
00316         RunIgProf        = options.RunIgProf
00317         RunCallgrind     = options.RunCallgrind
00318         RunMemcheck      = options.RunMemcheck
00319         RunDigiPileUp    = options.RunDigiPileUp
00320         RunTimeSizePU    = options.RunTimeSizePU
00321         RunIgProfPU      = options.RunIgProfPU
00322         RunCallgrindPU   = options.RunCallgrindPU
00323         RunMemcheckPU    = options.RunMemcheckPU
00324         PUInputFile      = options.PUInputFile
00325         userInputFile    = options.userInputFile
00326         if options.MailLogRecipients !="" and self.user not in options.MailLogRecipients: #To allow for the --mail "" case of suppressing the email and the default user case
00327            MailLogRecipients= self.user+","+options.MailLogRecipients #Add the user by default if there is a mail report
00328         else:
00329            MailLogRecipients=options.MailLogRecipients
00330         tarball          = options.tarball
00331     
00332         #################
00333         # Check logfile option
00334         #
00335         if not logfile == None:
00336             logfile = os.path.abspath(logfile)
00337             logdir = os.path.dirname(logfile)
00338             if not os.path.exists(logdir):
00339                 parser.error("Directory to output logfile does not exist")
00340                 sys.exit()
00341             logfile = os.path.abspath(logfile)
00342     
00343         #############
00344         # Check step Options
00345         #
00346         if "GEN,SIM" in stepOptions:
00347             self.logh.write("WARNING: Please use GEN-SIM with a hypen not a \",\"!\n")
00348         #Using the step option as a switch between different dictionaries for:
00349         #RunTimeSize,RunIgProf,RunCallgrind,RunMemCheck,RunDigiPileUp:
00350         if stepOptions == "" or stepOptions == 'Default':
00351             pass
00352         else:
00353             stepOptions='--usersteps=%s' % (stepOptions)        
00354     
00355         ###############
00356         # Check profile option
00357         #
00358         isnumreg = re.compile("^-?[0-9]*$")
00359         found    = isnumreg.search(profilers)
00360         if not found :
00361             parser.error("profile codes option contains non-numbers")
00362             sys.exit()
00363     
00364         ###############
00365         # Check output directory option
00366         #
00367         if outputdir == "":
00368             outputdir = os.getcwd()
00369         else:
00370             outputdir = os.path.abspath(outputdir)
00371     
00372         if not os.path.isdir(outputdir):
00373             parser.error("%s is not a valid output directory" % outputdir)
00374             sys.exit()
00375             
00376         ################
00377         # Check cpu option
00378         # 
00379         numetcomreg = re.compile("^[0-9,]*")
00380         if not numetcomreg.search(cpu):
00381             parser.error("cpu option needs to be a comma separted list of ints or a single int")
00382             sys.exit()
00383     
00384         cpustr = cpu
00385         cpu = []
00386         if "," in cpustr:
00387             cpu = map(lambda x: int(x),cpustr.split(","))
00388         else:
00389             cpu = [ int(cpustr)  ]
00390     
00391         ################
00392         # Check previous release directory
00393         #
00394         if not prevrel == "":
00395             prevrel = os.path.abspath(prevrel)
00396             if not os.path.exists(prevrel):
00397                 self.logh.write("ERROR: Previous release dir %s could not be found" % prevrel)
00398                 sys.exit()
00399     
00400         #############
00401         # Setup quicktest option
00402         #
00403         if quicktest:
00404             TimeSizeEvents = 1
00405             IgProfEvents = 1
00406             CallgrindEvents = 0
00407             MemcheckEvents = 0
00408             cmsScimark = 1
00409             cmsScimarkLarge = 1
00410     
00411         #############
00412         # Setup unit test option
00413         #
00414         if self._unittest:
00415             self._verbose = False
00416             if stepOptions == "":
00417                 stepOptions = "GEN-SIM,DIGI,L1,DIGI2RAW,HLT,RAW2DIGI-RECO"
00418             cmsScimark      = 0
00419             cmsScimarkLarge = 0
00420             CallgrindEvents  = 0
00421             MemcheckEvents  = 0
00422             IgProfEvents    = 0
00423             TimeSizeEvents  = 1
00424         
00425         #Split all the RunTimeSize etc candles in lists:
00426         TimeSizeCandles=[]
00427         IgProfCandles=[]
00428         CallgrindCandles=[]
00429         MemcheckCandles=[]
00430         TimeSizePUCandles=[]
00431         IgProfPUCandles=[]
00432         CallgrindPUCandles=[]
00433         MemcheckPUCandles=[]
00434         userInputRootFiles=[]
00435         if RunTimeSize:
00436             TimeSizeCandles = RunTimeSize.split(",")
00437         if RunIgProf:
00438             IgProfCandles = RunIgProf.split(",")
00439         if RunCallgrind:
00440             CallgrindCandles = RunCallgrind.split(",")
00441         if RunMemcheck:
00442             MemcheckCandles = RunMemcheck.split(",")
00443         if RunDigiPileUp:
00444             for candle in RunDigiPileUp.split(","):
00445                 if candle in TimeSizeCandles:
00446                     TimeSizePUCandles.append(candle)
00447                 if candle in IgProfCandles:
00448                     IgProfPUCandles.append(candle)
00449                 if candle in CallgrindCandles:
00450                     CallgrindPUCandles.append(candle)
00451                 if candle in MemcheckCandles:
00452                     MemcheckPUCandles.append(candle)
00453         if RunTimeSizePU:
00454             TimeSizePUCandles.extend(RunTimeSizePU.split(","))
00455             #Some smart removal of duplicates from the list!
00456             temp=set(TimeSizePUCandles)
00457             TimeSizePUCandles=list(temp) #Doing it in 2 steps to avoid potential issues with type of arguments
00458         if RunIgProfPU:
00459             IgProfPUCandles.extend(RunIgProfPU.split(","))
00460             #Some smart removal of duplicates from the list!
00461             temp=set(IgProfPUCandles)
00462             IgProfPUCandles=list(temp) #Doing it in 2 steps to avoid potential issues with type of arguments
00463         if RunCallgrindPU:
00464             CallgrindPUCandles.extend(RunCallgrindPU.split(","))
00465             #Some smart removal of duplicates from the list!
00466             temp=set(CallgrindPUCandles)
00467             CallgrindPUCandles=list(temp) #Doing it in 2 steps to avoid potential issues with type of arguments
00468         if RunMemcheckPU:
00469             MemcheckPUCandles.extend(RunMemcheckPU.split(","))
00470             #Some smart removal of duplicates from the list!
00471             temp=set(MemcheckPUCandles)
00472             MemcheckPUCandles=list(temp) #Doing it in 2 steps to avoid potential issues with type of arguments
00473         if userInputFile:
00474            userInputRootFiles=userInputFile.split(",")
00475 
00476            
00477 
00478         #############
00479         # Setup cmsdriver and eventual cmsdriverPUoption
00480         #
00481         cmsdriverPUOptions=""
00482         if cmsdriverOptions:
00483             #Set the eventual Pile Up cmsdriver options first:
00484             if TimeSizePUCandles or IgProfPUCandles or CallgrindPUCandles or MemcheckPUCandles:
00485                 #Bug fixed: no space between --pileup= and LowLumiPileUp (otherwise could omit the =)
00486                 cmsdriverPUOptions = '--cmsdriver="%s %s%s"'%(cmsdriverOptions," --pileup=",cmsDriverPileUpOption)
00487             #Set the regular ones too:
00488             cmsdriverOptions = '--cmsdriver="%s"'%cmsdriverOptions        
00489     
00490         return (castordir       ,
00491                 TimeSizeEvents  ,
00492                 IgProfEvents    ,
00493                 CallgrindEvents ,
00494                 MemcheckEvents  ,
00495                 cmsScimark      ,
00496                 cmsScimarkLarge ,
00497                 cmsdriverOptions,
00498                 cmsdriverPUOptions,
00499                 stepOptions     ,
00500                 quicktest       ,
00501                 profilers       ,
00502                 cpu             ,
00503                 cores           ,
00504                 prevrel         ,
00505                 bypasshlt       ,
00506                 runonspare      ,
00507                 outputdir       ,
00508                 logfile         ,
00509                 TimeSizeCandles ,
00510                 IgProfCandles   ,
00511                 CallgrindCandles,
00512                 MemcheckCandles ,
00513                 TimeSizePUCandles ,
00514                 IgProfPUCandles   ,
00515                 CallgrindPUCandles,
00516                 MemcheckPUCandles ,
00517                 PUInputFile     ,
00518                 userInputRootFiles,
00519                 MailLogRecipients,
00520                 tarball)
    
def cmsPerfSuite::PerfSuite::printDate (   self)

Definition at line 582 of file cmsPerfSuite.py.

00583                        :
00584         self.logh.write(self.getDate() + "\n")
        self.logh.flush()
def cmsPerfSuite::PerfSuite::printFlush (   self,
  command 
)

Print and flush a string (for output to a log file)

Definition at line 545 of file cmsPerfSuite.py.

00546                                 :
00547         if self._verbose:
00548             self.logh.write(str(command) + "\n")
00549             self.logh.flush()
    
def cmsPerfSuite::PerfSuite::runcmd (   self,
  command 
)

Run a command and return the exit status.

Definition at line 553 of file cmsPerfSuite.py.

00554                             :
00555         #Substitute popen with subprocess.Popen!
00556         #Using try/except until Popen becomes thread safe (it seems that everytime it is called
00557         #all processes are checked to reap the ones that are done, this creates a race condition with the wait()... that
00558         #results into an error with "No child process".
00559         #os.popen(command)
00560         try:
00561             process  = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
00562             pid=process.pid
00563             exitstat= process.wait()
00564             cmdout   = process.stdout.read()
00565             exitstat = process.returncode
00566         except OSError, detail:
00567             self.logh.write("Race condition in subprocess.Popen has robbed us of the exit code of the %s process (PID %s).Assume it failed!\n %s\n"%(command,pid,detail))
00568             self.logh.flush()
00569             exitstat=999
00570             cmdout="Race condition in subprocess.Popen has robbed us of the exit code of the %s process (PID %s).Assume it failed!\n %s"%(command,pid,detail)
00571         if self._verbose:
00572             self.logh.write(cmdout)# + "\n") No need of extra \n!
00573             self.logh.flush()
00574         if exitstat == None:
00575             self.logh.write("Something strange is going on! Exit code was None for command %s: check if it really ran!"%command)
00576             self.logh.flush()
00577             exitstat=0
00578         return exitstat
    
def cmsPerfSuite::PerfSuite::runCmdSet (   self,
  cmd 
)

Run a list of commands using system ! We should rewrite this not to use system (most cases it is unnecessary)

Definition at line 527 of file cmsPerfSuite.py.

00528                            :
00529         exitstat = 0
00530         if len(cmd) <= 1:
00531             exitstat = self.runcmd(cmd)
00532             if self._verbose:
00533                 self.printFlush(cmd)
00534         else:
00535             for subcmd in cmd:
00536                 if self._verbose:
00537                     self.printFlush(subcmd)
00538             exitstat = self.runcmd(" && ".join(cmd))
00539         if self._verbose:
00540             self.printFlush(self.getDate())
00541         return exitstat
    
def cmsPerfSuite::PerfSuite::runCmsInput (   self,
  cpu,
  dir,
  numevents,
  candle,
  cmsdrvopts,
  stepopt,
  profiles,
  bypasshlt,
  userInputFile 
)

Wrapper for cmsRelvalreportInput.

Definition at line 750 of file cmsPerfSuite.py.

00751                                                                                                       :
00752 
00753         #Crappy fix for optional options with special synthax (bypasshlt and userInputFile)
00754         bypass = ""
00755         if bypasshlt:
00756             bypass = "--bypass-hlt"
00757         userInputFileOption=""
00758         if userInputFile:
00759            userInputFileOption = "--filein %s"%userInputFile
00760         cmd = self.Commands[cpu][2]
00761         cmds=[]
00762         #print cmds
00763         cmds = ("cd %s"                    % (dir),
00764                 "%s %s \"%s\" %s %s %s %s %s" % (cmd,
00765                                               numevents,
00766                                               candle,
00767                                               profiles,
00768                                               cmsdrvopts,
00769                                               stepopt,
00770                                               bypass,userInputFileOption))
00771         exitstat=0
00772         exitstat = self.runCmdSet(cmds)
00773         if self._unittest and (not exitstat == 0):
00774             self.logh.write("ERROR: CMS Report Input returned a non-zero exit status \n" )
        return exitstat
def cmsPerfSuite::PerfSuite::runCmsReport (   self,
  cpu,
  dir,
  candle 
)

This function is a wrapper around cmsRelvalreport.

Definition at line 700 of file cmsPerfSuite.py.

00701                                          :
00702         cmd  = self.Commands[cpu][1]
00703         cmds = ("cd %s"                 % (dir),
00704                 "%s -i SimulationCandles_%s.txt -t perfreport_tmp -R -P >& %s.log" % (cmd,self.cmssw_version,candle))
00705         exitstat = 0
00706         if not self._debug:
00707             exitstat = self.runCmdSet(cmds)
00708             
00709         if self._unittest and (not exitstat == 0):
00710             self.logh.write("ERROR: CMS Report returned a non-zero exit status \n")
00711             sys.exit(exitstat)
00712         else:
00713             return(exitstat) #To return the exit code of the cmsRelvalreport.py commands to the runPerfSuite function
    
def cmsPerfSuite::PerfSuite::runPerfSuite (   self,
  castordir = "/castor/cern.ch/cms/store/relval/performance/",
  TimeSizeEvents = 100,
  IgProfEvents = 5,
  CallgrindEvents = 1,
  MemcheckEvents = 5,
  cmsScimark = 10,
  cmsScimarkLarge = 10,
  cmsdriverOptions = "",
  cmsdriverPUOptions = "",
  stepOptions = "",
  quicktest = False,
  profilers = "",
  cpus = [1],
  cores = 4,
  prevrel = "",
  bypasshlt = False,
  runonspare = True,
  perfsuitedir = os.getcwd(),
  logfile = None,
  TimeSizeCandles = "",
  IgProfCandles = "",
  CallgrindCandles = "",
  MemcheckCandles = "",
  TimeSizePUCandles = "",
  IgProfPUCandles = "",
  CallgrindPUCandles = "",
  MemcheckPUCandles = "",
  PUInputFile = "",
  userInputFile = "",
  MailLogRecipients = "",
  tarball = "" 
)

Runs benchmarking, cpu spinlocks on spare cores and profiles selected candles.

FIXME: Could redesign interface of functions to use keyword arguments: def runPerfSuite(**opts): then instead of using castordir variable, would use opts['castordir'] etc

Definition at line 877 of file cmsPerfSuite.py.

00909                                                         :
00910         
00911         #Set up a variable for the FinalExitCode to be used as the sum of exit codes:
00912         FinalExitCode=0
00913 
00914         #Set up the logfile first!
00915         if not logfile == None:
00916            try:
00917               self.logh = open(logfile,"a")
00918            except (OSError, IOError), detail:
00919               self.logh.write(detail + "\n")
00920               self.logh.flush()  
00921 
00922         #Adding HEPSPEC06 score if available in /build/HEPSPEC06.score file
00923         self.HEPSPEC06 = 0 #Set it to 0 by default (so it is easy to catch in the DB too)
00924         try:
00925            HEPSPEC06_file=open("/build/HEPSPEC06.score","r")
00926            for line in HEPSPEC06_file.readlines():
00927               if not line.startswith("#") and "HEPSPEC06" in line:
00928                  self.HEPSPEC06= line.split()[2]
00929         except IOError:
00930            self.logh.write("***Warning***: Could not find file /build/HEPSPEC06.score file on this machine!\n")
00931            self.logh.flush()
00932 
00933         #Adding a copy of /proc/cpuinfo and /proc/meminfo in the working directory so it can be kept in the tarball on CASTOR:
00934         localcpuinfo=os.path.join(perfsuitedir,"cpuinfo")
00935         cpuinfo_exitcode=-1
00936         if os.path.exists(localcpuinfo):
00937            cpuinfo_exitcode=0
00938         else:
00939            self.logh.write("Copying /proc/cpuinfo in current working directory (%s)\n"%perfsuitedir)
00940            cpuinfo_exitcode=self.runcmd("cp /proc/cpuinfo %s"%perfsuitedir)
00941         localmeminfo=os.path.join(perfsuitedir,"meminfo")
00942         meminfo_exitcode=-1
00943         if os.path.exists(localmeminfo):
00944            meminfo_exitcode=0
00945         else:
00946            self.logh.write("Copying /proc/meminfo in current working directory (%s)\n"%perfsuitedir)
00947            meminfo_exitcode=self.runcmd("cp /proc/meminfo %s"%perfsuitedir)
00948         if cpuinfo_exitcode or meminfo_exitcode:
00949            self.logh.write("There was an issue copying the cpuinfo or meminfo files!\n")
00950         self.logh.flush()
00951         
00952         try:        
00953             if not prevrel == "":
00954                 self.logh.write("Production of regression information has been requested with release directory %s\n" % prevrel)
00955             if not cmsdriverOptions == "":
00956                 self.logh.write("Running cmsDriver.py with user defined options: %s\n" % cmsdriverOptions)
00957                 #Attach the full option synthax for cmsRelvalreportInput.py:
00958                 cmsdriverOptionsRelvalInput="--cmsdriver="+cmsdriverOptions
00959                 #FIXME: should import cmsRelvalreportInput.py and avoid these issues...
00960             if not stepOptions == "":
00961                 self.logh.write("Running user defined steps only: %s\n" % stepOptions)
00962                 #Attach the full option synthax for cmsRelvalreportInput.py:
00963                 setpOptionsRelvalInput="--usersteps="+stepOptions
00964                 #FIXME: should import cmsRelvalreportInput.py and avoid these issues...
00965             if bypasshlt:
00966                 #Attach the full option synthax for cmsRelvalreportInput.py:
00967                 bypasshltRelvalInput="--bypass-hlt"
00968                 #FIXME: should import cmsRelvalreportInput.py and avoid these issues...
00969             self.logh.write("Current Architecture is %s\n"%self.cmssw_arch)
00970             self.logh.write("Current CMSSW version is %s\n"%self.cmssw_version)
00971             self.logh.write("This machine ( %s ) is assumed to have %s cores, and the suite will be run on cpu %s\n" %(self.host,cores,cpus))
00972             self.logh.write("This machine's HEPSPEC06 score is: %s \n"%self.HEPSPEC06)
00973             path=os.path.abspath(".")
00974             self.logh.write("Performance Suite started running at %s on %s in directory %s, run by user %s\n" % (self.getDate(),self.host,path,self.user))
00975             #Start the timer for the total performance suite running time:
00976             TotalTime=PerfSuiteTimer(start=datetime.datetime.now())
00977             #Also initialize the dictionary that will contain all the timing information:
00978             global TimerInfo
00979             TimerInfo={'TotalTime':{'TotalTime':TotalTime}} #Structure will be {'key':[PerfSuiteTimerInstance,...],...}
00980             #Obsolete popen4-> subprocess.Popen
00981             #showtags=os.popen4("showtags -r")[1].read()
00982             showtags=subprocess.Popen("showtags -r",shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
00983             self.logh.write(showtags) # + "\n") No need for extra \n!
00984             self.logh.flush()
00985             #For the log:
00986             if self._verbose:
00987                 self.logh.write("The performance suite results tarball will be stored in CASTOR at %s\n" % self._CASTOR_DIR)
00988                 self.logh.write("%s TimeSize events\n" % TimeSizeEvents)
00989                 self.logh.write("%s IgProf events\n"   % IgProfEvents)
00990                 self.logh.write("%s Callgrind events\n" % CallgrindEvents)
00991                 self.logh.write("%s Memcheck events\n" % MemcheckEvents)
00992                 self.logh.write("%s cmsScimark benchmarks before starting the tests\n"      % cmsScimark)
00993                 self.logh.write("%s cmsScimarkLarge benchmarks before starting the tests\n" % cmsScimarkLarge)
00994                 self.logh.flush()
00995             #Actual script actions!
00996             #Will have to fix the issue with the matplotlib pie-charts:
00997             #Used to source /afs/cern.ch/user/d/dpiparo/w0/perfreport2.1installation/share/perfreport/init_matplotlib.sh
00998             #Need an alternative in the release
00999 
01000             #Code for the architecture benchmarking use-case
01001             if len(cpus) > 1:
01002                 for cpu in cpus:
01003                     cpupath = os.path.join(perfsuitedir,"cpu_%s" % cpu)
01004                     if not os.path.exists(cpupath):
01005                         os.mkdir(cpupath)
01006             
01007             self.Commands = {}
01008             AllScripts = self.Scripts + self.AuxiliaryScripts
01009     
01010             for cpu in range(cmsCpuInfo.get_NumOfCores()): #FIXME use the actual number of cores of the machine here!
01011                 self.Commands[cpu] = []
01012 
01013             #Information for the log:
01014             self.logh.write("Full path of all the scripts used in this run of the Performance Suite:\n")
01015             for script in AllScripts:
01016                 which="which " + script
01017     
01018                 #Logging the actual version of cmsDriver.py, cmsRelvalreport.py, cmsSimPyRelVal.pl
01019                 #Obsolete popen4-> subprocess.Popen
01020                 #whichstdout=os.popen4(which)[1].read()
01021                 whichstdout=subprocess.Popen(which,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
01022                 self.logh.write(whichstdout) # + "\n") No need of the extra \n!
01023                 if script in self.Scripts:
01024                     for cpu in range(cmsCpuInfo.get_NumOfCores()):#FIXME use the actual number of cores of the machine here!
01025                         command="taskset -c %s %s" % (cpu,script)
01026                         self.Commands[cpu].append(command)
01027                         
01028             #First submit the cmsScimark benchmarks on the unused cores:
01029             scimark = ""
01030             scimarklarge = ""
01031             if not (self._unittest or self._noexec):
01032                 for core in range(cores):
01033                     if (not core in cpus) and runonspare:
01034                         self.logh.write("Submitting cmsScimarkLaunch.csh to run on core cpu "+str(core) + "\n")
01035                         subcmd = "cd %s ; cmsScimarkLaunch.csh %s" % (perfsuitedir, str(core))            
01036                         command="taskset -c %s sh -c \"%s\" &" % (str(core), subcmd)
01037                         self.logh.write(command + "\n")
01038     
01039                         #cmsScimarkLaunch.csh is an infinite loop to spawn cmsScimark2 on the other
01040                         #cpus so it makes no sense to try reading its stdout/err
01041                         #Obsolete popen4-> subprocess.Popen
01042                         #os.popen4(command)
01043                         subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
01044 
01045             self.logh.flush()
01046     
01047             #Don't do benchmarking if in debug mode... saves time
01048             benching = not self._debug
01049             ##FIXME:
01050             #We may want to introduce a switch here or agree on a different default (currently 10 cmsScimark and 10 cmsScimarkLarge)
01051             if benching and not (self._unittest or self._noexec): 
01052                 #Submit the cmsScimark benchmarks on the cpu where the suite will be run:
01053                 for cpu in cpus:
01054                     scimark      = open(os.path.join(perfsuitedir,"cmsScimark2.log")      ,"w")        
01055                     scimarklarge = open(os.path.join(perfsuitedir,"cmsScimark2_large.log"),"w")
01056                     if cmsScimark > 0:
01057                         self.logh.write("Starting with %s cmsScimark on cpu%s\n"       % (cmsScimark,cpu))
01058                         cmsScimarkInitialTime=PerfSuiteTimer(start=datetime.datetime.now()) #Create the cmsScimark PerfSuiteTimer
01059                         TimerInfo.update({'cmsScimarkTime':{'cmsScimarkInitial':cmsScimarkInitialTime}}) #Add the cmsScimarkInitialTime information to the general TimerInfo dictionary
01060                         self.benchmarks(cpu,perfsuitedir,scimark.name,cmsScimark)
01061                         cmsScimarkInitialTime.set_end(datetime.datetime.now()) #Stop the cmsScimark initial timer
01062     
01063                     if cmsScimarkLarge > 0:
01064                         self.logh.write("Following with %s cmsScimarkLarge on cpu%s\n" % (cmsScimarkLarge,cpu))
01065                         cmsScimarkLargeInitialTime=PerfSuiteTimer(start=datetime.datetime.now()) #Create the cmsScimarkLarge PerfSuiteTimer
01066                         TimerInfo['cmsScimarkTime'].update({'cmsScimarkLargeInitial':cmsScimarkLargeInitialTime}) #Add the cmsScimarkLargeInitialTime information to the general TimerInfo dictionary
01067                         self.benchmarks(cpu,perfsuitedir,scimarklarge.name,cmsScimarkLarge, large=True)
01068                         cmsScimarkLargeInitialTime.set_end(datetime.datetime.now()) #Stop the cmsScimarkLarge Initial timer
01069                 self.logh.flush()
01070             #Handling the Pile up input file here:
01071             if (TimeSizePUCandles or IgProfPUCandles or CallgrindPUCandles or MemcheckPUCandles) and not ("FASTSIM" in stepOptions):
01072                 #Note the FASTSIM exclusion... since there is no need to copy the file for FASTSIM.
01073                 PUInputName=os.path.join(perfsuitedir,"INPUT_PILEUP_EVENTS.root")
01074                 if PUInputFile:
01075                     #Define the actual command to copy the file locally:
01076                     #Allow the file to be mounted locally (or accessible via AFS)
01077                     copycmd="cp"
01078                     #Allow the file to be on CASTOR (taking a full CASTOR path)
01079                     if '/store/relval/' in PUInputFile:
01080                         copycmd="rfcp"
01081                         #Accept plain LFNs from DBS for RelVal CASTOR files:
01082                         #Minor fix to allow the case of user using the full path /castor/cern.ch/cms...
01083                         if PUInputFile.startswith('/store/relval/'):
01084                            PUInputFile="/castor/cern.ch/cms"+PUInputFile
01085                     #Copy the file locally
01086                     self.logh.write("Copying the file %s locally to %s\n"%(PUInputFile,PUInputName))
01087                     self.logh.flush()
01088                     GetPUInput=subprocess.Popen("%s %s %s"%(copycmd,PUInputFile,PUInputName), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
01089                     GetPUInputExitCode=GetPUInput.wait()
01090                     #Allow even the potential copy of a local file (even one already named INPUT_PILEUP_EVENTS.root!)
01091                     if GetPUInputExitCode:
01092                         self.logh.write("The copying of the pile-up input file returned a non-zero exit code: %s \nThis is the stdout+stderr if the command:\n%s\n"%(GetPUInputExitCode,GetPUInput.stdout))
01093                 #Ultimately accept the case of the file being already there and not being specified in the --PUInputFile option
01094                 if not os.path.exists(PUInputName):
01095                     self.logh.write("The necessary INPUT_PILEUP_EVENTS.root file was not found in the working directory %s\nExiting now!"%perfsuitedir)
01096                     self.logh.flush()
01097                     sys.exit(1)
01098                 else:
01099                     #Set up here the DIGI PILE UP options
01100                     self.printFlush("Some PILE UP tests will be run!")
01101                     #Actually setting them earlier... when handling options... May not need this else after all... or just as a log entry.
01102                     self.printFlush("cmsdriverPUOptions is %s"%cmsdriverPUOptions)
01103                     pass
01104             
01105             #TimeSize tests:
01106             if TimeSizeEvents > 0:
01107                TimeSizeTime=PerfSuiteTimer(start=datetime.datetime.now()) #Start the TimeSize timer
01108                TimerInfo.update({'TimeSize':{'TotalTime':TimeSizeTime}}) #Add the TimeSize timer to the dictionary
01109                if TimeSizeCandles:
01110                   self.logh.write("Launching the TimeSize tests (TimingReport, TimeReport, SimpleMemoryCheck, EdmSize) with %s events each\n" % TimeSizeEvents)
01111                   NoPileUpTime=PerfSuiteTimer(start=datetime.datetime.now()) #Start the TimeSize timer
01112                   TimerInfo['TimeSize'].update({'NoPileUpTime':NoPileUpTime}) #Add the TimeSize No Pile Up tests timer to the list
01113                   self.printDate()
01114                   self.logh.flush()
01115                   ReportExit=self.simpleGenReport(cpus,perfsuitedir,TimeSizeEvents,TimeSizeCandles,cmsdriverOptions,stepOptions,"TimeSize",profilers,bypasshlt,userInputFile)
01116                   FinalExitCode=FinalExitCode+ReportExit
01117                   #Adding a time stamp here to parse for performance suite running time data
01118                   self.printFlush("Regular TimeSize tests were finished at %s"%(self.getDate()))
01119                   NoPileUpTime.set_end(datetime.datetime.now()) #Stop TimeSize timer
01120                
01121                #Launch eventual Digi Pile Up TimeSize too:
01122                if TimeSizePUCandles:
01123                   self.logh.write("Launching the PILE UP TimeSize tests (TimingReport, TimeReport, SimpleMemoryCheck, EdmSize) with %s events each\n" % TimeSizeEvents)
01124                   PileUpTime=PerfSuiteTimer(start=datetime.datetime.now()) #Start the TimeSize timer
01125                   TimerInfo['TimeSize'].update({'PileUpTime':PileUpTime}) #Add the TimeSize Pile Up tests timer to the list
01126                   self.printDate()
01127                   self.logh.flush()
01128                   ReportExit=self.simpleGenReport(cpus,perfsuitedir,TimeSizeEvents,TimeSizePUCandles,cmsdriverPUOptions,stepOptions,"TimeSize",profilers,bypasshlt,userInputFile)
01129                   FinalExitCode=FinalExitCode+ReportExit
01130                   #Adding a time stamp here to parse for performance suite running time data
01131                   self.printFlush("Pileup TimeSize tests were finished at %s"%(self.getDate()))
01132                   PileUpTime.set_end(datetime.datetime.now()) #Stop TimeSize timer
01133                   
01134                #Check for issue with 
01135                if not (TimeSizeCandles or TimeSizePUCandles):
01136                   self.printFlush("A number of events (%s) for TimeSize tests was selected, but no candle for regular or pileup tests was selected!"%(TimeSizeEvents))
01137                #Adding a time stamp here to parse for performance suite running time data
01138                self.printFlush("All TimeSize tests were finished at %s"%(self.getDate()))
01139                TimeSizeTime.set_end(datetime.datetime.now()) #Stop TimeSize timer
01140             
01141             #Stopping all cmsScimark jobs and analysing automatically the logfiles
01142             #No need to waste CPU while the load does not affect Valgrind measurements!
01143             if not (self._unittest or self._noexec):
01144                 self.logh.write("Stopping all cmsScimark jobs now\n")
01145                 subcmd = "cd %s ; %s" % (perfsuitedir,self.AuxiliaryScripts[2])
01146                 stopcmd = "sh -c \"%s\"" % subcmd
01147                 self.printFlush(stopcmd)
01148                 #os.popen(stopcmd)
01149                 #Obsolete popen4-> subprocess.Popen
01150                 #self.printFlush(os.popen4(stopcmd)[1].read())
01151                 self.printFlush(subprocess.Popen(stopcmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read())
01152 
01153             #From here on we can use all available cores to speed up the performance suite remaining tests:
01154             if cores==0: #When specifying the cpu to run the suite on, one has to set cores to 0 to avoid threading of PerfSuite itself...
01155                                           #So we need to catch this case for the IB tests case where we assign the test to a specific cpu.
01156                 AvailableCores=cpus
01157             else:
01158                 AvailableCores=range(cores)
01159             #Initialize a list that will contain all the simpleGenReport keyword arguments (1 dictionary per test):
01160             TestsToDo=[]
01161             #IgProf tests:
01162             if IgProfEvents > 0:
01163                if IgProfCandles:
01164                    self.printFlush("Preparing IgProf tests")
01165                    #Special case for IgProf: user could pick with the option --profilers to run only IgProf perf or Mem (or Mem_Total alone etc)
01166                    #So in general we want to be able to split the perf and mem tests...
01167                    #For the case of --profiler option we will run only 1 test (i.e. it will get one core slot until it is done with whatever profiling choosen)
01168                    if profilers:
01169                       self.printFlush("Special profiler option for IgProf was indicated by the user: %s"%profilers)
01170                       #Prepare the simpleGenReport arguments for this test:
01171                       IgProfProfilerArgs={
01172                          'perfdir':perfsuitedir,
01173                          'NumEvents':IgProfEvents,
01174                          'candles':IgProfCandles,
01175                          'cmsdriverOptions':cmsdriverOptions,
01176                          'stepOptions':stepOptions,
01177                          'Name':"IgProf",
01178                          'profilers':profilers,
01179                          'bypasshlt':bypasshlt,
01180                          'userInputRootFiles':userInputFile
01181                          }
01182                       #Append the test to the TestsToDo list:
01183                       TestsToDo.append(IgProfProfilerArgs)
01184                       self.printFlush("Appended IgProf test with profiler option %s to the TestsToDo list"%profilers)
01185                    #For the default case (4,5,6,7) we split the tests into 2 jobs since they naturally are 2 cmsRun jobs and for machines with many cores this will
01186                    #make the performance suite run faster.
01187                    else:
01188                       self.printFlush("Splitting the IgProf tests into Perf and Mem to parallelize the cmsRun execution as much as possible:")
01189                       ##PERF##
01190                       #Prepare the simpleGenReport arguments for this test:
01191                       IgProfPerfArgs={
01192                          'perfdir':perfsuitedir,
01193                          'NumEvents':IgProfEvents,
01194                          'candles':IgProfCandles,
01195                          'cmsdriverOptions':cmsdriverOptions,
01196                          'stepOptions':stepOptions,
01197                          'Name':"IgProf_Perf",
01198                          'profilers':profilers,
01199                          'bypasshlt':bypasshlt,
01200                          'userInputRootFiles':userInputFile
01201                          }
01202                       #Append the test to the TestsToDo list:
01203                       TestsToDo.append(IgProfPerfArgs)
01204                       self.printFlush("Appended IgProf PERF test to the TestsToDo list")
01205                       ##MEM##
01206                       #Prepare the simpleGenReport arguments for this test:
01207                       IgProfMemArgs={
01208                          'perfdir':perfsuitedir,
01209                          'NumEvents':IgProfEvents,
01210                          'candles':IgProfCandles,
01211                          'cmsdriverOptions':cmsdriverOptions,
01212                          'stepOptions':stepOptions,
01213                          'Name':"IgProf_Mem",
01214                          'profilers':profilers,
01215                          'bypasshlt':bypasshlt,
01216                          'userInputRootFiles':userInputFile
01217                          }
01218                       #Append the test to the TestsToDo list:
01219                       TestsToDo.append(IgProfMemArgs)
01220                       self.printFlush("Appended IgProf MEM test to the TestsToDo list")
01221                 #The following will be handled in the while loop that handles the starting of the threads:
01222                 #ReportExit=self.simpleGenReport(cpus,perfsuitedir,IgProfEvents,IgProfCandles,cmsdriverOptions,stepOptions,"IgProf",profilers,bypasshlt,userInputFile)
01223                 #FinalExitCode=FinalExitCode+ReportExit
01224                 #Launch eventual Digi Pile Up IgProf too:
01225                if IgProfPUCandles:
01226                    self.printFlush("Preparing IgProf PileUp tests")
01227                    #Special case for IgProf: user could pick with the option --profilers to run only IgProf perf or Mem (or Mem_Total alone etc)
01228                    #So in general we want to be able to split the perf and mem tests...
01229                    #For the case of --profiler option we will run only 1 test (i.e. it will get one core slot until it is done with whatever profiling choosen)
01230                    if profilers:
01231                       self.printFlush("Special profiler option for IgProf was indicated by the user: %s"%profilers)
01232                       #Prepare the simpleGenReport arguments for this test:
01233                       IgProfProfilerPUArgs={
01234                          'perfdir':perfsuitedir,
01235                          'NumEvents':IgProfEvents,
01236                          'candles':IgProfPUCandles,
01237                          'cmsdriverOptions':cmsdriverPUOptions,
01238                          'stepOptions':stepOptions,
01239                          'Name':"IgProf",
01240                          'profilers':profilers,
01241                          'bypasshlt':bypasshlt,
01242                          'userInputRootFiles':userInputFile
01243                          }
01244                       #Append the test to the TestsToDo list:
01245                       TestsToDo.append(IgProfProfilerPUArgs)
01246                       self.printFlush("Appended IgProf PileUp test with profiler option %s to the TestsToDo list"%profilers)
01247                    else:
01248                       self.printFlush("Splitting the IgProf tests into Perf and Mem to parallelize the cmsRun execution as much as possible:")
01249                       ##PERF##
01250                       #Prepare the simpleGenReport arguments for this test:
01251                       IgProfPerfPUArgs={
01252                          'perfdir':perfsuitedir,
01253                          'NumEvents':IgProfEvents,
01254                          'candles':IgProfPUCandles,
01255                          'cmsdriverOptions':cmsdriverPUOptions,
01256                          'stepOptions':stepOptions,
01257                          'Name':"IgProf_Perf",
01258                          'profilers':profilers,
01259                          'bypasshlt':bypasshlt,
01260                          'userInputRootFiles':userInputFile
01261                          }
01262                       #Append the test to the TestsToDo list:
01263                       TestsToDo.append(IgProfPerfPUArgs)
01264                       self.printFlush("Appended IgProf MEM PileUp test to the TestsToDo list")
01265                       ##MEM##
01266                       #Prepare the simpleGenReport arguments for this test:
01267                       IgProfMemPUArgs={
01268                          'perfdir':perfsuitedir,
01269                          'NumEvents':IgProfEvents,
01270                          'candles':IgProfPUCandles,
01271                          'cmsdriverOptions':cmsdriverPUOptions,
01272                          'stepOptions':stepOptions,
01273                          'Name':"IgProf_Mem",
01274                          'profilers':profilers,
01275                          'bypasshlt':bypasshlt,
01276                          'userInputRootFiles':userInputFile
01277                          }
01278                       #Append the test to the TestsToDo list:
01279                       TestsToDo.append(IgProfMemPUArgs)
01280                       self.printFlush("Appended IgProf MEM PileUp test to the TestsToDo list")
01281                if not (IgProfCandles or IgProfPUCandles):
01282                    self.printFlush("A number of events (%s) for IgProf tests was selected, but no candle for regular or pileup tests was selected!"%(IgProfEvents))
01283                
01284                     
01285             #Valgrind tests:
01286             if CallgrindEvents > 0:
01287                if CallgrindCandles:
01288                   self.printFlush("Preparing Callgrind tests")
01289                   CallgrindArgs={
01290                      'perfdir':perfsuitedir,
01291                      'NumEvents':CallgrindEvents,
01292                      'candles':CallgrindCandles,
01293                      'cmsdriverOptions':cmsdriverOptions,
01294                      'stepOptions':stepOptions,
01295                      'Name':"Callgrind",
01296                      'profilers':profilers,
01297                      'bypasshlt':bypasshlt,
01298                      'userInputRootFiles':userInputFile
01299                      }
01300                   #Append the test to the TestsToDo list:
01301                   TestsToDo.append(CallgrindArgs)
01302                   self.printFlush("Appended Callgrind test to the TestsToDo list")
01303                #Launch eventual Digi Pile Up Callgrind too:
01304                if CallgrindPUCandles:
01305                   self.printFlush("Preparing Callgrind PileUp tests")
01306                   CallgrindPUArgs={
01307                      'perfdir':perfsuitedir,
01308                      'NumEvents':CallgrindEvents,
01309                      'candles':CallgrindPUCandles,
01310                      'cmsdriverOptions':cmsdriverPUOptions,
01311                      'stepOptions':stepOptions,
01312                      'Name':"Callgrind",
01313                      'profilers':profilers,
01314                      'bypasshlt':bypasshlt,
01315                      'userInputRootFiles':userInputFile
01316                      }
01317                   #Append the test to the TestsToDo list:
01318                   TestsToDo.append(CallgrindPUArgs)
01319                   self.printFlush("Appended Callgrind PileUp test to the TestsToDo list")
01320                if not (CallgrindCandles or CallgrindPUCandles):
01321                   self.printFlush("A number of events (%s) for Callgrind tests was selected, but no candle for regular or pileup tests was selected!"%(CallgrindEvents))
01322                   
01323             if MemcheckEvents > 0:
01324                if MemcheckCandles:
01325                   self.printFlush("Preparing Memcheck tests")
01326                   MemcheckArgs={
01327                      'perfdir':perfsuitedir,
01328                      'NumEvents':MemcheckEvents,
01329                      'candles':MemcheckCandles,
01330                      'cmsdriverOptions':cmsdriverOptions,
01331                      'stepOptions':stepOptions,
01332                      'Name':"Memcheck",
01333                      'profilers':profilers,
01334                      'bypasshlt':bypasshlt,
01335                      'userInputRootFiles':userInputFile
01336                      }
01337                   #Append the test to the TestsToDo list:
01338                   TestsToDo.append(MemcheckArgs)
01339                   self.printFlush("Appended Memcheck test to the TestsToDo list")
01340                #Launch eventual Digi Pile Up Memcheck too:
01341                if MemcheckPUCandles:
01342                   self.printFlush("Preparing Memcheck PileUp tests")
01343                   MemcheckPUArgs={
01344                      'perfdir':perfsuitedir,
01345                      'NumEvents':MemcheckEvents,
01346                      'candles':MemcheckPUCandles,
01347                      'cmsdriverOptions':cmsdriverPUOptions,
01348                      'stepOptions':stepOptions,
01349                      'Name':"Memcheck",
01350                      'profilers':profilers,
01351                      'bypasshlt':bypasshlt,
01352                      'userInputRootFiles':userInputFile
01353                      }
01354                   #Append the test to the TestsToDo list:
01355                   TestsToDo.append(MemcheckPUArgs)  
01356                   self.printFlush("Appended Memcheck PileUp test to the TestsToDo list")
01357                if not (MemcheckCandles or MemcheckPUCandles):
01358                   self.printFlush("A number of events (%s) for Memcheck tests was selected, but no candle for regular or pileup tests was selected!"%(MemcheckEvents))
01359                   
01360             #Here if there are any IgProf, Callgrind or MemcheckEvents to be run,
01361             #run the infinite loop that submits the PerfTest() threads on the available cores:
01362             if IgProfEvents or CallgrindEvents or MemcheckEvents:
01363                #FIXME:We should consider what behavior makes most sense in case we use the --cores option at this time only the cores=0 care is considered...
01364                self.printFlush("Threading all remaining tests on all %s available cores!"%len(AvailableCores))
01365                self.printDate()
01366                self.logh.flush()
01367                #Save the original AvailableCores list to use it as a test to break the infinite loop:
01368                #While in the regular RelVal use-case it makes sense to use the actual number of cores of the machines, in
01369                #the IB case the AvailableCores will always consist of only 1 single core..
01370                OriginalAvailableCores=list(AvailableCores) #Tricky list copy bug! without the list() OriginalAvalaibleCores would point to AvailableCores!
01371                #Print this out in the log for debugging reasons
01372                self.printFlush("Original available cores list: %s"%AvailableCores)
01373 
01374                #Create a dictionary to keep track of running threads on the various cores:
01375                activePerfTestThreads={}
01376                #Flag for waiting messages:
01377                Waiting=False
01378                while 1:
01379                   #Check if there are tests to run:
01380                   if TestsToDo:
01381                      #Using the Waiting flag to avoid writing this message every 5 seconds in the case
01382                      #of having more tests to do than available cores...
01383                      if not Waiting:
01384                         self.printFlush("Currently %s tests are scheduled to be run:"%len(TestsToDo))
01385                         self.printFlush(TestsToDo)
01386                      #Check the available cores:
01387                      if AvailableCores:
01388                         #Set waiting flag to False since we'll be doing something
01389                         Waiting=False
01390                         self.printFlush("There is/are %s core(s) available"%len(AvailableCores))
01391                         cpu=AvailableCores.pop()
01392                         self.printFlush("Let's use cpu %s"%cpu)
01393                         simpleGenReportArgs=TestsToDo.pop()
01394                         self.printFlush("Let's submit %s test on core %s"%(simpleGenReportArgs['Name'],cpu))
01395                         #Adding a Total timer for each of the threaded tests:
01396                         if simpleGenReportArgs['Name'] not in TimerInfo.keys():
01397                            #if 'TotalTime' not in TimerInfo[simpleGenReportArgs['Name']].keys():
01398                            self.PerfTestTotalTimer=PerfSuiteTimer(start=datetime.datetime.now()) #Start the TimeSize timer
01399                            TimerInfo.update({simpleGenReportArgs['Name']:{'TotalTime':self.PerfTestTotalTimer}}) #Add the TimeSize timer to the dictionary 
01400                         threadToDo=self.simpleGenReportThread(cpu,self,**simpleGenReportArgs) #Need to send self too, so that the thread has access to the PerfSuite.simpleGenReport() function
01401                         self.printFlush("Starting thread %s"%threadToDo)
01402                         ReportExitCode=threadToDo.start()
01403                         self.printFlush("Adding thread %s to the list of active threads"%threadToDo)
01404                         activePerfTestThreads[cpu]=threadToDo
01405                      #If there is no available core, pass, there will be some checking of activeThreads, a little sleep and then another check.
01406                      else:
01407                         pass
01408                   #Test activePerfThreads:
01409                   activeTestNames=[]
01410                   activeTestNamesPU=[]
01411                   for cpu in activePerfTestThreads.keys():
01412                      if activePerfTestThreads[cpu].isAlive():
01413                         #print "%% cpu %s activerPerfTestThreads[cpu] %s activePerfTestThreads[cpu].simpleGenReportArgs['cmsdriverOptions'] %s"%(cpu,activePerfTestThreads[cpu],activePerfTestThreads[cpu].simpleGenReportArgs['cmsdriverOptions'])
01414                         if "--pileup" in activePerfTestThreads[cpu].simpleGenReportArgs['cmsdriverOptions']:
01415                            activeTestNamesPU.append(activePerfTestThreads[cpu].simpleGenReportArgs['Name'])
01416                         else:
01417                            activeTestNames.append(activePerfTestThreads[cpu].simpleGenReportArgs['Name'])
01418                         pass
01419                      elif cpu not in AvailableCores:
01420                         #Set waiting flag to False since we'll be doing something
01421                         Waiting=False
01422                         self.printFlush(time.ctime())
01423                         self.printFlush("%s test, in thread %s is done running on core %s"%(activePerfTestThreads[cpu].simpleGenReportArgs['Name'],activePerfTestThreads[cpu],cpu) )
01424                         self.printFlush("About to append cpu %s to AvailableCores list"%cpu)
01425                         AvailableCores.append(cpu)
01426                         #Eliminate from activeTestNames lists:
01427                         #print activeTestNames
01428                         #print activeTestNamesPU
01429                         #print activePerfTestThreads[cpu].simpleGenReportArgs['Name']
01430                         if "--pileup" in activePerfTestThreads[cpu].simpleGenReportArgs['cmsdriverOptions']:
01431                            try:
01432                               activeTestNamesPU.remove(activePerfTestThreads[cpu].simpleGenReportArgs['Name'])
01433                            except:
01434                               pass
01435                         else:
01436                            try:
01437                               activeTestNames.remove(activePerfTestThreads[cpu].simpleGenReportArgs['Name'])
01438                            except:
01439                               pass
01440                         #Eliminate also from activePErfTestThreads dictionary:
01441                         activePerfTestThreads.pop(cpu)
01442                         #FIXME:
01443                         #Delicate check to stop the timer on the individual threaded test!
01444                         #Need to thik about it still...
01445                   #FIXME:
01446                   #Delicate check to stop the timers on the threaded tests:
01447                   #Check activePerfTestThreads dictionary for "Name" if any name is missing, the total can be stopped for that name.
01448                   #self.PerfTestTotalTimer
01449                   for TestName in ["IgProf_Perf","IgProf_Mem","Memcheck","Valgrind"]:
01450                      if (TestName not in activeTestNames) and (TestName not in activeTestNamesPU) :
01451                         try:
01452                            TimerInfo[TestName]['TotalTime'].set_end(datetime.datetime.now())
01453                         except:
01454                            #print "No %s test was running"%TestName
01455                            pass
01456                   #Buggy if... it seems we don't wait for the running thread to be finished...
01457                   #We should request:
01458                   #-All OriginalAvailableCores should be actually available.
01459                   if not AvailableCores==[] and (set(AvailableCores)==set(range(cmsCpuInfo.get_NumOfCores())) or set(AvailableCores)==set(OriginalAvailableCores)) and not TestsToDo:
01460                      self.printFlush("PHEW! We're done... all TestsToDo are done... at %s "%(self.getDate()))
01461                      #Debug printouts:
01462                      #print "AvailableCores",AvailableCores
01463                      #print "set(AvailableCores)",set(AvailableCores)
01464                      #print "set(range(cmsCpuInfo.get_NumOfCores())",set(range(cmsCpuInfo.get_NumOfCores()))
01465                      #print "OriginalAvailableCores",OriginalAvailableCores
01466                      #print "set(OriginalAvailableCores)",set(OriginalAvailableCores)                                   
01467                      #print "TestsToDo",TestsToDo
01468                      break
01469                   else:
01470                      #Putting the sleep statement first to avoid writing Waiting... before the output of the started thread reaches the log... 
01471                      time.sleep(5)
01472                      #Use Waiting flag to writing 1 waiting message while waiting and avoid having 1 message every 5 seconds...
01473                      if not Waiting:
01474                         self.printFlush(time.ctime())
01475                         self.printFlush("Waiting for tests to be done...")
01476                         sys.stdout.flush()
01477                         Waiting=True
01478             #End of the if for IgProf, Callgrind, Memcheck tests      
01479                   
01480             if benching and not (self._unittest or self._noexec):
01481                 #Ending the performance suite with the cmsScimark benchmarks again:
01482                 for cpu in cpus:
01483                     if cmsScimark > 0:
01484                         self.logh.write("Ending with %s cmsScimark on cpu%s\n"         % (cmsScimark,cpu))
01485                         cmsScimarkFinalTime=PerfSuiteTimer(start=datetime.datetime.now()) #Create the cmsScimark PerfSuiteTimer
01486                         TimerInfo['cmsScimarkTime'].update({'cmsScimarkFinal':cmsScimarkFinalTime}) #Add the cmsScimarkFinalTime information to the general TimerInfo dictionary
01487 
01488                         self.benchmarks(cpu,perfsuitedir,scimark.name,cmsScimark)
01489                         cmsScimarkFinalTime.set_end(datetime.datetime.now()) #Stop the cmsScimarkLarge Initial timer
01490                     if cmsScimarkLarge > 0:
01491                         self.logh.write("Following with %s cmsScimarkLarge on cpu%s\n" % (cmsScimarkLarge,cpu))
01492                         cmsScimarkLargeFinalTime=PerfSuiteTimer(start=datetime.datetime.now()) #Create the cmsScimarkLargePerfSuiteTimer
01493                         TimerInfo['cmsScimarkTime'].update({'cmsScimarkLargeFinal':cmsScimarkLargeFinalTime}) #Add the cmsScimarkLargeFinalTime information to the general TimerInfo dictionary
01494                         self.benchmarks(cpu,perfsuitedir,scimarklarge.name,cmsScimarkLarge,large=True)
01495                         cmsScimarkLargeFinalTime.set_end(datetime.datetime.now()) #Stop the cmsScimarkLarge Initial timer
01496     
01497             if prevrel:
01498                 self.logh.write("Running the regression analysis with respect to %s\n"%getVerFromLog(prevrel))
01499                 self.logh.write(time.ctime(time.time()))
01500                 self.logh.flush()
01501                 
01502                 crr.regressReports(prevrel,os.path.abspath(perfsuitedir),oldRelName = getVerFromLog(prevrel),newRelName=self.cmssw_version)
01503     
01504             #Create a tarball of the work directory
01505             if tarball:
01506                tarballTime=PerfSuiteTimer(start=datetime.datetime.now()) #Create the tarball PerfSuiteTimer
01507                TimerInfo.update({'tarballTime':{'TotalTime':tarballTime}})
01508                # Adding the str(stepOptions to distinguish the tarballs for 1 release
01509                # (GEN->DIGI, L1->RECO will be run in parallel)
01510                
01511                # Cleaning the stepOptions from the --usersteps=:
01512                if "=" in str(stepOptions):
01513                   fileStepOption=str(stepOptions).split("=")[1]
01514                else:
01515                   fileStepOption=str(stepOptions)
01516                if fileStepOption=="":
01517                   fileStepOption="UnknownStep"
01518                # Add the working directory used to avoid overwriting castor files (also put a check...)
01519                fileWorkingDir=os.path.basename(perfsuitedir)
01520                
01521                # Also add the --conditions and --eventcontent options used in the --cmsdriver options since it
01522                # is possible that the same tests will be run with different conditions and/or event content:               
01523                # Parse it out of --cmsdriver option:
01524                fileEventContentOption="UnknownEventContent"
01525                fileConditionsOption="UnknownConditions"
01526                for token in cmsdriverOptions.split("--"):
01527                   if token!='' and 'cmsdriver' not in token:
01528                      if "=" in token:
01529                         fileOption=token.split("=")[0]
01530                         fileOptionValue=token.split("=")[1].strip("'").strip('"')
01531                      else:
01532                         fileOption=token.split()[0]
01533                         fileOptionValue=token.split()[1].strip("'").strip('"')
01534                      if "eventcontent" or "conditions" in fileOption:
01535                         if "eventcontent" in fileOption:
01536                            fileEventContentOption=fileOptionValue
01537                         elif "conditions" in fileOption:
01538                            # check if we are using the autoCond style of flexible conditions
01539                            # if so, expand the condition here so that the file names contain the real conditions
01540                            if "auto:" in fileOptionValue: 
01541                               from Configuration.PyReleaseValidation.autoCond import autoCond
01542                               fileConditionsOption = autoCond[ fileOptionValue.split(':')[1] ]
01543                            else:
01544                               # "old style" conditions, hardcoded values ...
01545                               # FIXME:
01546                               # Should put at least the convention in cmsPerfCommons to know how to parse it...
01547                               # Potential weak point if the conditions tag convention changes...
01548                               if "," in fileOptionValue: #Since 330, conditions don't have FrontierConditions_GlobalTag, in front of them anymore...
01549                                  fileConditionsOption=fileOptionValue.split("::")[0].split(",")[1] #"Backward" compatibility
01550                               else:
01551                                  fileConditionsOption=fileOptionValue.split("::")[0] 
01552                   else: # empty token
01553                      #print "Print this is the token: %s"%token
01554                      pass
01555                   
01556                #self.printFlush("Conditions label to add to the tarball name is %s"%fileConditionsOption)
01557                #self.printFlush("Eventcontent label to add to the tarball name is %s"%fileEventContentOption)
01558                      #FIXME:
01559                      #Could add the allowed event contents in the cmsPerfCommons.py file and use those to match in the command line options... This assumes maintenance of cmsPerfCommons.py
01560 
01561 
01562                #Create a tarball with just the logfiles
01563                subprocess.Popen("ls -R | grep .root > rootFiles",shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
01564                LogFile = "%s_%s_%s_%s_%s_%s_%s_%s_log.tgz" % (self.cmssw_arch, self.cmssw_version, fileStepOption, fileConditionsOption, fileEventContentOption.split()[0], fileWorkingDir, self.host, self.user)
01565                AbsTarFileLOG = os.path.join(perfsuitedir,LogFile)
01566                tarcmd  = "tar zcfX %s %s %s" %(AbsTarFileLOG, "rootFiles", os.path.join(perfsuitedir,"*"))
01567                self.printFlush("Creating a tarball for the logfiles")
01568                self.printFlush(tarcmd)
01569                self.printFlush(subprocess.Popen(tarcmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
01570                self.printFlush(subprocess.Popen("rm rootFiles",shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())               
01571 
01572                fullcastorpathlog=os.path.join(castordir,LogFile)
01573 
01574 
01575                #Create the tarball with the contents of the directory + md5 checksum
01576                TarFile = "%s_%s_%s_%s_%s_%s_%s_%s.tgz" % (self.cmssw_arch, self.cmssw_version, fileStepOption, fileConditionsOption, fileEventContentOption.split()[0], fileWorkingDir, self.host, self.user)
01577                AbsTarFile = os.path.join(perfsuitedir,TarFile)
01578                tarcmd  = "tar -zcf %s %s" %(AbsTarFile, os.path.join(perfsuitedir,"*"))
01579                md5cmd = "md5sum %s" %(AbsTarFile)
01580                self.printFlush("Creating a tarball with the content of the directory")               
01581                self.printFlush(tarcmd)
01582                self.printFlush(md5cmd)               
01583                #FIXME:
01584                #Anything that will be logged after the tar command below will not enter the cmsPerfSuite.log in the tarball (by definition)...
01585                #To remain backward compatible the harvesting script needs to be based on the command above to identify the tarball location.
01586                #Obsolete popen4-> subprocess.Popen
01587                #self.printFlush(os.popen3(tarcmd)[2].read()) #Using popen3 to get only stderr we don't want the whole stdout of tar!
01588                self.printFlush(subprocess.Popen(tarcmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
01589                md5sum = subprocess.Popen(md5cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().split()[0]
01590                self.printFlush("The md5 checksum of the tarball: %s" %(md5sum))
01591                AbsTarFileMD5 = AbsTarFile + ".md5"
01592                md5filecmd = "echo %s > %s" % (md5sum, AbsTarFileMD5)
01593                self.printFlush(subprocess.Popen(md5filecmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
01594                                                 
01595                #Archive it on CASTOR
01596                #Before archiving check if it already exist if it does print a message, but do not overwrite, so do not delete it from local dir:
01597                fullcastorpathfile=os.path.join(castordir,TarFile)
01598                fullcastorpathmd5=os.path.join(castordir,TarFile + ".md5")
01599                
01600                checkcastor="nsls  %s" % fullcastorpathfile
01601                #Obsolete os.popen-> subprocess.Popen                
01602                #checkcastorout=os.popen3(checkcastor)[1].read()
01603                checkcastorout=subprocess.Popen(checkcastor,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read()                
01604                if checkcastorout.rstrip()==fullcastorpathfile:
01605                   castorcmdstderr="File %s is already on CASTOR! Will NOT OVERWRITE!!!"%fullcastorpathfile
01606                else:
01607                   castorcmd="rfcp %s %s" % (AbsTarFile,fullcastorpathfile)
01608                   castormd5cmd="rfcp %s %s" % (AbsTarFileMD5,fullcastorpathmd5)
01609                   castorlogcmd="rfcp %s %s" % (AbsTarFileLOG,fullcastorpathlog)
01610                   self.printFlush(castorcmd)
01611                   self.printFlush(castormd5cmd)
01612                   self.printFlush(castorlogcmd)
01613                   #Obsolete os.popen-> subprocess.Popen
01614                   #castorcmdstderr=os.popen3(castorcmd)[2].read()
01615                   castorcmdstderr=subprocess.Popen(castorcmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
01616                   subprocess.Popen(castormd5cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
01617                   subprocess.Popen(castorlogcmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()                  
01618                #Checking the stderr of the rfcp command to copy the tarball (.tgz) on CASTOR:
01619                if castorcmdstderr:
01620                    #If it failed print the stderr message to the log and tell the user the tarball (.tgz) is kept in the working directory
01621                    self.printFlush(castorcmdstderr)
01622                    self.printFlush("Since the CASTOR archiving for the tarball failed the file %s is kept in directory %s"%(TarFile, perfsuitedir))
01623                else:
01624                    #If it was successful then remove the tarball from the working directory:
01625                    self.printFlush("Successfully archived the tarball %s in CASTOR!"%(TarFile))
01626                    self.printFlush("The tarball can be found: %s"%(fullcastorpathfile))
01627                    self.printFlush("The logfile can be found: %s"%(fullcastorpathlog))                   
01628                    self.printFlush("Deleting the local copy of the tarballs")
01629                    rmtarballcmd="rm -Rf %s"%(AbsTarFile)
01630                    rmtarballmd5cmd="rm -Rf %s"%(AbsTarFileMD5)
01631                    rmtarballlogcmd="rm -Rf %s"%(AbsTarFileLOG)
01632                    self.printFlush(rmtarballcmd)
01633                    self.printFlush(rmtarballmd5cmd)
01634                    self.printFlush(rmtarballlogcmd)                   
01635                    #Obsolete os.popen-> subprocess.Popen
01636                    #self.printFlush(os.popen4(rmtarballcmd)[1].read())
01637                    self.printFlush(subprocess.Popen(rmtarballcmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
01638                    self.printFlush(subprocess.Popen(rmtarballmd5cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
01639                    self.printFlush(subprocess.Popen(rmtarballlogcmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
01640                tarballTime.set_end(datetime.datetime.now())
01641             else:
01642                self.printFlush("Performance Suite directory will not be archived in a tarball since --no_tarball option was chosen")
01643 
01644             #End of script actions!
01645     
01646             #Print a time stamp at the end:
01647             date=time.ctime(time.time())
01648             self.logh.write("Performance Suite finished running at %s on %s in directory %s\n" % (date,self.host,path))
01649             if self.ERRORS == 0:
01650                 self.logh.write("There were no errors detected in any of the log files!\n")
01651             else:
01652                 self.logh.write("ERROR: There were %s errors detected in the log files, please revise!\n" % self.ERRORS)
01653                 #print "No exit code test"
01654                 #sys.exit(1)
01655         except exceptions.Exception, detail:
01656            self.logh.write(str(detail) + "\n")
01657            self.logh.flush()
01658            if not self.logh.isatty():
01659               self.logh.close()
01660            raise
01661         #Add the possibility to send as an email the execution logfile to the user and whoever else interested:
01662         if MailLogRecipients != "": #Basically leave the option to turn it off too.. --mail ""
01663            self.printFlush("Sending email notification for this execution of the performance suite with command:")
01664            sendLogByMailcmd='cat cmsPerfSuite.log |mail -s "Performance Suite finished running on %s" '%self.host + MailLogRecipients
01665            self.printFlush(sendLogByMailcmd)
01666            #Obsolete os.popen-> subprocess.Popen
01667            #self.printFlush(os.popen4(sendLogByMailcmd)[1].read())
01668            self.printFlush(subprocess.Popen(sendLogByMailcmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
01669         else:
01670            self.printFlush('No email notification will be sent for this execution of the performance suite since option --mail "" was used')
01671         
01672         TotalTime.set_end(datetime.datetime.now())        
01673         self.printFlush("Total Running Time\t%s hrs (%s mins)"%(TotalTime.get_duration()['hours'],TotalTime.get_duration()['minutes']))
01674 
01675         #Dump of the TimerInfo information
01676         #First dump it as a pickleq file...
01677         #Well in order to do so without the complication of serializing a custom class instance need to make the dictionary fully string-made:
01678         TimerInfoStr={}
01679         PerfSuiteTimerInfo=open("PerfSuiteTimerInfo.pkl","wb")
01680         #pickle.dump(TimerInfo,PerfSuiteTimerInfo)
01681         #PerfSuiteTimerInfo.close()
01682         #For now print it at the bottom of the log:
01683         self.logh.write("Test type\tActual Test\tDuration\tStart Time\tEnd Time\n")
01684         for key in TimerInfo.keys():
01685            #self.printFlush(key)
01686            TimerInfoStr.update({key:{}})
01687            for test in TimerInfo[key].keys():
01688               TimerInfoStr[key].update({test:[str(TimerInfo[key][test].get_duration()['hours'])+" hrs ("+str(TimerInfo[key][test].get_duration()['minutes'])+" mins)",TimerInfo[key][test].get_start(),TimerInfo[key][test].get_end()]})
01689               self.logh.write(key+"\t"+test+"\t")
01690               self.logh.write("%s hrs (%s mins)\t"%(TimerInfo[key][test].get_duration()['hours'],TimerInfo[key][test].get_duration()['minutes']))
01691               self.logh.write("%s\t"%TimerInfo[key][test].get_start())
01692               self.logh.write("%s\n"%TimerInfo[key][test].get_end())
01693         pickle.dump(TimerInfoStr,PerfSuiteTimerInfo) 
01694         PerfSuiteTimerInfo.close()
01695         
01696         self.logh.write("Final Performance Suite exit code was %s"%FinalExitCode)
01697         self.logh.flush()
        sys.exit(FinalExitCode)
def cmsPerfSuite::PerfSuite::simpleGenReport (   self,
  cpus,
  perfdir = os.getcwd(),
  NumEvents = 1,
  candles = ['MinBias'],
  cmsdriverOptions = '',
  stepOptions = '',
  Name = '',
  profilers = '',
  bypasshlt = '',
  userInputRootFiles = '' 
)

Prepares the profiling directory and runs all the selected profiles (if this is not a unit test)

Making parameters named to facilitate the handling of arguments (especially with the threading use case)

Definition at line 779 of file cmsPerfSuite.py.

00780                                                                                                                                                                                  :
00781         callgrind = Name == "Callgrind"
00782         memcheck  = Name == "Memcheck"
00783     
00784         profCodes = {"TimeSize" : "0123",
00785                      "IgProf"   : "4567",
00786                      "IgProf_Perf":"47", #Added the Analyse to IgProf_Perf #FIXME: At the moment Analyse is always run whether 7 is selected or not! Issue to solve in cmsRelvalreportInput.py... but not really important (it's always been there, not impacting our use-cases).
00787                      "IgProf_Mem":"567",
00788                      "Callgrind": "8",
00789                      "Memcheck" : "9",
00790                      None       : "-1"} 
00791     
00792         profiles = profCodes[Name]
00793         if not profilers == "":
00794             profiles = profilers        
00795     
00796         RelvalreportExitCode=0
00797         
00798         for cpu in cpus:
00799             pfdir = perfdir
00800             if len(cpus) > 1:
00801                 pfdir = os.path.join(perfdir,"cpu_%s" % cpu)
00802             for candle in candles:
00803                 #Create the directory for cmsRelvalreport.py running (e.g. MinBias_TimeSize, etc)
00804                 #Catch the case of PILE UP:
00805                 if "--pileup" in cmsdriverOptions:
00806                    candlename=candle+"_PU"
00807                 else:
00808                    candlename=candle
00809                 adir=self.mkCandleDir(pfdir,candlename,Name)
00810                 if self._unittest:
00811                     # Run cmsDriver.py
00812                     if userInputRootFiles:
00813                        self.logh.write(userInputRootFiles)
00814                        userInputFile=userInputRootFiles[0]
00815                     else:
00816                        userInputFile=""
00817                     self.logh.flush()
00818                     self.runCmsInput(cpu,adir,NumEvents,candle,cmsdriverOptions,stepOptions,profiles,bypasshlt,userInputFile) 
00819                     self.testCmsDriver(cpu,adir,candle)
00820                 else:
00821                     if userInputRootFiles:
00822                        self.logh.write("Variable userInputRootFiles is %s\n"%userInputRootFiles)
00823                        #Need to use regexp, cannot rely on the order... since for different tests there are different candles...
00824                        #userInputFile=userInputRootFiles[candles.index(candle)]
00825                        #FIXME:
00826                        #Note the issue that the input files HAVE to have in their name the candle as is used in cmsPerfSuite.py command line!
00827                        #This is currently caught by a printout in the log: should be either taken care of with some exception to throw?
00828                        #Will put this in the documentation
00829                        userInputFile=""
00830                        candleregexp=re.compile(candle)
00831                        for file in userInputRootFiles:
00832                           if candleregexp.search(file):
00833                              userInputFile=file
00834                              self.logh.write("For these %s %s tests will use user input file %s\n"%(candlename,Name,userInputFile))
00835                        if userInputFile == "":
00836                           self.logh.write("***WARNING: For these %s %s tests could not find a matching input file in %s: will try to do without it!!!!!\n"%(candlename,Name,userInputRootFiles))
00837                        self.logh.flush()
00838                     else:
00839                        userInputFile=""
00840                     DummyTestName=candlename+"_"+stepOptions.split("=")[1]
00841                     DummyTimer=PerfSuiteTimer(start=datetime.datetime.now()) #Start the timer (DummyTimer is just a reference, but we will use the dictionary to access this later...
00842                     TimerInfo[Name].update({DummyTestName:DummyTimer}) #Add the TimeSize timer to the dictionary
00843                     #The following command will create the appropriate SimulationCandlesX.txt file in the relevant directory, ready to run cmsRelvalreport.py on it.
00844                     self.runCmsInput(cpu,adir,NumEvents,candle,cmsdriverOptions,stepOptions,profiles,bypasshlt,userInputFile)            
00845                     #Here where the no_exec option kicks in (do everything but do not launch cmsRelvalreport.py, it also prevents cmsScimark spawning...):
00846                     if self._noexec:
00847                         self.logh.write("Running in debugging mode, without executing cmsRelvalreport.py\n")
00848                         self.logh.flush()
00849                         pass
00850                     else:
00851                         #The following command will launch cmsRelvalreport.py on the SimulationCandlesX.txt input file created above.
00852                         ExitCode=self.runCmsReport(cpu,adir,candle)
00853                         self.logh.write("Individual cmsRelvalreport.py ExitCode %s\n"%ExitCode)
00854                         RelvalreportExitCode=RelvalreportExitCode+ExitCode
00855                         self.logh.write("Summed cmsRelvalreport.py ExitCode %s\n"%RelvalreportExitCode)
00856                         self.logh.flush()
00857                     DummyTimer.set_end(datetime.datetime.now())
00858                     
00859                     #for proflog in proflogs:
00860                     #With the change from 2>1&|tee to >& to preserve exit codes, we need now to check all logs...
00861                     #less nice... we might want to do this externally so that in post-processing its a re-usable tool
00862                     globpath = os.path.join(adir,"*.log") #"%s.log"%candle)
00863                     self.logh.write("Looking for logs that match %s\n" % globpath)
00864                     logs     = glob.glob(globpath)
00865                     for log in logs:
00866                         self.logh.write("Found log %s\n" % log)
00867                         self.displayErrors(log)
00868         self.printFlush("Returned cumulative RelvalreportExitCode is %s"%RelvalreportExitCode)
00869         return RelvalreportExitCode
    
def cmsPerfSuite::PerfSuite::testCmsDriver (   self,
  cpu,
  dir,
  cmsver,
  candle 
)

Test cmsDriver.py (parses the simcandles file, removing duplicate lines, and runs the cmsDriver part)

Definition at line 717 of file cmsPerfSuite.py.

00718                                                  :
00719         cmsdrvreg = re.compile("^cmsDriver.py")
00720         cmd  = self.Commands[cpu][0]
00721         noExit = True
00722         stepreg = re.compile("--step=([^ ]*)")
00723         previousCmdOnline = ""
00724         for line in open(os.path.join(dir,"SimulationCandles_%s.txt" % (cmsver))):
00725             if (not line.lstrip().startswith("#")) and not (line.isspace() or len(line) == 0): 
00726                 cmdonline  = line.split("@@@",1)[0]
00727                 if cmsdrvreg.search(cmdonline) and not previousCmdOnline == cmdonline:
00728                     stepbeingrun = "Unknown"
00729                     matches = stepreg.search(cmdonline)
00730                     if not matches == None:
00731                         stepbeingrun = matches.groups()[0]
00732                     if "PILEUP" in cmdonline:
00733                         stepbeingrun += "_PILEUP"
00734                     self.logh.write(cmdonline + "\n")
00735                     cmds = ("cd %s"      % (dir),
00736                             "%s  >& ../cmsdriver_unit_test_%s_%s.log"    % (cmdonline,candle,stepbeingrun))
00737                     if self._dryrun:
00738                         self.logh.write(cmds + "\n")
00739                     else:
00740                         out = self.runCmdSet(cmds)                    
00741                         if not out == None:
00742                             sig     = out >> 16    # Get the top 16 bits
00743                             xstatus = out & 0xffff # Mask out all bits except the first 16 
00744                             self.logh.write("FATAL ERROR: CMS Driver returned a non-zero exit status (which is %s) when running %s for candle %s. Signal interrupt was %s\n" % (xstatus,stepbeingrun,candle,sig))
00745                             sys.exit()
00746                 previousCmdOnline = cmdonline
        
def cmsPerfSuite::PerfSuite::valFilterReport (   self,
  dir 
)

Filter lines in the valgrind report that match GEN,SIM.

Definition at line 635 of file cmsPerfSuite.py.

00636                                  :
00637         #cmds = ("cd %s" % dir,
00638         #        "grep -v \"step=GEN,SIM\" SimulationCandles_%s.txt > tmp" % (self.cmssw_version),
00639         #        "mv tmp SimulationCandles_%s.txt"                         % (self.cmssw_version))
00640         #FIXME:
00641         #Quick and dirty hack to have valgrind MemCheck run on 5 events on both GEN,SIM and DIGI in QCD_80_120, while removing the line for GEN,SIM for Callgrind
00642         InputFileName=os.path.join(dir,"SimulationCandles_%s.txt"%(self.cmssw_version))
00643         InputFile=open(InputFileName,"r")
00644         InputLines=InputFile.readlines()
00645         InputFile.close()
00646         Outputfile=open(InputFileName,"w")
00647         simRegxp=re.compile("step=GEN,SIM")
00648         digiRegxp=re.compile("step=DIGI")
00649         CallgrindRegxp=re.compile("ValgrindFCE")
00650         MemcheckRegxp=re.compile("Memcheck")
00651         NumEvtRegxp=re.compile("-n 1")#FIXME Either use the ValgrindEventNumber or do a more general match!
00652         for line in InputLines:
00653             if simRegxp.search(line) and CallgrindRegxp.search(line):
00654                 continue
00655             elif simRegxp.search(line) and MemcheckRegxp.search(line):
00656                 #Modify
00657                 if NumEvtRegxp.search(line):
00658                     line=NumEvtRegxp.sub(r"-n 5",line)
00659                 else:
00660                     self.logh.write("The number of Memcheck event was not changed since the original number of Callgrind event was not 1!\n")
00661                 Outputfile.write(line)
00662             elif digiRegxp.search(line) and MemcheckRegxp.search(line):
00663                 #Modify
00664                 if NumEvtRegxp.search(line):
00665                     line=NumEvtRegxp.sub(r"-n 5",line)
00666                 else:
00667                     self.logh.write("The number of Memcheck event was not changed since the original number of Callgrind event was not 1!\n")
00668                 Outputfile.write(line)
00669             else:
00670                 Outputfile.write(line)
00671         self.logh.flush()
00672         Outputfile.close()
00673             
00674         #self.runCmdSet(cmds)
    

Member Data Documentation

Definition at line 61 of file cmsPerfSuite.py.

Developer options.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Check logfile option.

Check step Options Check profile option Check output directory option Check cpu option Check previous release directory Setup quicktest option Setup unit test option

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 877 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 877 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

FIXME: We may want to introduce a switch here or agree on a different default (currently 10 cmsScimark and 10 cmsScimarkLarge)

PERF## Prepare the simpleGenReport arguments for this test: MEM## Prepare the simpleGenReport arguments for this test: PERF## Prepare the simpleGenReport arguments for this test: MEM## Prepare the simpleGenReport arguments for this test:

Definition at line 887 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.

Definition at line 61 of file cmsPerfSuite.py.