Loading xlap.c +1 −0 Original line number Diff line number Diff line #define XLAP #include "xlap.h" Loading xlap/analyse/cdf.py +11 −9 Original line number Diff line number Diff line Loading @@ -3,15 +3,14 @@ import numpy as np from .util import cdf, extract_durations import matplotlib.pyplot as plt def multi_cdf(dfs, config, export=False, file_name="CDF.pdf"): durations = [x + "_D" for x in extract_durations(config)] durations.remove("EndToEnd_D") def multi_cdf(dfs, config, export=False, file_name="CDF.pdf", figsize= (4,4), cols=3, colors=None): durations = extract_durations(config) durations.remove("EndToEnd") cols = 3 rows = int(math.ceil(len(durations) / cols)) items = len(durations) fig, axes = plt.subplots(nrows=rows, ncols=cols) fig.set_size_inches(4 * cols, 4 * rows, forward=True) fig.set_size_inches(figsize[0] * cols, figsize[1] * rows, forward=True) names = [] for df in dfs: Loading @@ -22,16 +21,19 @@ def multi_cdf(dfs, config, export=False, file_name="CDF.pdf"): ax = axes[idx // cols, idx % cols] else: ax = axes[idx] for df in dfs: cdf(df[duration], grid=True, ax=ax) for i, df in enumerate(dfs): kwargs = dict() if colors is not None: kwargs["color"] = colors[i] cdf(df[duration + "_D"], grid=True, ax=ax, **kwargs) if(idx == 0): ax.legend(names) ax.set_xlabel("{} [us]".format(duration)) ax.set_ylabel("CDF") ax.set_xlabel("{} [us]".format(duration)) plt.subplots_adjust(wspace=0.3,hspace=0.3) plt.tight_layout() if export and file_name is not None: fig.savefig(file_name) plt.tight_layout() plt.show() xlap/analyse/correlation.py +21 −19 Original line number Diff line number Diff line Loading @@ -6,50 +6,52 @@ from xlap.analyse.util import extract_durations def corr(df, duration, grid=False, ax=None, color="black", marker="+"): df.plot.scatter(ax=ax, y="EndToEnd_D", x=duration, x=duration + "_D", grid=grid, loglog=True, marker=marker, color=color) def corr_multi(dfs, duration, **kwargs): names = [] for df in dfs: names.append(df.name) colors = ["green","blue","orange","purple","red","pink"] markers = ["v", "^", ">", "<", "+"] def corr_multi(dfs, duration, colors=None, **kwargs): if colors is None: colors = ["green","blue","orange"] markers = ["v", "^", ">", "<"] for idf, df in enumerate(dfs): corr(df, duration, color=colors[idf % len(colors)], marker=markers[idf % len(markers)], **kwargs) if len(names) > 1: kwargs["ax"].legend(names) kwargs["ax"].set_xlabel("{} [us]".format(duration)) def multi_correlation(dfs, config, export=False, file_name="MultiCorrelation.pdf"): durations = [x + "_D" for x in extract_durations(config)] durations.remove("EndToEnd_D") def multi_correlation(dfs, config, export=False, file_name="MultiCorrelation.pdf", figsize=(5.5,5.5), cols=2, colors=None, **kwargs): durations = extract_durations(config) durations.remove("EndToEnd") cols = 2 rows = int(math.ceil(len(durations) / cols)) items = len(durations) fig, axes = plt.subplots(nrows=rows, ncols=cols) fig.set_size_inches(5.5 * cols, 5.5 * rows, forward=True) fig.set_size_inches(figsize[0] * cols, figsize[1] * rows, forward=True) names = [] for df in dfs: if hasattr(df, "name"): names.append(df.name) for idx, duration in enumerate(durations): if items > cols: ax = axes[idx // cols, idx % cols] else: ax = axes[idx] corr_multi(dfs, duration, grid=True, ax=ax) corr_multi(dfs, duration, colors=colors, grid=True, ax=ax) if len(names) > 1 and idx == 0: ax.legend(names) ax.set_ylabel("EndToEnd" if idx == 0 else "") plt.subplots_adjust(wspace=0.3,hspace=0.3) plt.tight_layout() if export and file_name is not None: fig.savefig(file_name) plt.tight_layout() plt.show() def correlation(df, config, export=False, file_name="SingleCorrelation.pdf"): return multi_correlation([df], config, export, file_name) def correlation(df, config, export=False, file_name="SingleCorrelation.pdf", **kwargs): return multi_correlation([df], config, export, file_name, **kwargs) xlap/analyse/jitter.py +11 −8 Original line number Diff line number Diff line Loading @@ -3,12 +3,13 @@ import matplotlib.pyplot as plt from xlap.analyse.util import get_outlier_threshold, extract_durations, box def jitter_causes(df, durations, export=False, file_name=None): def jitter_causes(df, config, export=False, file_name=None, figsize=(8,3), color="black"): stats = df["EndToEnd_D"].describe() durations = extract_durations(config) threshold = get_outlier_threshold(stats) outliers = df[df["EndToEnd_D"] > threshold] reasons = [d + "_D" for d in durations.keys()] reasons = [d + "_D" for d in durations if d != "EndToEnd"] df_reasons = pd.DataFrame(index=outliers.index) Loading @@ -18,17 +19,17 @@ def jitter_causes(df, durations, export=False, file_name=None): df_reasons[reason] = outliers[outliers[reason] > reason_threshold].notnull() df_sum = df_reasons.sum().sort_values(ascending=False) ax = df_sum.plot.bar(x="Reason", y="Frequency", rot=45, grid=True, legend=False, color="black") ax = df_sum.plot.bar(x="Reason", y="Frequency", rot=45, grid=True, legend=False, color=color) fig = ax.get_figure() plt.ylabel("Frequency") ax.set_xticklabels(list(map(lambda x: x.get_text().replace("_D", ""), ax.get_xticklabels()))) fig.set_size_inches(8, 3, forward=True) fig.set_size_inches(figsize[0], figsize[1]) plt.tight_layout() if export: fig.savefig(file_name) print("Outliers:", len(outliers), ";", "Threshold[us]:", threshold) def trace_jitter(data_frame, config=None, threshold=None, export=False, file_name=None): def trace_jitter(data_frame, config=None, threshold=None, export=False, file_name=None, figsize=(8, 4.5)): """ Displays (and saves) a stacked boxplot of durations. """ Loading @@ -37,8 +38,10 @@ def trace_jitter(data_frame, config=None, threshold=None, export=False, file_nam if threshold is None: threshold = get_outlier_threshold(data_frame["EndToEnd_D"].describe()) df_no_outliers = data_frame[data_frame["EndToEnd_D"] <= threshold] box(df_no_outliers, (0, threshold), export, file_name) print("{} / {} are no outliers.".format(len(df_no_outliers), len(data_frame))) fig = plt.gcf() fig.set_size_inches(figsize[0], figsize[1]) box(df_no_outliers, (0, threshold), export, file_name, figsize) print("{} / {} are no outliers.".format(len(df_no_outliers), len(data_frame))) fig.canvas.set_window_title('Jitter Analysis') plt.show() return None xlap/analyse/latency.py +29 −62 Original line number Diff line number Diff line import pandas as pd import matplotlib.pyplot as plt from scipy.stats.stats import pearsonr from scipy.stats.stats import pearsonr, spearmanr import numpy as np import sys import graphviz class LatencyAnalysis(): def __init__(self, cfg=None, hdb=None): plt.rcParams['ps.useafm'] = True plt.rcParams['pdf.use14corefonts'] = True plt.rcParams['text.usetex'] = False plt.rcParams['font.family'] = 'sans-serif' #plt.rcParams['font.sans-serif'] = 'Latin Modern Sans' #plt.rcParams['font.monospace'] = 'FreeMono' self.cfg = cfg self.hdb = hdb correlations = [] labels = [] Loading @@ -27,6 +22,28 @@ class LatencyAnalysis(): self.corr = corr def plot_critical_regions(self, figsize=(5,5), export=False, file_name="latency-criticality.pdf"): """ plot regions, sorted by latency criticality """ hdb = self.hdb relevant = sorted([x for x in hdb if x['Correlation'] > 0], key=lambda x: -x['Correlation'], reverse=True) x = np.arange(len(relevant)) correlations = list(map(lambda x: x['Correlation'], relevant)) ticks = list(map(lambda x: "<%s, %s>" % (x['Start'][:-2], x['End'][:-2]), relevant)) fig, ax = plt.subplots(figsize=figsize) rects = ax.barh(x, correlations, align="center", tick_label="") autolabel(rects, ax, ticks) plt.xlabel("Latency Criticality") plt.tight_layout() if export: plt.savefig(file_name) plt.show() plt.close() def _get_thread_for_event(config, e): name = str(e)[:-2] try: Loading Loading @@ -158,64 +175,15 @@ def autolabel(rects, ax, labels): # If we can fit the label above the column, do that; # otherwise, put it inside the column. if p_width > 0.50: # arbitrary; 95% looked good to me. #label_position = width - (x_width) + 0.7 label_position = width - (x_width * 0.01) label_position = width - (x_width) + 0.75 color = "white" align = "right" else: label_position = width + (x_width * 0.002) mono = {'family': 'monospace'} ax.text(label_position, rect.get_y(), labels[i], ha=align, va='bottom', rotation=0, color=color, fontdict=mono) def _plot_critical_regions(hdb): """ plot regions, sorted by latency criticality """ relevant = sorted([x for x in hdb if x['Correlation'] > 0], key=lambda x: -x['Correlation'], reverse=True) x = np.arange(len(relevant)) correlations = list(map(lambda x: x['Correlation'], relevant)) ticks = list(map(lambda x: "<%s,%s>" % (x['Start'][:-2], x['End'][:-2]), relevant)) fig, ax = plt.subplots() rects = ax.barh(x, correlations, align="center", tick_label="") autolabel(rects, ax, ticks) plt.xlabel('Latency criticality') plt.tight_layout() plt.savefig("latency-criticality.pdf") plt.close() def get_durations(df, config): hb = [] events = [column for column in df.columns if column.endswith("_T")] label_position = width + (x_width * 0.01) for event1 in df[events]: for event2 in df[events]: if str(event1) == str(event2): continue if _happens_before(df, event1, event2, config): hb += [{'Start': str(event1), 'End': str(event2)}] hdb = [] e2e = list(df['EndToEnd_D']) for event1 in df[events]: for event2 in df[events]: if str(event1) == str(event2): continue # if _locally_happens_directly_before(df, event1, event2, hb, config): if _happens_directly_before(df, event1, event2, hb): # compute the correlation between e2e latency and event1-event2 latency l3 = list(df[event2] - df[event1]) ax.text(label_position, rect.get_y(), labels[i], ha=align, va='bottom', rotation=0, color=color, family="monospace") hdb += [{'Start': str(event1), 'Stop': str(event2), 'Source': 'cfa'}] return hdb def get_durations_2(dfs, config): df = dfs[0] + dfs[1] return get_durations(df, config) def analyse(df, config): hb = [] Loading @@ -240,12 +208,11 @@ def analyse(df, config): # compute the correlation between e2e latency and event1-event2 latency l3 = list(df[event2] - df[event1]) if any(map(lambda x: x != 0, l3)): correlation = pearsonr(l3, e2e)[0] correlation = spearmanr(l3, e2e)[0] else: correlation = 0 hdb += [{'Start': str(event1), 'End': str(event2), 'Correlation': correlation}] cfg = _plot_controlflow_graph(df, hdb) _plot_critical_regions(hdb) return LatencyAnalysis(cfg=cfg, hdb=hdb) Loading
xlap/analyse/cdf.py +11 −9 Original line number Diff line number Diff line Loading @@ -3,15 +3,14 @@ import numpy as np from .util import cdf, extract_durations import matplotlib.pyplot as plt def multi_cdf(dfs, config, export=False, file_name="CDF.pdf"): durations = [x + "_D" for x in extract_durations(config)] durations.remove("EndToEnd_D") def multi_cdf(dfs, config, export=False, file_name="CDF.pdf", figsize= (4,4), cols=3, colors=None): durations = extract_durations(config) durations.remove("EndToEnd") cols = 3 rows = int(math.ceil(len(durations) / cols)) items = len(durations) fig, axes = plt.subplots(nrows=rows, ncols=cols) fig.set_size_inches(4 * cols, 4 * rows, forward=True) fig.set_size_inches(figsize[0] * cols, figsize[1] * rows, forward=True) names = [] for df in dfs: Loading @@ -22,16 +21,19 @@ def multi_cdf(dfs, config, export=False, file_name="CDF.pdf"): ax = axes[idx // cols, idx % cols] else: ax = axes[idx] for df in dfs: cdf(df[duration], grid=True, ax=ax) for i, df in enumerate(dfs): kwargs = dict() if colors is not None: kwargs["color"] = colors[i] cdf(df[duration + "_D"], grid=True, ax=ax, **kwargs) if(idx == 0): ax.legend(names) ax.set_xlabel("{} [us]".format(duration)) ax.set_ylabel("CDF") ax.set_xlabel("{} [us]".format(duration)) plt.subplots_adjust(wspace=0.3,hspace=0.3) plt.tight_layout() if export and file_name is not None: fig.savefig(file_name) plt.tight_layout() plt.show()
xlap/analyse/correlation.py +21 −19 Original line number Diff line number Diff line Loading @@ -6,50 +6,52 @@ from xlap.analyse.util import extract_durations def corr(df, duration, grid=False, ax=None, color="black", marker="+"): df.plot.scatter(ax=ax, y="EndToEnd_D", x=duration, x=duration + "_D", grid=grid, loglog=True, marker=marker, color=color) def corr_multi(dfs, duration, **kwargs): names = [] for df in dfs: names.append(df.name) colors = ["green","blue","orange","purple","red","pink"] markers = ["v", "^", ">", "<", "+"] def corr_multi(dfs, duration, colors=None, **kwargs): if colors is None: colors = ["green","blue","orange"] markers = ["v", "^", ">", "<"] for idf, df in enumerate(dfs): corr(df, duration, color=colors[idf % len(colors)], marker=markers[idf % len(markers)], **kwargs) if len(names) > 1: kwargs["ax"].legend(names) kwargs["ax"].set_xlabel("{} [us]".format(duration)) def multi_correlation(dfs, config, export=False, file_name="MultiCorrelation.pdf"): durations = [x + "_D" for x in extract_durations(config)] durations.remove("EndToEnd_D") def multi_correlation(dfs, config, export=False, file_name="MultiCorrelation.pdf", figsize=(5.5,5.5), cols=2, colors=None, **kwargs): durations = extract_durations(config) durations.remove("EndToEnd") cols = 2 rows = int(math.ceil(len(durations) / cols)) items = len(durations) fig, axes = plt.subplots(nrows=rows, ncols=cols) fig.set_size_inches(5.5 * cols, 5.5 * rows, forward=True) fig.set_size_inches(figsize[0] * cols, figsize[1] * rows, forward=True) names = [] for df in dfs: if hasattr(df, "name"): names.append(df.name) for idx, duration in enumerate(durations): if items > cols: ax = axes[idx // cols, idx % cols] else: ax = axes[idx] corr_multi(dfs, duration, grid=True, ax=ax) corr_multi(dfs, duration, colors=colors, grid=True, ax=ax) if len(names) > 1 and idx == 0: ax.legend(names) ax.set_ylabel("EndToEnd" if idx == 0 else "") plt.subplots_adjust(wspace=0.3,hspace=0.3) plt.tight_layout() if export and file_name is not None: fig.savefig(file_name) plt.tight_layout() plt.show() def correlation(df, config, export=False, file_name="SingleCorrelation.pdf"): return multi_correlation([df], config, export, file_name) def correlation(df, config, export=False, file_name="SingleCorrelation.pdf", **kwargs): return multi_correlation([df], config, export, file_name, **kwargs)
xlap/analyse/jitter.py +11 −8 Original line number Diff line number Diff line Loading @@ -3,12 +3,13 @@ import matplotlib.pyplot as plt from xlap.analyse.util import get_outlier_threshold, extract_durations, box def jitter_causes(df, durations, export=False, file_name=None): def jitter_causes(df, config, export=False, file_name=None, figsize=(8,3), color="black"): stats = df["EndToEnd_D"].describe() durations = extract_durations(config) threshold = get_outlier_threshold(stats) outliers = df[df["EndToEnd_D"] > threshold] reasons = [d + "_D" for d in durations.keys()] reasons = [d + "_D" for d in durations if d != "EndToEnd"] df_reasons = pd.DataFrame(index=outliers.index) Loading @@ -18,17 +19,17 @@ def jitter_causes(df, durations, export=False, file_name=None): df_reasons[reason] = outliers[outliers[reason] > reason_threshold].notnull() df_sum = df_reasons.sum().sort_values(ascending=False) ax = df_sum.plot.bar(x="Reason", y="Frequency", rot=45, grid=True, legend=False, color="black") ax = df_sum.plot.bar(x="Reason", y="Frequency", rot=45, grid=True, legend=False, color=color) fig = ax.get_figure() plt.ylabel("Frequency") ax.set_xticklabels(list(map(lambda x: x.get_text().replace("_D", ""), ax.get_xticklabels()))) fig.set_size_inches(8, 3, forward=True) fig.set_size_inches(figsize[0], figsize[1]) plt.tight_layout() if export: fig.savefig(file_name) print("Outliers:", len(outliers), ";", "Threshold[us]:", threshold) def trace_jitter(data_frame, config=None, threshold=None, export=False, file_name=None): def trace_jitter(data_frame, config=None, threshold=None, export=False, file_name=None, figsize=(8, 4.5)): """ Displays (and saves) a stacked boxplot of durations. """ Loading @@ -37,8 +38,10 @@ def trace_jitter(data_frame, config=None, threshold=None, export=False, file_nam if threshold is None: threshold = get_outlier_threshold(data_frame["EndToEnd_D"].describe()) df_no_outliers = data_frame[data_frame["EndToEnd_D"] <= threshold] box(df_no_outliers, (0, threshold), export, file_name) print("{} / {} are no outliers.".format(len(df_no_outliers), len(data_frame))) fig = plt.gcf() fig.set_size_inches(figsize[0], figsize[1]) box(df_no_outliers, (0, threshold), export, file_name, figsize) print("{} / {} are no outliers.".format(len(df_no_outliers), len(data_frame))) fig.canvas.set_window_title('Jitter Analysis') plt.show() return None
xlap/analyse/latency.py +29 −62 Original line number Diff line number Diff line import pandas as pd import matplotlib.pyplot as plt from scipy.stats.stats import pearsonr from scipy.stats.stats import pearsonr, spearmanr import numpy as np import sys import graphviz class LatencyAnalysis(): def __init__(self, cfg=None, hdb=None): plt.rcParams['ps.useafm'] = True plt.rcParams['pdf.use14corefonts'] = True plt.rcParams['text.usetex'] = False plt.rcParams['font.family'] = 'sans-serif' #plt.rcParams['font.sans-serif'] = 'Latin Modern Sans' #plt.rcParams['font.monospace'] = 'FreeMono' self.cfg = cfg self.hdb = hdb correlations = [] labels = [] Loading @@ -27,6 +22,28 @@ class LatencyAnalysis(): self.corr = corr def plot_critical_regions(self, figsize=(5,5), export=False, file_name="latency-criticality.pdf"): """ plot regions, sorted by latency criticality """ hdb = self.hdb relevant = sorted([x for x in hdb if x['Correlation'] > 0], key=lambda x: -x['Correlation'], reverse=True) x = np.arange(len(relevant)) correlations = list(map(lambda x: x['Correlation'], relevant)) ticks = list(map(lambda x: "<%s, %s>" % (x['Start'][:-2], x['End'][:-2]), relevant)) fig, ax = plt.subplots(figsize=figsize) rects = ax.barh(x, correlations, align="center", tick_label="") autolabel(rects, ax, ticks) plt.xlabel("Latency Criticality") plt.tight_layout() if export: plt.savefig(file_name) plt.show() plt.close() def _get_thread_for_event(config, e): name = str(e)[:-2] try: Loading Loading @@ -158,64 +175,15 @@ def autolabel(rects, ax, labels): # If we can fit the label above the column, do that; # otherwise, put it inside the column. if p_width > 0.50: # arbitrary; 95% looked good to me. #label_position = width - (x_width) + 0.7 label_position = width - (x_width * 0.01) label_position = width - (x_width) + 0.75 color = "white" align = "right" else: label_position = width + (x_width * 0.002) mono = {'family': 'monospace'} ax.text(label_position, rect.get_y(), labels[i], ha=align, va='bottom', rotation=0, color=color, fontdict=mono) def _plot_critical_regions(hdb): """ plot regions, sorted by latency criticality """ relevant = sorted([x for x in hdb if x['Correlation'] > 0], key=lambda x: -x['Correlation'], reverse=True) x = np.arange(len(relevant)) correlations = list(map(lambda x: x['Correlation'], relevant)) ticks = list(map(lambda x: "<%s,%s>" % (x['Start'][:-2], x['End'][:-2]), relevant)) fig, ax = plt.subplots() rects = ax.barh(x, correlations, align="center", tick_label="") autolabel(rects, ax, ticks) plt.xlabel('Latency criticality') plt.tight_layout() plt.savefig("latency-criticality.pdf") plt.close() def get_durations(df, config): hb = [] events = [column for column in df.columns if column.endswith("_T")] label_position = width + (x_width * 0.01) for event1 in df[events]: for event2 in df[events]: if str(event1) == str(event2): continue if _happens_before(df, event1, event2, config): hb += [{'Start': str(event1), 'End': str(event2)}] hdb = [] e2e = list(df['EndToEnd_D']) for event1 in df[events]: for event2 in df[events]: if str(event1) == str(event2): continue # if _locally_happens_directly_before(df, event1, event2, hb, config): if _happens_directly_before(df, event1, event2, hb): # compute the correlation between e2e latency and event1-event2 latency l3 = list(df[event2] - df[event1]) ax.text(label_position, rect.get_y(), labels[i], ha=align, va='bottom', rotation=0, color=color, family="monospace") hdb += [{'Start': str(event1), 'Stop': str(event2), 'Source': 'cfa'}] return hdb def get_durations_2(dfs, config): df = dfs[0] + dfs[1] return get_durations(df, config) def analyse(df, config): hb = [] Loading @@ -240,12 +208,11 @@ def analyse(df, config): # compute the correlation between e2e latency and event1-event2 latency l3 = list(df[event2] - df[event1]) if any(map(lambda x: x != 0, l3)): correlation = pearsonr(l3, e2e)[0] correlation = spearmanr(l3, e2e)[0] else: correlation = 0 hdb += [{'Start': str(event1), 'End': str(event2), 'Correlation': correlation}] cfg = _plot_controlflow_graph(df, hdb) _plot_critical_regions(hdb) return LatencyAnalysis(cfg=cfg, hdb=hdb)