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()