Skip to main content

TensorTrait

Trait TensorTrait 

Source
pub trait TensorTrait<T>: Send + Sync
where T: Num + Clone + Debug,
{
Show 19 methods // Required methods fn new(shape: &[usize], name: Option<&str>) -> Result<Self> where Self: Sized; fn from_fd(fd: OwnedFd, shape: &[usize], name: Option<&str>) -> Result<Self> where Self: Sized; fn clone_fd(&self) -> Result<OwnedFd>; fn memory(&self) -> TensorMemory; fn name(&self) -> String; fn shape(&self) -> &[usize]; fn reshape(&mut self, shape: &[usize]) -> Result<()>; fn map_with(&self, access: CpuAccess) -> Result<TensorMap<T>>; fn buffer_identity(&self) -> &BufferIdentity; // Provided methods fn len(&self) -> usize { ... } fn is_empty(&self) -> bool { ... } fn size(&self) -> usize { ... } fn capacity_bytes(&self) -> usize { ... } fn set_logical_shape(&mut self, shape: &[usize]) -> Result<()> { ... } fn map(&self) -> Result<TensorMap<T>> { ... } fn map_read(&self) -> Result<TensorMap<T>> { ... } fn map_write(&self) -> Result<TensorMap<T>> { ... } fn map_mut(&self) -> Result<TensorMap<T>> { ... } fn view(&self, offset_bytes: usize, shape: &[usize]) -> Result<Self> where Self: Sized { ... }
}
Expand description

The operations every memory backend implements.

This is the seam that lets Tensor<T> hide which backend is in play. The implementors are DmaTensor (Linux DMA-BUF), IoSurfaceTensor (macOS/iOS), AHardwareBufferTensor (Android), ShmTensor, MemTensor, and PboTensor; TensorStorage<T> dispatches to whichever is active. Backend types are not public — allocate a Tensor<T> or TensorDyn and call these methods through it.

Import the trait to get shape, size, map, clone_fd, buffer_identity, and the zero-copy sub-region view on a tensor value. Tensor::view and Tensor::batch route through TensorTrait::view, so each backend’s identity-sharing rule lives in exactly one place.

Required Methods§

Source

fn new(shape: &[usize], name: Option<&str>) -> Result<Self>
where Self: Sized,

Create a new tensor with the given shape and optional name. If no name is given, a random name will be generated.

Source

fn from_fd(fd: OwnedFd, shape: &[usize], name: Option<&str>) -> Result<Self>
where Self: Sized,

Import an existing buffer as a tensor, taking ownership of its file descriptor. The buffer is adopted in place — no bytes are copied.

The backend is detected, not chosen: the fd already belongs to a buffer type, and this call’s job is to recognize which. On Linux that is decided by the fd’s filesystem magic, which is stable UAPI (include/uapi/linux/magic.h):

FilesystemMagicResulting TensorMemory
dma_bufDMA_BUF_MAGIC (0x444d4142)TensorMemory::Dma
tmpfs (/dev/shm and memfd)TMPFS_MAGIC (0x01021994)TensorMemory::Shm
anything elserejected — see Errors

Both supported types are identified positively. An unrecognized filesystem is an error, never a fallback to shared memory: the wrong branch does not fail loudly (a DMA-BUF is mmap-able, so it would import as a perfectly functional tensor that merely isn’t DMA, and a pipe would import as a zero-length one), so guessing would trade a clear error here for silent loss of zero-copy far downstream.

The device number is deliberately not consulted. dma_buf files live on an internal kernel mount whose st_dev comes from get_anon_bdev() — an IDA shared with every other anonymous pseudo-filesystem and allocated in boot order — so the minor a DMA-BUF lands on varies by kernel build and is not part of any ABI.

On non-Linux Unix (macOS/iOS/Android) there is no fd-based DMA import; the fd is always adopted as TensorMemory::Shm.

§Arguments
  • fd - Owned descriptor for the buffer to import. Ownership transfers to the returned tensor and the fd is closed on drop; pass clone_fd output to keep your own handle.
  • shape - Logical shape to interpret the buffer with. Must describe no more elements than the buffer holds.
  • name - Optional name; a random one is generated when None.
§Returns

A tensor sharing the imported buffer’s memory, whose memory() reports the detected backend.

