载入中...
搜索中...
未找到
Tensor.cpp
浏览该文件的文档.
1#include "tensor/Tensor.h"
2#include "tensor/CpuKernels.h"
3#include "tensor/Graph.h"
4#include "tensor/Quant.h"
5
6#include "common/Exception.h"
7
8#include <algorithm>
9#include <cmath>
10#include <cstring>
11
12namespace eve::tensor {
13namespace {
14
15int productLocal(const int *dims, int rank) {
16 int n = 1;
17 for (int i = 0; i < rank; ++i) {
18 if (dims[i] <= 0) throw eve::Exception("Tensor: dims must be > 0");
19 n *= dims[i];
20 }
21 return n;
22}
23
24} // namespace
25
26const char *dtypeName(DType dtype) {
27 switch (dtype) {
28 case DType::Int32: return "int32";
29 case DType::Fp16: return "fp16";
30 case DType::Fp8E4M3: return "fp8";
31 case DType::Fp4E2M1: return "fp4";
32 case DType::Int8: return "int8";
33 case DType::Int4: return "int4";
34 case DType::Float32:
35 default: return "float32";
36 }
37}
38
39bool parseDType(const std::string &name, DType &out) {
40 if (name == "float32" || name == "f32") {
41 out = DType::Float32;
42 return true;
43 }
44 if (name == "int32" || name == "i32") {
45 out = DType::Int32;
46 return true;
47 }
48 if (name == "fp16" || name == "f16") {
49 out = DType::Fp16;
50 return true;
51 }
52 if (name == "fp8" || name == "f8") {
53 out = DType::Fp8E4M3;
54 return true;
55 }
56 if (name == "fp4" || name == "f4") {
57 out = DType::Fp4E2M1;
58 return true;
59 }
60 if (name == "int8" || name == "i8") {
61 out = DType::Int8;
62 return true;
63 }
64 if (name == "int4" || name == "i4") {
65 out = DType::Int4;
66 return true;
67 }
68 return false;
69}
70
71int Tensor::product(const int *dims, int rank) { return productLocal(dims, rank); }
72
73void Tensor::initDims(DType dtype, const int *dims, int rank) {
74 if (rank < 1 || rank > kMaxRank)
75 throw eve::Exception("Tensor: rank must be 1..%d", kMaxRank);
76 rank_ = rank;
77 for (int i = 0; i < kMaxRank; ++i) dims_[i] = 0;
78 for (int i = 0; i < rank; ++i) dims_[i] = dims[i];
79 size_ = productLocal(dims, rank);
80 dtype_ = dtype;
82 data_.clear();
83 } else {
84 data_.assign(static_cast<size_t>(size_), 0.f);
85 }
86 bytes_.clear();
87 qScales_.clear();
88 qGroup_ = 0;
89 device_ = "cpu";
90 kind_ = Kind::Eager;
91 graph_ = nullptr;
92 nodeId_ = -1;
93}
94
95Tensor::Tensor(const int *dims, int rank) { initDims(DType::Float32, dims, rank); }
96Tensor::Tensor(DType dtype, const int *dims, int rank) { initDims(dtype, dims, rank); }
98 int d[] = {d0};
99 initDims(DType::Float32, d, 1);
100}
101Tensor::Tensor(int d0, int d1) {
102 int d[] = {d0, d1};
103 initDims(DType::Float32, d, 2);
104}
105Tensor::Tensor(int d0, int d1, int d2) {
106 int d[] = {d0, d1, d2};
107 initDims(DType::Float32, d, 3);
108}
109Tensor::Tensor(int d0, int d1, int d2, int d3) {
110 int d[] = {d0, d1, d2, d3};
111 initDims(DType::Float32, d, 4);
112}
113Tensor::Tensor(int d0, int d1, int d2, int d3, int d4) {
114 int d[] = {d0, d1, d2, d3, d4};
115 initDims(DType::Float32, d, 5);
116}
117Tensor::Tensor(int d0, int d1, int d2, int d3, int d4, int d5) {
118 int d[] = {d0, d1, d2, d3, d4, d5};
119 initDims(DType::Float32, d, 6);
120}
121
122Tensor *Tensor::makeSymbolic(Graph *graph, int nodeId, const int *dims, int rank) {
123 auto *t = new Tensor();
124 t->kind_ = Kind::Symbolic;
125 t->graph_ = graph;
126 t->nodeId_ = nodeId;
127 t->rank_ = rank;
128 for (int i = 0; i < kMaxRank; ++i) t->dims_[i] = 0;
129 for (int i = 0; i < rank; ++i) t->dims_[i] = dims[i];
130 t->size_ = productLocal(dims, rank);
131 t->dtype_ = DType::Float32;
132 t->device_ = "cpu";
133 return t;
134}
135
136void Tensor::ensureEager(const char *op) const {
137 if (kind_ != Kind::Eager)
138 throw eve::Exception("Tensor.%s: symbolic tensor has no value (compile/run first)", op);
139}
140
141int Tensor::getDim(int axis) const {
142 if (axis < 0 || axis >= rank_) throw eve::Exception("Tensor.getDim: axis out of range");
143 return dims_[axis];
144}
145
146int Tensor::offset2(int i0, int i1) const {
147 if (rank_ != 2) throw eve::Exception("Tensor: expected rank 2");
148 if (i0 < 0 || i0 >= dims_[0] || i1 < 0 || i1 >= dims_[1])
149 throw eve::Exception("Tensor: index out of range");
150 return i0 * dims_[1] + i1;
151}
152
153int Tensor::offset3(int i0, int i1, int i2) const {
154 if (rank_ != 3) throw eve::Exception("Tensor: expected rank 3");
155 if (i0 < 0 || i0 >= dims_[0] || i1 < 0 || i1 >= dims_[1] || i2 < 0 || i2 >= dims_[2])
156 throw eve::Exception("Tensor: index out of range");
157 return (i0 * dims_[1] + i1) * dims_[2] + i2;
158}
159
160int Tensor::offset4(int i0, int i1, int i2, int i3) const {
161 if (rank_ != 4) throw eve::Exception("Tensor: expected rank 4");
162 if (i0 < 0 || i0 >= dims_[0] || i1 < 0 || i1 >= dims_[1] || i2 < 0 || i2 >= dims_[2] ||
163 i3 < 0 || i3 >= dims_[3])
164 throw eve::Exception("Tensor: index out of range");
165 return ((i0 * dims_[1] + i1) * dims_[2] + i2) * dims_[3] + i3;
166}
167
168int Tensor::offset5(int i0, int i1, int i2, int i3, int i4) const {
169 if (rank_ != 5) throw eve::Exception("Tensor: expected rank 5");
170 if (i0 < 0 || i0 >= dims_[0] || i1 < 0 || i1 >= dims_[1] || i2 < 0 || i2 >= dims_[2] ||
171 i3 < 0 || i3 >= dims_[3] || i4 < 0 || i4 >= dims_[4])
172 throw eve::Exception("Tensor: index out of range");
173 return (((i0 * dims_[1] + i1) * dims_[2] + i2) * dims_[3] + i3) * dims_[4] + i4;
174}
175
176int Tensor::offset6(int i0, int i1, int i2, int i3, int i4, int i5) const {
177 if (rank_ != 6) throw eve::Exception("Tensor: expected rank 6");
178 if (i0 < 0 || i0 >= dims_[0] || i1 < 0 || i1 >= dims_[1] || i2 < 0 || i2 >= dims_[2] ||
179 i3 < 0 || i3 >= dims_[3] || i4 < 0 || i4 >= dims_[4] || i5 < 0 || i5 >= dims_[5])
180 throw eve::Exception("Tensor: index out of range");
181 return ((((i0 * dims_[1] + i1) * dims_[2] + i2) * dims_[3] + i3) * dims_[4] + i4) * dims_[5] +
182 i5;
183}
184
185float *Tensor::data() {
186 ensureEager("data");
187 if (isQuantized()) throw eve::Exception("Tensor.data: quantized tensor; dequantized() first");
188 return data_.data();
189}
190const float *Tensor::data() const {
191 ensureEager("data");
192 if (isQuantized()) throw eve::Exception("Tensor.data: quantized tensor; dequantized() first");
193 return data_.data();
194}
195
196float Tensor::get(int flatIndex) const {
197 ensureEager("get");
198 if (flatIndex < 0 || flatIndex >= size_) throw eve::Exception("Tensor.get: index out of range");
199 if (isQuantized()) return q::dequantValue(dtype_, bytes_.data(), qScales_.data(), qGroup_, flatIndex);
200 return data_[static_cast<size_t>(flatIndex)];
201}
202
203void Tensor::set(int flatIndex, float value) {
204 ensureEager("set");
205 if (flatIndex < 0 || flatIndex >= size_) throw eve::Exception("Tensor.set: index out of range");
206 if (isQuantized()) throw eve::Exception("Tensor.set: quantized tensors are immutable");
207 data_[static_cast<size_t>(flatIndex)] = value;
208}
209
210std::vector<float> Tensor::dequantized() const {
211 ensureEager("dequantized");
212 if (!isQuantized()) return data_;
213 std::vector<float> out(static_cast<size_t>(size_));
214 q::dequantizeAll(dtype_, bytes_.data(), qScales_.data(), qGroup_, size_, out.data());
215 return out;
216}
217
218float Tensor::get1(int i0) const {
219 if (rank_ != 1) throw eve::Exception("Tensor.get1: expected rank 1");
220 return get(i0);
221}
222void Tensor::set1(int i0, float value) {
223 if (rank_ != 1) throw eve::Exception("Tensor.set1: expected rank 1");
224 set(i0, value);
225}
226float Tensor::get2(int i0, int i1) const {
227 ensureEager("get2");
228 return data_[static_cast<size_t>(offset2(i0, i1))];
229}
230void Tensor::set2(int i0, int i1, float value) {
231 ensureEager("set2");
232 data_[static_cast<size_t>(offset2(i0, i1))] = value;
233}
234float Tensor::get3(int i0, int i1, int i2) const {
235 ensureEager("get3");
236 return data_[static_cast<size_t>(offset3(i0, i1, i2))];
237}
238void Tensor::set3(int i0, int i1, int i2, float value) {
239 ensureEager("set3");
240 data_[static_cast<size_t>(offset3(i0, i1, i2))] = value;
241}
242float Tensor::get4(int i0, int i1, int i2, int i3) const {
243 ensureEager("get4");
244 return data_[static_cast<size_t>(offset4(i0, i1, i2, i3))];
245}
246void Tensor::set4(int i0, int i1, int i2, int i3, float value) {
247 ensureEager("set4");
248 data_[static_cast<size_t>(offset4(i0, i1, i2, i3))] = value;
249}
250float Tensor::get5(int i0, int i1, int i2, int i3, int i4) const {
251 ensureEager("get5");
252 return data_[static_cast<size_t>(offset5(i0, i1, i2, i3, i4))];
253}
254void Tensor::set5(int i0, int i1, int i2, int i3, int i4, float value) {
255 ensureEager("set5");
256 data_[static_cast<size_t>(offset5(i0, i1, i2, i3, i4))] = value;
257}
258float Tensor::get6(int i0, int i1, int i2, int i3, int i4, int i5) const {
259 ensureEager("get6");
260 return data_[static_cast<size_t>(offset6(i0, i1, i2, i3, i4, i5))];
261}
262void Tensor::set6(int i0, int i1, int i2, int i3, int i4, int i5, float value) {
263 ensureEager("set6");
264 data_[static_cast<size_t>(offset6(i0, i1, i2, i3, i4, i5))] = value;
265}
266
267void Tensor::fill(float value) {
268 ensureEager("fill");
269 std::fill(data_.begin(), data_.end(), value);
270}
271
272void Tensor::copyFrom(const Tensor *other) {
273 ensureEager("copyFrom");
274 if (!other) throw eve::Exception("Tensor.copyFrom: other is null");
275 other->ensureEager("copyFrom");
276 checkSameShape(other, "copyFrom");
277 std::memcpy(data_.data(), other->data_.data(), sizeof(float) * static_cast<size_t>(size_));
278 dtype_ = other->dtype_;
279}
280
282 ensureEager("clone");
283 auto *out = new Tensor(dtype_, dims_, rank_);
284 out->data_ = data_;
285 out->device_ = device_;
286 return out;
287}
288
289void Tensor::checkSameShape(const Tensor *other, const char *op) const {
290 if (!other) throw eve::Exception("Tensor.%s: other is null", op);
291 if (rank_ != other->rank_ || size_ != other->size_)
292 throw eve::Exception("Tensor.%s: shape mismatch", op);
293 for (int i = 0; i < rank_; ++i) {
294 if (dims_[i] != other->dims_[i]) throw eve::Exception("Tensor.%s: shape mismatch", op);
295 }
296}
297
298namespace {
299
300Tensor *broadcastBinary(OpType op, const Tensor *a, const Tensor *b, const char *name) {
301 a->ensureEager(name);
302 b->ensureEager(name);
303 int aDims[Tensor::kMaxRank] = {};
304 int bDims[Tensor::kMaxRank] = {};
305 for (int k = 0; k < a->getRank(); ++k) aDims[k] = a->getDim(k);
306 for (int k = 0; k < b->getRank(); ++k) bDims[k] = b->getDim(k);
307 int od[Tensor::kMaxRank] = {};
308 int orank = 0;
309 if (!kernels::broadcastShape(aDims, a->getRank(), bDims, b->getRank(), od, orank))
310 throw eve::Exception("Tensor.%s: broadcast shape mismatch", name);
311 auto *out = new Tensor(od, orank);
312 kernels::binaryOp(op, a->data(), aDims, a->getRank(), b->data(), bDims, b->getRank(),
313 out->data(), od, orank);
314 return out;
315}
316
317} // namespace
318
319Tensor *Tensor::add(const Tensor *other) const { return broadcastBinary(OpType::Add, this, other, "add"); }
320Tensor *Tensor::sub(const Tensor *other) const { return broadcastBinary(OpType::Sub, this, other, "sub"); }
321Tensor *Tensor::multiply(const Tensor *other) const {
322 return broadcastBinary(OpType::Multiply, this, other, "multiply");
323}
324Tensor *Tensor::div(const Tensor *other) const { return broadcastBinary(OpType::Divide, this, other, "div"); }
325
327 ensureEager("addScalar");
328 auto *out = new Tensor(dtype_, dims_, rank_);
329 kernels::unaryOp(OpType::AddScalar, data_.data(), size_, out->data_.data(), s, 0.f);
330 return out;
331}
333 ensureEager("subScalar");
334 auto *out = new Tensor(dtype_, dims_, rank_);
335 kernels::unaryOp(OpType::SubScalar, data_.data(), size_, out->data_.data(), s, 0.f);
336 return out;
337}
339 ensureEager("mulScalar");
340 auto *out = new Tensor(dtype_, dims_, rank_);
341 kernels::unaryOp(OpType::MulScalar, data_.data(), size_, out->data_.data(), s, 0.f);
342 return out;
343}
345 ensureEager("divScalar");
346 auto *out = new Tensor(dtype_, dims_, rank_);
347 kernels::unaryOp(OpType::DivScalar, data_.data(), size_, out->data_.data(), s, 0.f);
348 return out;
349}
350Tensor *Tensor::powScalar(float exp) const {
351 ensureEager("powScalar");
352 auto *out = new Tensor(dtype_, dims_, rank_);
353 kernels::unaryOp(OpType::PowScalar, data_.data(), size_, out->data_.data(), exp, 0.f);
354 return out;
355}
357 ensureEager("maximumScalar");
358 auto *out = new Tensor(dtype_, dims_, rank_);
359 kernels::unaryOp(OpType::MaximumScalar, data_.data(), size_, out->data_.data(), s, 0.f);
360 return out;
361}
363 ensureEager("minimumScalar");
364 auto *out = new Tensor(dtype_, dims_, rank_);
365 kernels::unaryOp(OpType::MinimumScalar, data_.data(), size_, out->data_.data(), s, 0.f);
366 return out;
367}
368
369#define EVE_TENSOR_UNARY(name, opType) \
370 Tensor *Tensor::name() const { \
371 ensureEager(#name); \
372 auto *out = new Tensor(dtype_, dims_, rank_); \
373 kernels::unaryOp((opType), data_.data(), size_, out->data_.data(), 0.f, 0.f); \
374 return out; \
375 }
376
389
390#undef EVE_TENSOR_UNARY
391
392Tensor *Tensor::clamp(float lo, float hi) const {
393 ensureEager("clamp");
394 if (lo > hi) std::swap(lo, hi);
395 auto *out = new Tensor(dtype_, dims_, rank_);
396 kernels::unaryOp(OpType::Clamp, data_.data(), size_, out->data_.data(), lo, hi);
397 return out;
398}
399
400void Tensor::addInPlace(const Tensor *other) {
401 ensureEager("addInPlace");
402 other->ensureEager("addInPlace");
403 checkSameShape(other, "addInPlace");
404 float *a = data_.data();
405 const float *b = other->data_.data();
406 for (int i = 0; i < size_; ++i) a[i] += b[i];
407}
408
409void Tensor::multiplyInPlace(const Tensor *other) {
410 ensureEager("multiplyInPlace");
411 other->ensureEager("multiplyInPlace");
412 checkSameShape(other, "multiplyInPlace");
413 float *a = data_.data();
414 const float *b = other->data_.data();
415 for (int i = 0; i < size_; ++i) a[i] *= b[i];
416}
417
419 ensureEager("addScalarInPlace");
420 float *a = data_.data();
421 for (int i = 0; i < size_; ++i) a[i] += s;
422}
423
425 ensureEager("mulScalarInPlace");
426 float *a = data_.data();
427 for (int i = 0; i < size_; ++i) a[i] *= s;
428}
429
431 ensureEager("reluInPlace");
432 float *a = data_.data();
433 for (int i = 0; i < size_; ++i)
434 if (a[i] < 0.f) a[i] = 0.f;
435}
436
437float Tensor::reduceSum() const {
438 ensureEager("reduceSum");
439 double acc = 0.0;
440 for (int i = 0; i < size_; ++i) acc += data_[static_cast<size_t>(i)];
441 return float(acc);
442}
443
444float Tensor::reduceMean() const {
445 return size_ > 0 ? reduceSum() / float(size_) : 0.f;
446}
447
448float Tensor::reduceMin() const {
449 ensureEager("reduceMin");
450 if (size_ <= 0) return 0.f;
451 float m = data_[0];
452 for (int i = 1; i < size_; ++i) m = std::min(m, data_[static_cast<size_t>(i)]);
453 return m;
454}
455
456float Tensor::reduceMax() const {
457 ensureEager("reduceMax");
458 if (size_ <= 0) return 0.f;
459 float m = data_[0];
460 for (int i = 1; i < size_; ++i) m = std::max(m, data_[static_cast<size_t>(i)]);
461 return m;
462}
463
464float Tensor::dot(const Tensor *other) const {
465 ensureEager("dot");
466 other->ensureEager("dot");
467 checkSameShape(other, "dot");
468 double acc = 0.0;
469 const float *a = data_.data();
470 const float *b = other->data_.data();
471 for (int i = 0; i < size_; ++i) acc += double(a[i]) * double(b[i]);
472 return float(acc);
473}
474
475Tensor *Tensor::matmul(const Tensor *other) const {
476 ensureEager("matmul");
477 if (!other) throw eve::Exception("Tensor.matmul: other is null");
478 other->ensureEager("matmul");
479 std::vector<float> aq, bq;
480 const float *a = data_.data();
481 const float *b = other->data_.data();
482 if (isQuantized()) {
483 aq = dequantized();
484 a = aq.data();
485 }
486 if (other->isQuantized()) {
487 bq = other->dequantized();
488 b = bq.data();
489 }
490 if (rank_ == 2 && other->rank_ == 2) {
491 int m = dims_[0], k = dims_[1], n = other->dims_[1];
492 if (k != other->dims_[0]) throw eve::Exception("Tensor.matmul: inner dims mismatch");
493 auto *out = new Tensor(m, n);
494 float *c = out->data_.data();
495 for (int i = 0; i < m; ++i) {
496 for (int j = 0; j < n; ++j) {
497 double acc = 0.0;
498 for (int t = 0; t < k; ++t) acc += double(a[i * k + t]) * double(b[t * n + j]);
499 c[i * n + j] = float(acc);
500 }
501 }
502 return out;
503 }
504 if (rank_ == 3 && other->rank_ == 3) {
505 const int batch = dims_[0];
506 const int m = dims_[1], k = dims_[2], n = other->dims_[2];
507 if (batch != other->dims_[0] || k != other->dims_[1])
508 throw eve::Exception("Tensor.matmul: batched dims mismatch");
509 auto *out = new Tensor(batch, m, n);
510 for (int bb = 0; bb < batch; ++bb) {
511 const float *ap = a + size_t(bb) * m * k;
512 const float *bp = b + size_t(bb) * k * n;
513 float *c = out->data_.data() + size_t(bb) * m * n;
514 for (int i = 0; i < m; ++i) {
515 for (int j = 0; j < n; ++j) {
516 double acc = 0.0;
517 for (int t = 0; t < k; ++t)
518 acc += double(ap[i * k + t]) * double(bp[t * n + j]);
519 c[i * n + j] = float(acc);
520 }
521 }
522 }
523 return out;
524 }
525 throw eve::Exception("Tensor.matmul: expected rank 2x2 or 3x3 (got %dx%d)", rank_, other->rank_);
526}
527
529 ensureEager("transpose");
530 if (rank_ != 2) throw eve::Exception("Tensor.transpose: expected rank 2");
531 if (isQuantized()) {
532 // Dequantize so the transposed result is a plain fp32 tensor (the
533 // compiled graph path keeps the packed bytes and dequantizes in-kernel).
534 const std::vector<float> f = dequantized();
535 auto *t = new Tensor(dims_[1], dims_[0]);
536 for (int i = 0; i < dims_[1]; ++i)
537 for (int j = 0; j < dims_[0]; ++j)
538 t->set2(i, j, f[static_cast<size_t>(j * dims_[1] + i)]);
539 return t;
540 }
541 int order[] = {1, 0};
542 return permute(order, 2);
543}
544
545Tensor *Tensor::permute(const int *order, int rank) const {
546 ensureEager("permute");
547 if (rank != rank_) throw eve::Exception("Tensor.permute: rank mismatch");
548 if (isQuantized())
549 throw eve::Exception("Tensor.permute: quantized tensor; dequantize first");
550 int od[Tensor::kMaxRank] = {};
551 for (int k = 0; k < rank; ++k) {
552 if (order[k] < 0 || order[k] >= rank)
553 throw eve::Exception("Tensor.permute: order out of range");
554 od[k] = dims_[order[k]];
555 }
556 auto *out = new Tensor(dtype_, od, rank);
557 kernels::permute(data_.data(), dims_, rank, order, out->data_.data(), od);
558 return out;
559}
560
561Tensor *Tensor::reshape1(int d0) const {
562 ensureEager("reshape1");
563 if (d0 != size_) throw eve::Exception("Tensor.reshape1: size mismatch");
564 auto *out = new Tensor(dtype_, &d0, 1);
565 out->data_ = data_;
566 return out;
567}
568
569Tensor *Tensor::reshape2(int d0, int d1) const {
570 ensureEager("reshape2");
571 if (d0 * d1 != size_) throw eve::Exception("Tensor.reshape2: size mismatch");
572 int d[] = {d0, d1};
573 auto *out = new Tensor(dtype_, d, 2);
574 out->data_ = data_;
575 return out;
576}
577
578Tensor *Tensor::reshape3(int d0, int d1, int d2) const {
579 ensureEager("reshape3");
580 if (d0 * d1 * d2 != size_) throw eve::Exception("Tensor.reshape3: size mismatch");
581 int d[] = {d0, d1, d2};
582 auto *out = new Tensor(dtype_, d, 3);
583 out->data_ = data_;
584 return out;
585}
586
587Tensor *Tensor::reshape4(int d0, int d1, int d2, int d3) const {
588 ensureEager("reshape4");
589 if (d0 * d1 * d2 * d3 != size_) throw eve::Exception("Tensor.reshape4: size mismatch");
590 int d[] = {d0, d1, d2, d3};
591 auto *out = new Tensor(dtype_, d, 4);
592 out->data_ = data_;
593 return out;
594}
595
596Tensor *Tensor::reshape5(int d0, int d1, int d2, int d3, int d4) const {
597 ensureEager("reshape5");
598 if (d0 * d1 * d2 * d3 * d4 != size_) throw eve::Exception("Tensor.reshape5: size mismatch");
599 int d[] = {d0, d1, d2, d3, d4};
600 auto *out = new Tensor(dtype_, d, 5);
601 out->data_ = data_;
602 return out;
603}
604
605Tensor *Tensor::reshape6(int d0, int d1, int d2, int d3, int d4, int d5) const {
606 ensureEager("reshape6");
607 if (d0 * d1 * d2 * d3 * d4 * d5 != size_)
608 throw eve::Exception("Tensor.reshape6: size mismatch");
609 int d[] = {d0, d1, d2, d3, d4, d5};
610 auto *out = new Tensor(dtype_, d, 6);
611 out->data_ = data_;
612 return out;
613}
614
615Tensor *Tensor::flatten() const { return reshape1(size_); }
616
617} // namespace eve::tensor
std::string value
uint32_t i1
Definition Grass.cpp:62
uint32_t i2
Definition Grass.cpp:62
uint32_t i0
Definition Grass.cpp:62
glm::vec3 n
Definition Grass.cpp:64
const Graph & graph
uint32_t a
uint32_t b
uint32_t c
float f
const char * name
Definition RockMesh.cpp:21
int d
#define EVE_TENSOR_UNARY(name, opType)
Definition Tensor.cpp:369
float m[16]
uint32_t s
Definition Weather.cpp:28
float32 / int32 tensor (rank 1–6), row-major. Eager: owns a buffer. Symbolic: node in a Func graph (n...
Definition Tensor.h:43
Tensor * mulScalar(float s) const
Definition Tensor.cpp:338
Tensor * reshape5(int d0, int d1, int d2, int d3, int d4) const
Definition Tensor.cpp:596
Tensor * sub(const Tensor *other) const
Definition Tensor.cpp:320
float reduceSum() const
归约:求和 / 均值 / 最小 / 最大。
Definition Tensor.cpp:437
bool isQuantized() const
Definition Tensor.h:82
void fill(float value)
Definition Tensor.cpp:267
void ensureEager(const char *op) const
Definition Tensor.cpp:136
Tensor * add(const Tensor *other) const
Eager 逐元素运算(符号张量会抛异常)。
Definition Tensor.cpp:319
void copyFrom(const Tensor *other)
Definition Tensor.cpp:272
void set3(int i0, int i1, int i2, float value)
Definition Tensor.cpp:238
float reduceMax() const
Definition Tensor.cpp:456
void addScalarInPlace(float s)
Definition Tensor.cpp:418
static constexpr int kMaxRank
Definition Tensor.h:45
Tensor * reshape4(int d0, int d1, int d2, int d3) const
Definition Tensor.cpp:587
float get3(int i0, int i1, int i2) const
Definition Tensor.cpp:234
float get1(int i0) const
Definition Tensor.cpp:218
float get4(int i0, int i1, int i2, int i3) const
Definition Tensor.cpp:242
std::vector< float > dequantized() const
Definition Tensor.cpp:210
void mulScalarInPlace(float s)
Definition Tensor.cpp:424
float get5(int i0, int i1, int i2, int i3, int i4) const
Definition Tensor.cpp:250
Tensor * reshape6(int d0, int d1, int d2, int d3, int d4, int d5) const
Definition Tensor.cpp:605
Tensor * reshape2(int d0, int d1) const
Definition Tensor.cpp:569
float * data()
原始数据指针(eager)。
Definition Tensor.cpp:185
Tensor * clamp(float lo, float hi) const
Definition Tensor.cpp:392
Tensor * reshape1(int d0) const
Definition Tensor.cpp:561
float dot(const Tensor *other) const
Definition Tensor.cpp:464
int nodeId() const
Definition Tensor.h:65
Tensor * exp() const
float get6(int i0, int i1, int i2, int i3, int i4, int i5) const
Definition Tensor.cpp:258
Tensor * divScalar(float s) const
Definition Tensor.cpp:344
Tensor * multiply(const Tensor *other) const
Definition Tensor.cpp:321
float get2(int i0, int i1) const
Definition Tensor.cpp:226
Graph * graph() const
Definition Tensor.h:64
Tensor * powScalar(float exp) const
Definition Tensor.cpp:350
Tensor * subScalar(float s) const
Definition Tensor.cpp:332
void set1(int i0, float value)
Definition Tensor.cpp:222
int getDim(int axis) const
Definition Tensor.cpp:141
Tensor * transpose() const
Definition Tensor.cpp:528
void set(int flatIndex, float value)
Definition Tensor.cpp:203
Tensor * clone() const
Definition Tensor.cpp:281
void set4(int i0, int i1, int i2, int i3, float value)
Definition Tensor.cpp:246
float get(int flatIndex) const
Definition Tensor.cpp:196
Tensor * maximumScalar(float s) const
Definition Tensor.cpp:356
Tensor * div(const Tensor *other) const
Definition Tensor.cpp:324
static Tensor * makeSymbolic(Graph *graph, int nodeId, const int *dims, int rank)
Symbolic handle into a graph node.
Definition Tensor.cpp:122
void set2(int i0, int i1, float value)
Definition Tensor.cpp:230
Tensor * reshape3(int d0, int d1, int d2) const
Definition Tensor.cpp:578
void multiplyInPlace(const Tensor *other)
Definition Tensor.cpp:409
DType dtype() const
Definition Tensor.h:78
Tensor * flatten() const
Definition Tensor.cpp:615
Tensor * matmul(const Tensor *other) const
矩阵乘法 / 转置 / 变形。
Definition Tensor.cpp:475
Tensor * minimumScalar(float s) const
Definition Tensor.cpp:362
Tensor * addScalar(float s) const
Definition Tensor.cpp:326
float reduceMean() const
Definition Tensor.cpp:444
Tensor * permute(const int *order, int rank) const
Definition Tensor.cpp:545
static int product(const int *dims, int rank)
Definition Tensor.cpp:71
void addInPlace(const Tensor *other)
Eager 原地运算。
Definition Tensor.cpp:400
void set6(int i0, int i1, int i2, int i3, int i4, int i5, float value)
Definition Tensor.cpp:262
void set5(int i0, int i1, int i2, int i3, int i4, float value)
Definition Tensor.cpp:254
float reduceMin() const
Definition Tensor.cpp:448
void binaryOp(OpType type, const float *a, const int *aDims, int aRank, const float *b, const int *bDims, int bRank, float *out, const int *outDims, int outRank)
void permute(const float *in, const int *inDims, int rank, const int *order, float *out, const int *outDims)
bool broadcastShape(const int *aDims, int aRank, const int *bDims, int bRank, int *outDims, int &outRank)
void unaryOp(OpType type, const float *in, int count, float *out, float s0, float s1)
void dequantizeAll(DType dt, const uint8_t *bytes, const float *scales, int group, int count, float *out)
Definition Quant.h:204
float dequantValue(DType dt, const uint8_t *bytes, const float *scales, int group, int idx)
Definition Quant.h:174
bool isQuantDType(DType dt)
Definition Quant.h:16
bool parseDType(const std::string &name, DType &out)
Definition Tensor.cpp:39
DType
Tensor element types.
Definition Tensor.h:22
const char * dtypeName(DType dtype)
Definition Tensor.cpp:26