Skip to main content

ariadnetor_tensor/dense/
constructors.rs

1//! Factory methods for `DenseTensorData<T>` taking explicit memory order.
2//!
3//! Backend-aware callers use these via `ComputeBackendTensorExt`;
4//! explicit-order callers (tests, kernels) invoke them directly. The
5//! `*_in_order` suffix names the explicit-order signature shape.
6
7use aligned_vec::{AVec, ConstAlign};
8use ariadnetor_core::backend::MemoryOrder;
9use num_traits::{One, Zero};
10use rand::RngExt;
11
12use crate::{DenseLayout, DenseStorage, DenseTensorData, TensorData};
13
14impl<T> DenseTensorData<T>
15where
16    T: Clone,
17{
18    /// Zero-filled tensor in the requested memory order.
19    pub fn zeros_in_order(shape: Vec<usize>, order: MemoryOrder) -> Self
20    where
21        T: Zero,
22    {
23        let total: usize = shape.iter().product();
24        let mut data: AVec<T, ConstAlign<64>> = AVec::with_capacity(64, total);
25        data.resize(total, T::zero());
26        let storage = DenseStorage::from_aligned(data);
27        let layout = DenseLayout::new(shape, order);
28        TensorData::new(storage, layout)
29    }
30
31    /// Ones-filled tensor in the requested memory order.
32    pub fn ones_in_order(shape: Vec<usize>, order: MemoryOrder) -> Self
33    where
34        T: One + Zero,
35    {
36        let total: usize = shape.iter().product();
37        let mut data: AVec<T, ConstAlign<64>> = AVec::with_capacity(64, total);
38        data.resize(total, T::one());
39        let storage = DenseStorage::from_aligned(data);
40        let layout = DenseLayout::new(shape, order);
41        TensorData::new(storage, layout)
42    }
43
44    /// Tensor filled with `value` in the requested memory order.
45    pub fn filled_in_order(shape: Vec<usize>, value: T, order: MemoryOrder) -> Self {
46        let total: usize = shape.iter().product();
47        let mut data: AVec<T, ConstAlign<64>> = AVec::with_capacity(64, total);
48        data.resize(total, value);
49        let storage = DenseStorage::from_aligned(data);
50        let layout = DenseLayout::new(shape, order);
51        TensorData::new(storage, layout)
52    }
53
54    /// `n × n` identity matrix in the requested memory order.
55    ///
56    /// The identity matrix is symmetric, so the flat buffer is the
57    /// same under either memory order; only the layout's `order()`
58    /// differs.
59    pub fn eye_in_order(n: usize, order: MemoryOrder) -> Self
60    where
61        T: Zero + One,
62    {
63        let mut buf = vec![T::zero(); n * n];
64        for i in 0..n {
65            buf[i * n + i] = T::one();
66        }
67        let mut data: AVec<T, ConstAlign<64>> = AVec::with_capacity(64, n * n);
68        for elem in buf {
69            data.push(elem);
70        }
71        let storage = DenseStorage::from_aligned(data);
72        let layout = DenseLayout::new(vec![n, n], order);
73        TensorData::new(storage, layout)
74    }
75
76    /// Random-filled tensor (standard distribution) in the requested
77    /// memory order. Random values are layout-invariant; only the
78    /// layout's `order()` tag matters for downstream interpretation.
79    pub fn random_in_order<R: rand::Rng>(shape: Vec<usize>, order: MemoryOrder, rng: &mut R) -> Self
80    where
81        rand::distr::StandardUniform: rand::distr::Distribution<T>,
82    {
83        let total: usize = shape.iter().product();
84        let mut data: AVec<T, ConstAlign<64>> = AVec::with_capacity(64, total);
85        for _ in 0..total {
86            data.push(rng.random());
87        }
88        let storage = DenseStorage::from_aligned(data);
89        let layout = DenseLayout::new(shape, order);
90        TensorData::new(storage, layout)
91    }
92}