pub struct TensorHandle<T>{
pub repr: TensorRepr<T>,
pub axes: Vec<AxisMeta>,
}Expand description
Main tensor handle unifying all representations.
TensorHandle provides a unified interface for working with tensors regardless
of their internal representation (dense, sparse, or low-rank). This enables
polymorphic tensor operations and automatic representation selection.
§Design Goals
- Unified API: Same interface for dense, sparse, and low-rank tensors
- Metadata Tracking: Axis names and sizes for better debugging
- Type Safety: Compile-time guarantees about tensor properties
- Zero-Cost Abstraction: No runtime overhead when representation is known
§Examples
§Creating from Dense Tensors
use tenrso_core::{DenseND, TensorHandle, AxisMeta};
// With explicit axis metadata
let tensor = DenseND::<f64>::zeros(&[32, 128]);
let axes = vec![
AxisMeta::new("batch", 32),
AxisMeta::new("features", 128),
];
let handle = TensorHandle::from_dense(tensor, axes);
assert_eq!(handle.rank(), 2);
assert_eq!(handle.axes[0].name, "batch");§Automatic Axis Naming
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::ones(&[2, 3, 4]);
let handle = TensorHandle::from_dense_auto(tensor);
// Axes are named "axis_0", "axis_1", "axis_2"
assert_eq!(handle.axes[0].name, "axis_0");
assert_eq!(handle.axes[1].name, "axis_1");
assert_eq!(handle.axes[2].name, "axis_2");§Querying Tensor Properties
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::zeros(&[10, 20, 30]);
let handle = TensorHandle::from_dense_auto(tensor);
// Get rank and shape
assert_eq!(handle.rank(), 3);
assert_eq!(handle.shape().as_slice(), &[10, 20, 30]);
// Access the underlying dense tensor
if let Some(dense) = handle.as_dense() {
assert_eq!(dense.len(), 6000);
}§Converting Between Representations
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::random_uniform(&[5, 5], 0.0, 1.0);
let handle = TensorHandle::from_dense_auto(tensor);
// Convert to dense (no-op if already dense)
let dense = handle.to_dense().unwrap();
assert_eq!(dense.shape(), &[5, 5]);Fields§
§repr: TensorRepr<T>Internal representation (Dense/Sparse/LowRank)
axes: Vec<AxisMeta>Axis metadata with symbolic names and sizes
Implementations§
Source§impl<T> TensorHandle<T>
impl<T> TensorHandle<T>
Sourcepub fn from_dense(dense: DenseND<T>, axes: Vec<AxisMeta>) -> TensorHandle<T>
pub fn from_dense(dense: DenseND<T>, axes: Vec<AxisMeta>) -> TensorHandle<T>
Create a tensor handle from a dense tensor
§Arguments
dense- The dense tensoraxes- Axis metadata (must match tensor shape)
§Examples
use tenrso_core::{DenseND, TensorHandle, AxisMeta};
let tensor = DenseND::<f64>::zeros(&[2, 3]);
let axes = vec![
AxisMeta::new("rows", 2),
AxisMeta::new("cols", 3),
];
let handle = TensorHandle::from_dense(tensor, axes);
assert_eq!(handle.rank(), 2);Sourcepub fn from_dense_auto(dense: DenseND<T>) -> TensorHandle<T>
pub fn from_dense_auto(dense: DenseND<T>) -> TensorHandle<T>
Create a tensor handle from a dense tensor with automatic axis naming
Axes are named “axis_0”, “axis_1”, etc.
§Examples
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::zeros(&[2, 3, 4]);
let handle = TensorHandle::from_dense_auto(tensor);
assert_eq!(handle.rank(), 3);
assert_eq!(handle.axes[0].name, "axis_0");Sourcepub fn shape(&self) -> SmallVec<[usize; 6]>
pub fn shape(&self) -> SmallVec<[usize; 6]>
Get the shape of this tensor.
Returns a SmallVec containing the size of each dimension.
§Complexity
O(rank) - constructs SmallVec from axis metadata
§Examples
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::zeros(&[10, 20, 30]);
let handle = TensorHandle::from_dense_auto(tensor);
let shape = handle.shape();
assert_eq!(shape.as_slice(), &[10, 20, 30]);Sourcepub fn as_dense(&self) -> Option<&DenseND<T>>
pub fn as_dense(&self) -> Option<&DenseND<T>>
Get a reference to the dense representation if this is a dense tensor.
Returns None if the tensor is stored in sparse or low-rank format.
§Complexity
O(1) - pattern matching on enum variant
§Examples
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::ones(&[5, 5]);
let handle = TensorHandle::from_dense_auto(tensor);
// Access the underlying dense tensor
if let Some(dense) = handle.as_dense() {
assert_eq!(dense.shape(), &[5, 5]);
assert_eq!(dense.len(), 25);
}Sourcepub fn as_dense_mut(&mut self) -> Option<&mut DenseND<T>>
pub fn as_dense_mut(&mut self) -> Option<&mut DenseND<T>>
Get a mutable reference to the dense representation if this is a dense tensor.
Returns None if the tensor is stored in sparse or low-rank format.
§Complexity
O(1) - pattern matching on enum variant
§Examples
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::zeros(&[3, 3]);
let mut handle = TensorHandle::from_dense_auto(tensor);
// Modify the underlying dense tensor
if let Some(dense) = handle.as_dense_mut() {
dense.as_array_mut()[[0, 0]] = 1.0;
}
assert_eq!(handle.as_dense().unwrap()[&[0, 0]], 1.0);Sourcepub fn to_dense(&self) -> Result<DenseND<T>, Error>
pub fn to_dense(&self) -> Result<DenseND<T>, Error>
Convert this tensor to dense representation if not already dense.
For dense tensors, this clones the underlying data. For sparse and low-rank tensors, this will be implemented in future releases.
§Complexity
- Dense: O(n) where n is the number of elements (clone operation)
- Sparse: Not yet implemented
- LowRank: Not yet implemented
§Errors
Returns an error if the tensor is sparse or low-rank (not yet implemented).
§Examples
use tenrso_core::{DenseND, TensorHandle};
let tensor = DenseND::<f64>::ones(&[4, 4]);
let handle = TensorHandle::from_dense_auto(tensor);
// Convert to dense (clones the data)
let dense = handle.to_dense().unwrap();
assert_eq!(dense.shape(), &[4, 4]);
assert_eq!(dense.len(), 16);Trait Implementations§
Source§impl<T> Clone for TensorHandle<T>
impl<T> Clone for TensorHandle<T>
Source§fn clone(&self) -> TensorHandle<T>
fn clone(&self) -> TensorHandle<T>
1.0.0§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl<T> Freeze for TensorHandle<T>
impl<T> RefUnwindSafe for TensorHandle<T>where
T: RefUnwindSafe,
impl<T> Send for TensorHandle<T>where
T: Send,
impl<T> Sync for TensorHandle<T>where
T: Sync,
impl<T> Unpin for TensorHandle<T>where
T: Unpin,
impl<T> UnwindSafe for TensorHandle<T>where
T: UnwindSafe + RefUnwindSafe,
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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