6 : shape_(shape), mapped_data_(nullptr) {
8 throw std::invalid_argument(
"Tensor shape cannot be empty.");
11 std::accumulate(
shape.begin(),
shape.end(), 1ULL, std::multiplies<>());
16 double *preallocated_ptr)
17 : shape_(shape), mapped_data_(preallocated_ptr) {
19 throw std::invalid_argument(
"Tensor shape cannot be empty.");
20 if (!preallocated_ptr)
21 throw std::invalid_argument(
"Preallocated pointer is null.");
24 std::accumulate(
shape.begin(),
shape.end(), 1ULL, std::multiplies<>());
59 throw std::invalid_argument(
60 "Shapes must match for inplace multiplication.");
62 double *my_data =
data();
63 const double *other_data = other.
data();
65 my_data[i] *= other_data[i];
70 double *my_data =
data();
76 std::size_t stride = 1;
77 for (
int i =
static_cast<int>(
shape_.size()) - 1; i >= 0; --i) {
85 if (indices.size() !=
shape_.size()) {
86 throw std::invalid_argument(
87 "Number of indices must match tensor dimensionality.");
89 std::size_t flat_idx = 0;
90 for (std::size_t i = 0; i < indices.size(); ++i) {
91 if (indices[i] >=
shape_[i]) {
92 throw std::out_of_range(
"Index out of bounds for tensor dimension.");
94 flat_idx += indices[i] *
strides_[i];
Dense row-major array of doubles with a fixed shape.
double * mapped_data_
borrowed buffer; takes precedence when non-null
std::vector< std::size_t > shape_
DenseTensor(const std::vector< std::size_t > &shape)
Creates an owning tensor filled with zeros.
double & at(const std::vector< std::size_t > &indices)
Checked element access by one index per dimension.
double * data()
Pointer to the first element: the borrowed buffer when one is bound, otherwise the owned storage.
const std::vector< std::size_t > & shape() const
Extent of each dimension, as given at construction.
double & operator[](std::size_t flat_idx)
Element access by flat row-major index.
std::vector< double > owned_data_
empty for a tensor created over caller memory
void multiply_inplace(const DenseTensor &other)
Multiplies this tensor by another, element by element.
std::size_t compute_flat_index(const std::vector< std::size_t > &indices) const
Checked conversion used by at(). Throws as documented there.
void bind_data(double *ptr)
Redirects the tensor to a caller buffer.
void fill(double value)
Sets every element to value.
std::size_t num_elements_
std::vector< std::size_t > strides_
row-major strides, same length as shape_
std::size_t size() const
Total number of elements, the product of the shape.
bncore::DenseTensor, a row-major multi-dimensional array of doubles that either owns its storage or b...