Tensor & memory
64-byte alignment, shared storage, and lifetimes.
01Layout and construction#
Dense contiguous row-major float32, with up to 8 axes. Tensor(shape) does not zero memory. zeros, full, and from_values create initialized data. A default empty Tensor has rank=0 and numel=0. AlignedStorage aligns data to 64 bytes.
auto a = Tensor::zeros({2, 3});auto b = Tensor::full({2, 3}, 0.5f);auto c = Tensor::from_values({2, 2}, {1, 2, 3, 4});02Copy or view#
Assignment copies the header and shares data. clone makes an independent copy. reshape/view_as give the storage a different shape. Writing through [] or data() changes other views too; there is no general copy-on-write.
auto shared = c;auto independent = c.clone();auto flat = c.reshape({4});shared[0] = 9; // c[0] and flat[0] also become 903Dimension inference#
Tensor::reshape infers one size_t(-1) dimension while preserving element count. Literal -1 can cause narrowing; use an explicit cast. The Reshape module does not perform this inference and needs a concrete shape.
auto t = Tensor::zeros({2, 3, 4});auto rows = t.reshape({2, static_cast<std::size_t>(-1)}); // [2,12]04Borrowed memory#
borrow(float*,shape) is nonowning; lifetime belongs to the caller. resize/copy_from need not preserve borrowed memory. operator[] is unchecked; size(axis) throws ModelError for invalid axes.
05Buffer reuse#
resize_dims reuses storage with sole ownership, enough capacity, and zero offset. Keeping a returned header alive across the next call may force allocation. allocation_count tracks AlignedStorage only, not all heap allocations.