pub enum ComputeOp {
MatmulTiles {
block: BlockShape,
sub_blocks: (usize, usize),
num_blocks: usize,
operand: Precision,
acc: AccPolicy,
dataflow: DataflowPolicy,
interm: Option<BufferId>,
granularity: Granularity,
},
Requant {
m: i64,
s: u32,
},
Bias {
bias: BufferId,
},
Relu,
Generic {
iters: Vec<IterSpec>,
ins: Vec<ElemAccess>,
out: ElemAccess,
body: TensorBody,
},
Scalar(ScalarBody),
}Variants§
MatmulTiles
Requant
Bias
Relu
Generic
★ THE GENERAL FORM — an iteration space, an affine access map per operand, and a scalar body.
Everything the vector/SFPU path does is one of these. The two facts that make it general:
A reduction is not an operator, it is an ITERATOR. An axis marked
IterKind::Reduce is folded away and does not appear in out.
A broadcast is not an operator, it is an ABSENT TERM. An operand whose map omits an
axis is CONSTANT along it. A per-row scalar omits the column axis; a per-column weight
omits the row axis. Two operators (RowRescale, RowBroadcast) become one map read two
ways, and the printer recovers mul_tiles_bcast_cols vs mul_tiles_bcast_rows from which
axis is missing — which is the compiler doing the work instead of a human naming the case.
The iteration space is at ELEMENT granularity (a row axis over the tile’s 32 rows, a column
axis over col_tiles * 32), because that is the only granularity at which a row reduction
and a column broadcast are expressible at all; tile-level indices cannot say “constant along
the columns inside a tile”.
Fields
ins: Vec<ElemAccess>One map per operand, positionally matching the stage’s ins.
out: ElemAccessbody: TensorBodyScalar(ScalarBody)
A scalar dataflow body applied element-wise over the input tiles (the choreography form of a
StageKind::Scalar stage).
Implementations§
Source§impl ComputeOp
impl ComputeOp
Sourcepub fn shape(&self) -> Result<ComputeShape<'_>, &'static str>
pub fn shape(&self) -> Result<ComputeShape<'_>, &'static str>
The op’s ComputeShape. A requant’s multiplier enters its body as a constant, which holds it exactly while it
is within ±2⁵³.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for ComputeOp
impl<'de> Deserialize<'de> for ComputeOp
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 Eq for ComputeOp
impl StructuralPartialEq for ComputeOp
Auto Trait Implementations§
impl Freeze for ComputeOp
impl RefUnwindSafe for ComputeOp
impl Send for ComputeOp
impl Sync for ComputeOp
impl Unpin for ComputeOp
impl UnsafeUnpin for ComputeOp
impl UnwindSafe for ComputeOp
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.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.