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