# The decode-form pricing WITH POWER AND CLOCK SAMPLED CONCURRENTLY (#1861)
#
#   for S in 27 36 32; do I8_ONLY_BITS=4 I8_MCG_INT_CONTROL=1 \
#     python3 bench_codebook.py --rows 4096 8192 --shape $S --bits 4 \
#       --inner 400 --rounds 7 --sample-ms 8; done
#
# 206 gpu0, sole tenant, RTX 4090 at its 450 W default cap, NO clock pin
# (clocks.max.sm 3165, applications_clocks_setting Not Active -- checked before
# the run, because a leftover `-lgc` inflates any arithmetic-saving lever).
#
# WHY THIS RUN EXISTS.  At the cap, deleting arithmetic buys SM CLOCK on top of
# its direct instruction saving (#1911), so a time-only reading of an
# arithmetic lever is incomplete.  `--inner 400` is what makes the question
# answerable: each timed region is 130-270 ms, long enough to reach the steady
# state the cap governs.  The earlier `--inner 12` run
# (receipt_bench_codebook.txt) burst for ~4 ms and NEVER reached it.
#
# THE FIRST THING THIS CORRECTS IS MY OWN EARLIER READING.  That short-burst run
# reported NULL_DECODE at x1.00 on shapes 32 and 36 and I wrote that the decode
# "is worth nothing" there.  Under the cap it is worth 5.3% (s32) and 2.6%
# (s36).  The decode was never free; the burst was too short to charge for it.
#
# THE SIGN OF THE mcg CORRECTION IS THE OPPOSITE OF THE PREDICTED ONE.  The
# expectation was that mcg's dearer decode would draw more current and LOSE
# clock, costing ~10% more than its instruction count.  At the matched rows --
# every arm at swcap=100% and 448-449 W, shape 27 and 36 at M=8192 -- mcg runs
# at a HIGHER SM clock than mul1 (2505 vs 2445 MHz on s27, 2355 vs 2340 on s36)
# while being 3.2% and 1.2% slower.  mcg's decode is fp16-pipe work (lop3,
# hadd2, hfma2, prmt) where mul1's is one integer dp4a, and per unit time it
# draws LESS.  So the clock dividend runs in mcg's FAVOUR and gives back part of
# its instruction cost instead of compounding it.
#
# Clock-normalising s27 M=8192 (defensible only because every arm is pinned at
# the same 449 W): mcg's instruction penalty is ~5.9% and the clock returns
# ~2.5 points, delivering 3.2%.  NULL_DECODE normalises to 638.4 us against
# mul1's 638.3 -- i.e. at this shape, under the cap, deleting the decode buys
# essentially NOTHING in instructions and its whole 9.8% win is clock.  Read
# that as an inference from an uncontrolled clock, not as #1911's pinned
# split; the honest statement is that the delivered ratios track the clock
# ratios closely, which is what being power-limited means.
#
# WHICH ROWS ARE COMPARABLE.  Only ones where every arm is in the SAME regime.
# At M=4096 the arms sit at 86-100% swcap and 354-379 W -- different regimes,
# so no conclusion is drawn from those rows.  M=8192 on s27 and s36 has all
# four arms at 100% and 448-449 W.  On s32 mul1 alone is at 87.8%, so that row
# is reported and not leaned on.
#
# POWER IS NOT THE TIEBREAK BETWEEN THE TWO mcg FORMS, and could not have been:
# they are 45-104% apart on time (x1.45-2.04), at the same wattage.  Nor is
# accuracy -- derived over the full domain with the rounding term taken as the
# argmin, the integer form TIES the fp16 one at 5.2668e-05 (mcg_grid.py).
# Neither axis favours it; one strongly disfavours it.
#
# NULL_DECODE DRAWS MORE POWER THAN THE DECODING ARMS (438.5 W vs 394.5 on
# s32).  "Less arithmetic, less current" is not the rule: removing the decode
# lets the MMA pipe saturate harder.  What the cap fixes is the WATTS; what
# varies is how much result each arm gets for them.

