Skip to content
Snippets Groups Projects

Task timers

Open Aidan Chalk requested to merge task_timers into master
+ 233
0
Compare changes
  • Side-by-side
  • Inline
Files
+ 189
0
#!/usr/bin/env python
"""
Usage:
plot_tasks.py options TASKTIMERS output.png
where TASKTIMERS is a task timers file generated by quicksched.
This file is part of QuickSched.
Copyright (c) 2017 Aidan Chalk (aidan.chalk@stfc.ac.uk)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.collections as collections
import matplotlib.cm as cmx
import matplotlib.gridspec as gridspec
import matplotlib.ticker as plticker
import pylab as pl
import numpy as np
import sys
import math
import argparse
parser = argparse.ArgumentParser(description="Task graphs")
#Read in command line
parser.add_argument("input", help="Task data file")
parser.add_argument("outpng", help="Name for output graphic file (PNG)")
parser.add_argument("-l", "--limit", dest="limit", help="Upper time limit in millisecs", default=0, type=int)
parser.add_argument("-t", "--ticks", dest="tpms", help="Ticks per millisecond", default=2.9e6, type=int)
parser.add_argument("-e", "--expand", dest="expand", help="Thread expansion factor (def:1)", default=1, type=int)
parser.add_argument("--height", dest="height", help="Height of plot in inches (def:4)", default=4, type=float)
parser.add_argument("--width", dest="width", help="Width of plot in inches (def:16)", default=16, type=float)
parser.add_argument("--legend", dest="nolegend", help="Show the legend (def:false)", default=False, action="store_true")
parser.add_argument("-v", "--verbose", dest="verbose", help="Show colour assignments and other details (def: false)", default=False, action="store_true")
args=parser.parse_args()
infile = args.input
outpng=args.outpng
delta_t = args.limit
expand = args.expand
tpms = args.tpms
# Basic plot configuration.
PLOT_PARAMS = {"axes.labelsize": 10,
"axes.titlesize": 10,
"font.size": 14,
"legend.fontsize": 12,
"xtick.labelsize": 11,
"ytick.labelsize": 11,
"figure.figsize" : (args.width, args.height),
"figure.subplot.left" : 0.03,
"figure.subplot.right" : 0.995,
"figure.subplot.bottom" : 0.1,
"figure.subplot.top" : 0.99,
"figure.subplot.wspace" : 0.,
"figure.subplot.hspace" : 0.,
"lines.markersize" : 6,
"lines.linewidth" : 3.
}
colours = ["cyan", "lightgray", "darkblue", "yellow", "tan", "dodgerblue",
"sienna", "aquamarine", "bisque", "blue", "green", "brown",
"purple", "mocassin", "olivedrab", "chartreuse", "darksage",
"darkgreen", "green", "mediumseagreen", "mediumaquamarine",
"darkslategrey", "mediumturquoise", "black", "cadetblue", "skyblue",
"red", "slategray", "gold", "slateblue", "blueviolet",
"mediumorchid", "firebrick", "magenta", "hotpink", "pink"]
pl.rcParams.update(PLOT_PARAMS)
#read input.
data = pl.loadtxt(infile)
nthread=int(max(data[:,1])) + 1
#Recompute timings in MS if possible.
if(tpms != 0):
data[:,2] = data[:,2] / tpms
data[:,3] = data[:,3] / tpms
start_t = min(data[:,2])
data[:,2] -= start_t
data[:,3] -= start_t
end_t = (max(data[:,3]))
start_t = min(data[:,2])
delta_t = end_t - start_t
tasks = {}
tasks[-1] = []
for i in range(nthread*expand):
tasks[i] = []
ecounter = []
for i in range(nthread):
ecounter.append(0)
num_lines = pl.size(data) /4
for line in range(num_lines):
thread = int(data[line, 1])
#Expand to cover extra lines if expanding
ethread = thread*expand + (ecounter[thread]%expand)
ecounter[thread] = ecounter[thread] + 1
thread = ethread
tasks[thread].append({})
tasktype = data[line,0]
tasks[thread][-1]["type"] = tasktype
tic = data[line,2]
toc = data[line,3]
tasks[thread][-1]["tic"] = tic
tasks[thread][-1]["toc"] = toc
print tasktype
tasks[thread][-1]["colour"] = colours[int(tasktype)]
nthread = nthread * expand
typesseen = []
fig = pl.figure()
ax = fig.add_subplot(1,1,1)
ax.set_xlim(-delta_t * 0.03, delta_t * 1.03)
ax.set_ylim(0, nthread)
for i in range(nthread):
tictocs = []
colours = []
j = 0
for task in tasks[i]:
print task["toc"] - task["tic"], task["colour"]
tictocs.append((task["tic"], task["toc"] - task["tic"]))
colours.append(task["colour"])
qtask = task["type"]
if qtask not in typesseen:
pl.plot([],[],color=task["colour"], label=qtask)
typesseen.append(qtask)
ax.broken_barh(tictocs, [i+0.05, 0.90], facecolors = colours, linewidth=0)
# Legend and room for it.
nrow = len(typesseen) / 5
if args.nolegend:
ax.set_ylim(0, nthread + nrow + 1)
ax.legend(loc=1, shadow=True, mode="expand", ncol=5)
if len(typesseen) * 5 < nrow:
nrow = nrow + 1
ax.fill_between([0, 0], nthread+0.5, nthread + nrow + 0.5, facecolor="white")
# Start and end of time-step
ax.plot([start_t, start_t], [0, nthread], 'k--', linewidth=1)
ax.plot([end_t, end_t], [0, nthread], 'k--', linewidth=1)
ax.set_xlabel("time [ms or ticks]")
if expand == 1:
ax.set_ylabel("Thread ID" )
else:
ax.set_ylabel("Thread ID * " + str(expand) )
ax.set_yticks(pl.array(range(nthread)), True)
pl.savefig(outpng, format = 'png', dpi = 1000)
pl.savefig('tasks.eps', format = 'eps', dpi = 1000)
pl.show()
print "Graphics done, output written to", outpng
sys.exit(0)
Loading