Skip to main content

Linear

Struct Linear 

Source
pub struct Linear { /* private fields */ }
Expand description

Minimal inlined Linear layer, lazy.

Computes y = x @ W + b, delegating to WeightStorage::apply_linear — the same builder every lazy model in fuel-core uses. That buys F32, BF16, Q4_0 and LoRA weights for free; a hand-rolled const_f32_like + matmul here would have been f32-only.

§Weight layout — CHANGED from the eager version

[in_features, out_features], applied as x @ W.

The eager Linear this replaces stored [out_features, in_features] and computed x @ W.t() (PyTorch’s nn.Linear convention). WeightStorage uses the transposed layout, and adopting it is what makes the quantized and LoRA paths reachable. The difference is silent — feeding [out, in] data to a square layer produces a wrong answer rather than an error — so it is called out here rather than left to be discovered.

fuel-parallel has no consumers today, so nothing in-tree breaks.

§Why host storage rather than a Tensor weight

Tensor is graph-affine: two tensors combine iff they share a graph. A Linear holding a Tensor weight could only ever be applied to inputs on that one graph — useless for a model that builds a fresh graph per step, which is exactly what Fuel’s lazy decode path does. WeightStorage materializes onto the input’s graph at forward time, so one Linear serves any number of graphs.

Implementations§

Source§

impl Linear

Source

pub fn new( weight: WeightStorage, in_features: usize, out_features: usize, bias: Option<Arc<[f32]>>, ) -> Result<Self>

Build from a WeightStorage laid out [in_features, out_features].

Returns Err on a size mismatch rather than deferring it: the apply_linear path this delegates to reports mismatches via assert_eq!/unwrap(), which would be a panic on a production path. Validating here keeps Fuel’s never-panic rule intact.

The element-count check applies to F32/BF16 only — a Q4_0 weight’s elem_count counts packed u32 words, not logical elements, so its dimensions are checked by WeightStorage itself against the values stored in the variant.

Source

pub fn from_f32( weight: impl Into<Arc<[f32]>>, in_features: usize, out_features: usize, bias: Option<Arc<[f32]>>, ) -> Result<Self>

Convenience constructor for a plain f32 weight, [in_features, out_features].

Source

pub fn features(&self) -> (usize, usize)

(in_features, out_features).

Source

pub fn forward(&self, x: &Tensor) -> Result<Tensor>

Forward: y = x @ W + b, built on x’s graph.

The eager original branched on x.is_contiguous() and hand-picked between a reshape-then-matmul and a broadcast matmul, “to avoid a broadcasted matmul — it’s much slower”. That is a dispatch-time optimisation, and in a lazy DAG choosing it here would be the model layer making a strategy decision that belongs to the optimizer. Lazy matmul is N-D batched with rank-2 broadcasting, so the whole dance collapses to one delegated call and the optimizer keeps its job.

Trait Implementations§

Source§

impl Clone for Linear

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Linear

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more