v2.0.0
Loading...
Searching...
No Matches
ml_tensor.cpp
Go to the documentation of this file.
1//=============================================================================================================
28
29//=============================================================================================================
30// INCLUDES
31//=============================================================================================================
32
33#include "ml_tensor.h"
34
35//=============================================================================================================
36// STL INCLUDES
37//=============================================================================================================
38
39#include <algorithm>
40#include <cstring>
41#include <numeric>
42#include <stdexcept>
43
44//=============================================================================================================
45// USED NAMESPACES
46//=============================================================================================================
47
48using namespace MLLIB;
49using namespace Eigen;
50
51//=============================================================================================================
52// STATIC HELPERS
53//=============================================================================================================
54
55int64_t MlTensor::computeSize(const std::vector<int64_t>& shape)
56{
57 if (shape.empty())
58 return 0;
59 return std::accumulate(shape.begin(), shape.end(),
60 int64_t(1), std::multiplies<int64_t>());
61}
62
63//=============================================================================================================
64// DEFINE MEMBER METHODS
65//=============================================================================================================
66
68: m_storage(nullptr)
69, m_data(nullptr)
70, m_shape()
71, m_size(0)
72{
73}
74
75//=============================================================================================================
76
77MlTensor::MlTensor(std::vector<float>&& data, std::vector<int64_t> shape)
78: m_shape(std::move(shape))
79, m_size(computeSize(m_shape))
80{
81 if (static_cast<int64_t>(data.size()) != m_size) {
82 throw std::invalid_argument("MlTensor: buffer size does not match shape");
83 }
84 m_storage = std::make_shared<std::vector<float>>(std::move(data));
85 m_data = m_storage->data();
86}
87
88//=============================================================================================================
89
90MlTensor::MlTensor(const float* data, std::vector<int64_t> shape)
91: m_shape(std::move(shape))
92, m_size(computeSize(m_shape))
93{
94 m_storage = std::make_shared<std::vector<float>>(data, data + m_size);
95 m_data = m_storage->data();
96}
97
98//=============================================================================================================
99
100MlTensor::MlTensor(const MatrixXf& mat)
101: m_shape({mat.rows(), mat.cols()})
102, m_size(mat.size())
103{
104 m_storage = std::make_shared<std::vector<float>>(static_cast<size_t>(m_size));
105 m_data = m_storage->data();
106 // Copy column-major Eigen → row-major contiguous storage (one memop)
107 Map<RowMajorMatrixXf>(m_data, mat.rows(), mat.cols()) = mat;
108}
109
110//=============================================================================================================
111
112MlTensor::MlTensor(const MatrixXd& mat)
113: m_shape({mat.rows(), mat.cols()})
114, m_size(mat.size())
115{
116 m_storage = std::make_shared<std::vector<float>>(static_cast<size_t>(m_size));
117 m_data = m_storage->data();
118 Map<RowMajorMatrixXf>(m_data, mat.rows(), mat.cols()) = mat.cast<float>();
119}
120
121//=============================================================================================================
122
123MlTensor MlTensor::view(float* data, std::vector<int64_t> shape)
124{
125 MlTensor t;
126 t.m_shape = std::move(shape);
127 t.m_size = computeSize(t.m_shape);
128 t.m_storage = nullptr; // non-owning
129 t.m_data = data;
130 return t;
131}
132
133//=============================================================================================================
134
136{
137 return MlTensor(data, {static_cast<int64_t>(rows), static_cast<int64_t>(cols)});
138}
139
140//=============================================================================================================
141
142int MlTensor::ndim() const
143{
144 return static_cast<int>(m_shape.size());
145}
146
147//=============================================================================================================
148
149int64_t MlTensor::size() const
150{
151 return m_size;
152}
153
154//=============================================================================================================
155
156const std::vector<int64_t>& MlTensor::shape() const
157{
158 return m_shape;
159}
160
161//=============================================================================================================
162
163int64_t MlTensor::shape(int dim) const
164{
165 if (dim < 0)
166 dim += ndim();
167 assert(dim >= 0 && dim < ndim());
168 return m_shape[static_cast<size_t>(dim)];
169}
170
171//=============================================================================================================
172
173int MlTensor::rows() const
174{
175 assert(ndim() >= 1);
176 return static_cast<int>(m_shape[0]);
177}
178
179//=============================================================================================================
180
181int MlTensor::cols() const
182{
183 assert(ndim() >= 2);
184 return static_cast<int>(m_shape[1]);
185}
186
187//=============================================================================================================
188
190{
191 return m_data;
192}
193
194//=============================================================================================================
195
196const float* MlTensor::data() const
197{
198 return m_data;
199}
200
201//=============================================================================================================
202
204{
205 assert(ndim() == 2);
206 return RowMajorMatrixMap(m_data, m_shape[0], m_shape[1]);
207}
208
209//=============================================================================================================
210
212{
213 assert(ndim() == 2);
214 return ConstRowMajorMatrixMap(m_data, m_shape[0], m_shape[1]);
215}
216
217//=============================================================================================================
218
219MatrixXf MlTensor::toMatrixXf() const
220{
221 assert(ndim() == 2);
222 // Assign row-major map to column-major MatrixXf (Eigen transposes layout)
223 return Map<const RowMajorMatrixXf>(m_data, m_shape[0], m_shape[1]);
224}
225
226//=============================================================================================================
227
228MatrixXd MlTensor::toMatrixXd() const
229{
230 assert(ndim() == 2);
231 return Map<const RowMajorMatrixXf>(m_data, m_shape[0], m_shape[1]).cast<double>();
232}
233
234//=============================================================================================================
235
236MlTensor MlTensor::reshape(std::vector<int64_t> newShape) const
237{
238 int64_t newSize = computeSize(newShape);
239 if (newSize != m_size) {
240 throw std::invalid_argument("MlTensor::reshape: new shape size differs from current");
241 }
242
243 MlTensor t;
244 t.m_storage = m_storage; // share ownership (or null for views)
245 t.m_data = m_data;
246 t.m_shape = std::move(newShape);
247 t.m_size = newSize;
248 return t;
249}
250
251//=============================================================================================================
252
254{
255 return m_storage == nullptr && m_data != nullptr;
256}
257
258//=============================================================================================================
259
260bool MlTensor::empty() const
261{
262 return m_size == 0;
263}
N-dimensional, row-major, reference-counted float32 tensor used as the universal MLLIB data carrier.
Tensors, model abstraction, ONNX Runtime inference and Python training drivers used across mne-cpp.
int cols() const
Eigen::MatrixXf toMatrixXf() const
Eigen::Map< RowMajorMatrixXf > RowMajorMatrixMap
Definition ml_tensor.h:77
static MlTensor fromBuffer(const float *data, int rows, int cols)
Eigen::MatrixXd toMatrixXd() const
static MlTensor view(float *data, std::vector< int64_t > shape)
int ndim() const
RowMajorMatrixMap matrix()
int64_t size() const
int rows() const
MlTensor reshape(std::vector< int64_t > newShape) const
bool empty() const
const std::vector< int64_t > & shape() const
bool isView() const
Eigen::Map< const RowMajorMatrixXf > ConstRowMajorMatrixMap
Definition ml_tensor.h:78