Commit e5fd2741 authored by Andreas Schmidt's avatar Andreas Schmidt

+= thesis AS fixes

parent cd40ae35
#define XLAP
#include "xlap.h"
......
......@@ -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:
......@@ -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_ylabel("CDF")
ax.set_xlabel("{} [us]".format(duration))
ax.set_ylabel("CDF")
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()
......@@ -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)
......@@ -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)
......@@ -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.
"""
......@@ -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
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 = []
......@@ -25,6 +20,28 @@ class LatencyAnalysis():
corr = pd.Series(correlations, index=labels)
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):
......@@ -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")]
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)}]
label_position = width + (x_width * 0.01)
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 = []
......@@ -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)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.lines import Line2D
from xlap.analyse.util import extract_durations
from ipywidgets import interact
import ipywidgets as widgets
colors = {
"sender": "#CA0020",
"receiver": "#0571B0",
"EndToEnd": "black"
}
linestyles = {
"sender": (0,(1,1,3,1,1,1)),
"receiver": (0,(1,1)),
"EndToEnd": (0,())
}
def _create_line(config):
tr = config["time_reference"]
color = {
"sender": "#AAAAAA",
"receiver": "#888888",
"e2e": "black"
}
def _creator(duration_name):
if duration_name == "EndToEnd":
return [tr["sender"]["Start"] + "_T", tr["receiver"]["Stop"] + "_T", color["e2e"], "EndToEnd"]
return [tr["sender"]["Start"] + "_T", tr["receiver"]["Stop"] + "_T", colors["EndToEnd"], linestyles["EndToEnd"], "EndToEnd"]
elif duration_name == "Sender":
return [tr["sender"]["Start"] + "_T", tr["sender"]["Stop"] + "_T", color["sender"], "Sender"]
return [tr["sender"]["Start"] + "_T", tr["sender"]["Stop"] + "_T", colors["sender"], linestyles["sender"], "Sender"]
elif duration_name == "Receiver":
return [tr["receiver"]["Start"] + "_T", tr["receiver"]["Stop"] + "_T", color["receiver"], "Receiver"]
return [tr["receiver"]["Start"] + "_T", tr["receiver"]["Stop"] + "_T", colors["receiver"], linestyles["receiver"], "Receiver"]
else:
duration = config["durations"][duration_name]
return [duration["Start"] + "_T", duration["Stop"] + "_T", color[duration["Source"]], duration_name]
return [duration["Start"] + "_T", duration["Stop"] + "_T", colors[duration["Source"]], linestyles[duration["Source"]], duration_name]
return _creator
def trace(data_frame, config, export=False, file_name="TraceJitter.pdf"):
def trace(data_frame, config, export=False, file_name="PacketTrace.pdf", figsize=(8, 4.5), bbox_to_anchor=(1.05, 1), loc=2, t_max=None):
"""
:param data_frame:
......@@ -38,7 +48,7 @@ def trace(data_frame, config, export=False, file_name="TraceJitter.pdf"):
:return:
"""
fig, ax = plt.subplots(figsize=(8, 4.5))
fig, ax = plt.subplots(figsize=figsize)
plt.grid()
line_creator = _create_line(config)
......@@ -54,23 +64,34 @@ def trace(data_frame, config, export=False, file_name="TraceJitter.pdf"):
starts = data_frame[series[0]] - base
ends = data_frame[series[1]] - base
plt.hlines(range(n), starts, ends, series[2], linewidths=[5])
plt.hlines(range(n), starts, ends, series[2], series[3], linewidths=[5])
plt.xlabel("Time [us]")
if t_max is not None:
ax.set_xlim([0,t_max])
fig.canvas.draw()
ax.set_yticklabels(series[3])
ax.set_yticklabels(series[4])
ax.yaxis.set_ticks(np.arange(0, n, 1))
sides = ["sender","receiver","EndToEnd"]
handles = list(map(lambda x: Line2D([0], [0], color=colors[x], linestyle=linestyles[x], lw=5, label=x.title() if x != "EndToEnd" else x), sides))
plt.legend(handles=handles,bbox_to_anchor=bbox_to_anchor, loc=loc, borderaxespad=0.)
plt.tight_layout()
if export:
plt.savefig(file_name)
plt.show()
def traces(df, config):
def traces(df, config, figsize=(10, 4.5), global_xaxis=False):
"""
Display a slider to select sequence numbers and the respective trace.
"""
t_max = None
if global_xaxis:
t_max = df["EndToEnd_D"].max()
@interact(seq_no=widgets.IntSlider(min=1, max=len(df), step=1, value=47))
def _f(seq_no):
trace(df.ix[seq_no], config)
trace(df.iloc[seq_no], config, figsize=figsize, t_max=t_max)
......@@ -37,7 +37,7 @@ def extract_durations(config):
return ["EndToEnd", "Sender"] + durations_send + ["Receiver"] + durations_recv
def box(data_frame, xlim=None, export=False, file_name=None):
def box(data_frame, xlim=None, export=False, file_name=None, figsize=(8, 4.5)):
"""
Display a boxplot for the durations contained in data_frame.
:param data_frame:
......@@ -45,13 +45,13 @@ def box(data_frame, xlim=None, export=False, file_name=None):
:param file_name:
:return:
"""
ax = data_frame.plot.box(vert=False, grid=True)
ax = data_frame.plot.box(vert=False, grid=True,figsize=figsize)
fig = ax.get_figure()
ax.set_yticklabels(list(map(lambda x: x.get_text().replace("_D", ""), ax.get_yticklabels())))
plt.xlabel("Time [us]")
if xlim is not None:
plt.xlim(xlim)
fig.set_size_inches(8, 4.5, forward=True)
plt.tight_layout()
if export and file_name is not None:
fig.savefig(file_name)
......
......@@ -3,14 +3,10 @@ import argparse
from xlap.parse import evaluate, parse_config
import xlap.analyse.jitter as jitter
import xlap.analyse.latency as latency
import xlap.analyse.diff as difference
import xlap.analyse.e2e as e2e
tasks = {
"jitter": None,
"latency": None,
"difference": None,
"e2e": None,
"capture": None
}
......@@ -45,30 +41,10 @@ def main():
f.write("\n")
else:
print(output)
elif command == "e2e":
khz1 = 2000000
khz2 = 3000000
path="../publications/rtn-18/eval/20180419_energy/"
df_data1 = evaluate(path+"sender-"+str(khz1)+".csv", path+"receiver-"+str(khz1)+".csv", config=config, kind=0)
df_data2 = evaluate(path+"sender-"+str(khz2)+".csv", path+"receiver-"+str(khz2)+".csv", config=config, kind=0)
e2e.analyse(df_data1, df_data2, config)
elif command == "latency":
df_data = evaluate(data_files["sender"], data_files["receiver"], config=config, kind=0)
a = latency.analyse(df_data, config)
print(a.corr.sort_values(ascending=False))
elif command == "difference":
path="../publications/rtn-18/eval/20180420_"
khz = 3000000
df_data1 = evaluate(path+"base1/sender-"+str(khz)+".csv", path+"base1/receiver-"+str(khz)+".csv", config=config, kind=0)
# sanity check:
#df_data2 = evaluate("../prrt/out/s.csv", "../prrt/out/r.csv", config=config, kind=0)
# same setup, different measurement run:
#df_data2 = evaluate("../prrt/out/s+same.csv", "../prrt/out/r+same.csv", config=config, kind=0)
# different setup:
#df_data2 = evaluate("../prrt/out/s+send.csv", "../prrt/out/r+send.csv", config=config, kind=0)
df_data2 = evaluate(path+"base2/sender-"+str(khz)+".csv", path+"base2/receiver-"+str(khz)+".csv", config=config, kind=0)
#df_data2 = evaluate(path+"changed/sender-"+str(khz)+".csv", path+"changed/receiver-"+str(khz)+".csv", config=config, kind=0)
difference.analyse(df_data1, df_data2, config)
else:
df_data = evaluate(data_files["sender"], data_files["receiver"], config=config, kind=0)
......
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