Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 33 additions & 17 deletions util/plot_shmoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,27 @@ def generate_data(


def main(out_file: str, *genargs) -> int:
# CLI invocations cannot pass real `None`; the documented usage in this
# file's header uses positional placeholders for the optional measurement
# arguments, which then arrive here as the literal string "None". Convert
# those (and empty strings) to actual `None` so the downstream
# `is not None` checks behave as intended.
genargs = tuple(None if g in ('None', '') else g for g in genargs)

# Generate data to be plotted
data = generate_data(*genargs)

# Determine plotting mode from args, assign correct data
bar_cmap = mpl.colormaps['viridis']
bar_cmap.set_under('white')
bar_show = True
if genargs[6] is not None:
if len(genargs) > 6 and genargs[6] is not None:
bar_legend = 'En. Eff. (MFLOP/s/W)'
bar_data = data['effs_mflop_per_s_per_w']
elif genargs[4] is not None:
elif len(genargs) > 4 and genargs[4] is not None:
bar_legend = 'Energy (mJ)'
bar_data = data['es_mj']
elif genargs[1] is not None:
elif len(genargs) > 1 and genargs[1] is not None:
bar_legend = 'Power (mW)'
bar_data = data['ps_mw']
else:
Expand All @@ -119,22 +126,31 @@ def main(out_file: str, *genargs) -> int:
fig = plt.figure(figsize=(3.3*scale, 2.0*scale))
ax = plt.subplot(111)

# Style axes
xdata = data['vs_v']
ydata = data['fs_mhz']
xticks = xdata[::5]
yticks = ydata[::6]
# Style axes. The plotted axes are frequency on X (matching xlabel) and
# voltage on Y (matching ylabel); name the local variables accordingly so
# the tick wiring below cannot drift from the pcolormesh argument order.
freq_mhz = data['fs_mhz']
volt_v = data['vs_v']
freq_ticks = freq_mhz[::3]
volt_ticks = volt_v[::5]
ax.set_xlabel('Frequency (MHz)', fontsize=10)
ax.set_ylabel('Core Voltage (V)', fontsize=10)
plt.xticks(xticks, rotation=0)
ax.set_yticks(yticks)
ax.set_xticklabels(xticks)
ax.set_yticklabels(yticks)
ax.xaxis.set_major_formatter(lambda val: f'{val:.0f}')
ax.yaxis.set_major_formatter(lambda val: f'{val:1.2f}')

# Plot the desired data and save
c = ax.pcolormesh(ydata, xdata, bar_data, cmap=bar_cmap, edgecolor='silver', linewidth=0.0)
ax.set_xticks(freq_ticks)
ax.set_yticks(volt_ticks)
ax.set_xticklabels([f'{v:.0f}' for v in freq_ticks])
ax.set_yticklabels([f'{v:.2f}' for v in volt_ticks])
# Matplotlib >= 3.5 calls the formatter as ``fmt(value, pos)``; the
# original 1-arg lambdas raised TypeError during draw, preventing the
# plot from ever being saved.
ax.xaxis.set_major_formatter(lambda val, _pos: f'{val:.0f}')
ax.yaxis.set_major_formatter(lambda val, _pos: f'{val:1.2f}')

# Plot the desired data and save. pcolormesh(X, Y, C): X = frequency,
# Y = voltage. `bar_data` has shape (len(volt_v), len(freq_mhz)) so
# `bar_data[volt_idx][freq_idx]` lands at (freq_mhz[freq_idx],
# volt_v[volt_idx]).
c = ax.pcolormesh(freq_mhz, volt_v, bar_data, cmap=bar_cmap,
edgecolor='silver', linewidth=0.0)
if bar_show:
cbar = fig.colorbar(c, ax=ax)
cbar.set_label(bar_legend, fontsize=10)
Expand Down