Skip to content

Instantly share code, notes, and snippets.

@JoshuaJB
Created March 31, 2020 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshuaJB/4270ef152c7be9c98a7d95861bebd0b0 to your computer and use it in GitHub Desktop.
Save JoshuaJB/4270ef152c7be9c98a7d95861bebd0b0 to your computer and use it in GitHub Desktop.
Full graph generation code for Sims, Bakita, and Anderson, ECRTS 2019
#!/usr/bin/python3
import matplotlib.pyplot as plt
import numpy
def read_sample(file):
"""Lazy function (generator) to read a file piece by piece.
Default chunk size: 1k."""
while True:
line = file.readline()
if line == b"*****\n":
break
if not line or line == "":
break
# raise Exception("No more data to read from this sample file.")
yield line
def load_data(file):
header = file.readline()
if not header:
return (None,None)
return (numpy.loadtxt(read_sample(file), delimiter=","), header.decode("utf-8").strip())
def util_header(header):
elems = header.split(',')
range_str = ""
if ':' in header: # Autodetect new range-based utilizations
ranges = eval(elems[3].replace(':',','))
for elem in ranges:
range_str += format_range(elem)
else:
range_str = format_range(elems[3:5])
return "Task Utilization ∈ " + range_str
def format_range(domain):
range_str = "[{0:.1f}, {1:.1f}]"
"""
range_str = ""
if float(domain[0]) == 0:
range_str += "({0:.1f}, "
else:
range_str += "[{0:.1f}, "
if float(domain[1]) == 1:
range_str += "{1:.1f})"
else:
range_str += "{1:.1f}]"
"""
return range_str.format(float(domain[0]), float(domain[1]))
def format_header(header, util_on=True):
elems = header.split(',')
# Autodetect if this is uniform by inspecting the field count
if ':' in header: # New, range-based system
cores = "{0} Cores, ".format(int(elems[0]))
util = util_header(header) + "\n" if util_on else ""
sf = "{} Periods, Pessimistic Model".format(elems[8])
#sf = s ∈ Gauss(0.72,{0:.2f}), f ∈ Gauss(0.72,{1:.2f})".format(float(elems[6]), float(elems[7]))
#if len(elems) == 9:
# sf += ", {} Periods".format(elems[8])
return cores + util + sf
elif len(elems) > 10:
cores = "{0} Cores, ".format(int(elems[0]))
utile = util_header(header) + ", σ = {0:.3f}\n" if util_on else "σ = {0:.3f}, "
utile = utile.format(float(elems[11]))
sf = "s ∈ Uniform({0:.2f},{1:.2f}), f ∈ Uniform({2:.2f},{3:.2f})".format(float(elems[7]), float(elems[8]), float(elems[9]), float(elems[10]))
return cores + utile + sf
elif len(elems) > 8:
cores = "{0} Cores, ".format(int(elems[0]))
util = util_header(header) + "\n" if util_on else ""
sf = "s ∈ Gauss(0.72,{0:.2f}), f ∈ Gauss(0.72,{1:.2f})".format(float(elems[7]), float(elems[8]))
return cores + util + sf
def setup_figure(fig, header):
#fig.legend(["[1] Oʙʟɪᴠɪᴏᴜs", "[2] Gʀᴇᴇᴅʏ-Tʜʀᴇᴀᴅ", "[3] Gʀᴇᴇᴅʏ-Pʜʏsɪᴄᴀʟ", "[4] Gʀᴇᴇᴅʏ-Mɪxᴇᴅ", "Oᴘᴛɪᴍᴀʟ"])#, loc="lower left")
fig.legend(["CERT-MT (optimal)", "CERT-MT (greedy)", "Optimal Partitioned EDF"])
fig.set_ylim(0,1.02)
fig.set_xlabel('Utilization')
fig.set_ylabel('Schedulability Ratio')
fig.set_title(header)
def add_plot(target, dat, m_range_max=None):
# Divide, but ignore if divisor is 0
util_bins = dat[:,0]
# Autodetect if we're plotting using the old unified count line, or the new per-alg count
if len(dat[1]) <= 12:
UMA_cols = dat[:,2:].T
task_count = dat[:,1]
things = numpy.divide(UMA_cols, task_count, out=numpy.zeros_like(UMA_cols), where=task_count!=0).T
else:
alg_cnt = len(dat[0,1:])//2
sample_cnt = len(dat) - 1
things = numpy.zeros((len(dat),alg_cnt))
for i in range(sample_cnt):
#print(dat[i,:])
for j in range(alg_cnt):
if dat[i,j*2+1] == 0:
things[i,j] = 0
else:
things[i,j] = dat[i,j*2+2]/dat[i,j*2+1]
#print(things[i,:])
# Crop charts
stop_idx = len(util_bins) - 1
if m_range_max:
for idx in range(len(util_bins)):
if util_bins[idx] > m_range_max:
stop_idx = idx
break
# Autodetect mode (SMART vs CERT-MT)
if len(dat[1]) <= 12 and (sum(things[:stop_idx,0])!=0 or sum(things[:stop_idx,1])!=0 or sum(things[:stop_idx,2])!=0 or sum(things[:stop_idx,3])!=0 or sum(things[:stop_idx,4])!=0):
# SMART
target.plot(util_bins[:stop_idx], things[:stop_idx,0], "-")
annotate_mode = 9 # Figure number to generate annotations for
if annotate_mode == 1:
target.annotate("[1,2,4]", xy=(20.75, 0.7), xycoords="data", xytext=(18.75, 0.7),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[3]", xy=(21.25, 0.5), xycoords="data", xytext=(23.25, 0.5),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
elif annotate_mode == 6:
target.annotate("[1,2,4]", xy=(5.35, 0.5), xycoords="data", xytext=(4.75, 0.5),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[3]", xy=(5.25, 0.7), xycoords="data", xytext=(5.75, 0.7),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
elif annotate_mode == 7:
target.annotate("[1,2,4]", xy=(19.75, 0.9), xycoords="data", xytext=(21.75, 0.9),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[3]", xy=(19, 0.9), xycoords="data", xytext=(18, 0.8),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
elif annotate_mode == 8:
target.annotate("[3]", xy=(17.7, 0.65), xycoords="data", xytext=(16.45, 0.50),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[1]", xy=(17.5, 0.9), xycoords="data", xytext=(16.25, 0.75),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[2,4]", xy=(18, 0.7), xycoords="data", xytext=(19.5, 0.7),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
elif annotate_mode == 9:
target.annotate("[1]", xy=(16.75, 0.15), xycoords="data", xytext=(16, 0.05),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[3]", xy=(16.9, 0.12), xycoords="data", xytext=(18.2, 0.21),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[2,4]", xy=(16.7, 0.25), xycoords="data", xytext=(18, 0.34),
textcoords="data", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
elif annotate_mode == 10:
target.annotate("[2]", xy=(16.1, 0), xycoords="data", xytext=(0.05, 0.17),
textcoords="axes fraction", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[1]", xy=(16.25, 0.75), xycoords="data", xytext=(0.03, 0.5),
textcoords="axes fraction", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[3]", xy=(17.5, 0.4), xycoords="data", xytext=(0.37, 0.4),
textcoords="axes fraction", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.annotate("[4]", xy=(16.75, 0.6), xycoords="data", xytext=(0.3, 0.6),
textcoords="axes fraction", arrowprops=dict(facecolor="black",
shrink=0.1, width=2, headwidth=8, ), horizontalalignment="center",
verticalalignment="bottom",)
target.plot(util_bins[:stop_idx], things[:stop_idx,1], "--")
target.plot(util_bins[:stop_idx], things[:stop_idx,2], "-.")
target.plot(util_bins[:stop_idx], things[:stop_idx,3], ":")
if sum(things[:stop_idx,5])!=0:
target.plot(util_bins[:stop_idx], things[:stop_idx,4])
else:
styles = ["-", "--", ":", "-."]
st_idx = 0
# CERT-MT
for i in range(5,len(things[0])):
if sum(things[:stop_idx,i]) > 0:
target.plot(util_bins[:stop_idx], things[:stop_idx,i], styles[st_idx])
st_idx += 1
def plot_util_quad_from_file(path, m_range_max=None, save=False):
file = open(path, "rb")
file.readline() # Dump first line
fig = plt.figure()
cached_header = ""
for i in range(1,5):
dat, header = load_data(file)
if dat is None:
break
cached_header = header
etc = fig.add_subplot(2,2,i)
add_plot(etc, dat, m_range_max)
setup_figure(etc, util_header(header))
fig.suptitle(format_header(cached_header, util_on=False), fontsize=18)
fig.tight_layout(rect=[0, 0.03, 1, 0.90])
if not save:
plt.show()
else:
sdir = "/playpen/jbakita/SMART-ECRTS19/uniform-normal/results2/graphs/"
plt.savefig(sdir + format_header(cached_header, util_on=False) + ".pdf")
plt.close(fig)
def plot_utils_from_file(path, m_range_max=None, save=None):
if save:
plt.rcParams['figure.figsize'] = [6, 3]
else:
plt.rcParams['figure.figsize'] = [14, 5]
file = open(path, "rb")
file.readline() # Dump first line
# Read all
dats = []
while True:
dat, header = load_data(file)
if dat is None:
break
dats.append((dat,header))
for (dat, header) in sorted(dats, key=lambda t: t[1][:-8]):
f = plt.figure()
fig = f.add_subplot(1, 1, 1)
add_plot(fig, dat, m_range_max)
setup_figure(fig, format_header(header, util_on=True))
if not save:
plt.show()
else:
#sdir = "/playpen/jbakita/SMART-ECRTS19/uniform-normal/results2/graphs/"
plt.savefig(save + format_header(header, util_on=True).replace('\n',' ') + ".pdf", bbox_inches="tight")
plt.close(f)
### TO USE ###
# 1. Change the annotate variable on line 112 to the figure number
# 2. Uncomment the plot command for that figure number
# 3. Access output in `results/graphs` per-algorithm
###
#Fig1 plot_utils_from_file("gaussian-average/results/16_1000_1_1_normal.txt", 1.5*16, "gaussian-average/results/graphs/")
#Fig10 plot_utils_from_file("uniform-normal/results/16_1000_055_65_1_65_1_normal.txt", 1.5*16, "uniform-normal/results/graphs/")
#Fig6 plot_utils_from_file("gaussian-average/results/4_1000_1_1_normal.txt", 1.5*4, "gaussian-average/results/graphs/")
#Fig7 plot_utils_from_file("gaussian-average/results/16_1000_1_1_normal.txt", 1.5*16, "gaussian-average/results/graphs/")
#Fig8 plot_utils_from_file("gaussian-average/results/16_1000_1_1_normal.txt", 1.5*16, "gaussian-average/results/graphs/")
#Fig9 plot_utils_from_file("gaussian-average/results/16_1000_1_1_normal.txt", 1.5*16, "gaussian-average/results/graphs/")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment