Skip to main content

Tensor

Struct Tensor 

Source
pub struct Tensor {
    pub name: String,
    pub dtype: DType,
    pub shape: Shape,
    pub param_id: Option<u64>,
    /* private fields */
}
Expand description

A single tensor in a burnpack container, decoupled from any tensor library.

The bytes are in little-endian layout, and are reached with to_bytes, into_bytes, or into_parts. Their length is available up front via byte_len whether or not they exist yet. For every dtype but DType::QFloat that length is the element count implied by shape and dtype; quantized data packs its values and appends scales inline, so it is not a product of the two.

Construct one with new when the data is already in memory, or deferred when it is not. A Reader produces resident tensors, though for a file-backed source the bytes are still only read from disk on access.

§Thread safety

On targets with pointer-width atomics, Tensor is Send + Sync whether its bytes are resident or deferred. Accordingly, deferred requires its provider to be Send + Sync on those targets. Without pointer-width atomics, deferred providers are held in an Rc, so Tensor implements neither trait.

Fields§

§name: String

Fully-qualified tensor name (e.g. "encoder.layer1.weight").

§dtype: DType

Data type of the tensor.

§shape: Shape

Tensor shape.

§param_id: Option<u64>

Optional parameter id, used to preserve identities for stateful training.

Implementations§

Source§

impl Tensor

Source

pub fn new( name: String, dtype: DType, shape: impl Into<Shape>, param_id: Option<u64>, bytes: Bytes, ) -> Self

Create a tensor from its metadata and raw bytes.

Source

pub fn deferred( name: String, dtype: DType, shape: impl Into<Shape>, param_id: Option<u64>, byte_len: usize, provider: impl Fn() -> Result<Bytes, Error> + Send + Sync + 'static, ) -> Self

Create a tensor whose bytes are produced on demand.

byte_len must equal the length of the Bytes provider eventually returns, since Writer reserves exactly that much space in the data section before calling it. Getting it wrong would misplace every later tensor, so it is checked twice: while planning, against shape and dtype, and while writing, against the bytes actually produced. Quantized data is exempt from the first, its length being packed values plus inline scales rather than a product of the two, so there the write-time check is the only guard.

provider runs at most once per write, when the writer reaches this tensor, and its result is dropped before the next tensor’s is requested. Producing the data there - reading a parameter back from a device, say - is what bounds a save’s peak host memory by the largest single tensor rather than by the whole model.

Source

pub fn byte_len(&self) -> usize

Number of raw bytes the tensor occupies, known without producing them.

Source

pub fn to_bytes(&self) -> Result<Bytes, Error>

The tensor’s raw little-endian bytes, leaving it intact.

Named to_ rather than bytes because it can cost the whole tensor: a Deferred one re-runs its provider (nothing is cached), and a Resident one is deep-copied unless its Bytes can share their backing. Prefer into_bytes, or into_parts when the metadata is wanted too.

Source

pub fn into_bytes(self) -> Result<Bytes, Error>

Take the tensor’s raw little-endian bytes, producing them if deferred.

Infallible in practice for a tensor from a Reader, which only produces resident tensors; the Result is there for deferred ones, whose provider can fail.

Source

pub fn into_parts( self, ) -> Result<(String, DType, Shape, Option<u64>, Bytes), Error>

Split into (name, dtype, shape, param_id, bytes), producing the bytes if deferred.

The fields are public, but taking the bytes consumes the tensor, so reading both otherwise means cloning the metadata first. This hands over everything in one move.

Trait Implementations§

Source§

impl Clone for Tensor

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 Tensor

Shows the format-level metadata and the byte length, but never draws the bytes: a Deferred tensor would have to run its provider, which is exactly what a debug print must not trigger.

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> 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.