pub enum Objective {
Balanced,
Traffic,
Transactions,
Issue,
Weighted {
per_byte: f64,
per_txn: f64,
per_inst: f64,
},
Roofline(Rates),
}Variants§
Balanced
The shared resource, then the arithmetic spread, then the movement spread, then transactions.
The default, and here is the whole argument, in the order the terms bind.
- DRAM is SHARED. Wormhole has six channels against sixty-four sites, so a plan whose sites each fetch their own operands leans on the one resource nobody can add more of. It leads.
- The busiest site’s ARITHMETIC. A plan that reads DRAM once and then does all the multiplying on a handful of cores ties on the first term and is obviously wrong — it is not using the machine. This is why the fabric has sixty-four sites at all, so it comes second, and it is what refuses the single-site plan that minimizing traffic alone walks straight into.
- The busiest MOVEMENT ENGINE. Two sites can move the same tiles and still differ: issuing both operand reads on one engine serialises them, pairing the second with the store overlaps a block’s write with the next block’s reads. The busier engine paces the site.
- The matrix engine’s calls, then the operand tiles it loads. Same bytes, same arithmetic: a sub-block that covers eight tiles per call asks for an eighth of the calls a one-tile sub-block does, and at equal calls the sub-block’s shape decides what the engine loads, by its own rule.
- Transactions. Same tiles, same engines, different block depth — this is what is left, and it is last because it is the axis the model knows least about.
Nothing here is tuned. It is lexicographic over exact integer counts and invents no rate, no bandwidth and no energy constant; the only machine facts it leans on are that DRAM is shared, that sites are not, and how many movement engines a site has.
It ranks only admissible plans: a ragged grid is one only where no evenly divided plan beats it on
every predicted total (admissible).
Traffic
The whole device’s movement, whatever the spread.
★ AND IT COLLAPSES ONTO ONE SITE, which is worth stating rather than hiding. A single site reads
each operand tile exactly once — that IS the traffic minimum — so asking only for less traffic
asks for no parallelism. Measured at 512^3: this picks a 16x16 per-site block on ONE core,
1,572,864 bytes against Balanced’s 2,621,952. It is a real corner of the frontier and it is
occasionally what someone wants (a batch of tiny problems, one per core); it is not a default,
and calling it “energy” would have been a lie, because energy is power times TIME.
Transactions
Transactions first, for a NOC limited by requests in flight rather than by bytes.
Issue
Issue slots first, for a fabric whose instruction bandwidth binds before its NOC does.
Weighted
An explicit per-event weighting — it takes its numbers from the caller rather than from a fit.
Roofline(Rates)
The roofline: the plan whose slowest resource finishes first, each count of the work over the cited
roof of the resource it loads (super::roofs::Rates), with Balanced’s key as the exact tiebreak.
It prices what Balanced only orders. Balanced puts DRAM bytes ahead of the busiest site’s
arithmetic whatever the two cost; the roofline asks which of them the chip will wait on, at rates read
from the vendor’s own documents, so a plan that moves a few more bytes to spread the arithmetic wins
exactly when the arithmetic is the bound. A resource with no roof is not priced. The cycles are rounded
up to a whole cycle, so the rates decide which plans tie and the counts order the ties exactly.
Implementations§
Source§impl Objective
impl Objective
Sourcepub const ALL: [Objective; 4]
pub const ALL: [Objective; 4]
Every objective, for reporting the frontier rather than a single winner.
Sourcepub fn roofline(target: &SpatialTarget, element: Precision) -> Objective
pub fn roofline(target: &SpatialTarget, element: Precision) -> Objective
The roofline objective for programs whose traffic and operands are elements on target.
Sourcepub fn key(self, w: &Work) -> RankKey
pub fn key(self, w: &Work) -> RankKey
Rank a plan’s work; lower is better: exact counts compared in order, most significant first, each in a place of its own and the unused places zero. The integer variants compare EXACTLY — no float rounding ever decides a plan — the weighted one is scaled and rounded once, at the end, and the roofline’s bound is rounded up to a whole cycle before the exact counts break its ties.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Objective
impl<'de> Deserialize<'de> for Objective
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Copy for Objective
impl StructuralPartialEq for Objective
Auto Trait Implementations§
impl Freeze for Objective
impl RefUnwindSafe for Objective
impl Send for Objective
impl Sync for Objective
impl Unpin for Objective
impl UnsafeUnpin for Objective
impl UnwindSafe for Objective
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.