From 7291d18e1c47fcdd38b2ff19a49bbcf0e24210b8 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 29 Jun 2017 15:31:02 +0200 Subject: [PATCH 1/5] The task plot analysis scripts now also displays the number of particle updates done in that time-step. It also shows the time distribution for pairs sorted by SID. --- examples/analyse_tasks.py | 51 +++++++++++++++++++++++++++++++++------ examples/main.c | 10 +++++--- examples/plot_tasks.py | 2 +- src/engine.c | 8 +++--- src/runner.c | 12 ++++++++- src/task.h | 3 +++ 6 files changed, 69 insertions(+), 17 deletions(-) diff --git a/examples/analyse_tasks.py b/examples/analyse_tasks.py index 17816cab6..bb16a1431 100755 --- a/examples/analyse_tasks.py +++ b/examples/analyse_tasks.py @@ -56,6 +56,11 @@ TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", SUBTYPES = ["none", "density", "gradient", "force", "grav", "external_grav", "tend", "xv", "rho", "gpart", "multipole", "spart", "count"] +SIDS = ["(-1,-1,-1)", "(-1,-1, 0)", "(-1,-1, 1)", "(-1, 0,-1)", + "(-1, 0, 0)", "(-1, 0, 1)", "(-1, 1,-1)", "(-1, 1, 0)", + "(-1, 1, 1)", "( 0,-1,-1)", "( 0,-1, 0)", "( 0,-1, 1)", + "( 0, 0,-1)"] + # Read input. data = pl.loadtxt( infile ) @@ -66,11 +71,17 @@ print "# Maximum thread id:", maxthread full_step = data[0,:] tic_step = int(full_step[4]) toc_step = int(full_step[5]) +updates = int(full_step[6]) +g_updates = int(full_step[7]) +s_updates = int(full_step[8]) CPU_CLOCK = float(full_step[-1]) / 1000.0 data = data[1:,:] if args.verbose: - print "CPU frequency:", CPU_CLOCK * 1000.0 - + print "# CPU frequency:", CPU_CLOCK * 1000.0 +print "# updates:", updates +print "# g_updates:", g_updates +print "# s_updates:", s_updates + # Avoid start and end times of zero. data = data[data[:,4] != 0] data = data[data[:,5] != 0] @@ -78,6 +89,7 @@ data = data[data[:,5] != 0] # Calculate the time range. total_t = (toc_step - tic_step)/ CPU_CLOCK print "# Data range: ", total_t, "ms" +print # Correct times to relative values. start_t = float(tic_step) @@ -90,15 +102,16 @@ for i in range(maxthread): tasks[i] = [] # Gather into by thread data. -num_lines = pl.size(data) / 10 +num_lines = pl.size(data) / pl.size(full_step) for line in range(num_lines): thread = int(data[line,0]) tic = int(data[line,4]) / CPU_CLOCK toc = int(data[line,5]) / CPU_CLOCK tasktype = int(data[line,1]) subtype = int(data[line,2]) + sid = int(data[line, -1]) - tasks[thread].append([tic,toc,tasktype,subtype]) + tasks[thread].append([tic,toc,tasktype,subtype, sid]) # Sort by tic and gather used thread ids. threadids = [] @@ -110,10 +123,11 @@ for i in range(maxthread): # Times per task. print "# Task times:" print "# -----------" -print "# {0:<16s}: {1:>7s} {2:>9s} {3:>9s} {4:>9s} {5:>9s} {6:>9s}"\ +print "# {0:<17s}: {1:>7s} {2:>9s} {3:>9s} {4:>9s} {5:>9s} {6:>9s}"\ .format("type/subtype", "count","minimum", "maximum", "sum", "mean", "percent") alltasktimes = {} +sidtimes = {} for i in threadids: tasktimes = {} for task in tasks[i]: @@ -127,12 +141,19 @@ for i in threadids: alltasktimes[key] = [] alltasktimes[key].append(dt) + my_sid = task[4] + if my_sid > -1: + if not my_sid in sidtimes: + sidtimes[my_sid] = [] + sidtimes[my_sid].append(dt) + + print "# Thread : ", i for key in sorted(tasktimes.keys()): taskmin = min(tasktimes[key]) taskmax = max(tasktimes[key]) tasksum = sum(tasktimes[key]) - print "{0:18s}: {1:7d} {2:9.4f} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.2f}"\ + print "{0:19s}: {1:7d} {2:9.4f} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.2f}"\ .format(key, len(tasktimes[key]), taskmin, taskmax, tasksum, tasksum / len(tasktimes[key]), tasksum / total_t * 100.0) print @@ -142,12 +163,28 @@ for key in sorted(alltasktimes.keys()): taskmin = min(alltasktimes[key]) taskmax = max(alltasktimes[key]) tasksum = sum(alltasktimes[key]) - print "{0:18s}: {1:7d} {2:9.4f} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.2f}"\ + print "{0:19s}: {1:7d} {2:9.4f} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.2f}"\ .format(key, len(alltasktimes[key]), taskmin, taskmax, tasksum, tasksum / len(alltasktimes[key]), tasksum / (len(threadids) * total_t) * 100.0) print +# For pairs, show stuf sorted by SID +print "# By SID (all threads): " +print "# {0:<17s}: {1:>7s} {2:>9s} {3:>9s} {4:>9s} {5:>9s} {6:>9s}"\ + .format("Pair/Sub-pair SID", "count","minimum", "maximum", + "sum", "mean", "percent") + +for sid in range(0,13): + sidmin = min(sidtimes[sid]) + sidmax = max(sidtimes[sid]) + sidsum = sum(sidtimes[sid]) + print "{0:3d} {1:15s}: {2:7d} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.4f} {7:9.2f}"\ + .format(sid, SIDS[sid], len(sidtimes[sid]), sidmin, sidmax, sidsum, + sidsum / len(sidtimes[sid]), + sidsum / (len(threadids) * total_t) * 100.0) +print + # Dead times. print "# Times not in tasks (deadtimes)" print "# ------------------------------" diff --git a/examples/main.c b/examples/main.c index 5a4e56ad4..5d747b2c4 100644 --- a/examples/main.c +++ b/examples/main.c @@ -717,19 +717,21 @@ int main(int argc, char *argv[]) { FILE *file_thread; file_thread = fopen(dumpfile, "w"); /* Add some information to help with the plots */ - fprintf(file_thread, " %i %i %i %i %lli %lli %i %i %i %lli\n", -2, -1, -1, - 1, e.tic_step, e.toc_step, 0, 0, 0, cpufreq); + fprintf(file_thread, " %i %i %i %i %lli %lli %zi %zi %zi %i %lli\n", -2, + -1, -1, 1, e.tic_step, e.toc_step, e.updates, e.g_updates, + e.s_updates, 0, cpufreq); for (int l = 0; l < e.sched.nr_tasks; l++) { if (!e.sched.tasks[l].implicit && e.sched.tasks[l].toc != 0) { fprintf( - file_thread, " %i %i %i %i %lli %lli %i %i %i %i\n", + file_thread, " %i %i %i %i %lli %lli %i %i %i %i %i\n", e.sched.tasks[l].rid, e.sched.tasks[l].type, e.sched.tasks[l].subtype, (e.sched.tasks[l].cj == NULL), e.sched.tasks[l].tic, e.sched.tasks[l].toc, (e.sched.tasks[l].ci == NULL) ? 0 : e.sched.tasks[l].ci->count, (e.sched.tasks[l].cj == NULL) ? 0 : e.sched.tasks[l].cj->count, (e.sched.tasks[l].ci == NULL) ? 0 : e.sched.tasks[l].ci->gcount, - (e.sched.tasks[l].cj == NULL) ? 0 : e.sched.tasks[l].cj->gcount); + (e.sched.tasks[l].cj == NULL) ? 0 : e.sched.tasks[l].cj->gcount, + e.sched.tasks[l].sid); } } fclose(file_thread); diff --git a/examples/plot_tasks.py b/examples/plot_tasks.py index 88f176687..43fb5f004 100755 --- a/examples/plot_tasks.py +++ b/examples/plot_tasks.py @@ -183,7 +183,7 @@ ecounter = [] for i in range(nthread): ecounter.append(0) -num_lines = pl.size(data) / 10 +num_lines = pl.size(data) / pl.size(full_step) for line in range(num_lines): thread = int(data[line,0]) diff --git a/src/engine.c b/src/engine.c index 1281470db..827778100 100644 --- a/src/engine.c +++ b/src/engine.c @@ -331,7 +331,8 @@ static void *engine_do_redistribute(int *counts, char *parts, for (int k = 0; k < 2 * nr_nodes; k++) { char buff[MPI_MAX_ERROR_STRING]; MPI_Error_string(stats[k].MPI_ERROR, buff, &res); - message("request from source %i, tag %i has error '%s'.", stats[k].MPI_SOURCE, stats[k].MPI_TAG, buff); + message("request from source %i, tag %i has error '%s'.", + stats[k].MPI_SOURCE, stats[k].MPI_TAG, buff); } error("Failed during waitall for part data."); } @@ -605,7 +606,6 @@ void engine_redistribute(struct engine *e) { if (s->nr_gparts > 0) space_gparts_sort(s, g_dest, s->nr_gparts, 0, nr_nodes - 1, e->verbose); - #ifdef SWIFT_DEBUG_CHECKS /* Verify that the gpart have been sorted correctly. */ for (size_t k = 0; k < s->nr_gparts; k++) { @@ -621,8 +621,8 @@ void engine_redistribute(struct engine *e) { const int new_node = c->nodeID; if (g_dest[k] != new_node) - error("gpart's new node index not matching sorted index (%d != %d).", - g_dest[k], new_node); + error("gpart's new node index not matching sorted index (%d != %d).", + g_dest[k], new_node); if (gp->x[0] < c->loc[0] || gp->x[0] > c->loc[0] + c->width[0] || gp->x[1] < c->loc[1] || gp->x[1] > c->loc[1] + c->width[1] || diff --git a/src/runner.c b/src/runner.c index 08605b909..735865bad 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1739,9 +1739,19 @@ void *runner_main(void *data) { struct cell *ci = t->ci; struct cell *cj = t->cj; -/* Mark the thread we run on */ #ifdef SWIFT_DEBUG_TASKS + /* Mark the thread we run on */ t->rid = r->cpuid; + + /* And recover the pair direction */ + if (t->type == task_type_pair || t->type == task_type_sub_pair) { + struct cell *ci_temp = ci; + struct cell *cj_temp = cj; + double shift[3]; + t->sid = space_getsid(e->s, &ci_temp, &cj_temp, shift); + } else { + t->sid = -1; + } #endif /* Check that we haven't scheduled an inactive task */ diff --git a/src/task.h b/src/task.h index 052f3e803..cd15e09cc 100644 --- a/src/task.h +++ b/src/task.h @@ -162,6 +162,9 @@ struct task { /*! ID of the queue or runner owning this task */ short int rid; + /*! Information about the direction of the pair task */ + short int sid; + /*! Start and end time of this task */ ticks tic, toc; #endif -- GitLab From d5fce023e8ffb010f4f2d0bacb8f9a277073c04b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 29 Jun 2017 18:59:33 +0100 Subject: [PATCH 2/5] Also updated the MPI-version of the scripts. --- examples/analyse_tasks.py | 20 +++++++++---- examples/analyse_tasks_MPI.py | 53 ++++++++++++++++++++++++++++++++--- examples/main.c | 9 +++--- 3 files changed, 68 insertions(+), 14 deletions(-) diff --git a/examples/analyse_tasks.py b/examples/analyse_tasks.py index bb16a1431..d28553173 100755 --- a/examples/analyse_tasks.py +++ b/examples/analyse_tasks.py @@ -176,13 +176,21 @@ print "# {0:<17s}: {1:>7s} {2:>9s} {3:>9s} {4:>9s} {5:>9s} {6:>9s}"\ "sum", "mean", "percent") for sid in range(0,13): - sidmin = min(sidtimes[sid]) - sidmax = max(sidtimes[sid]) - sidsum = sum(sidtimes[sid]) + if sid in sidtimes: + sidmin = min(sidtimes[sid]) + sidmax = max(sidtimes[sid]) + sidsum = sum(sidtimes[sid]) + sidcount = len(sidtimes[sid]) + sidmean = sidsum / sidcount + else: + sidmin = 0. + sidmax = 0. + sidsum = 0. + sidcount = 0 + sidmean = 0. print "{0:3d} {1:15s}: {2:7d} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.4f} {7:9.2f}"\ - .format(sid, SIDS[sid], len(sidtimes[sid]), sidmin, sidmax, sidsum, - sidsum / len(sidtimes[sid]), - sidsum / (len(threadids) * total_t) * 100.0) + .format(sid, SIDS[sid], sidcount, sidmin, sidmax, sidsum, + sidmean, sidsum / (len(threadids) * total_t) * 100.0) print # Dead times. diff --git a/examples/analyse_tasks_MPI.py b/examples/analyse_tasks_MPI.py index c90c8caee..37d64c3f0 100755 --- a/examples/analyse_tasks_MPI.py +++ b/examples/analyse_tasks_MPI.py @@ -56,14 +56,25 @@ TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair", SUBTYPES = ["none", "density", "gradient", "force", "grav", "external_grav", "tend", "xv", "rho", "gpart", "multipole", "spart", "count"] +SIDS = ["(-1,-1,-1)", "(-1,-1, 0)", "(-1,-1, 1)", "(-1, 0,-1)", + "(-1, 0, 0)", "(-1, 0, 1)", "(-1, 1,-1)", "(-1, 1, 0)", + "(-1, 1, 1)", "( 0,-1,-1)", "( 0,-1, 0)", "( 0,-1, 1)", + "( 0, 0,-1)"] + # Read input. data = pl.loadtxt( infile ) # Get the CPU clock to convert ticks into milliseconds. full_step = data[0,:] +updates = int(full_step[7]) +g_updates = int(full_step[8]) +s_updates = int(full_step[9]) CPU_CLOCK = float(full_step[-1]) / 1000.0 if args.verbose: print "# CPU frequency:", CPU_CLOCK * 1000.0 +print "# updates:", updates +print "# g_updates:", g_updates +print "# s_updates:", s_updates nranks = int(max(data[:,0])) + 1 print "# Number of ranks:", nranks @@ -92,6 +103,7 @@ for rank in range(nranks): # Calculate the time range. total_t = (toc_step - tic_step)/ CPU_CLOCK print "# Data range: ", total_t, "ms" + print # Correct times to relative values. start_t = float(tic_step) @@ -105,15 +117,16 @@ for rank in range(nranks): tasks[i] = [] # Gather into by thread data. - num_lines = pl.size(data) / 12 + num_lines = pl.shape(data)[0] for line in range(num_lines): thread = int(data[line,1]) tic = int(data[line,5]) / CPU_CLOCK toc = int(data[line,6]) / CPU_CLOCK tasktype = int(data[line,2]) subtype = int(data[line,3]) + sid = int(data[line, -1]) - tasks[thread].append([tic,toc,tasktype,subtype]) + tasks[thread].append([tic,toc,tasktype,subtype, sid]) # Sort by tic and gather used threads. threadids = [] @@ -124,10 +137,12 @@ for rank in range(nranks): # Times per task. print "# Task times:" print "# -----------" - print "# {0:<16s}: {1:>7s} {2:>9s} {3:>9s} {4:>9s} {5:>9s} {6:>9s}"\ + print "# {0:<17s}: {1:>7s} {2:>9s} {3:>9s} {4:>9s} {5:>9s} {6:>9s}"\ .format("type/subtype", "count","minimum", "maximum", "sum", "mean", "percent") + alltasktimes = {} + sidtimes = {} for i in threadids: tasktimes = {} for task in tasks[i]: @@ -140,13 +155,19 @@ for rank in range(nranks): if not key in alltasktimes: alltasktimes[key] = [] alltasktimes[key].append(dt) + + my_sid = task[4] + if my_sid > -1: + if not my_sid in sidtimes: + sidtimes[my_sid] = [] + sidtimes[my_sid].append(dt) print "# Thread : ", i for key in sorted(tasktimes.keys()): taskmin = min(tasktimes[key]) taskmax = max(tasktimes[key]) tasksum = sum(tasktimes[key]) - print "{0:18s}: {1:7d} {2:9.4f} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.2f}"\ + print "{0:19s}: {1:7d} {2:9.4f} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.2f}"\ .format(key, len(tasktimes[key]), taskmin, taskmax, tasksum, tasksum / len(tasktimes[key]), tasksum / total_t * 100.0) print @@ -162,6 +183,30 @@ for rank in range(nranks): tasksum / (len(threadids) * total_t) * 100.0) print + # For pairs, show stuf sorted by SID + print "# By SID (all threads): " + print "# {0:<17s}: {1:>7s} {2:>9s} {3:>9s} {4:>9s} {5:>9s} {6:>9s}"\ + .format("Pair/Sub-pair SID", "count","minimum", "maximum", + "sum", "mean", "percent") + + for sid in range(0,13): + if sid in sidtimes: + sidmin = min(sidtimes[sid]) + sidmax = max(sidtimes[sid]) + sidsum = sum(sidtimes[sid]) + sidcount = len(sidtimes[sid]) + sidmean = sidsum / sidcount + else: + sidmin = 0. + sidmax = 0. + sidsum = 0. + sidcount = 0 + sidmean = 0. + print "{0:3d} {1:15s}: {2:7d} {3:9.4f} {4:9.4f} {5:9.4f} {6:9.4f} {7:9.2f}"\ + .format(sid, SIDS[sid], sidcount, sidmin, sidmax, sidsum, + sidmean, sidsum / (len(threadids) * total_t) * 100.0) + print + # Dead times. print "# Times not in tasks (deadtimes)" print "# ------------------------------" diff --git a/examples/main.c b/examples/main.c index 5d747b2c4..e067e08d4 100644 --- a/examples/main.c +++ b/examples/main.c @@ -681,13 +681,14 @@ int main(int argc, char *argv[]) { /* Open file and position at end. */ file_thread = fopen(dumpfile, "a"); - fprintf(file_thread, " %03i 0 0 0 0 %lli %lli 0 0 0 0 %lli\n", myrank, - e.tic_step, e.toc_step, cpufreq); + fprintf(file_thread, " %03i 0 0 0 0 %lli %lli %zi %zi %zi 0 0 %lli\n", myrank, + e.tic_step, e.toc_step, e.updates, e.g_updates, + e.s_updates, cpufreq); int count = 0; for (int l = 0; l < e.sched.nr_tasks; l++) { if (!e.sched.tasks[l].implicit && e.sched.tasks[l].toc != 0) { fprintf( - file_thread, " %03i %i %i %i %i %lli %lli %i %i %i %i %i\n", + file_thread, " %03i %i %i %i %i %lli %lli %i %i %i %i %i %i\n", myrank, e.sched.tasks[l].rid, e.sched.tasks[l].type, e.sched.tasks[l].subtype, (e.sched.tasks[l].cj == NULL), e.sched.tasks[l].tic, e.sched.tasks[l].toc, @@ -699,7 +700,7 @@ int main(int argc, char *argv[]) { : 0, (e.sched.tasks[l].cj != NULL) ? e.sched.tasks[l].cj->gcount : 0, - e.sched.tasks[l].flags); + e.sched.tasks[l].flags, e.sched.tasks[l].sid); } fflush(stdout); count++; -- GitLab From 2fb6d30b78218ae2a80db15eadb4a040c637e432 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 29 Jun 2017 20:00:41 +0200 Subject: [PATCH 3/5] Code formatting --- examples/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/main.c b/examples/main.c index e067e08d4..4cc3a36d4 100644 --- a/examples/main.c +++ b/examples/main.c @@ -681,15 +681,16 @@ int main(int argc, char *argv[]) { /* Open file and position at end. */ file_thread = fopen(dumpfile, "a"); - fprintf(file_thread, " %03i 0 0 0 0 %lli %lli %zi %zi %zi 0 0 %lli\n", myrank, - e.tic_step, e.toc_step, e.updates, e.g_updates, - e.s_updates, cpufreq); + fprintf(file_thread, " %03i 0 0 0 0 %lli %lli %zi %zi %zi 0 0 %lli\n", + myrank, e.tic_step, e.toc_step, e.updates, e.g_updates, + e.s_updates, cpufreq); int count = 0; for (int l = 0; l < e.sched.nr_tasks; l++) { if (!e.sched.tasks[l].implicit && e.sched.tasks[l].toc != 0) { fprintf( - file_thread, " %03i %i %i %i %i %lli %lli %i %i %i %i %i %i\n", - myrank, e.sched.tasks[l].rid, e.sched.tasks[l].type, + file_thread, + " %03i %i %i %i %i %lli %lli %i %i %i %i %i %i\n", myrank, + e.sched.tasks[l].rid, e.sched.tasks[l].type, e.sched.tasks[l].subtype, (e.sched.tasks[l].cj == NULL), e.sched.tasks[l].tic, e.sched.tasks[l].toc, (e.sched.tasks[l].ci != NULL) ? e.sched.tasks[l].ci->count -- GitLab From 57cfc3862d8736280af2dfca4a1f41da1f2a1436 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 29 Jun 2017 20:48:20 +0200 Subject: [PATCH 4/5] Applied @d74sky's suggestion to put the legend of the plots outside of the plotting area to avoid overlap --- examples/plot_tasks.py | 18 +++++++++--------- examples/plot_tasks_MPI.py | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/plot_tasks.py b/examples/plot_tasks.py index 43fb5f004..e80c3635c 100755 --- a/examples/plot_tasks.py +++ b/examples/plot_tasks.py @@ -78,7 +78,7 @@ PLOT_PARAMS = {"axes.labelsize": 10, "figure.figsize" : (args.width, args.height), "figure.subplot.left" : 0.03, "figure.subplot.right" : 0.995, - "figure.subplot.bottom" : 0.1, + "figure.subplot.bottom" : 0.09, "figure.subplot.top" : 0.99, "figure.subplot.wspace" : 0., "figure.subplot.hspace" : 0., @@ -243,21 +243,21 @@ for i in range(nthread): # Legend and room for it. nrow = len(typesseen) / 5 if not args.nolegend: - if len(typesseen) * 5 < nrow: - 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) - + ax.set_ylim(0, nthread + 0.5) + ax.legend(loc=1, shadow=True, bbox_to_anchor=(0., 1.05 ,1., 0.2), mode="expand", ncol=5) + box = ax.get_position() + ax.set_position([box.x0, box.y0, box.width, box.height*0.8]) + # Start and end of time-step ax.plot([0, 0], [0, nthread + nrow + 1], 'k--', linewidth=1) ax.plot([end_t, end_t], [0, nthread + nrow + 1], 'k--', linewidth=1) -ax.set_xlabel("Wall clock time [ms]") +ax.set_xlabel("Wall clock time [ms]", labelpad=0.) if expand == 1: - ax.set_ylabel("Thread ID" ) + ax.set_ylabel("Thread ID", labelpad=0 ) else: - ax.set_ylabel("Thread ID * " + str(expand) ) + ax.set_ylabel("Thread ID * " + str(expand), labelpad=0 ) ax.set_yticks(pl.array(range(nthread)), True) loc = plticker.MultipleLocator(base=expand) diff --git a/examples/plot_tasks_MPI.py b/examples/plot_tasks_MPI.py index 83465aee8..85d7c5456 100755 --- a/examples/plot_tasks_MPI.py +++ b/examples/plot_tasks_MPI.py @@ -278,12 +278,12 @@ for rank in range(nranks): # Legend and room for it. nrow = len(typesseen) / 5 - if len(typesseen) * 5 < nrow: - nrow = nrow + 1 ax.fill_between([0, 0], nethread+0.5, nethread + nrow + 0.5, facecolor="white") - ax.set_ylim(0, nethread + nrow + 1) + ax.set_ylim(0, nethread + 0.5) if data.size > 0: - ax.legend(loc=1, shadow=True, mode="expand", ncol=5) + ax.legend(loc=1, shadow=True, bbox_to_anchor=(0., 1.05 ,1., 0.2), mode="expand", ncol=5) + box = ax.get_position() + ax.set_position([box.x0, box.y0, box.width, box.height*0.8]) # Start and end of time-step ax.plot([0, 0], [0, nethread + nrow + 1], 'k--', linewidth=1) -- GitLab From cf53e67af866d14edd98f43512e947839892b9ae Mon Sep 17 00:00:00 2001 From: "Peter W. Draper" Date: Fri, 30 Jun 2017 13:56:10 +0100 Subject: [PATCH 5/5] plot analysis: separate each MPI rank into its own file and associate with the appropriate figure --- examples/analyse_tasks_MPI.py | 15 +++++++++++++-- examples/process_plot_tasks_MPI | 6 ++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/examples/analyse_tasks_MPI.py b/examples/analyse_tasks_MPI.py index 37d64c3f0..b78d73e87 100755 --- a/examples/analyse_tasks_MPI.py +++ b/examples/analyse_tasks_MPI.py @@ -42,6 +42,9 @@ parser.add_argument("input", help="Thread data file (-y output)") parser.add_argument("-v", "--verbose", dest="verbose", help="Verbose output (default: False)", default=False, action="store_true") +parser.add_argument("-r", "--rank", dest="rank", + help="Rank to process (default: all)", + default="all", action="store") args = parser.parse_args() infile = args.input @@ -78,6 +81,14 @@ print "# s_updates:", s_updates nranks = int(max(data[:,0])) + 1 print "# Number of ranks:", nranks +if args.rank == "all": + ranks = range(nranks) +else: + ranks = [int(args.rank)] + if ranks[0] >= nranks: + print "Error: maximum rank is " + str(nranks - 1) + sys.exit(1) + maxthread = int(max(data[:,1])) + 1 print "# Maximum thread id:", maxthread @@ -85,8 +96,8 @@ print "# Maximum thread id:", maxthread sdata = data[data[:,5] != 0] sdata = data[data[:,6] != 0] -# Now we process all the ranks. -for rank in range(nranks): +# Now we process the required ranks. +for rank in ranks: print "# Rank", rank data = sdata[sdata[:,0] == rank] diff --git a/examples/process_plot_tasks_MPI b/examples/process_plot_tasks_MPI index b2672b371..691822ebc 100755 --- a/examples/process_plot_tasks_MPI +++ b/examples/process_plot_tasks_MPI @@ -62,7 +62,9 @@ nrank=$(($nrank-1)) # And process them, echo "Processing thread info files..." echo $list | xargs -P $NPROCS -n 3 /bin/bash -c "./plot_tasks_MPI.py --expand 1 --limit $TIMERANGE \$0 \$2 " -echo $list | xargs -P $NPROCS -n 3 /bin/bash -c "./analyse_tasks_MPI.py \$0 > \$2.stats" +for i in $(seq 0 $nrank); do + echo $list | xargs -P $NPROCS -n 3 /bin/bash -c "./analyse_tasks_MPI.py -r $i \$0 > \$2${i}.stats" +done echo "Writing output index.html file" # Construct document - serial. @@ -93,7 +95,7 @@ EOF2
 EOF2
-cat step${s}r.stats >> step${s}r${i}.html
+cat step${s}r${i}.stats >> step${s}r${i}.html
 cat <> step${s}r${i}.html
 
-- GitLab