Skip to main content

ErasedHostTensor

Struct ErasedHostTensor 

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

A host tensor whose element type is recovered at run time.

The payload keeps its own concrete type and is recovered by identity, so no byte reinterpretation happens and a caller-owned payload is duplicated through its own entry point rather than by copying bytes.

The value also carries the layout of the view it presents. Clone shares that payload, so a metadata-only permutation is cheap; duplicate copies it, so a caller that needs its own storage asks for one explicitly. A typed read applies the layout, and the dense accessors refuse a strided view instead of presenting the payload as if it were the view.

§Examples

use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let value = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2], vec![1.0_f64, 2.0])?);
assert_eq!(value.downcast_ref::<f64>().unwrap().as_slice(), &[1.0, 2.0]);
assert_eq!(value.clone().element_count(), 2);

Implementations§

Source§

impl ErasedHostTensor

Source

pub fn new<T: Scalar>(value: TypedTensor<T, DynRank, Host>) -> Self

Erase a host tensor’s element type.

The result presents the tensor’s dense column-major layout.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![7_i32])?);
assert!(erased.is::<i32>());
Source

pub fn type_id(&self) -> TypeId

Identity of the stored element type.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![1.0_f32])?);
assert_eq!(erased.type_id(), core::any::TypeId::of::<TypedTensor<f32, DynRank, Host>>());
Source

pub fn element_type_id(&self) -> TypeId

Identity of the stored element type, without the tensor wrapper.

This is what a runtime tag reports for an externally defined scalar.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![1.0_f64])?);
assert_eq!(erased.element_type_id(), core::any::TypeId::of::<f64>());
Source

pub fn shape(&self) -> &[usize]

Shape of the presented view.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 3], vec![0.0_f64; 6])?);
assert_eq!(erased.shape(), &[2, 3]);
Source

pub fn strides(&self) -> &[isize]

Element strides of the presented view.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 3], vec![0.0_f64; 6])?);
assert_eq!(erased.strides(), &[1, 2]);
Source

pub fn offset(&self) -> isize

Element offset of the presented view.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2], vec![0.0_f64; 2])?);
assert_eq!(erased.offset(), 0);
Source

pub fn is_contiguous(&self) -> bool

Whether the presented view is the dense column-major layout of its shape.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 3], vec![0.0_f64; 6])?);
assert!(erased.is_contiguous());
Source

pub fn element_count(&self) -> usize

Number of elements in the presented view.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 3], vec![0.0_f64; 6])?);
assert_eq!(erased.element_count(), 6);
Source

pub fn shares_payload_with(&self, other: &Self) -> bool

Whether two erased values present the same stored payload.

A metadata-only view answers true, and an independent copy answers false.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![1.0_f64])?);
assert!(erased.shares_payload_with(&erased.clone()));
assert!(!erased.shares_payload_with(&erased.duplicate()));
Source

pub fn duplicate(&self) -> Self

Copy the payload into an independent value with the same view.

The copy is the caller’s own storage, so later mutation of either value leaves the other unchanged.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![1.0_f64])?);
let mut copy = erased.duplicate();
copy.downcast_mut::<f64>().unwrap().host_data_mut()[0] = 5.0;
assert_eq!(erased.as_dense::<f64>().unwrap().0, &[1.0]);
Source

pub fn permuted(&self, axes: &[usize]) -> Result<Self>

Present the same elements under a permuted axis order.

This is metadata only: the payload is shared, no element is moved, and the result’s shape and strides follow axes.

§Errors

Returns a validation error carrying tenferro_tensor_core::ValidationError::InvalidPermutationLength when axes does not have one entry per axis, tenferro_tensor_core::ValidationError::AxisOutOfBounds when an axis is out of range, or tenferro_tensor_core::ValidationError::DuplicateAxis when an axis repeats.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 3], vec![0.0_f64; 6])?);
let permuted = erased.permuted(&[1, 0])?;
assert_eq!(permuted.shape(), &[3, 2]);
assert_eq!(permuted.strides(), &[2, 1]);
assert!(permuted.shares_payload_with(&erased));
Source

pub fn to_contiguous(&self) -> Result<Self>

Materialize the presented view into a dense column-major payload.

The result owns its elements in the view’s axis order, so a subsequent read with the dense accessors returns the same logical values in a contiguous buffer.

§Errors

Returns a validation error carrying tenferro_tensor_core::ValidationError::ShapeDataLengthMismatch when the view names storage the payload does not have.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?);
let contiguous = erased.permuted(&[1, 0])?.to_contiguous()?;
assert_eq!(contiguous.shape(), &[2, 2]);
assert!(contiguous.is_contiguous());
assert_eq!(contiguous.as_dense::<f64>().unwrap().0, &[1.0, 3.0, 2.0, 4.0]);
Source

