CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FWCore/Services/bin/prof2calltree.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 '''
00004 The output from the profiler has names that end in 'names' and 'paths'.
00005 This script expects you run c++filt on the 'names' file and save
00006 it will the same prefix, but with 'nice_names' on the end.
00007 This will be improved on the release of simple profiler.
00008 
00009 The output file from this script has the same prefix as the input
00010 files, but ends in 'calltree'.  This file can be fed directly into
00011 kcachegrind.
00012 '''
00013 
00014 import sys
00015 import csv
00016 
00017 if len(sys.argv) < 3:
00018     print "usage: ",sys.argv[0]," prefix_of_run_data tick_cutoff n|o"
00019     sys.exit(1)
00020 
00021 prefix = sys.argv[1]
00022 cutoff = int(sys.argv[2])
00023 newold_flag = 'o'
00024 
00025 if len(sys.argv) > 3:
00026     newold_flag = sys.argv[3]
00027 
00028 outfile = open(prefix+"calltree","w")
00029 pathfile = open(prefix+"paths","r")
00030 
00031 names = {}
00032 edges = {}
00033 
00034 def tostring(l):
00035     x=""
00036     for i in l: x += "%d "%i
00037     return x
00038 
00039 class Node:
00040     def __init__(me,fid,name):
00041         me.fid = int(fid)
00042         me.name = name
00043         me.ticks_as_parent = 0
00044         me.ticks_as_child = 0
00045         me.ticks_as_parent_recur = 0
00046         me.calls = 0
00047         me.children = {} # set() - want to use set, but not until 2.4
00048 
00049     def parentTicks(me,count):
00050         me.ticks_as_parent += int(count)
00051     
00052     def childTicks(me,count):
00053         c = int(count)
00054         me.ticks_as_parent += c
00055         me.ticks_as_child += c
00056         
00057     def recurTicks(me,count):
00058         me.ticks_as_parent_recur += int(count)
00059 
00060     def addChild(me,child_id):
00061         me.children[child_id]=0  # .add(child_id) -cannot use set functions yet
00062 
00063     def __str__(me):
00064         return "(%d,%s,%d,%d,%s)"%(me.fid,me.name,me.ticks_as_parent,me.ticks_as_child,tostring(me.children.keys()))
00065 
00066 class EdgeCount:
00067     def __init__(me):
00068         me.count = 0
00069 
00070     def addTicks(me,count):
00071         me.count += count
00072 
00073     def __str__(me):
00074         return "%d"%me.count
00075 
00076 if newold_flag == 'o':
00077     namefile = open(prefix+"nice_names","r")
00078     for entry in namefile:
00079         front=entry.split(' ',2)
00080         back=front[2].rsplit(' ',16)
00081         name=back[0]
00082         name=name.replace(' ','-')
00083         #print name
00084         #names[front[0]]=(front[0],name,back[1],back[2],back[3],back[4],back[5])
00085         names[int(front[0])] = Node(front[0],name)
00086 else:
00087     namefile = csv.reader(open(prefix+"nice_names","rb"),delimiter='\t')
00088     for row in namefile:
00089         names[int(row[0])] = Node(row[0],row[-1])
00090     
00091 
00092 print >>outfile,"events: ticks"
00093 
00094 for entry in names.values():
00095     print >>outfile,"fn=(%s) %s"%(entry.fid,entry.name)
00096     # print entry[1]
00097 
00098 print >>outfile
00099 
00100 # all the 0 values below are line numbers (none in my case)
00101 #------------------------------
00102 # fn=func    <- parent function
00103 # 0 100      <- cost, accumulated into "incl" and "self" for func
00104 # cfn=func2  <- child function
00105 # calls=2 0  <- times called from func
00106 #               (accumulated into "called" for func2)
00107 # 0 350      <- cost involved in call
00108 #               (accumulated into "incl" for func2)
00109 
00110 # "incl" for a function appears in the graphed box, it is the sum over
00111 #        all incoming wires
00112 # A wire contains cost value from cfn entry
00113 
00114 for pe in pathfile:
00115     all = pe.split()
00116     l = len(all)
00117     #entry = names[all[-1:]]
00118     #print all
00119 
00120     ticks = int(all[1])
00121     if ticks < cutoff: continue
00122     last = int(all[l-1])
00123     names[last].childTicks(ticks)
00124 
00125     for i in range(2,l-1):
00126         edge = (int(all[i]), int(all[i+1]))
00127         node = names[edge[0]]
00128         node.recurTicks(ticks)
00129         if edge[0]!=edge[1]:
00130             node.parentTicks(ticks)
00131             node.addChild(edge[1])
00132             edges.setdefault(edge,EdgeCount()).addTicks(ticks)
00133 
00134 #for x in names.values():
00135 #    print x
00136 
00137 for node in names.values():
00138     cost=0
00139     #if len(node.children) == 0:
00140     cost = node.ticks_as_child
00141     print >>outfile,"fn=(%d)"%node.fid
00142     print >>outfile,"0 %d"%cost
00143     #print >>outfile,"\n\n"
00144     
00145     for child in node.children.keys():
00146         count = edges[(node.fid,child)].count
00147         print >>outfile,"cfn=(%d)"%child
00148         print >>outfile,"calls=%d 0"%count
00149         print >>outfile,"0 %d"%count
00150         
00151     print >>outfile,"\n\n"
00152