# HG changeset patch # User Nina Engelhardt # Date 1331229139 -3600 # Node ID c946cba3fda00105bcb8425665989330e5f7db0b # Parent 2021f42cc6721fe66a4b8ed115c67b34a298d38f column view diff -r 2021f42cc672 -r c946cba3fda0 scripts/ucc_and_loop_graph_treatment/column_view.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/ucc_and_loop_graph_treatment/column_view.py Thu Mar 08 18:52:19 2012 +0100 @@ -0,0 +1,108 @@ +#!/usr/bin/python + +import svgfig as sf + +__column_width = 100 + + + +def fig_from_node(graph,node,positioning=None): + """Build globally positioned node representation.""" + core = graph.node[node]['core'] + if positioning==None: + x1 = core * 3 * __column_width + __column_width + else: + x1 = core * 3 * __column_width + 2 * __column_width + x2 = x1 + __column_width + if positioning != None: + y1 = positioning[node] - graph.node[node]['weight'] + elif graph.node[node].has_key('AssignerInvocation_start'): + y1 = graph.node[node]['AssignerInvocation_start'] - graph.node['start']['starttimes'][core] + elif graph.node[node].has_key('Assigner_start'): + y1 = graph.node[node]['Assigner_start'] - graph.node['start']['starttimes'][core] + elif graph.node[node].has_key('Work_start'): + y1 = graph.node[node]['Work_start'] - graph.node['start']['starttimes'][core] + elif graph.node[node].has_key('AppResponderInvocation_start'): + y1 = graph.node[node]['AppResponderInvocation_start'] - graph.node['start']['starttimes'][core] + elif graph.node[node].has_key('AppResponder_start'): + y1 = graph.node[node]['AppResponder_start'] - graph.node['start']['starttimes'][core] + else: + raise NameError('Node insufficiently annotated') + y2 = y1 + graph.node[node]['weight'] + if positioning != None and node[0]>7: + f='blue' + elif node[0]>7: + f='red' + else: + f='gray' + r = sf.Rect(x1,y1,x2,y2,fill=f) + s = sf.Text((x1+x2)/2 , (y1+y2)/2 ,str(node),text_anchor="middle") + if graph.node[node].has_key('AssignerInvocation_start') and graph.node[node].has_key('Assigner_start'): + h = graph.node[node]['Assigner_start'] - graph.node[node]['AssignerInvocation_start'] + r1 = sf.Rect(x1,y1,x2,y1+h,fill='green',fill_opacity="70%") + return sf.Fig(r,r1,s) + return sf.Fig(r,s) + +def tsc_fig_from_node(graph,node,maxh): + tscstarttime = graph.node['start']['tscstarttime'] + core = graph.node[node]['core'] + x1 = 3 * core * __column_width + x2 = x1 + __column_width + y1 = graph.node[node]['Timestamp_start'] - tscstarttime + if graph.node[node].has_key('Timestamp_end'): + y2 = graph.node[node]['Timestamp_end'] - tscstarttime + else: + y2 = y1 + graph.node[node]['weight'] + if node[0]>7: + f='yellow' + else: + f='gray' + r = sf.Rect(x1,y1,x2,y2,fill=f) + s = sf.Text((x1+x2)/2 , (y1+y2)/2 ,str(node),text_anchor="middle") + try: + if maxh < y2: + maxh = y2 + except: + pass + return sf.Fig(r,s),maxh + +def fig_nodes(graph,vertical_scale_factor,positioning=None): + """Build all nodes.""" + nodes = [] + for node in graph: + if node != 'start' and node != 'end': + try: + nodes.append(fig_from_node(graph,node,positioning=positioning)) + except Exception as e: + print node,e + return sf.Fig(*nodes,trans="x,{}*y".format(vertical_scale_factor)) + +def save_column_view(graph,num_cores,total_height,positioning=None): + vertical_scale_factor = 10000.0/float(total_height) + f = sf.Fig(fig_nodes(graph,vertical_scale_factor,positioning=positioning)) + f.d.append(get_tsc_scale(graph,num_cores,total_height)) + if positioning!=None: + f.d.append(fig_nodes(graph,vertical_scale_factor)) + w = 3*__column_width*num_cores + c = sf.canvas(f.SVG(),width="{}px".format(w),height="10000px",viewBox='0 0 {} 10000'.format(w)) + c.save() + +def get_tsc_scale(graph,num_cores,total_height): + nodes=sf.Fig() + maxh = 0 + for node in graph: + if node != 'start' and node != 'end': + try: + n , maxh = tsc_fig_from_node(graph,node,maxh) + nodes.d.append(n) + except Exception as e: + print node,e + nodes.trans = "x,{}*y".format(10000.0/float(total_height)) + return nodes + +def save_tsc_scale(graph,num_cores,total_height): + nodes = get_tsc_scale(graph,num_cores,total_height) + w = 3*__column_width*num_cores + #h = maxh + c = sf.canvas(nodes.SVG(),width="{}px".format(w),height="{}px".format(10000),viewBox='0 0 {} {}'.format(w,10000)) + c.save('tsc.svg') diff -r 2021f42cc672 -r c946cba3fda0 scripts/ucc_and_loop_graph_treatment/parse_loop_graph.py --- a/scripts/ucc_and_loop_graph_treatment/parse_loop_graph.py Fri Feb 10 16:15:55 2012 +0100 +++ b/scripts/ucc_and_loop_graph_treatment/parse_loop_graph.py Thu Mar 08 18:52:19 2012 +0100 @@ -4,6 +4,7 @@ import csv import networkx as nx import matplotlib.pyplot as plt +import column_view def read_from_file(filename): d = {} @@ -35,33 +36,6 @@ continue return d -def add_attributes_to_nodes_from_file(g,filename): - counterreader = (csv.reader)(filename,skipinitialspace=True) - for row in counterreader: - if row[0] == "event": - n = (int(row[2]),int(row[3])) - g.node[n][row[1]] = int(row[4]) - g.node["start"]['weight'] = 0 - g.node["end"]['weight'] = 0 - for n in g: - try: - if n!="start" and n!="end": - g.node[n]['weight'] = g.node[n]['CoreLoop_afterWork'] - g.node[n]['CoreLoop_beforeWork'] + g.node[n]['MasterLoop_afterReqHdlr'] - g.node[n]['MasterLoop_beforeReqHdlr'] + g.node[n]['MasterLoop_afterAssign'] - g.node[n]['MasterLoop_beforeAssign'] - except KeyError as e: - print e,n - - -# counterreader = (csv.reader)(filename) -# for row in counterreader: -# n = (int(row[0]),int(row[1])) -# g.node[n]['suspend_point'] = row[2] -# g.node[n]['schedule_check_cycles'] = int(row[4])-int(row[19]) -# g.node[n]['sync_cycles'] = int(row[25])-int(row[24]) -# g.node[n]['assign_cycles'] = int(row[10])-int(row[7]) -# g.node[n]['work_comm_cycles'] = int(row[16])-int(row[13]) -# g.node[n]['status_cycles'] = int(row[22])-int(row[16]) -# g.node[n]['weight'] = g.node[n]['schedule_check_cycles'] + g.node[n]['sync_cycles'] + g.node[n]['assign_cycles'] + g.node[n]['work_comm_cycles'] + g.node[n]['status_cycles'] - def loopgraph_from_dict(d): g = nx.DiGraph() g.add_node("start") @@ -84,8 +58,60 @@ g.add_edge(node,"end") return g +def add_attributes_to_nodes_from_file(g,filename): + counterreader = (csv.reader)(filename,skipinitialspace=True) + for row in counterreader: + if row[0] == "event": + n = (int(row[2]),int(row[3])) + g.node[n][row[1]] = int(row[4]) + g.node[n]['core'] = int(row[6]) + g.node["start"]['weight'] = 0 + g.node["end"]['weight'] = 0 + starttimes = {} + tscstarttimes = {} + tscendtimes = {} + for n in g: + try: + if n!="start" and n!="end": + weight = 0 + if g.node[n].has_key('Assigner_start') and g.node[n].has_key('AssignerInvocation_start'): + weight += g.node[n]['Assigner_start'] - g.node[n]['AssignerInvocation_start'] + if g.node[n].has_key('Assigner_end') and g.node[n].has_key('Assigner_start'): + weight += g.node[n]['Assigner_end'] - g.node[n]['Assigner_start'] + if g.node[n].has_key('Work_start') and g.node[n].has_key('Assigner_end'): + weight += g.node[n]['Work_start'] - g.node[n]['Assigner_end'] + if g.node[n].has_key('Work_end') and g.node[n].has_key('Work_start'): + weight += g.node[n]['Work_end'] - g.node[n]['Work_start'] + if g.node[n].has_key('AppResponderInvocation_start') and g.node[n].has_key('Work_end'): + weight += g.node[n]['AppResponderInvocation_start'] - g.node[n]['Work_end'] + if g.node[n].has_key('AppResponder_start') and g.node[n].has_key('AppResponderInvocation_start'): + weight += g.node[n]['AppResponder_start'] - g.node[n]['AppResponderInvocation_start'] + if g.node[n].has_key('AppResponder_end') and g.node[n].has_key('AppResponder_start'): + weight += g.node[n]['AppResponder_end'] - g.node[n]['AppResponder_start'] + if g.node[n].has_key('NextAssigner_start') and g.node[n].has_key('AppResponder_end'): + weight += g.node[n]['NextAssigner_start'] - g.node[n]['AppResponder_end'] + assert weight > 0 + g.node[n]['weight'] = weight #+ weight/10 + if g.node[n].has_key('AssignerInvocation_start'): + if not starttimes.has_key(g.node[n]['core']) or starttimes[g.node[n]['core']] > g.node[n]['AssignerInvocation_start']: + starttimes[g.node[n]['core']] = g.node[n]['AssignerInvocation_start'] + if g.node[n].has_key('Timestamp_start'): + if not tscstarttimes.has_key(g.node[n]['core']) or tscstarttimes[g.node[n]['core']] > g.node[n]['Timestamp_start']: + tscstarttimes[g.node[n]['core']] = g.node[n]['Timestamp_start'] + if g.node[n].has_key('Timestamp_start'): + if not tscendtimes.has_key(g.node[n]['core']) or tscendtimes[g.node[n]['core']] < g.node[n]['Timestamp_start']: + tscendtimes[g.node[n]['core']] = g.node[n]['Timestamp_start'] + except Exception as e: + print e,n + g.node['start']['starttimes']=starttimes + g.node['start']['tscstarttimes']=tscstarttimes + g.node['start']['tscstarttime']=min(tscstarttimes.values()) + g.node['start']['tscendtime']=max(tscendtimes.values()) + def path_length(graph,path): length = 0 + if path==None: + return 0 for node in path: try: length += graph.node[node]['weight'] @@ -101,14 +127,44 @@ if not graph.has_node(end): return None longest = None + print graph.predecessors(end) for node in graph.predecessors(end): if node not in path: newpath = find_critical_path(graph, start, node, path) - if newpath: - if not longest or path_length(graph,newpath) > path_length(graph,longest): + if newpath!=None: + ll=path_length(graph,longest) + nl=path_length(graph,newpath) + if (longest==None) or nl > ll: longest = newpath + #print nl, ll return longest +def annotate_critical_path(graph, start, end, lend={}, predd={}): + path_to_here = 0 + if len(graph.predecessors(end)) == 0: + assert end == start + for node in graph.predecessors(end): + if not lend.has_key(node): + lend,predd = annotate_critical_path(graph, start, node, lend, predd) + try: + if lend[node] > path_to_here: + path_to_here = lend[node] + predd[end] = node + except KeyError: + print node, nlend + exit(0) + lend[end] = path_to_here + graph.node[end]['weight'] + return lend,predd + +def get_path(predd,end): + path = [] + node = end + while predd.has_key(node): + path = [node] + path + node = predd[node] + path = [node] + path + return path + def build_cg(loopfile,counterfile): d = read_from_file(loopfile) print "Parsed file", loopfile.name, "and found:" @@ -124,16 +180,43 @@ print len(d["hwDep"]), "Hardware constraints" g = loopgraph_from_dict(d) add_attributes_to_nodes_from_file(g,counterfile) - critical_path = find_critical_path(g,"start","end") + #cont = raw_input("Calculate and show critical path (y/N)? ") + #if not cont.startswith(('y','Y')): + # sys.exit() + lend,predd = annotate_critical_path(g, 'start', 'end') + print "Critical path length:",lend['end'] + critical_path = get_path(predd,'end') if critical_path == None: print "No path found!" nx.draw(g) else: - print "Expected execution time:\t",path_length(g,critical_path),"cycles" + #print "Critical path:",critical_path + print "Expected execution time:",path_length(g,critical_path),"cycles" try: - print "Actual execution time:\t", g.node[(2,98)]['MasterLoop_beforeReqHdlr'] - g.node[(2,1)]['MasterLoop_beforeAssign'], "cycles" - except KeyError: - pass + actual_time = g.node['start']['tscendtime'] - g.node['start']['tscstarttime'] + print "Actual execution time:", actual_time, "cycles" + dif = actual_time - lend['end'] + print "(Difference:", dif, "- Relative Error:", 100*float(dif)/float(lend['end']),"%)" + print g.node['start']['starttimes'] + print g.node['start']['tscstarttimes'] + column_view.save_column_view(g,4,max(actual_time,lend['end']),lend) + #column_view.save_tsc_scale(g,4,lend['end']) + return # + print "Node \tCalculated\t Actual\tCore\tDifference\tNon-cumulative part" + drf = 0 + for n in critical_path: + if g.node[n].has_key('AppResponder_end'): + clen = g.node[n]['AppResponder_end'] + elif g.node[n].has_key('AppResponder_start'): + clen = g.node[n]['AppResponder_start'] + else: + print n + if n!='start' and n!='end': + print "{}\t{:10}\t{:10}\t({})\t{:10}\t{:10}".format(n,lend[n],clen,g.node[n]['core'],clen-lend[n],clen-lend[n]-drf) + drf = clen-lend[n] + except KeyError as e: + print e + return # colors = [] for node in g.nodes(): if node in critical_path: @@ -145,12 +228,23 @@ def main(): - if len(sys.argv)<2: - sys.exit() - uccfile = open(sys.argv[1]) - counterfile = open(sys.argv[2]) + if len(sys.argv)<3: + if len(sys.argv)==2: + uccfile = open("LoopGraph.{0}".format(sys.argv[1])) + counterfile = open("Counters.{0}.csv".format(sys.argv[1])) + else: + print "Usage: {} SCGfile Counterfile".format(sys.argv[0]) + sys.exit() + else: + uccfile = open(sys.argv[1]) + counterfile = open(sys.argv[2]) + print sys.getrecursionlimit() build_cg(uccfile,counterfile) if __name__ == "__main__": - main() + sys.setrecursionlimit(10000) + try: + main() + except Exception as e: + print e