pub fn is<T: Scalar>(&self) -> bool

Whether the stored tensor has element type T.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![1.0_f64])?);
assert!(erased.is::<f64>());
Source

pub fn downcast_ref<T: Scalar>(&self) -> Option<&TypedTensor<T, DynRank, Host>>

Borrow the whole payload when it is dense and has element type T.

A strided view answers None rather than presenting the payload as if it were the view. Use ErasedHostTensor::element_at or ErasedHostTensor::to_contiguous for a view.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?);
assert_eq!(erased.downcast_ref::<f64>().unwrap().shape(), &[2, 2]);

// A strided view is not the dense payload, so the dense borrow refuses it.
assert!(erased.permuted(&[1, 0])?.downcast_ref::<f64>().is_none());
Source

pub fn downcast_mut<T: Scalar>( &mut self, ) -> Option<&mut TypedTensor<T, DynRank, Host>>

Mutably borrow the whole payload when it is dense, unique, and has element type T.

A strided view or a payload shared with another value answers None, so aliasing is never reachable through this entry point. Use ErasedHostTensor::element_at_mut for a view.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let mut erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![1_i64])?);
erased.downcast_mut::<i64>().unwrap().host_data_mut()[0] = 9;
assert_eq!(erased.downcast_ref::<i64>().unwrap().as_slice(), &[9]);
Source

pub fn into_typed<T: Scalar>(self) -> Option<TypedTensor<T, DynRank, Host>>

Take the whole payload when it is dense and has element type T.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![2.0_f64])?);
assert_eq!(erased.into_typed::<f64>().unwrap().as_slice(), &[2.0]);
Source

pub fn payload_element_count(&self) -> usize

Number of elements the stored payload holds.

A strided view may reach fewer than all of them, so this is the extent a buffer-length check must use rather than the view’s own count.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 2], vec![0.0_f64; 4])?);
assert_eq!(erased.payload_element_count(), 4);
Source

pub fn as_dense<T: Scalar>(&self) -> Option<(&[T], &[usize])>

Borrow the dense element slice and its shape when the view is contiguous and has element type T.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2], vec![1.0_f64, 2.0])?);
assert_eq!(erased.as_dense::<f64>().unwrap().0, &[1.0, 2.0]);
Source

pub fn element_at<T: Scalar>(&self, index: &[usize]) -> Option<&T>

Borrow one element of the presented view by logical index.

This applies the view’s strides and offset, so it reads the element the view names even when the view is not contiguous.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?);
let permuted = erased.permuted(&[1, 0])?;
assert_eq!(permuted.element_at::<f64>(&[1, 0]), Some(&3.0));
assert_eq!(permuted.element_at::<f64>(&[2, 0]), None);
Source

pub fn element_at_mut<T: Scalar>(&mut self, index: &[usize]) -> Option<&mut T>

Mutably borrow one element of the presented view by logical index.

This applies the view’s strides and offset. It answers None when the payload is shared with another value, so two live views never produce two mutable borrows of one element. A writer therefore holds the only reference: build the view, release the value it came from, and mutate through the view, or call ErasedHostTensor::duplicate for a payload of its own.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let erased = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0])?);

// A view that shares its payload refuses a mutable element borrow.
let mut shared = erased.permuted(&[1, 0])?;
assert!(shared.element_at_mut::<f64>(&[1, 0]).is_none());

// An independent copy accepts it, and the original stays unchanged.
let mut owned = erased.permuted(&[1, 0])?.duplicate();
*owned.element_at_mut::<f64>(&[1, 0]).unwrap() = 20.0;
assert_eq!(owned.element_at::<f64>(&[1, 0]), Some(&20.0));
assert_eq!(erased.as_dense::<f64>().unwrap().0, &[1.0, 2.0, 3.0, 4.0]);

Trait Implementations§

Source§

impl Clone for ErasedHostTensor

Source§

fn clone(&self) -> Self

Share the payload and copy only the layout metadata.

This is a metadata-only operation, so it is what a permutation and a metadata view use. Use ErasedHostTensor::duplicate for an independent copy of the storage.

§Examples
use tenferro_tensor::{DynRank, ErasedHostTensor, Host, TypedTensor};

let value = ErasedHostTensor::new(TypedTensor::<_, DynRank, Host>::from_host_vec_col_major(vec![1], vec![7_i64])?);
let view = value.clone();
assert!(view.shares_payload_with(&value));
assert!(!view.duplicate().shares_payload_with(&value));
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for ErasedHostTensor

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<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> 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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.