pub struct Template { /* private fields */ }Expand description
A template under construction: tensors, stages, buffers and local hand-off edges, in id order.
★ THE ONE BUILDER EVERY TEMPLATE COMES FROM — the recognized workloads below, the B-P4 Qwen
compositions, and the hand-built probes of spatial_algebra_expansion_lock. Building a stage any
other way is how two programs end up disagreeing about what a stage IS.
Implementations§
Source§impl Template
impl Template
pub fn new(target: &SpatialTarget) -> Result<Template, SpatialReject>
Sourcepub fn trip(&mut self, trip: Trip) -> TripId
pub fn trip(&mut self, trip: Trip) -> TripId
Declare a loop count the program reads from its data (Trip).
pub fn tensor( &mut self, name: &str, role: TensorRole, rows: usize, cols: usize, dtype: Precision, init: TensorInit, ) -> TensorId
pub fn buffer( &mut self, name: &str, page_tiles: usize, dtype: Precision, ) -> BufferId
Sourcepub fn buffer_deep(
&mut self,
name: &str,
depth_pages: usize,
page_tiles: usize,
dtype: Precision,
) -> BufferId
pub fn buffer_deep( &mut self, name: &str, depth_pages: usize, page_tiles: usize, dtype: Precision, ) -> BufferId
A buffer that lives only between two compute stages. It is neither filled by a reader nor
drained by a writer, so it takes the intermediate circular-buffer class rather than an
operand or output slot.
A hand-off of an explicit DEPTH. Double buffering is the right default — it lets a producer fill
page n+1 while the consumer drains page n — but it costs twice the local memory, and a stage
whose page is consumed by the very next stage in its own item never overlaps anything. A section
that fans into many sub-blocks pays that doubling once per operand per sub-block, which is how a
426 KB site budget disappears.
Sourcepub fn scratch_deep(
&mut self,
name: &str,
depth_pages: usize,
page_tiles: usize,
dtype: Precision,
) -> BufferId
pub fn scratch_deep( &mut self, name: &str, depth_pages: usize, page_tiles: usize, dtype: Precision, ) -> BufferId
Template::scratch with an explicit depth.
pub fn scratch( &mut self, name: &str, page_tiles: usize, dtype: Precision, ) -> BufferId
pub fn stage( &mut self, name: &str, kind: StageKind, ins: Vec<BufferId>, outs: Vec<BufferId>, ) -> StageId
Sourcepub fn load(
&mut self,
name: &str,
tensor: TensorId,
steps: Vec<(LoopVar, usize)>,
block_w: usize,
out: BufferId,
) -> StageId
pub fn load( &mut self, name: &str, tensor: TensorId, steps: Vec<(LoopVar, usize)>, block_w: usize, out: BufferId, ) -> StageId
A load of block_w tiles of one tile-row of tensor, addressed by the item’s coordinates.
Sourcepub fn load_block(
&mut self,
name: &str,
tensor: TensorId,
steps: Vec<(LoopVar, usize)>,
block_h: usize,
block_w: usize,
stride_h: usize,
out: BufferId,
) -> StageId
pub fn load_block( &mut self, name: &str, tensor: TensorId, steps: Vec<(LoopVar, usize)>, block_h: usize, block_w: usize, stride_h: usize, out: BufferId, ) -> StageId
A load of a block_h x block_w TILE BLOCK whose rows are stride_h tiles apart — the shape a
strided view needs when the rows it wants are not adjacent in the tensor. A causal conv’s ring is
taps x chan flattened, so one channel block’s taps sit chan/tile tiles apart.
Sourcepub fn store_block(
&mut self,
name: &str,
tensor: TensorId,
base: usize,
steps: Vec<(LoopVar, usize)>,
block_h: usize,
block_w: usize,
stride_h: usize,
input: BufferId,
) -> StageId
pub fn store_block( &mut self, name: &str, tensor: TensorId, base: usize, steps: Vec<(LoopVar, usize)>, block_h: usize, block_w: usize, stride_h: usize, input: BufferId, ) -> StageId
The store twin of Template::load_block, with an explicit tile base — the constant part of
an address whose variable part is the item’s coordinate.
Sourcepub fn store_block_over(
&mut self,
name: &str,
tensor: TensorId,
base: usize,
steps: Vec<(LoopVar, usize)>,
block_h: usize,
block_w: usize,
stride_h: usize,
sub_blocks: (usize, usize),
input: BufferId,
) -> StageId
pub fn store_block_over( &mut self, name: &str, tensor: TensorId, base: usize, steps: Vec<(LoopVar, usize)>, block_h: usize, block_w: usize, stride_h: usize, sub_blocks: (usize, usize), input: BufferId, ) -> StageId
Template::store_block over the item’s sub_blocks — the extent the pattern’s LV_SUB_H / LV_SUB_W steps
walk. ★ A TEMPLATE STATES WHAT ITS PLAN SAYS: placement reshapes only the store of the section’s result to a
site’s block, so every other store’s sub-blocks are the template’s, and the coverage check reads them.
Sourcepub fn load_block_at(
&mut self,
name: &str,
tensor: TensorId,
base: usize,
steps: Vec<(LoopVar, usize)>,
block_h: usize,
block_w: usize,
stride_h: usize,
out: BufferId,
) -> StageId
pub fn load_block_at( &mut self, name: &str, tensor: TensorId, base: usize, steps: Vec<(LoopVar, usize)>, block_h: usize, block_w: usize, stride_h: usize, out: BufferId, ) -> StageId
Template::load_block with an explicit tile base.
pub fn store( &mut self, name: &str, tensor: TensorId, steps: Vec<(LoopVar, usize)>, block_w: usize, input: BufferId, ) -> StageId
Sourcepub fn stage_reads(&self, s: StageId, b: BufferId) -> bool
pub fn stage_reads(&self, s: StageId, b: BufferId) -> bool
Whether a stage names a buffer among its operands (a chain wires by this, not by position).
Sourcepub fn stage_output(&self, s: StageId) -> BufferId
pub fn stage_output(&self, s: StageId) -> BufferId
The buffer a chain stage writes.
Sourcepub fn page_tiles(&self, b: BufferId) -> usize
pub fn page_tiles(&self, b: BufferId) -> usize
Tiles per page of a buffer — the page WIDTH every flat access map is taken over.
Sourcepub fn edge_many(&mut self, from: StageId, buffer: BufferId, to: Vec<StageId>)
pub fn edge_many(&mut self, from: StageId, buffer: BufferId, to: Vec<StageId>)
One hand-off read by SEVERAL stages. A buffer has exactly one producing EDGE, not one per consumer — a fan-out is a single edge with a list of readers, which is also what the choreography needs in order to pop the page once rather than once per reader.
pub fn edge(&mut self, from: StageId, buffer: BufferId, to: StageId)
pub fn finish( self, name: String, items: Vec<WorkItem>, acc: AccPolicy, claim: NumericsClaim, target: &SpatialTarget, ) -> Result<SpatialProgram, SpatialReject>
Auto Trait Implementations§
impl Freeze for Template
impl RefUnwindSafe for Template
impl Send for Template
impl Sync for Template
impl Unpin for Template
impl UnsafeUnpin for Template
impl UnwindSafe for Template
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
§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.