Skip to content

WP6: static capacities — 16x on a sampler that rebuilds every step - #64

Merged
TobiBu merged 1 commit into
perf/svgd-gather-accumulationfrom
perf/svgd-static-capacity
Sep 5, 2026
Merged

WP6: static capacities — 16x on a sampler that rebuilds every step#64
TobiBu merged 1 commit into
perf/svgd-gather-accumulationfrom
perf/svgd-static-capacity

Conversation

@TobiBu

@TobiBu TobiBu commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Stacked on #63.

Every partition rebuild produces different (near_rows, M) shapes, so a sampler that rebuilds
each step recompiles each step. Every bench builds once and times the update warmed, so
this cost appears in none of the committed numbers — it was invisible to every gate.

Six rebuilds of a perturbed N = 10⁴ cloud give six distinct signatures (41075/428752,
41141/412000, 41168/420016, 41179/419152, 41401/406768, 41255/407584). Measured over 8
rebuild-plus-update steps at N = 10⁴:

capacity total build alone
"exact" 35.52 s (8 compilations) 30.66 s
"pow2" 2.20 s (1 compilation) 1.50 s

16×, and note the build is most of it: the traversal was recompiling too.

capacity= takes "exact" (default, unchanged), "bucket" (an eighth of an octave — at most
12.5 % padding and stable against the observed ~1 % rebuild-to-rebuild drift, where "pow2"
costs 1.6× on the same data), "pow2", or an explicit integer. tree_svgd_step and
run_tree_svgd default to "pow2".

One claim corrected by its own test: padding reduces shape churn but does not remove it —
at N = 4000 M alternates 2048/4096, so "pow2" still compiles twice. Only an explicit
integer capacity guarantees a single shape
, and the test says so.

Evidence: reports/YGGDRAX_perf_report.md §5.5.

🤖 Generated with Claude Code

… step

The partition's lengths are data dependent, so its *shapes* change every
rebuild and both the traversal and the update retrace. No benchmark in this
work could see that: they all build once and time the update warmed. Measured
end to end instead -- 8 rebuild-and-update steps at N=1e4, A100, float64, the
whole loop timed including compilation:

    capacity   compilations    total     build    update
    "exact"               8   35.52 s   30.66 s   4.77 s
    "bucket"              2    2.67 s    1.57 s   1.09 s
    "pow2"                1    2.20 s    1.50 s   0.69 s

16x, and the surprise is where: the build falls 30.66 -> 1.50 s, so the
traversal was recompiling too, not just the update. This is the largest single
number anywhere in this performance work and it was invisible to every gate.

assemble_svgd_topology(capacity=) pads the near and far lists and carries
near_live / near_dir_live / far_live so the padding contributes nothing;
verified inert -- all six combinations of capacity x accumulation agree to
5.6e-17 and theta=0 still matches exact to 2.2e-15. tree_svgd_step and
run_tree_svgd, which rebuild every call, default to "pow2";
build_svgd_topology keeps "exact" so a one-shot caller pays no padding.

A bucketed policy is not a *guarantee*, which a test caught after I had claimed
it was: it pins the shape only while the count stays inside one bucket, and at
N=4000 M sits on a boundary and alternates 2048/4096 under "pow2". Only an
explicit integer capacity guarantees one shape. The test asserts the property
that is actually true.
@TobiBu
TobiBu force-pushed the perf/svgd-static-capacity branch from 5e9cb60 to 3d30287 Compare September 5, 2026 19:36
@TobiBu
TobiBu merged commit 7dc4feb into main Sep 5, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant