Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
184 commits
Select commit Hold shift + click to select a range
9f938f1
eval: dry-run cost-profile prediction backend
evaleev Jul 29, 2026
5bcc97f
optimize: batched cost model for multimode batching
evaleev Jul 29, 2026
f130582
eval: multimode batched evaluator
evaleev Jul 29, 2026
9ce6641
core: supporting changes for batched evaluation
evaleev Jul 29, 2026
aa4219e
tests: multimode batched evaluation, cost model, lifetime mask, dry-run
evaleev Jul 29, 2026
1001236
doc: design specs and plans for multimode batched evaluation
evaleev Jul 29, 2026
8a4335a
tests: make unit tests pass under Debug (asserts-on) build
evaleev Jul 30, 2026
bb51cad
opt: default order_aware_recompute to true
evaleev Jul 30, 2026
4657819
opt: complete the inner_pow no-default policy (fix g++ -Werror)
evaleev Jul 30, 2026
c01758a
dryrun: report replay-tallied (recompute-aware) cost
evaleev Jul 30, 2026
618fd41
dryrun: water-20 test compares order_aware true vs false recompute
evaleev Jul 30, 2026
27f44ce
opt: revert order_aware_recompute default to false
evaleev Jul 30, 2026
7eada54
opt: decouple order-aware cost model from node-level external placement
evaleev Jul 30, 2026
a169e82
opt: default order_aware_recompute to true (recompute-aware selection)
evaleev Jul 30, 2026
3772574
dryrun: schedule-dump instrumentation + cost_profile per-node avoidab…
evaleev Jul 31, 2026
6fafb77
dryrun: exact per-node avoidable via cost-homogeneous slice-context b…
evaleev Aug 1, 2026
d78de41
dryrun: define avoidable recompute in FLOPs vs the build-once ideal
evaleev Aug 1, 2026
987fda3
eval: remove the dead free-batchable-mode caching veto (disjunct a)
evaleev Aug 1, 2026
3d1e977
doc: placement-as-register-allocation design (retire the caching veto)
evaleev Aug 1, 2026
93949ad
doc: fold the O1 resolution into the placement spec
evaleev Aug 2, 2026
68495f8
doc: design O2 (the greedy split pass) in the placement spec
evaleev Aug 2, 2026
f50821c
doc: scope O2 as a placement-only second phase on a fixed schedule
evaleev Aug 2, 2026
1b8b9e8
doc: design O3 (cell footprint + peak profile) in the placement spec
evaleev Aug 2, 2026
08de8bd
doc: design O5 (home_scope + demotion fold) in the placement spec
evaleev Aug 2, 2026
03bcf04
doc: resolve O4 and scope O6 -- placement spec design-complete
evaleev Aug 2, 2026
202209e
doc: implementation plan for the home-scope placement design
evaleev Aug 2, 2026
476ee7d
doc: correct Phase 1 Steps 6-7 -- fix is per-op hwmark only, folds un…
evaleev Aug 2, 2026
0a0d465
eval: add CacheManager current/chain residency accessors
evaleev Aug 2, 2026
854dffa
eval: peak_bytes = true co-resident sum, not max(scratch,cache)
evaleev Aug 2, 2026
36b6821
test: re-baseline dryrun witness peak figures to co-resident sum
evaleev Aug 2, 2026
c3e8c22
doc/test: address Phase-1 final-review findings
evaleev Aug 2, 2026
602b6b1
eval: de-alias chain-resident operands in the peak trace (fix I1 over…
evaleev Aug 2, 2026
d16ea99
doc: Phase 2 implementation plan (router as a read+store override seam)
evaleev Aug 3, 2026
1133eb7
eval: batching-aware occurrence key via canonicalize_slots (Phase 2 T1)
evaleev Aug 3, 2026
57204f5
eval: PlacementRouter keyed on SlotCanonicalizationMetadata + access_…
evaleev Aug 3, 2026
c2c3cd3
eval: router consult on the Enter read and place_at_this_level store,…
evaleev Aug 3, 2026
ecfa669
doc: correct now-stale PlacementRouter comments (router is wired in T3)
evaleev Aug 3, 2026
47dd1ff
eval: prove a router override relocates a value's build+read home (Ph…
evaleev Aug 3, 2026
0bae127
test: route Phase 2 T4 relocation proof through router.route() (fix r…
evaleev Aug 3, 2026
e2feca7
doc: design for subsuming demoted_external into a corrected occurrenc…
evaleev Aug 3, 2026
dddd413
doc: retract demotion-subsumption, record why the meet is load-bearin…
evaleev Aug 3, 2026
c430b12
doc: home_scope seed is pure perfect-CSE; demotion is an O2 move, not…
evaleev Aug 3, 2026
ff83a35
doc: residency = sliced only; unify sliced_modes and remove contracte…
evaleev Aug 3, 2026
3803c24
doc: fold the placement-hacks audit into the Phase 3 design (section 8)
evaleev Aug 3, 2026
8351063
doc: correct audit CAT-3 -- most candidates are cache semantics or fa…
evaleev Aug 3, 2026
98f8d45
doc: Phase 3a is the non-regressing seed predictor; CAT-1 delete/unif…
evaleev Aug 3, 2026
7c21329
doc: Phase 3a implementation plan (non-regressing home_scope seed pre…
evaleev Aug 3, 2026
7280064
eval: parameterize the residency walk + add stamp_seed_residency (Pha…
evaleev Aug 4, 2026
b76b796
test: discriminating Contracted-mode seed_residency guard; simplify s…
evaleev Aug 4, 2026
6648343
eval: home_scope accessor + reconcile in_scope_batched_on_node with t…
evaleev Aug 4, 2026
f27bb20
test: seed_residency against-definition + byte-unchanged-runtime guar…
evaleev Aug 4, 2026
5765a3a
doc: Phase 3b static peak-profile detailed design (section 9)
evaleev Aug 4, 2026
95c6af4
plan: Phase 3b static peak-profile tasks (T1 sizer/depth, T2 sweep, T…
evaleev Aug 4, 2026
cc38aba
eval: peak-profile footprint sizer + home-depth resolver (Phase 3b T1)
evaleev Aug 4, 2026
894df8e
doc: Phase 3b use-sites are structural (empty router), interval = [pr…
evaleev Aug 4, 2026
5afce79
eval: peak-profile linearize + interval sweep -> PeakProfile (Phase 3…
evaleev Aug 4, 2026
064ce8d
test: peak-profile replay oracle + Phase-1 anchor (Phase 3b T3)
evaleev Aug 4, 2026
0564cee
eval: cell_footprint block-sizes the meet, not the per-occurrence ect…
evaleev Aug 4, 2026
f31bda7
test: correct the V-uniqueness rationale comment (root/empty-ectx, no…
evaleev Aug 4, 2026
3337b32
doc: Phase 4 design -- threshold-driven O2 spill + CAT-1 cutover (no …
evaleev Aug 4, 2026
a5f426a
plan: Phase 4a O2 shrink-first spill pass (T1 cells, T2 greedy, T3 wi…
evaleev Aug 4, 2026
1392fd1
eval: O2 working cells + shrink candidates + Schedule projection (Pha…
evaleev Aug 4, 2026
91278fd
eval: rematerialization spill pass -- shrink greedy loop + infeasibil…
evaleev Aug 4, 2026
1531426
doc: note the O2 pass is named remat (rematerialization) in code, wit…
evaleev Aug 4, 2026
f396c20
test: remat lowers a linearized forest's peak end-to-end + witness no…
evaleev Aug 4, 2026
5afe573
doc: Phase 4b decomposition + 4b-1 (unified meet) detailed design (se…
evaleev Aug 4, 2026
69d76af
plan: Phase 4b-1 unified meet (T1 unify+delete contracted, T2 retire …
evaleev Aug 4, 2026
17817a7
doc: correct Cociorva 2002 attribution -- sliced remat is theirs (til…
evaleev Aug 4, 2026
c01dd73
eval: unify sliced_modes to the all-batched-modes meet; delete contra…
evaleev Aug 4, 2026
e65cbda
eval: retire the duplicate seed_residency; home_scope reads sliced_mo…
evaleev Aug 4, 2026
3624a0d
eval: rename linearize/linearize_rich -> compute_dag_path/compute_dag…
evaleev Aug 4, 2026
290ecba
doc: Phase 4b-2 design -- hash threading + remat_to_router (section 10)
evaleev Aug 4, 2026
b1da3e8
plan: Phase 4b-2 remat_to_router (T1 thread hash, T2 emitter + valida…
evaleev Aug 4, 2026
5e70775
eval: thread value hash onto ValueCell (Phase 4b-2 T1)
evaleev Aug 4, 2026
f8daac9
eval: remat_to_router emits overrides for moved cells (Phase 4b-2 T2)
evaleev Aug 4, 2026
73bed7c
eval: 4b-2 review fixes -- rename shadowing param; pin second-occurre…
evaleev Aug 4, 2026
726c0a5
test: proper two-distinct-keys->one-home remat_to_router case + refra…
evaleev Aug 4, 2026
b5be98a
doc: Phase 4b-3 runtime-cutover design (section 11) + retract the fin…
evaleev Aug 4, 2026
0c63961
plan: Phase 4b-3 runtime cutover (T1 SeQuant veto delete + invariant,…
evaleev Aug 4, 2026
64ac92a
eval: delete the has_demoted_external veto; placement is router-or-se…
evaleev Aug 4, 2026
35ec4b5
eval: CacheManager owns its placement router (Phase 4b-3 T2)
evaleev Aug 4, 2026
89980b7
eval: schedule sink replaces the SEQUANT_SCHED_DUMP env gate
evaleev Aug 5, 2026
696104f
dryrun: cost_profile routes its replay's schedule events to a caller …
evaleev Aug 5, 2026
fb1422d
dryrun: cost_profile keeps its cache across the whole forest (no per-…
evaleev Aug 5, 2026
2a12bf1
dryrun: mode_batches reads a caller-supplied batch partition (Part 2)
evaleev Aug 5, 2026
1e15ec1
dryrun: tile nested batch sub-ranges along the partition (Part 2 fix)
evaleev Aug 5, 2026
a0a2705
eval: split evaluate() into a thin top-level entry + evaluate_impl en…
evaleev Aug 6, 2026
bf228d0
eval: measure avoidable recompute at (value, slice) granularity
evaleev Aug 6, 2026
ac61d6a
eval: apply remat router to run-scope hoist targets (defer moved values)
evaleev Aug 7, 2026
1e1fb6f
Add CSE-aware rematerialization split design spec
evaleev Aug 8, 2026
8bc524b
eval: extract shared slicing-signature helper
evaleev Aug 8, 2026
e4f8b1a
eval: pin occurrence-key DAG-globality; correct stale coloring doc
evaleev Aug 8, 2026
1aa50b1
eval: router home resolves to per-occurrence physical depth
evaleev Aug 8, 2026
fddbbf9
eval: split signature-inconsistent occurrences in the hoist path
evaleev Aug 8, 2026
39a5173
eval: defense-in-depth signature-consistency guard on the router read
evaleev Aug 8, 2026
46b495e
remat: price divergently-sliced (split) cells at 2x
evaleev Aug 8, 2026
e181e3d
Add CSE-aware rematerialization split implementation plan
evaleev Aug 8, 2026
f5d05d3
fix: dryrun cost each op in annotation space, not the value's stored …
evaleev Aug 9, 2026
beffd34
test: canon_indices preserves distinct composite proto pairs
evaleev Aug 9, 2026
f926c06
doc: spec for label-free DryRun value (positional shape + overrides)
evaleev Aug 9, 2026
6cf7226
remat-cse-split spec/plan: replication-factor pricing, DAG-scope caveats
evaleev Aug 9, 2026
1d8cc33
dryrun: label-free positional ExtentOverrides (cost prediction only)
evaleev Aug 9, 2026
e941151
eval: router home is a DAG-scope resolved per use to physical depth
evaleev Aug 9, 2026
7743e6a
remat: split along relabeled modes, priced by replication factor
evaleev Aug 9, 2026
72fb296
eval: qualify get_indices with .template for gcc-13
evaleev Aug 9, 2026
9899337
eval: release-safe router-read guard (recompute on inconsistent share)
evaleev Aug 9, 2026
28c8ab6
doc: spec for retiring the replay hold-gate (measure peak, place for …
evaleev Aug 9, 2026
226b368
doc: plan for path A (measure C60 profile with the replay hold-gate off)
evaleev Aug 9, 2026
6137461
test: C60 witnesses measure the true gate-off profile (retire the 100…
evaleev Aug 9, 2026
17b61c8
doc: plan for path B (remat-enforced budget, crux-first equivalence g…
evaleev Aug 9, 2026
6fefeb0
test: probe remat modelled-vs-replayed peak on C60 (path B Task 1 gate)
evaleev Aug 9, 2026
4d0cb2c
eval+doc: resolve Task 1b -- two execution models on one placement sp…
evaleev Aug 9, 2026
3a72d44
doc: correct Task 1b spec -- drop the enclosing_modes=Forest-footprin…
evaleev Aug 10, 2026
0fe8acd
test: water-20 aux-batch fragmentation surrogate confirms gC rf==1
evaleev Aug 10, 2026
625e5cd
test: water-20 remat + DP peak_threshold sweeps (schedule vs placemen…
evaleev Aug 10, 2026
0446058
test: seed homes 17/21 gC composites INSIDE the K loop (peak-threshol…
evaleev Aug 10, 2026
7439107
doc: spec for whole-scope batched DAG execution (scope-tree scheduler…
evaleev Aug 10, 2026
eeee211
doc: refine whole-scope DAG spec per review (noise tolerance, lazy or…
evaleev Aug 10, 2026
7b27b9e
doc: C60 top-scope feasibility is a placement/optimizer concern, not …
evaleev Aug 10, 2026
ce1fa3d
doc: implementation plan for whole-scope batched DAG execution
evaleev Aug 10, 2026
e88228b
Add scope-tree schedule (Task 1 of whole-scope batched DAG execution)
evaleev Aug 10, 2026
bfc080d
Fix scope-tree mode_is_external to match by index type, not exact Index
evaleev Aug 10, 2026
212e4b2
Add whole-scope executor skeleton (Task 2 of whole-scope batched DAG …
evaleev Aug 10, 2026
f89ddb5
Fix round 1: restore trace bookkeeping dropped from evaluate_whole_scope
evaleev Aug 10, 2026
b6fab95
whole-scope executor: single aux batch loop + the build-once CSE win …
evaleev Aug 10, 2026
1e7fe3c
whole-scope executor: hold the backend scope guard across the K loop …
evaleev Aug 10, 2026
6d75495
whole-scope executor: nested aux+occ scope tree recursion (Task 4)
evaleev Aug 10, 2026
f3b7dcb
doc: add Task 5 (weighted use-count lifetimes / remove ensure_hoist_s…
evaleev Aug 10, 2026
6b3fc3e
whole-scope executor: map contracted mode to each member's own axis (…
evaleev Aug 10, 2026
baa5fd3
whole-scope executor: restore grouped nested recursion (Task 4 fix ro…
evaleev Aug 10, 2026
f9eae84
whole-scope executor: add weighted_use_count in-block lifetime (Task …
evaleev Aug 10, 2026
5e234b1
whole-scope executor: weighted-life homed values, drop ensure_hoist_s…
evaleev Aug 10, 2026
592a86f
whole-scope executor: refresh walk_scope doc for weighted-life homing
evaleev Aug 10, 2026
693f663
doc: Task 5 Step 6 -- retain ensure_hoist_slot for forest descent (ow…
evaleev Aug 10, 2026
f9f1f74
whole-scope executor: coexistence flag + cost-model peak selection (T…
evaleev Aug 10, 2026
0ba1d53
doc: add Task 8 (MPQC runtime validation -- CSV-CCk energies, forest-…
evaleev Aug 10, 2026
c250d71
whole-scope executor: water-20 + C60 whole-branch validation witnesse…
evaleev Aug 10, 2026
9118a3c
whole-scope executor: witness fix round 1 -- water-20 structural comp…
evaleev Aug 10, 2026
67e8ba2
eval: whole-scope driver seam on CacheManager + forest-evaluate dispatch
evaleev Aug 10, 2026
20a69db
eval: guard last_type_is_cache_manager against empty pack
evaleev Aug 11, 2026
e89a9b4
eval: exclude the cache-appending forwarder when any arg is a cache
evaleev Aug 11, 2026
ef79b4e
eval: emit BatchGroup/BatchMember/BatchAxes loop markers from the who…
evaleev Aug 11, 2026
2d3bd1c
eval trace: uniform per-op sliced-mode + loop-scope annotations (fore…
evaleev Aug 11, 2026
139db04
eval: drop trailing comma in scope_annot list (scope={i,i,K} not {i,i…
evaleev Aug 11, 2026
49d54d5
add remat home + use DAG-scope to the per-op trace annotation
evaleev Aug 11, 2026
18a9a7a
add PeakMonitor and wire hierarchy-wide co-resident high-water into C…
evaleev Aug 11, 2026
44380a2
meter: per-node exec tally and MeterReport assembly (peak, persistent…
evaleev Aug 11, 2026
b078c35
meter: strengthen [meter] test to cover exec/cost split, persistent b…
evaleev Aug 11, 2026
c98f5c7
meter: dry-run driver running the real policy-selected executor with …
evaleev Aug 11, 2026
7f305fd
witness: meter both executors and report Kappa-free home={} rebuilds …
evaleev Aug 11, 2026
9ef658e
meter: install the batched custom evaluator on the forest-descent path
evaleev Aug 11, 2026
cca0086
legality: value build-site derivation over the contraction DAG
evaleev Aug 12, 2026
cd49f61
test_legality: include io/shorthands.hpp for deserialize
evaleev Aug 12, 2026
7cf9640
legality: four-way per-axis classifier (loop-local/reduction/loop-car…
evaleev Aug 12, 2026
04fb946
legality: require LoopLocal coverage in the water-20 test; assert for…
evaleev Aug 12, 2026
67d53fe
legality: home-floor computation from per-axis roles
evaleev Aug 12, 2026
3c8146f
legality: forced loop splits and the monotone classification fixpoint
evaleev Aug 12, 2026
976ed2f
legality: SP1 acceptance test for all four LoopRole values
evaleev Aug 12, 2026
290e8ce
legality: SP2-facing notes on implicit LoopInvariant, per-instance sp…
evaleev Aug 12, 2026
9599b11
legality: Q2b compares all same-type slots; per-type split grouping; …
evaleev Aug 12, 2026
cf690de
ordered-schedule: the OrderedSchedule IR (ScopeBlock tree with ordina…
evaleev Aug 12, 2026
cc7edaa
ordered-schedule: restore whole-schedule single-producer (SSA-like) i…
evaleev Aug 12, 2026
6b3d494
ordered-schedule: deterministic sequencer for the non-split case (hom…
evaleev Aug 12, 2026
b8a5b08
ordered-schedule: replace the scalar-key sort with a real per-step to…
evaleev Aug 12, 2026
3b508cc
ordered-schedule: forced loop splits + grown demotion fixpoint (LoopL…
evaleev Aug 12, 2026
090e152
ordered-schedule: single-sided forced-split demotion trigger (fix asy…
evaleev Aug 12, 2026
879b1bd
ordered-schedule: water-20 + cross-iteration acceptance and executor-…
evaleev Aug 12, 2026
1af1a6c
ordered-schedule: fail-safe assert for non-innermost forced split + S…
evaleev Aug 12, 2026
bf39b82
ordered-executor: skeleton, gating flag, and root-block BuildStep int…
evaleev Aug 12, 2026
aa03a5e
ordered-executor: extract shared forest-root combine into forest_comb…
evaleev Aug 12, 2026
927c248
ordered-executor: Contracted loop blocks with AccumulateSum reduction…
evaleev Aug 12, 2026
5c3ded4
ordered-executor: assert against silent multi-physical-label axis mis…
evaleev Aug 12, 2026
4a6d17a
ordered-executor: AccumulateScatter outputs and forced-split producer…
evaleev Aug 12, 2026
16502a9
ordered-executor: water-20 numerical-equivalence and home={} build-on…
evaleev Aug 12, 2026
3ce140f
ordered-executor: peak monitoring, run-completeness assertion, and un…
evaleev Aug 12, 2026
dcf15af
diagnostics: co-resident peak live-set introspection + w20 peak-compo…
evaleev Aug 12, 2026
1e2b20d
scope_executor: drop dead `perm` local left by the root-combine extra…
evaleev Aug 12, 2026
3ceb5cc
diagnostics: access-clock last-use timeline for eager-release reclaim…
evaleev Aug 12, 2026
2fda7de
cache_manager: bounded/persistent ensure_home_slot overload
evaleev Aug 12, 2026
8a14c38
cache_manager: test ensure_home_slot upgrade-existing-entry branch
evaleev Aug 12, 2026
37572b2
ordered-executor: n_blocks block-count function over OrderedSchedule
evaleev Aug 12, 2026
d321187
ordered-executor: thread lifted is_volatile node predicate
evaleev Aug 12, 2026
1ce782b
ordered-executor: read-from-home access discipline with exact static …
evaleev Aug 13, 2026
6535ed5
ordered-executor: reuse resident persistent loop outputs instead of r…
evaleev Aug 13, 2026
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ set(SeQuant_eval_src
SeQuant/core/eval/eval_expr.hpp
SeQuant/core/eval/eval_node.hpp
SeQuant/core/eval/eval_node_compare.hpp
SeQuant/core/eval/node_batch_annotation.hpp
SeQuant/core/eval/result.cpp
SeQuant/core/eval/result.hpp
SeQuant/core/eval/fwd.hpp
Expand Down
121 changes: 120 additions & 1 deletion SeQuant/core/batch_policy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <cstddef>
#include <functional>
#include <limits>

namespace sequant {

Expand All @@ -12,7 +13,39 @@ class Tensor;
/// One batchability policy shared by the single-term optimizer and the runtime
/// batched evaluator (make_evaluator, Task A3). All predicates default empty.
struct BatchPolicy {
std::function<bool(Index const&)> is_batchable_index = {};
/// Spaces batchable in the CONTRACTED role: a mode of such a space is
/// batchable where it is summed. Companion to \ref
/// is_batchable_external_index (the EXTERNAL role). Splitting batchability by
/// role lets a caller admit a space only where batching it is meaningful --
/// e.g. a space batchable only as an external spectator contributes none of
/// its contracted occurrences to the optimizer's 2^m search. Building block;
/// the derived "batchable in any role" query is \ref is_batchable_index().
/// Defaults to decline every index; a caller opts spaces in explicitly.
std::function<bool(Index const&)> is_batchable_contracted_index =
[](Index const&) { return false; };
/// Spaces batchable in the EXTERNAL role: a mode of such a space is batchable
/// where it is open on the term root (a spectator carried to the result), not
/// where it is contracted. Building block; declared adjacent to its
/// contracted companion. Defaults to decline every index; a caller that wants
/// external batching sets this predicate explicitly (there is no fallback to
/// the contracted role).
std::function<bool(Index const&)> is_batchable_external_index =
[](Index const&) { return false; };

/// Derived "batchable in ANY role": the union of the two building-block
/// predicates. This is NEVER a settable field -- it is computed from
/// \ref is_batchable_contracted_index and \ref is_batchable_external_index.
/// The runtime batched evaluator's accept predicate is this union (a mode is
/// accepted at runtime if it is batchable in either role); the factorizer's
/// role filters instead consume the individual building blocks. The building
/// blocks default-decline, so both are always callable here.
std::function<bool(Index const&)> is_batchable_index() const {
auto contracted = is_batchable_contracted_index;
auto external = is_batchable_external_index;
return [contracted, external](Index const& ix) {
return contracted(ix) || external(ix);
};
}
/// Per-index per-batch slice size (in elements) for a batchable index -- an
/// UPPER BOUND, not a goal. Both the single-term optimizer and the runtime
/// batched evaluator treat it as a ceiling: the realized whole-tile batch is
Expand All @@ -21,6 +54,41 @@ struct BatchPolicy {
std::function<std::size_t(Index const&)> batch_target_size = {};
std::function<bool(Tensor const&)> is_volatile_leaf = {};

/// If true, an external/spectator index -- open on the whole network's result
/// yet contracted at no node -- is eligible for batching; its per-slice size
/// comes from \c batch_target_size(ix) like any batchable index. Default
/// false = no spectator batching (byte-identical to non-spectator behavior).
/// Necessary but not sufficient: spectator axes are emitted only under a
/// TIME-FIRST objective (DenseTimeSpaceBatched) and only when the selected
/// root's modeled peak exceeds \c peak_threshold. Spectator batching is
/// therefore currently unavailable under the space-first objectives.
bool batch_spectator_indices = false;

/// Enable the order-aware multilevel recompute cost model (resident-scan peak
/// + ordered-key flops recompute). SELECTION knob ONLY: it makes the DP
/// charge recompute realistically and thus pick a different (better-batching)
/// factorization. It does NOT control external-mode EMISSION -- that is the
/// independent \ref node_level_placement. Consulted only by the batched
/// objectives (threaded via CostParams). Default TRUE: the recompute-aware
/// model is the more realistic cost for selection. This is SAFE precisely
/// because it is now selection-only -- the node-level emission it used to
/// force is separately gated by \ref node_level_placement (default off), so
/// the emission stays the correct, cheap root-level forest seed. (Before the
/// decouple, defaulting this true forced the node-level runtime regression.)
bool order_aware_recompute = true;

/// Emission-placement knob for external (spectator) modes, INDEPENDENT of the
/// order-aware cost model. Only meaningful with \ref batch_spectator_indices.
/// If true, the emit uses node-level placement (per-node External stamps); if
/// false (default) it uses the root-level forest seed (one global spectator
/// loop). Node-level placement is currently a net runtime REGRESSION -- ~6x
/// wall time and ~8x batch scopes on water-8, and it produces a wrong
/// residual on water-20 -- because it nests a batch scope at every carrying
/// node and the batched evaluator replays each. It stays OFF by default until
/// that is fixed; the root-seed emission is correct and cheap regardless of
/// order_aware_recompute.
bool node_level_placement = false;

/// If true, restrict batching to persistent (amplitude-independent) subtrees,
/// declining to batch any subtree that contains a volatile leaf. If false
/// (the default), batch ACROSS THE BOARD: slicing the batch axis shrinks any
Expand All @@ -40,6 +108,57 @@ struct BatchPolicy {
/// accumulator + contribution co-residency of a node that contracts a
/// batchable index.
double accumulation_factor = 0.0;

/// Coexistence switch (Task 6 of the whole-scope batched DAG execution
/// design, `doc/dev/specs/2026-08-10-whole-scope-batched-dag-execution-
/// design.md`) between the two RUNTIME EXECUTION MODELS: forest descent
/// (default false -- one tree at a time, `sequant::evaluate(Nodes const&,
/// ...)`, unchanged) and whole-scope descent (true -- one fused scope-tree
/// walk over the whole forest, `sequant::eval::evaluate_whole_scope`, so a
/// value shared across trees is built once per home block and reused,
/// rather than rebuilt per tree). Consulted by the `sequant::evaluate(
/// Nodes const&, BatchPolicy const&, ...)` driver overload
/// (`scope_executor.hpp`) to select the driver, and by
/// `sequant::eval::dryrun::cost_profile()` to select the matching peak
/// model: the co-residency oracle (`peak_profile_sweep` over `home_modes`)
/// when true, since that model is what predicts the whole-scope realized
/// peak, vs the batched-scratch replay high-watermark (models forest
/// descent) when false. Purely additive: false reproduces today's behavior
/// on both call sites byte-for-byte.
bool whole_scope_execution = false;

/// SP3 gating switch (`doc/dev/specs/2026-08-05-dryrun-wetrun-schedule-
/// equivalence-design.md` follow-on, the ordered-scope batched-eval
/// design): between forest descent / whole-scope descent (both selected
/// above via \ref whole_scope_execution) and the new ORDERED executor
/// (true -- `sequant::eval::evaluate_ordered_schedule`, driven by the SP2
/// `eval::OrderedSchedule` IR rather than the narrow `ScopeSchedule` scope
/// tree). Consulted by the `sequant::evaluate(Nodes const&, BatchPolicy
/// const&, ...)` driver overload (`scope_executor.hpp`) BEFORE \ref
/// whole_scope_execution, so it takes priority when both are set (setting
/// both is well-defined: the ordered executor wins) and the two pre-
/// existing dispatch arms (forest descent / whole-scope descent) are
/// reached, byte-identically, only when this flag is false. Default false
/// reproduces today's dispatch byte-for-byte on every existing caller.
bool ordered_schedule_execution = false;

/// Peak-memory budget in BYTES for the batched objectives. Its meaning
/// DIFFERS between them:
///
/// - SPACE-FIRST (DenseSpaceTimeBatched): a hard feasibility gate. The
/// single-term optimizer minimizes flops among schedules whose modeled peak
/// is <= peak_threshold, falling back to min-peak (best effort) when none
/// fit. Default +infinity => every schedule feasible => min flops => no
/// batching, i.e. here a finite value is the *enable* trigger for batching.
///
/// - TIME-FIRST (DenseTimeSpaceBatched): NOT a feasibility gate. Root
/// selection ignores it entirely (peak breaks exact flop ties only), so it
/// can neither constrain the schedule's peak nor enable CONTRACTED-axis
/// batching (which is emitted regardless). Its ONLY effect is to trigger
/// EXTERNAL (spectator) axis emission, together with
/// \c batch_spectator_indices: axes are emitted iff the selected root's
/// modeled peak exceeds this threshold.
double peak_threshold = std::numeric_limits<double>::infinity();
};

} // namespace sequant
Expand Down
Loading
Loading