=== clock pin / power-limit state before the run ===
clocks.max.sm [MHz], power.limit [W], enforced.power.limit [W], clocks_event_reasons.applications_clocks_setting
3165 MHz, 450.00 W, 450.00 W, Not Active
=== shape 27 ===
[state] 210, 32.94, 37, Not Active

  shape 27 at K=4, per codebook, off the compiled kernel:
    mul1                         regs/thread=199  blocks/SM=2  smem=49152 B  local=0 B
    mcg                          regs/thread=196  blocks/SM=2  smem=49152 B  local=0 B
    mcg (integer-form control)   regs/thread=201  blocks/SM=2  smem=49152 B  local=0 B

  M=4096 k=4096 n=4096 shape=27 K=4   burst=128 ms/region  sample=8 ms  cap=450 W   [state] 2505, 446.48, 57, Active
    mul1                                320.4 us   429.00 TOPS  paired x1.0000 vs mul1    2625 MHz   367.2 W  swcap= 86.4%  n=110
    mcg                                 327.9 us   419.10 TOPS  paired x1.0282 vs mul1    2550 MHz   378.8 W  swcap= 86.0%  n=114
    mcg (integer-form control)          650.2 us   211.38 TOPS  paired x2.0392 vs mul1    2625 MHz   369.2 W  swcap= 94.2%  n=226
    NULL_DECODE s40 (no decode at all)    285.8 us   480.88 TOPS  paired x0.8921 vs mul1    2715 MHz   354.1 W  swcap=100.0%  n=98

  M=8192 k=4096 n=4096 shape=27 K=4   burst=255 ms/region  sample=8 ms  cap=450 W   [state] 2490, 450.25, 55, Active
    mul1                                638.3 us   430.65 TOPS  paired x1.0000 vs mul1    2445 MHz   449.3 W  swcap=100.0%  n=222
    mcg                                 659.4 us   416.86 TOPS  paired x1.0321 vs mul1    2505 MHz   449.0 W  swcap=100.0%  n=228
    mcg (integer-form control)         1293.0 us   212.59 TOPS  paired x2.0258 vs mul1    2490 MHz   448.9 W  swcap=100.0%  n=447
    NULL_DECODE s40 (no decode at all)    581.3 us   472.87 TOPS  paired x0.9104 vs mul1    2685 MHz   448.3 W  swcap=100.0%  n=203
=== shape 36 ===
[state] 2865, 98.12, 39, Not Active

  shape 36 at K=4, per codebook, off the compiled kernel:
    mul1                         regs/thread=224  blocks/SM=2  smem=36864 B  local=0 B
    mcg                          regs/thread=223  blocks/SM=2  smem=36864 B  local=0 B
    mcg (integer-form control)   regs/thread=225  blocks/SM=2  smem=36864 B  local=0 B

  M=4096 k=4096 n=4096 shape=36 K=4   burst=134 ms/region  sample=8 ms  cap=450 W   [state] 2445, 447.88, 57, Active
    mul1                                335.7 us   409.37 TOPS  paired x1.0000 vs mul1    2475 MHz   393.7 W  swcap= 86.1%  n=115
    mcg                                 333.9 us   411.58 TOPS  paired x0.9959 vs mul1    2535 MHz   370.4 W  swcap= 86.1%  n=115
    mcg (integer-form control)          483.8 us   284.09 TOPS  paired x1.4497 vs mul1    2475 MHz   371.6 W  swcap= 85.7%  n=168
    NULL_DECODE s41 (no decode at all)    322.3 us   426.43 TOPS  paired x0.9625 vs mul1    2550 MHz   371.2 W  swcap= 86.6%  n=112

  M=8192 k=4096 n=4096 shape=36 K=4   burst=267 ms/region  sample=8 ms  cap=450 W   [state] 2535, 448.88, 59, Active
    mul1                                667.6 us   411.76 TOPS  paired x1.0000 vs mul1    2340 MHz   449.4 W  swcap=100.0%  n=230
    mcg                                 669.7 us   410.48 TOPS  paired x1.0121 vs mul1    2355 MHz   449.2 W  swcap=100.0%  n=233
    mcg (integer-form control)          965.7 us   284.65 TOPS  paired x1.4451 vs mul1    2385 MHz   449.1 W  swcap=100.0%  n=334
    NULL_DECODE s41 (no decode at all)    651.8 us   421.71 TOPS  paired x0.9740 vs mul1    2475 MHz   448.6 W  swcap=100.0%  n=228
DONEP

=== shape 32, M=8192, under the cap ===
  shape 32 at K=4, per codebook, off the compiled kernel:
    mul1                         regs/thread=122  blocks/SM=2  smem=24576 B  local=0 B
    mcg                          regs/thread=121  blocks/SM=2  smem=24576 B  local=0 B
    mcg (integer-form control)   regs/thread=125  blocks/SM=2  smem=24576 B  local=0 B

  M=8192 k=4096 n=4096 shape=32 K=4   burst=264 ms/region  sample=8 ms  cap=450 W   [state] 2610, 448.51, 58, Active
    mul1                                661.2 us   415.75 TOPS  paired x1.0000 vs mul1    2295 MHz   394.5 W  swcap= 87.8%  n=229
    mcg                                 672.3 us   408.83 TOPS  paired x1.0209 vs mul1    2385 MHz   398.8 W  swcap=100.0%  n=232
    mcg (integer-form control)         1261.5 us   217.90 TOPS  paired x1.9080 vs mul1    2490 MHz   418.1 W  swcap=100.0%  n=437
    NULL_DECODE s42 (no decode at all)    626.4 us   438.79 TOPS  paired x0.9475 vs mul1    2535 MHz   438.5 W  swcap=100.0%  n=218
