Skip to content

SA and VU power scaled by the unit count twice on the enable_dvfs=False branch #7

Closed

Description

@lifrankfan

I tried reproducing the six per-component static-energy share ranges reported in section 3,
pages 4 and 5 of the ReGate paper, and could not with NeuSim at 58fbd3f. After debugging on
the assumption it was a problem with my configs, I noticed num_sa and num_vu are applied
twice.

ChipConfig.static_power_sa_W is already a whole-chip value:

# neusim/configs/chips/ChipConfig.py:119-120
def static_power_sa_W(self) -> float:
    return self.static_power_W_per_sa * self.num_sa

analyze_sa_static_energy multiplies it by num_sa again, outside the branch:

# neusim/npusim/backend/power_model.py:194-198
if config.enable_dvfs:
    _, static_sa_W = get_power_from_dvfs("SA", op.dvfs_sa)   # per-SA
else:
    static_sa_W = config.static_power_sa_W                   # already per_sa * num_sa
static_sa_W *= config.num_sa                                 # hits both branches

The multiply looks intended for the DVFS branch, whose table is per-unit
(neusim/npusim/backend/dvfs_power_getter.py:43, "SA and VU points are for a single SA/VU").
Since it sits outside the if, it also applies to the branch whose input is already a chip
total. enable_dvfs defaults to False (ChipConfig.py:93), so that is the branch that runs
unless --dvfs_policy is set to a non-default value
(neusim/run_scripts/energy_operator_analysis_main.py:85-86).

Four sites: SA static (:198), VU static (:370), SA/VU dynamic (:178-179).

What it does

llama3-8b decode on tpuv5p, batch 1, NoPG. Share of static energy:

component ReGate §3 frozen artifact NeuSim
SA 8-14% 9.5 43.9
VU 1.9-5.6% 2.5 8.6

Feeding identical operator statistics to both power models, the ratio is exactly num_sa on
SA and num_vu on VU across all seven chip configs, and 1.000 on the four components the
multiply does not touch.

The chip constants agree with the single multiply independently of the artifact: summing the
six static components once gives each chip's stored idle_power_W exactly on tpuv2, tpuv3
and tpuv4 (53.000 / 84.000 / 90.000 W). With the second multiply none of them match.

Reproducing

https://github.com/lifrankfan/neusim-power-double-count

./run_all.sh regenerates everything against NeuSim 58fbd3f and the
MICRO'25 artifact at 004dbfc. Full output is committed as RESULTS.txt.

What I have not established

  • Why the line is there. The public history in both repositories starts with a squashed drop
    that already contains it, so nothing I can see says whether it was deliberate.
  • 24 of the 1680 cells carry a second difference besides the power model. All are tpuv5p,
    which the artifact clocks at 1.75 GHz and NeuSim at 1.70. Frequency feeds the FLOPS
    utilization that scales dynamic energy, so those ratios read 8.235 rather than 8.000
    (8 x 1.75/1.70). The other six chips are clean.

My question

Is the unit-count scaling at those four sites meant for the DVFS branch only, and should the
default branch use static_power_sa_W as ChipConfig already defines it?

If that is the right reading, I have a patch that moves the multiply inside the branch rather
than deleting it (the DVFS branch needs it): patches/fix-double-multiply.patch in the repo
above. Happy to open it as a PR, but it changes reported SA and VU energy on the default path,
so that seemed like your call rather than mine.

Activity

  1. XZman commented on Sep 2, 2026

    @XZman
    Collaborator

    Thank you very much for your bug report, Frank!

    As your patch suggests, the line static_sa_W *= config.num_sa should go inside the dvfs branch of that if statement. This happens accidentally when I merged my private DVFS dev repo into NeuSim. The future plan is to refactor the DVFS lookup table as part of the ChipConfig, so that the DVFS-related configs are not hardcoded inside a python module, and hopefully we can avoid this kind of "if" statement glues. But for now, please feel free to open a PR and apply your patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions