tenferro_tensor/lib.rs
1//! Dense tensor type with CPU/GPU support.
2//!
3//! This crate provides [`Tensor<T>`], a multi-dimensional array type composed of
4//! shape, strides, and a device-aware [`DataBuffer`]. It supports:
5//!
6//! - **Zero-copy view operations**: [`Tensor::view`], [`Tensor::permute`],
7//! [`Tensor::broadcast`], [`Tensor::diagonal`], [`Tensor::select`],
8//! [`Tensor::narrow`] modify only metadata (dims/strides)
9//! - **Data operations**: [`Tensor::contiguous`] / [`Tensor::into_contiguous`] copy
10//! data into a contiguous layout (the consuming variant avoids allocation when
11//! the tensor is already contiguous); [`Tensor::reshape`] returns a zero-copy
12//! view when possible and otherwise materializes first; [`Tensor::tril`] /
13//! [`Tensor::triu`] extract triangular parts
14//! - **Factory functions**: [`Tensor::zeros`], [`Tensor::ones`], [`Tensor::eye`]
15//! - **DLPack interop**: [`DataBuffer`] supports both Rust-owned (`Vec<T>`) and
16//! externally-owned memory (e.g., imported via DLPack) with automatic cleanup.
17//!
18//! # Memory layout
19//!
20//! tenferro uses **column-major** layout as its internal canonical order.
21//! [`MemoryOrder`] is still accepted at import/materialization boundaries
22//! (e.g., [`Tensor::from_slice`], [`Tensor::contiguous`]), but shape/view
23//! semantics such as [`Tensor::view`] and [`Tensor::reshape`] follow the
24//! column-major internal contract.
25//!
26//! This matches Julia, Fortran, Eigen3's default layout, and BLAS/LAPACK-style
27//! linear algebra backends. Row-major ecosystems should normalize at the
28//! boundary rather than expecting the tensor core to preserve row-major
29//! semantics through view operations.
30//!
31//! # No strided-rs dependency
32//!
33//! This crate does **not** depend on `strided-rs`. The strided-rs types
34//! (`StridedView`, `StridedViewMut`) are backend implementation details
35//! used only in `tenferro-prims`. To pass tensor data to prims backends,
36//! use [`DataBuffer::as_slice`] combined with [`Tensor::dims`],
37//! [`Tensor::strides`], and [`Tensor::offset`].
38//!
39//! # Examples
40//!
41//! ## Creating tensors
42//!
43//! ```ignore
44//! use tenferro_tensor::{MemoryOrder, Tensor};
45//! use tenferro_device::LogicalMemorySpace;
46//!
47//! let a = Tensor::<f64>::zeros(
48//! &[3, 4],
49//! LogicalMemorySpace::MainMemory,
50//! MemoryOrder::ColumnMajor,
51//! ).unwrap();
52//! let b = Tensor::<f64>::ones(
53//! &[3, 4],
54//! LogicalMemorySpace::MainMemory,
55//! MemoryOrder::RowMajor,
56//! ).unwrap();
57//!
58//! let data = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
59//! let m = Tensor::<f64>::from_slice(&data, &[2, 3], MemoryOrder::ColumnMajor).unwrap();
60//! ```
61//!
62//! ## Transpose, view, and reshape
63//!
64//! ```ignore
65//! let mt = m.permute(&[1, 0]).unwrap();
66//! assert_eq!(mt.dims(), &[3, 2]);
67//!
68//! let flat_view = m.view(&[6]).unwrap();
69//! assert_eq!(flat_view.dims(), &[6]);
70//!
71//! let flat = m.reshape(&[6]).unwrap();
72//! assert_eq!(flat.dims(), &[6]);
73//! ```
74//!
75//! ## Broadcasting and materialization
76//!
77//! ```ignore
78//! let col = Tensor::<f64>::ones(
79//! &[3, 1],
80//! LogicalMemorySpace::MainMemory,
81//! MemoryOrder::ColumnMajor,
82//! ).unwrap();
83//! let expanded = col.broadcast(&[3, 4]).unwrap();
84//! let owned = expanded.contiguous(MemoryOrder::ColumnMajor);
85//! assert_eq!(owned.dims(), &[3, 4]);
86//! ```
87
88#[cfg(feature = "cuda")]
89mod cuda_runtime;
90
91mod buffer;
92mod completion_event;
93mod layout;
94pub mod structured_tensor;
95mod tensor;
96
97pub use buffer::DataBuffer;
98pub use completion_event::CompletionEvent;
99pub use layout::MemoryOrder;
100pub use structured_tensor::StructuredTensor;
101pub use tensor::{KeepCountScalar, Tensor};
102
103#[cfg(test)]
104mod tests;