tplot_profiling.py - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch) (HTM) git clone git://src.adamsgaard.dk/pism (DIR) Log (DIR) Files (DIR) Refs (DIR) LICENSE --- tplot_profiling.py (4816B) --- 1 #!/usr/bin/env python3 2 import pylab as plt 3 import numpy as np 4 from argparse import ArgumentParser 5 import importlib 6 import sys 7 import os.path 8 9 """ Produce pie charts using PISM's profiling output produced using 10 the -profile option. """ 11 12 parser = ArgumentParser() 13 parser.add_argument("FILE", nargs=1) 14 options = parser.parse_args() 15 16 filename = options.FILE[0] 17 18 dirname, basename = os.path.split(filename) 19 sys.path.insert(0, dirname) 20 21 modulename = os.path.splitext(basename)[0] 22 r = importlib.import_module(modulename) 23 24 colors = [(141, 211, 199), (255, 255, 179), (190, 186, 218), (251, 128, 114), 25 (128, 177, 211), (253, 180, 98), (179, 222, 105), (252, 205, 229), 26 (217, 217, 217), (188, 128, 189), (204, 235, 197), (255, 237, 111)] 27 colors = np.array(colors) / 255.0 28 29 n_procs = r.size 30 s = r.Stages["time-stepping loop"] 31 32 big_events = ["basal_yield_stress", 33 "stress_balance", 34 "surface", 35 "ocean", 36 "age", 37 "energy", 38 "basal_hydrology", 39 "fracture_density", 40 "mass_transport", 41 "calving", 42 "bed_deformation", 43 "io"] 44 45 small_events = {} 46 small_events["energy"] = ["ice_energy", "btu"] 47 small_events["stress_balance"] = ["stress_balance.shallow", "stress_balance.modifier", 48 "stress_balance.strain_heat", "stress_balance.vertical_velocity"] 49 small_events["stress_balance.modifier"] = ["sia.bed_smoother", 50 "sia.gradient", "sia.flux", "sia.3d_velocity"] 51 small_events["io"] = ["io.backup", "io.extra_file", "io.model_state"] 52 53 better_names = {"stress_balance.shallow": "SSA", 54 "stress_balance.modifier": "SIA", 55 "stress_balance.strain_heat": "Strain heating", 56 "stress_balance.vertical_velocity": "Vertical velocity"} 57 58 59 def get_event_times(event, n_procs): 60 result = [s[event][j]["time"] for j in range(n_procs)] 61 62 max = np.max(result) 63 min = np.min(result) 64 65 if max > 0: 66 return max, min, min / max 67 else: 68 return max, min, 0.0 69 70 71 total_time = np.max([s["summary"][j]["time"] for j in range(n_procs)]) 72 73 74 def get_data(event_list): 75 "Get event data from the time-stepping loop stage." 76 return {e: get_event_times(e, n_procs) for e in event_list if e in list(s.keys())} 77 78 79 def aggregate(data, total_time): 80 "Combine small events." 81 d = data.copy() 82 other = [0, 0, 0] 83 other_label = "" 84 for event in data: 85 if data[event][0] / float(total_time) < 0.01: 86 print("Lumping '%s' (%f%%) with others..." % (event, 87 100.0 * data[event][0] / total_time)) 88 del d[event] 89 other[0] += data[event][0] 90 other[1] += data[event][1] 91 if other[0] > 0: 92 other[2] = other[1] / other[0] 93 else: 94 other[2] = 0.0 95 other_label += "\n{}".format(event) 96 97 d["other"] = other 98 return d 99 100 101 def plot(data, total, grand_total): 102 103 events = [(e, data[e][0]) for e in data] 104 events.sort(key=lambda x: x[1]) 105 106 def better_name(n): 107 if n in list(better_names.keys()): 108 return better_names[n] 109 else: 110 return n 111 112 names = [e[0] for e in events] 113 times = [e[1] for e in events] 114 times_percent = [100.0 * t / float(total) for t in times] 115 116 if grand_total is not None: 117 comments = ["(%3.1f s, %3.1f%%)" % (time, 100.0 * time / grand_total) for time in times] 118 else: 119 comments = ["(%3.1f s)" % time for time in times] 120 121 labels = [better_name(name) + " " + comment for name, comment in zip(names, comments)] 122 123 explode = [0.05]*len(times) 124 plt.pie(times_percent, autopct="%3.1f%%", labels=labels, colors=colors, startangle=0.0, explode=explode) 125 plt.margins(x=0.2, y=0.1) 126 plt.axis('equal') 127 128 129 def figure(title, event_list, total, grand_total=None): 130 plt.figure(figsize=(10,5)) 131 plt.title("%s (%s)" % (title, filename)) 132 data = get_data(event_list) 133 plot(aggregate(data, total), total, grand_total) 134 # plot(data, total, grand_total) 135 return data 136 137 138 big = figure("Time-stepping loop", 139 big_events, 140 total_time) 141 142 energy = figure("Energy step", 143 small_events["energy"], 144 big["energy"][0], total_time) 145 146 stressbalance = figure("Stress balance", 147 small_events["stress_balance"], 148 big["stress_balance"][0], total_time) 149 150 sia = figure("SIA", 151 small_events["stress_balance.modifier"], 152 stressbalance["stress_balance.modifier"][0], total_time) 153 154 io = figure("I/O during run", 155 small_events["io"], 156 big["io"][0], total_time) 157 158 plt.show()