Expand description
Batch lane policy: the shared vocabulary and the one decision function.
Three libraries decide how a batch of independent problems is split over a
thread budget (tcontract’s packed driver and faer strategy, cpueinsum’s
grouped GEMM, tlinalg’s lane plan). This module gives them one vocabulary
and one pure function, batch_decision, so a caller can force a route and
two crates cannot drift on the same decision. The types are plain data with
no scheduler dependency; they live apart from Exec so moving
them later is a re-export, not a redesign.
§Strategies
BatchStrategy::Auto is the only heuristic. Every other variant forces a
route and never falls back: the route either honors it (clamped to the
items and the budget) or the library reports
crate::ExecError::StrategyUnavailable.
Forced strategies are evaluated against the original host budget. Only
Auto narrows, because the packed driver narrows its Exec twice (see
below).
§What Auto computes
Auto has two forms, chosen by the query. This is how one formula serves
both the shared work model and the packed driver’s legacy rule:
- Without
balanced_lanes, the issue’s generic formula: estimateitem_nsandtotal_ns, cap the lanes attotal_ns / min_work_per_lane_ns, and fan out only whenlanes >= 2,items >= min_itemsanditems >= lanes * min_items_per_lane. Each lane runs items serially; with one lane,item_threadsis the width of one item, so a route that permits it (faer) can parallelize inside the item. - With
balanced_lanes, the packed two-stage rule below, which the defaultWorkModelreproduces to the lane.
§Widths come from the token
Auto never owns a width model. Every width it needs is the token’s:
Exec::width_for turns the estimated serial time of
the region and the number of sections (dispatches) it performs into the width at
which the region pays, using the dispatch cost of the token’s kind (team, plain
token inside its pool, plain token outside it; threadteam owns the table and
the PAYS multiple). A batch has two such regions: the whole batch spread over
lanes (one section) and one item on a team (BatchQuery::item_sections
sections). The rules below combine them:
| Rule | Source | Encoding here |
|---|---|---|
| packed balanced lanes | crates/tcontract/src/driver/batch.rs:38, plan/mod.rs:641, driver/route.rs:49 | Auto + balanced_lanes + the default WorkModel (its item cost is ns_per_flop()) |
| faer item-width-1 | crates/tcontract/src/strategy/faer.rs:243 | Auto + item_parallel; a decision with item_threads > 1 is the inner route, lanes > 1 with item threads one is the outer route |
contract_batched item count | crates/tcontract/src/batch.rs:140 | forced strategies, not Auto: BatchStrategy::Outer when the items fill the budget; below that one lane, the caller running each item on the whole budget (Sequential/Inner). It has no work threshold. |
The packed rule is two-stage. plan/mod.rs first narrows the Exec to the
width the whole batch pays for, and driver/batch.rs recomputes the width
against that narrowed budget and only then applies its tiny (one item alone
does not pay a team) and balanced (every lane non-empty, the split near-even,
the batch alone fills the budget) tests. Auto reproduces exactly that: it
narrows budget with the token, then applies the tiny/balanced tests when the
query says balanced_lanes, and reports the narrowed width as item_threads
when it keeps one lane.
§Examples
use tcontract_exec::batch::{batch_decision, BatchPolicy, BatchQuery, BatchStrategy};
use tcontract_exec::{Exec, Pool};
let sp = threadteam::Pool::builder().threads(8).build().unwrap();
let pool = Pool::borrow(&sp);
let exec = Exec::new(&pool, 8).unwrap();
let query = BatchQuery::new(16, 64.0);
// A forced route is clamped, never a fallback.
let outer = BatchPolicy::new(BatchStrategy::Outer);
let d = batch_decision(&outer, &exec, &query);
assert_eq!(d.lanes, exec.budget().min(8));
assert_eq!(d.item_threads, 1);Structs§
- Batch
Decision - The route
batch_decisionselected. - Batch
Policy - A strategy and the model its
Autoarm applies. - Batch
Query - What one batch of one route looks like to
batch_decision. - Work
Model - The cost and fan-out model
BatchStrategy::Autoapplies.
Enums§
- Batch
Strategy - How the items of a batch are split over a thread budget.
Functions§
- batch_
decision - Decide the route for one batch on the budget and the dispatch costs of
execunderpolicy. - batch_
decision_ within batch_decisionfor a stage that was narrowed tobudgetslots (at most the token’s own) without narrowing the token: the widths minimise over1..=budgetwith the token’s dispatch costs (Exec::width_for_within).