§Errors
  • Error::UnknownBufferType - the fd is on a filesystem that is neither dma_buf nor tmpfs, so its buffer type cannot be determined. Carries the observed fstatfs magic as a u32, normalized so it can be looked up in magic.h directly on both 32- and 64-bit targets. Typical causes: a regular file, a pipe or socket, or a MFD_HUGETLB memfd (hugetlbfs, not tmpfs). Linux only.
  • Error::UnknownDeviceType - the fd’s st_dev major is non-zero, i.e. it lives on a real block device rather than an anonymous or in-memory filesystem. Linux only.
  • Error::InvalidSize - shape is empty or describes zero elements.
  • Error::NixError - fstat, fstatfs, or mmap failed on the descriptor.
§Examples
use edgefirst_tensor::{Tensor, TensorMemory, TensorTrait};

let src = Tensor::<u8>::new(&[480, 640, 3], Some(TensorMemory::Dma), None)?;

// Round-tripping a DMA-BUF fd preserves the backend — the import is
// still zero-copy, and still eligible for GPU/NPU paths.
let imported = Tensor::<u8>::from_fd(src.clone_fd()?, src.shape(), None)?;
assert_eq!(imported.memory(), TensorMemory::Dma);
Source

fn clone_fd(&self) -> Result<OwnedFd>

Clone the file descriptor associated with this tensor.

Source

fn memory(&self) -> TensorMemory

Get the memory type of this tensor.

Source

fn name(&self) -> String

Get the name of this tensor.

Source

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

Get the shape of this tensor.

Source

fn reshape(&mut self, shape: &[usize]) -> Result<()>

Reshape this tensor to the given shape. The total number of elements must remain the same.

Source

fn map_with(&self, access: CpuAccess) -> Result<TensorMap<T>>

Map the tensor into memory with the given access direction and return a TensorMap for accessing the data.

access selects the platform mapping mode (read-only IOSurface lock, dma-buf sync direction, AHardwareBuffer lock usage) and the map’s mutability: a map obtained with CpuAccess::Read rejects as_mut_slice. CpuAccess::None is not a mappable direction and returns Error::InvalidArgument.

Prefer the typed wrappers map_read / map_write / map_mut.

Source

fn buffer_identity(&self) -> &BufferIdentity

Get the buffer identity for cache keying and liveness tracking.

Provided Methods§

Source

fn len(&self) -> usize

Get the number of elements in this tensor.

Source

fn is_empty(&self) -> bool

Check if the tensor is empty.

Source

fn size(&self) -> usize

Get the size in bytes of this tensor.

Source

fn capacity_bytes(&self) -> usize

Bytes of the underlying allocation (>= the current logical size()). Defaults to the logical size for storages without spare capacity.

Source

fn set_logical_shape(&mut self, shape: &[usize]) -> Result<()>

Set the logical shape to any shape whose byte size fits the allocation capacity, without the equal-size constraint of reshape.

Source

fn map(&self) -> Result<TensorMap<T>>

Map the tensor read-write (equivalent to map_with(CpuAccess::ReadWrite) — the historical map() behavior).

Source

fn map_read(&self) -> Result<TensorMap<T>>

Map the tensor for CPU reading only. The returned map rejects as_mut_slice; on macOS this takes the read-only IOSurface lock (skips the unlock flush), on Linux the dma-buf read-direction sync.

Source

fn map_write(&self) -> Result<TensorMap<T>>

Map the tensor for CPU writing (fill-only: reading through a write map may see write-combined memory — do not read the slice).

Source

fn map_mut(&self) -> Result<TensorMap<T>>

Map the tensor read-write (alias of map with the intent spelled out).

Source

fn view(&self, offset_bytes: usize, shape: &[usize]) -> Result<Self>
where Self: Sized,

Create a zero-copy sub-region view of this backing that shares the underlying allocation and BufferIdentity.

The window is [offset_bytes, offset_bytes + shape.product() * size_of::<T>()) measured from this tensor’s own logical start, so a sub-view of a sub-view composes by adding offsets. Sharing the parent’s identity is the contract that lets identity-keyed caches (e.g. the GL EGLImage import cache) treat offset-distinct windows as one buffer rather than unrelated allocations — view must never mint a fresh identity.

Defaults to Error::NotImplemented; every backend that supports sub-views overrides it (Mem, Shm, Linux DMA, macOS IOSurface, Pbo).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<T> TensorTrait<T> for PboTensor<T>
where T: Num + Clone + Debug + Send + Sync,

Source§

impl<T> TensorTrait<T> for Tensor<T>
where T: Num + Clone + Debug + Send + Sync,