Skip to content

[Compiler] Study whether the auto-large-GRF rebuild threshold should be non-zero (allow some spilling at 128 GRF) #7821

Description

@etiotto

Background

MAX_REG_SPILL (third_party/intel/backend/compiler.py) and max_reg_spill (third_party/intel/backend/driver.c) control when a kernel is rebuilt with a larger GRF size. #7615 lowered both from 1000 bytes to 0, so the comparison spill_size > max_reg_spill now triggers on any spill at all.

The rebuild applies to kernels left on grf_mode='default' with num_warps <= 32, and targets 256 GRF (512 on CRI). It is skipped when a GRF size flag is already present, so explicitly pinned modes and grf_mode='auto' are unaffected.

Problem

With a threshold of 0, any kernel that spills a single byte is silently recompiled at 256 GRF. As raised in #7615 (comment), that effectively makes 256 GRF the default for register-hungry kernels, overridable only by pinning grf_mode or autotuning it — which is a policy change rather than a spill mitigation, and it does not appear to have been justified by benchmarking.

The trade-off it resolves unconditionally is a real one in both directions: 256 GRF halves the maximum work-group size and correspondingly the thread occupancy, so for a kernel spilling a small amount, paying that occupancy cost may well be worse than paying for the spill. The threshold's value decides which side to err on, and 0 removes the possibility of erring towards occupancy.

There is also a secondary cost the PR review flagged and left open: every spilling kernel is now compiled twice, so this affects compilation time and CI duration (see the review discussion on #7615 about PyTorch CI limits and tracking inductor timing).

Questions to answer

  • Where is the crossover? For a kernel at grf_mode='128', how much spill can be tolerated before halved occupancy at 256 GRF becomes the better trade?
  • Is that crossover expressible as a single byte threshold at all, or does it depend on the kernel's occupancy sensitivity, shape, or num_warps?
  • Should the threshold differ per architecture? The rebuild targets 512 GRF on CRI and 256 elsewhere, so the occupancy cost being paid is not the same everywhere.
  • What is the compile-time cost of the current setting across the benchmark suites and in CI, given that every spilling kernel is now built twice?
  • Was there a reason to prefer 0 over 1000 that isn't captured in [NIT] Rebuild the kernel with large GRF size to reduce the register spilling size aggressively. #7615? The change is described only as "aggressively" reducing spill size.

Done when

There is benchmark data across the suites, at both settings and ideally a few intermediate thresholds, sufficient to either justify keeping 0 or to recommend a specific non-zero value — plus a measurement of the compile-time impact. Any change should keep the two constants aligned, since they duplicate the same policy in the Python and C paths.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions