Skip to main content

Module batch

Module batch 

Source
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 rayon 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 ExecError::StrategyUnavailable. BatchStrategy::WholeBatchVendor is the one forced route that may be unavailable, and it is refused from the query’s vendor capability alone, before any output write.

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: estimate item_ns and total_ns, cap the lanes at total_ns / min_work_per_lane_ns, and fan out only when lanes >= 2, items >= min_items and items >= lanes * min_items_per_lane. Each lane runs items serially; with one lane, item_threads is 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 default WorkModel reproduces to the lane.

§The legacy rules and how Auto expresses them

This step lands the vocabulary with defaults that reproduce today’s tcontract packed decision; the sweep that fits one shared default to all three libraries is a later step. The three legacy rules and their mapping:

Legacy ruleSourceEncoding here
packed balanced lanescrates/tcontract/src/driver/batch.rs:38, plan/mod.rs:641, driver/route.rs:49Auto + balanced_lanes + the default WorkModel (its width is the existing WidthPolicy, its item cost is NS_PER_FLOP)
faer item-width-1crates/tcontract/src/strategy/faer.rs:243Auto + 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 countcrates/tcontract/src/batch.rs:140forced 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:641 first narrows the Exec to width_for(total_ns) over the whole batch, and driver/batch.rs:38 recomputes the width against that narrowed budget and only then applies its tiny (one item already below the serial threshold) 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 model.width, 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. The test auto_matches_legacy_packed_table pins this on a table.

§Examples

use std::num::NonZeroUsize;
use tcontract_exec::batch::{batch_decision, BatchPolicy, BatchQuery, BatchStrategy};
use tcontract_exec::ExecError;

let budget = NonZeroUsize::new(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, budget, &query).unwrap();
assert_eq!((d.lanes, d.item_threads, d.vendor_batch), (8, 1, false));

// The vendor route needs the caller to say it exists.
let vendor = BatchPolicy::new(BatchStrategy::WholeBatchVendor);
assert!(matches!(
    batch_decision(&vendor, budget, &query),
    Err(ExecError::StrategyUnavailable { .. })
));

Structs§

BatchDecision
The route batch_decision selected.
BatchPolicy
A strategy and the model its Auto arm applies.
BatchQuery
What one batch of one route looks like to batch_decision.
WorkModel
The cost and fan-out model BatchStrategy::Auto applies.

Enums§

BatchStrategy
How the items of a batch are split over a thread budget.

Functions§

batch_decision
Decide the route for one batch on budget threads under policy.