Commit d4a0d13b authored by Andreas Schmidt's avatar Andreas Schmidt

Improve latency code (graphviz, filtering, reformat).

parent 2ffc0736
...@@ -4,6 +4,7 @@ from xlap.analyse.util import get_outlier_threshold, extract_durations, box ...@@ -4,6 +4,7 @@ from xlap.analyse.util import get_outlier_threshold, extract_durations, box
from scipy.stats.stats import pearsonr from scipy.stats.stats import pearsonr
import numpy as np import numpy as np
import sys import sys
import graphviz
def _get_thread_for_event(config, e): def _get_thread_for_event(config, e):
...@@ -14,6 +15,7 @@ def _get_thread_for_event(config, e): ...@@ -14,6 +15,7 @@ def _get_thread_for_event(config, e):
print("Cannot find %s".format(name), file=sys.stderr) print("Cannot find %s".format(name), file=sys.stderr)
return None return None
def _happens_before(df, a, b, config): def _happens_before(df, a, b, config):
""" """
check if a happens-before b in the trace check if a happens-before b in the trace
...@@ -35,12 +37,14 @@ def _happens_before(df, a, b, config): ...@@ -35,12 +37,14 @@ def _happens_before(df, a, b, config):
# If in doubt, a and b are concurrent. # If in doubt, a and b are concurrent.
return not (df[a] >= df[b]).any() return not (df[a] >= df[b]).any()
def _fast_happens_before(df, a, b, hb): def _fast_happens_before(df, a, b, hb):
""" """
check if a happens-before b, using a pre-computed relation check if a happens-before b, using a pre-computed relation
""" """
return any(r['Start'] == str(a) and r['End'] == str(b) for r in hb) return any(r['Start'] == str(a) and r['End'] == str(b) for r in hb)
def _happens_directly_before(df, a, b, hb): def _happens_directly_before(df, a, b, hb):
""" """
check if a happens-directly-before b in the trace check if a happens-directly-before b in the trace
...@@ -55,6 +59,7 @@ def _happens_directly_before(df, a, b, hb): ...@@ -55,6 +59,7 @@ def _happens_directly_before(df, a, b, hb):
return False return False
return True return True
def _locally_happens_directly_before(df, a, b, hb, config): def _locally_happens_directly_before(df, a, b, hb, config):
""" """
check if a happens-directly-before b in the trace but, be a little bit more check if a happens-directly-before b in the trace but, be a little bit more
...@@ -101,20 +106,19 @@ def _locally_happens_directly_before(df, a, b, hb, config): ...@@ -101,20 +106,19 @@ def _locally_happens_directly_before(df, a, b, hb, config):
else: else:
return _happens_directly_before(df, a, b, hb) return _happens_directly_before(df, a, b, hb)
def _plot_controlflow_graph(df, hdb): def _plot_controlflow_graph(df, hdb):
""" """
print the control flow graph in a format that dot understands generate the control flow graph using dot
""" """
print("Digraph G {") t_columns = [x for x in df.columns if x.endswith("_T")]
for event1 in df: d = graphviz.Digraph(filename="graph", format="pdf")
if not str(event1).endswith("_T"): for event1 in df[t_columns]:
continue d.node(str(event1)[:-2])
print("\t_node__"+str(event1) + "[label=\""+str(event1)[:-2]+"\"]")
for edge in hdb: for edge in hdb:
print("\t_node__"+edge['Start'] + " -> _node__"+edge['End'] + ";") d.edge(edge["Start"][:-2], edge["End"][:-2])
#for edge in hdb: d.render() # saves to graph.pdf in local folder
# print("\t_node__"+edge['Start'] + " -> _node__"+edge['End'] + "[label=\""+str(edge['Correlation'])+"\"];") return d
print("}")
# Taken from: http://composition.al/blog/2015/11/29/a-better-way-to-add-labels-to-bar-charts-with-matplotlib/ # Taken from: http://composition.al/blog/2015/11/29/a-better-way-to-add-labels-to-bar-charts-with-matplotlib/
...@@ -133,7 +137,7 @@ def autolabel(rects, ax, labels): ...@@ -133,7 +137,7 @@ def autolabel(rects, ax, labels):
# If we can fit the label above the column, do that; # If we can fit the label above the column, do that;
# otherwise, put it inside the column. # otherwise, put it inside the column.
if p_width > 0.50: # arbitrary; 95% looked good to me. if p_width > 0.50: # arbitrary; 95% looked good to me.
label_position = width - (x_width) + 0.7 label_position = width - (x_width) + 0.7
color = "white" color = "white"
align = "right" align = "right"
...@@ -143,64 +147,58 @@ def autolabel(rects, ax, labels): ...@@ -143,64 +147,58 @@ def autolabel(rects, ax, labels):
ax.text(label_position, rect.get_y(), labels[i], ha=align, va='bottom', rotation=0, color=color) ax.text(label_position, rect.get_y(), labels[i], ha=align, va='bottom', rotation=0, color=color)
def _plot_critical_regions(df,hdb): def _plot_critical_regions(df, hdb):
""" """
plot regions, sorted by latency criticality plot regions, sorted by latency criticality
""" """
plt.rcParams["font.family"] = "serif" plt.rcParams["font.family"] = "serif"
for region in sorted(hdb, key = lambda x: -x['Correlation']): for region in sorted(hdb, key=lambda x: -x['Correlation']):
print("%-10f %10s -> %10s"%(region['Correlation'], region['Start'], region['End']), file=sys.stderr) print("%-10f %10s -> %10s" % (region['Correlation'], region['Start'], region['End']), file=sys.stderr)
relevant = sorted([x for x in hdb if x['Correlation'] > 0], key = lambda x: -x['Correlation'], reverse=True) relevant = sorted([x for x in hdb if x['Correlation'] > 0], key=lambda x: -x['Correlation'], reverse=True)
x = np.arange(len(relevant)) x = np.arange(len(relevant))
correlations = list(map(lambda x: x['Correlation'], relevant)) correlations = list(map(lambda x: x['Correlation'], relevant))
ticks = list(map(lambda x: "%s-%s" % (x['Start'][:-2], x['End'][:-2]), relevant)) ticks = list(map(lambda x: "%s-%s" % (x['Start'][:-2], x['End'][:-2]), relevant))
fig, ax = plt.subplots() fig, ax = plt.subplots()
rects = ax.barh(x, correlations, align="center", tick_label="") rects = ax.barh(x, correlations, align="center", tick_label="")
autolabel(rects, ax, ticks) autolabel(rects, ax, ticks)
# TODO: find a more elegant solution for the label text plt.tight_layout()
plt.tight_layout() plt.savefig("latency-criticality.pdf")
plt.savefig("latency-criticality.pdf") plt.close()
plt.close()
def analyse(df, config):
hb = []
def analyse(df, config): events = [column for column in df.columns if column.endswith("_T")]
hb = []
for event1 in df: for event1 in df[events]:
if not str(event1).endswith("_T"): for event2 in df[events]:
continue if str(event1) == str(event2):
print(str(event1) + " ...", file=sys.stderr) continue
for event2 in df: if _happens_before(df, event1, event2, config):
if not str(event2).endswith("_T"): hb += [{'Start': str(event1), 'End': str(event2)}]
continue
if str(event1) == str(event2): hdb = []
continue e2e = list(df['EndToEnd_D'])
if _happens_before(df, event1, event2, config): for event1 in df[events]:
hb += [{'Start':str(event1), 'End':str(event2)}] for event2 in df[events]:
if str(event1) == str(event2):
hdb = [] continue
e2e = list(df['EndToEnd_D']) # if _locally_happens_directly_before(df, event1, event2, hb, config):
for event1 in df: if _happens_directly_before(df, event1, event2, hb):
if not str(event1).endswith("_T"): # compute the correlation between e2e latency and event1-event2 latency
continue l3 = list(df[event2] - df[event1])
for event2 in df: if any(map(lambda x: x != 0, l3)):
if not str(event2).endswith("_T"): correlation = pearsonr(l3, e2e)[0]
continue else:
if str(event1) == str(event2): correlation = 0
continue
#if _locally_happens_directly_before(df, event1, event2, hb, config): hdb += [{'Start': str(event1), 'End': str(event2), 'Correlation': correlation}]
if _happens_directly_before(df, event1, event2, hb):
# compute the correlation between e2e latency and event1-event2 latency cfg = _plot_controlflow_graph(df, hdb)
l3 = list(df[event2] - df[event1]) _plot_critical_regions(df, hdb)
if any(map(lambda x: x != 0, l3)): return {
correlation = pearsonr(l3, e2e)[0] "cfg": cfg
else: }
correlation = 0
hdb += [{'Start':str(event1), 'End':str(event2), 'Correlation':correlation}]
_plot_controlflow_graph(df, hdb)
_plot_critical_regions(df, hdb)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment