diff --git a/examples/plot_tasks_MPI.py b/examples/plot_tasks_MPI.py index 59f1eaab3d4eaa96bbf0c53c0f16971638c06f6a..02bc4a03510afce396429316fb4489926bc41b12 100755 --- a/examples/plot_tasks_MPI.py +++ b/examples/plot_tasks_MPI.py @@ -2,7 +2,7 @@ """ Usage: plot_tasks_MPI.py input.dat png-output-prefix [time-range-ms] - + where input.dat is a thread info file for a step of an MPI run. Use the '-y interval' flag of the swift MPI commands to create these. The output plots will be called 'png-output-prefix<mpi-rank>.png', i.e. one each for all the @@ -40,6 +40,8 @@ matplotlib.use("Agg") import pylab as pl import numpy as np import sys +#import warnings +#warnings.simplefilter("error") # Basic plot configuration. PLOT_PARAMS = {"axes.labelsize": 10, @@ -62,9 +64,9 @@ pl.rcParams.update(PLOT_PARAMS) # Tasks and subtypes. Indexed as in tasks.h. TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", "init", - "ghost", "extra_ghost", "kick", "kick_fixdt", "send", "recv", + "ghost", "extra_ghost", "kick", "kick_fixdt", "send", "recv", "grav_gather_m", "grav_fft", "grav_mm", "grav_up", - "grav_external", "cooling", "count"] + "grav_external", "cooling", "count"] TASKCOLOURS = {"none": "black", "sort": "lightblue", @@ -84,7 +86,7 @@ TASKCOLOURS = {"none": "black", "grav_mm": "mediumturquoise", "grav_up": "mediumvioletred", "grav_external": "darkred", - "cooling", "darkblue", + "cooling": "darkblue", "count": "powerblue"} SUBTYPES = ["none", "density", "gradient", "force", "grav", "tend", "count"] @@ -114,7 +116,7 @@ outbase = sys.argv[2] delta_t = 0 if len( sys.argv ) == 4: delta_t = int(sys.argv[3]) - + # Read input. data = pl.loadtxt( infile ) @@ -157,93 +159,107 @@ for rank in range(nranks): tic_step = int(full_step[5]) toc_step = int(full_step[6]) data = data[1:,:] + typesseen = [] - start_t = tic_step - data[:,5] -= start_t - data[:,6] -= start_t - end_t = (toc_step - start_t) / CPU_CLOCK * 1000 - - tasks = {} - tasks[-1] = [] - for i in range(nthread): - tasks[i] = [] - - num_lines = pl.shape(data)[0] - for line in range(num_lines): - thread = int(data[line,1]) - tasks[thread].append({}) - tasks[thread][-1]["type"] = TASKTYPES[int(data[line,2])] - tasks[thread][-1]["subtype"] = SUBTYPES[int(data[line,3])] - tic = int(data[line,5]) / CPU_CLOCK * 1000 - toc = int(data[line,6]) / CPU_CLOCK * 1000 - tasks[thread][-1]["tic"] = tic - tasks[thread][-1]["toc"] = toc - tasks[thread][-1]["t"] = (toc + tic)/ 2 - - combtasks = {} - combtasks[-1] = [] - for i in range(nthread): - combtasks[i] = [] - - for thread in range(nthread): - tasks[thread] = sorted(tasks[thread], key=lambda l: l["t"]) - lasttype = "" - types = [] - for task in tasks[thread]: - if task["type"] not in types: - types.append(task["type"]) - if lasttype == "" or not lasttype == task["type"]: - combtasks[thread].append({}) - combtasks[thread][-1]["type"] = task["type"] - combtasks[thread][-1]["subtype"] = task["subtype"] - combtasks[thread][-1]["tic"] = task["tic"] - combtasks[thread][-1]["toc"] = task["toc"] - if task["type"] == "self" or task["type"] == "pair" or task["type"] == "sub": - combtasks[thread][-1]["colour"] = SUBCOLOURS[task["subtype"]] + # Dummy image for ranks that have no tasks. + if data.size == 0: + print "rank ", rank, " has no tasks" + fig = pl.figure() + ax = fig.add_subplot(1,1,1) + ax.set_xlim(-delta_t * 0.03 * 1000 / CPU_CLOCK, delta_t * 1.03 * 1000 / CPU_CLOCK) + ax.set_ylim(0, nthread) + start_t = tic_step + end_t = (toc_step - start_t) / CPU_CLOCK * 1000 + else: + + start_t = tic_step + data[:,5] -= start_t + data[:,6] -= start_t + end_t = (toc_step - start_t) / CPU_CLOCK * 1000 + + tasks = {} + tasks[-1] = [] + for i in range(nthread): + tasks[i] = [] + + num_lines = pl.shape(data)[0] + for line in range(num_lines): + thread = int(data[line,1]) + tasks[thread].append({}) + tasks[thread][-1]["type"] = TASKTYPES[int(data[line,2])] + tasks[thread][-1]["subtype"] = SUBTYPES[int(data[line,3])] + tic = int(data[line,5]) / CPU_CLOCK * 1000 + toc = int(data[line,6]) / CPU_CLOCK * 1000 + tasks[thread][-1]["tic"] = tic + tasks[thread][-1]["toc"] = toc + tasks[thread][-1]["t"] = (toc + tic)/ 2 + + combtasks = {} + combtasks[-1] = [] + for i in range(nthread): + combtasks[i] = [] + + for thread in range(nthread): + tasks[thread] = sorted(tasks[thread], key=lambda l: l["t"]) + lasttype = "" + types = [] + for task in tasks[thread]: + if task["type"] not in types: + types.append(task["type"]) + if lasttype == "" or not lasttype == task["type"]: + combtasks[thread].append({}) + combtasks[thread][-1]["type"] = task["type"] + combtasks[thread][-1]["subtype"] = task["subtype"] + combtasks[thread][-1]["tic"] = task["tic"] + combtasks[thread][-1]["toc"] = task["toc"] + if task["type"] == "self" or task["type"] == "pair" or task["type"] == "sub": + combtasks[thread][-1]["colour"] = SUBCOLOURS[task["subtype"]] + else: + combtasks[thread][-1]["colour"] = TASKCOLOURS[task["type"]] + lasttype = task["type"] else: - combtasks[thread][-1]["colour"] = TASKCOLOURS[task["type"]] - lasttype = task["type"] - else: - combtasks[thread][-1]["toc"] = task["toc"] + combtasks[thread][-1]["toc"] = task["toc"] + + fig = pl.figure() + ax = fig.add_subplot(1,1,1) + ax.set_xlim(-delta_t * 0.03 * 1000 / CPU_CLOCK, delta_t * 1.03 * 1000 / CPU_CLOCK) + ax.set_ylim(0, nthread) + tictoc = np.zeros(2) + for i in range(nthread): + + # Collect ranges and colours into arrays. + tictocs = np.zeros(len(combtasks[i])*2) + colours = np.empty(len(combtasks[i])*2, dtype='object') + coloursseen = [] + j = 0 + for task in combtasks[i]: + tictocs[j] = task["tic"] + tictocs[j+1] = task["toc"] + colours[j] = task["colour"] + colours[j+1] = task["colour"] + j = j + 2 + if task["colour"] not in coloursseen: + coloursseen.append(task["colour"]) + + # Legend support, collections don't add to this. + if task["subtype"] != "none": + qtask = task["type"] + "/" + task["subtype"] + else: + qtask = task["type"] - typesseen = [] - fig = pl.figure() - ax = fig.add_subplot(1,1,1) - ax.set_xlim(-delta_t * 0.03 * 1000 / CPU_CLOCK, delta_t * 1.03 * 1000 / CPU_CLOCK) - ax.set_ylim(0, nthread) - tictoc = np.zeros(2) - for i in range(nthread): - - # Collect ranges and colours into arrays. - tictocs = np.zeros(len(combtasks[i])*2) - colours = np.empty(len(combtasks[i])*2, dtype='object') - coloursseen = [] - j = 0 - for task in combtasks[i]: - tictocs[j] = task["tic"] - tictocs[j+1] = task["toc"] - colours[j] = task["colour"] - colours[j+1] = task["colour"] - j = j + 2 - if task["colour"] not in coloursseen: - coloursseen.append(task["colour"]) - - # Legend support, collections don't add to this. - if task["subtype"] != "none": - qtask = task["type"] + "/" + task["subtype"] - else: - qtask = task["type"] - if qtask not in typesseen: - pl.plot([], [], color=task["colour"], label=qtask) - typesseen.append(qtask) - - # Now plot each colour, faster to use a mask to select colour ranges. - for colour in coloursseen: - collection = collections.BrokenBarHCollection.span_where(tictocs, ymin=i+0.05, ymax=i+0.95, - where=colours == colour, - facecolor=colour, - linewidths=0) - ax.add_collection(collection) + if qtask not in typesseen: + pl.plot([], [], color=task["colour"], label=qtask) + typesseen.append(qtask) + + # Now plot each colour, faster to use a mask to select colour ranges. + for colour in coloursseen: + collection = collections.BrokenBarHCollection.span_where(tictocs, + ymin=i+0.05, + ymax=i+0.95, + where=colours == colour, + facecolor=colour, + linewidths=0) + ax.add_collection(collection) # Legend and room for it. @@ -252,7 +268,8 @@ for rank in range(nranks): nrow = nrow + 1 ax.fill_between([0, 0], nthread+0.5, nthread + nrow + 0.5, facecolor="white") ax.set_ylim(0, nthread + nrow + 1) - ax.legend(loc=1, shadow=True, mode="expand", ncol=5) + if data.size > 0: + ax.legend(loc=1, shadow=True, mode="expand", ncol=5) # Start and end of time-step ax.plot([0, 0], [0, nthread + nrow + 1], 'k--', linewidth=1)