CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/Validation/Performance/scripts/cmsRelRegress.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import os, re, sys, glob
00004 import optparse as opt
00005 import cmsPerfRegress as cpr
00006 from cmsPerfCommons import Candles, CandFname, getVerFromLog
00007 
00008 def getParameters():
00009     global _debug
00010     global PROG_NAME
00011     PROG_NAME = os.path.basename(sys.argv[0])
00012     parser = opt.OptionParser(usage="""%s [OLD_REL_DIR] [NEW_REL_DIR]
00013 
00014 To compare 2 cmsPerfSuite.py directories pass the previous release as the first argument and the latest release as the second argument """ % PROG_NAME)
00015     #
00016     # Options
00017     #
00018     devel  = opt.OptionGroup(parser, "Developer Options",
00019                                      "Caution: use these options at your own risk."
00020                                      "It is believed that some of them bite.\n")    
00021     devel.add_option(
00022         '-d',
00023         '--debug',
00024         type='int',
00025         dest='debug',
00026         default = 0,
00027         help='Show debug output',
00028         #metavar='DEBUG',
00029         )
00030     parser.add_option_group(devel)
00031     (options,args) = parser.parse_args()
00032     _debug = options.debug
00033     
00034     if not len(args) == 2:
00035         print "ERROR: Not enough arguments"
00036         sys.exit()
00037         
00038     path1 = os.path.abspath(args[0])
00039     path2 = os.path.abspath(args[1])    
00040     if os.path.exists(path1) and os.path.exists(path2):
00041         return (path1, path2)
00042     else:
00043         print "Error: one of the paths does not exist"
00044         sys.exit()
00045 
00046 def getOldRelName(oldRelName,adir):
00047     #Not sure this function is used but as it was written before it was useless.
00048     #Now it parses the adir directory looking for the CMSSW_X_Y_Z(_preN) in the path.
00049     if oldRelName == "":
00050         oldRelPath = os.path.dirname(adir)
00051         oldRelPathDirs = oldRelPath.split("/")
00052         for dir in oldRelPathDirs:
00053             if 'CMSSW' in dir:
00054                 oldRelName=dir
00055     return oldRelName
00056 
00057 def compareSimMemPair(newLog,candle,profdir,curdir,oldlog,oldRelName=""):
00058     print "oldlog %s"%oldlog
00059     print "curdir %s"%curdir
00060     #oldRelName = getOldRelName(oldRelName,olddir)
00061     oldRelName = getOldRelName(oldRelName,oldlog)
00062     print "OLD REL NAME: %s"%oldRelName
00063     #base = os.path.basename(newLog)
00064     #oldlog = os.path.join(olddir,curdir,base)
00065     rootf  = "simpmem-regress.root"
00066     try:
00067         print "TRY candle %s"%candle
00068         print "HERE Oldlog:%s"%oldlog
00069         print "HERE newLog:%s"%newLog
00070         cpr.cmpSimpMemReport(rootf,curdir,oldlog,newLog,1,True,candle,prevrev = oldRelName)
00071     except cpr.SimpMemParseErr, detail:
00072         print "WARNING: Could not parse data from log file %s; not performing regression" % detail.message
00073     except OSError, detail:
00074         print "WARNING: The OS returned the following error when comparing %s and %s" % (oldlog,log), detail
00075     except IOError, detail:
00076         print "IOError:", detail
00077     else:
00078         print "Successfully compared %s and %s" % (oldlog,newLog)        
00079         
00080 def regressReports(olddir,newdir,oldRelName = "",newRelName=""):
00081 
00082     profSets = ["Callgrind",
00083                 #"Memcheck", #No regression on Memcheck profiles!
00084                 "IgProf",
00085                 "TimeSize",
00086                 #Adding the PU directories:
00087                 "PU_Callgrind",
00088                 "PU_IgProf",
00089                 "PU_TimeSize"
00090                 ]
00091     for candle in Candles:
00092         #Loop over the known profilers sets (tests) defined above:
00093         for profset in profSets:
00094             #Check there is a directory with the profile set (test) being considered:
00095             adir = os.path.join(newdir,"%s_%s" % (candle,profset))
00096             if os.path.exists(adir):
00097                 #Start working in directory adir (e.g. MinBias_TimeSize)
00098                 print "Found directory %s"%adir
00099 
00100                 #Set up the profilers based on the directory name
00101                 Profs = []
00102                 if   profset == "Callgrind" or  profset == "PU_Callgrind":
00103                     Profs = ["valgrind"] # callgrind actually
00104                 elif profset == "TimeSize" or profset == "PU_TimeSize":
00105                     Profs = [ "TimingReport",
00106                               #"TimeReport", We do not run regression on the plain html TimeReport profile...
00107                               "SimpleMemoryCheck",
00108                               "EdmSize"]
00109                 elif profset == "IgProf" or profset == "PU_IgProf" :
00110                     Profs = [ "IgProfperf", #This was missing!
00111                               "IgProfMemTotal",
00112                               "IgProfMemLive"]
00113                 #Now for each individual profile in the profile set (e.g for TimeSize TimeReport, TimingReport, SimpleMemoryCheck, EdmSize
00114                 #collect the various logfiles
00115                 for prof in Profs:
00116                     print "Checking %s profile(s)"%prof
00117                     if   prof == "EdmSize" or prof == "valgrind":
00118                         stepLogs = glob.glob("%s/%s_*_%s"       % (adir,CandFname[candle],prof))
00119                     elif prof == "IgProfMemLive" or prof == "IgProfMemTotal": 
00120                         stepLogs = glob.glob("%s/%s_*_%s.gz"       % (adir,CandFname[candle],"IgProfMemTotal")) #This hack necessary since we reuse the IgProfMemTotal profile for MemLive too (it's a unique IgProfMem profile, read with different counters) 
00121                     elif prof == "IgProfperf":
00122                         stepLogs = glob.glob("%s/%s_*_%s.gz"       % (adir,CandFname[candle],prof))
00123                     elif prof == "SimpleMemoryCheck":
00124                         #With the change in the use of tee now the SimpleMemoryCheck info will be in the _TimingReport.log too...
00125                         #The following lines only will work for the unprofiled steps... hence... no need to report them!
00126                         #stepLogs = os.path.join(adir,"%s.log" % candle)
00127                         stepLogs = glob.glob("%s/%s_*_%s.log"   % (adir,CandFname[candle],'TimingReport'))
00128                     elif prof == "TimingReport":
00129                         stepLogs = glob.glob("%s/%s_*_%s.log"   % (adir,CandFname[candle],prof))
00130 
00131                     #Debug:
00132                     print "Found the following step logs: %s"%stepLogs
00133                     
00134                     profdir = os.path.basename(adir)
00135 
00136                     #Giant if to single out the SimpleMemoryCheck case that is in the elif at the bottom... maybe should flip things around...
00137                     #Basically here we do everything but SimpleMemoryCheck:
00138                     if prof == "TimingReport" or prof == "EdmSize" or prof == "valgrind" or prof == "IgProfMemTotal" or prof == "IgProfMemLive" or prof == "IgProfperf":
00139                         #This hack necessary since we reuse the IgProfMemTotal profile for MemLive too
00140                         #(it's a unique IgProfMem profile, read with different counters)
00141                         if prof == "IgProfMemLive": 
00142                             stepreg = re.compile("%s_([^_]*(_PILEUP)?)_%s((.log)|(.gz))?" % (CandFname[candle],"IgProfMemTotal"))
00143                         else:
00144                             stepreg = re.compile("%s_([^_]*(_PILEUP)?)_%s((.log)|(.gz))?" % (CandFname[candle],prof))
00145 
00146                         #Loop on the step logfiles collected above
00147                         for log in stepLogs:
00148                             base = os.path.basename(log)
00149                             #Handle the fact the profile ("log") for IgProf is always compressed (.gz):
00150                             if prof == "IgProfMemTotal" or prof == "IgProfMemLive" or prof == "IgProfperf":
00151                                 base = base.split(".gz")[0]
00152                             #Use the regular expression defined above to read out the step from the log/profile
00153                             searchob = stepreg.search(base)
00154 
00155                             #If in this log the regular expression was able match (and so to extract the step)
00156                             if searchob:
00157                                 #print searchob.groups()
00158                                 step = searchob.groups()[0]
00159                                 #print "and the step taken is %s"%step
00160                                 outpath = os.path.join(adir,"%s_%s_%s_regression" % (CandFname[candle],step,prof))
00161                                 oldlog  = os.path.join(olddir,"%s_%s" % (candle,profset),base)
00162                                 #Again handle the fact the profile ("log") for IgProf is always compressed (.gz):
00163                                 if prof == "IgProfMemTotal" or prof == "IgProfMemLive" or prof == "IgProfperf":
00164                                     oldlog  = os.path.join(olddir,"%s_%s" % (candle,profset),base + ".gz")
00165                                 if not os.path.exists(outpath):
00166                                     os.mkdir(outpath)
00167                                 if os.path.exists(oldlog):
00168                                     try:
00169                                         print ""
00170                                         print "** "
00171                                         if not prof == "TimingReport":
00172                                             print "** Comparing", candle, step, prof, "previous release: %s, latest release %s" % (oldlog,log)
00173                                             print "**"
00174 
00175                                         if   prof == "EdmSize":
00176                                             cpr.cmpEdmSizeReport(outpath,oldlog,log)
00177                                         elif prof == "TimingReport":
00178                                             logdir = "%s_%s_%s" % (CandFname[candle],step,prof)
00179                                             outd   = os.path.join(adir,logdir)
00180                                             rootf  = "timing-regress.root" 
00181                                             oldlog = os.path.join(olddir,profdir,base)
00182                                             if os.path.exists(log) and os.path.exists(oldlog) and os.path.exists(outd):
00183                                                 print "** Comparing", candle, step, prof, "previous release: %s and latest release: %s" % (oldlog,log)
00184                                                 print "**"
00185                                                 oldRelName = getOldRelName("",oldlog)
00186                                                 #print "TIMING OLD REL extracted from %s :\n %s"%(oldlog,oldRelName)
00187                                                 cpr.cmpTimingReport(rootf, outd, oldlog, log, 1, batch = True, prevrev = oldRelName)
00188                                             else:
00189                                                 print "WARNING: While comparing", candle, step, prof, " at least one of the logfiles/directories: old (%s) or new (%s) was not found!!!" % (oldlog,log)
00190                                                 break
00191                                         elif prof == "valgrind":
00192                                             cpr.cmpCallgrindReport(outpath,oldlog,log)
00193                                         elif prof == "IgProfperf":
00194                                             IgProfMemOpt="" #No need to specify the counter, for IgProfPerf...
00195                                             cpr.cmpIgProfReport(outpath,oldlog,log,IgProfMemOpt)
00196                                         elif prof == "IgProfMemTotal":
00197                                             IgProfMemOpt="-y MEM_TOTAL"
00198                                             cpr.cmpIgProfReport(outpath,oldlog,log,IgProfMemOpt)
00199                                         elif prof == "IgProfMemLive":
00200                                             IgProfMemOpt="-y MEM_LIVE"
00201                                             cpr.cmpIgProfReport(outpath,oldlog,log,IgProfMemOpt)
00202                                     except cpr.PerfReportErr,detail:
00203                                         print "WARNING: Perfreport return non-zero exit status when comparing %s and %s. Perfreport output follows" % (oldlog,log)
00204                                         print detail.message
00205                                     except cpr.TimingParseErr,detail:
00206                                         print "WARNING: Could not parse data from log file %s; not performing regression" % detail.message                                            
00207                                     except OSError, detail:
00208                                         print "WARNING: The OS returned the following error when comparing %s and %s" % (oldlog,log), detail
00209                                     except IOError, detail:
00210                                         print "IOError:", detail
00211                                     else:
00212                                         print "Successfully compared %s and %s" % (oldlog,log)                                            
00213                                 else:
00214                                     print "WARNING: Could not find an equivalent logfile for %s in the previous release dir %s " % (log,oldlog)
00215                                         
00216                                                             
00217                             else:
00218                                 continue
00219                     elif prof == "SimpleMemoryCheck":
00220                         #print "The logfiles for SimpleMemoryCheck are %s"%stepLogs
00221                         for log in stepLogs:
00222                             #print "The logfile considered now is %s"%log 
00223                             stepreg = re.compile("%s_([^_]*(_PILEUP)?)_%s((.log)|(.gz))?" % (CandFname[candle],"TimingReport"))
00224                             base = os.path.basename(log)
00225                             #Use the regular expression defined above to read out the step from the log/profile
00226                             searchob = stepreg.search(base)
00227                             #print "Value of searchob is %s"%searchob
00228                             #If in this log the regular expression was able match (and so to extract the step)
00229                             if searchob:
00230                                 #print searchob.groups()
00231                                 step = searchob.groups()[0]
00232                                 print "and the step taken is %s"%step
00233                                 #outpath = os.path.join(adir,"%s_%s_%s_regression" % (CandFname[candle],step,prof))
00234                                 oldlog  = os.path.join(olddir,"%s_%s" % (candle,profset),base)
00235                             if os.path.exists(oldlog):
00236                                 print ""
00237                                 print "** "
00238                                 print "** Comparing for SimpleMemoryCheck", candle, step, prof, "previous release: %s, latest release %s" % (oldlog,log)
00239                                 print "**"
00240                                 #The try/except is folded in the following function for SimpleMemoryCheck:
00241                                 compareSimMemPair(log,candle,profdir,adir,oldlog,oldRelName="")
00242                                
00243     if newRelName == "":
00244         newRelName = getVerFromLog(newdir)
00245     regress = open("%s/REGRESSION.%s.vs.%s" % (newdir,getVerFromLog(olddir),newRelName),"w")
00246     regress.write(olddir)
00247     regress.close()
00248 
00249 def _main():
00250     (oldpath,newpath) = getParameters()
00251     regressReports(oldpath,newpath,oldRelName=getVerFromLog(oldpath))
00252 
00253               
00254 if __name__ == "__main__":
00255     _main()
00256