载入中...
搜索中...
未找到
TF.cpp
浏览该文件的文档.
1#include "tensor/TF.h"
2#include "tensor/CpuKernels.h"
3#include "tensor/GpuBackend.h"
4#include "tensor/Graph.h"
5#include "tensor/Quant.h"
6#include "tensor/Tensor.h"
7
8#include "common/Exception.h"
9
10#include <simplesquirrel/simplesquirrel.hpp>
11
12#include <cmath>
13#include <cstdint>
14#include <cstring>
15
16namespace eve::tensor {
17namespace {
18// Below this element count the GPU dispatch/readback round-trip costs more
19// than the CPU loop saves; only worth trying the compute-shader path above it.
20constexpr int kGpuReduceMinSize = 1 << 14; // 16384 floats
21
22int convOutSize(int inSize, int kernel, int stride, int pad) {
23 const int out = (inSize + 2 * pad - kernel) / stride + 1;
24 if (out <= 0) throw Exception("TF.conv: output size must be > 0");
25 return out;
26}
27
28int normalizeAxis(int axis, int rank) {
29 if (axis < 0) axis += rank;
30 if (axis < 0 || axis >= rank) throw Exception("TF: axis out of range");
31 return axis;
32}
33
34void reduceOutDims(const int *dims, int rank, int axis, int keepDims, int *out, int &outRank) {
35 outRank = rank;
36 for (int k = 0; k < rank; ++k) out[k] = dims[k];
37 if (keepDims) {
38 out[axis] = 1;
39 } else if (rank == 1) {
40 out[0] = 1;
41 } else {
42 for (int k = axis; k < rank - 1; ++k) out[k] = out[k + 1];
43 out[rank - 1] = 0;
44 --outRank;
45 }
46}
47
48} // namespace
49
51
52TF::TF() : seed_(1), rngState_(1) {}
53
54float TF::nextUniform() const {
55 rngState_ = rngState_ * 1664525u + 1013904223u;
56 return float(rngState_ >> 8) * (1.f / 16777216.f);
57}
58
59float TF::nextGaussian() const {
60 float u1 = nextUniform();
61 float u2 = nextUniform();
62 if (u1 < 1e-7f) u1 = 1e-7f;
63 return std::sqrt(-2.f * std::log(u1)) * std::cos(6.28318530718f * u2);
64}
65
66void TF::setRandomSeed(uint32_t seed) {
67 seed_ = seed == 0 ? 1u : seed;
68 rngState_ = seed_;
69}
70
71uint32_t TF::getRandomSeed() const { return seed_; }
72
74 if (f) traceStack_.push_back(f);
75}
76
78 if (traceStack_.empty()) return;
79 if (traceStack_.back() == f) {
80 traceStack_.pop_back();
81 return;
82 }
83 for (auto it = traceStack_.begin(); it != traceStack_.end(); ++it) {
84 if (*it == f) {
85 traceStack_.erase(it);
86 return;
87 }
88 }
89}
90
91Func *TF::tracing() const {
92 return traceStack_.empty() ? nullptr : traceStack_.back();
93}
94
95Func *TF::func() { return new Func(this); }
96
97Tensor *TF::filled(const int *dims, int rank, float value) {
98 if (Func *f = tracing()) return f->emitFill(dims, rank, value);
99 auto *t = new Tensor(dims, rank);
100 t->fill(value);
101 return t;
102}
103
105 int d[] = {d0};
106 return filled(d, 1, 0.f);
107}
108Tensor *TF::zeros2(int d0, int d1) {
109 int d[] = {d0, d1};
110 return filled(d, 2, 0.f);
111}
112Tensor *TF::zeros3(int d0, int d1, int d2) {
113 int d[] = {d0, d1, d2};
114 return filled(d, 3, 0.f);
115}
116Tensor *TF::zeros4(int d0, int d1, int d2, int d3) {
117 int d[] = {d0, d1, d2, d3};
118 return filled(d, 4, 0.f);
119}
120Tensor *TF::zeros5(int d0, int d1, int d2, int d3, int d4) {
121 int d[] = {d0, d1, d2, d3, d4};
122 return filled(d, 5, 0.f);
123}
124Tensor *TF::zeros6(int d0, int d1, int d2, int d3, int d4, int d5) {
125 int d[] = {d0, d1, d2, d3, d4, d5};
126 return filled(d, 6, 0.f);
127}
128
130 int d[] = {d0};
131 return filled(d, 1, 1.f);
132}
133Tensor *TF::ones2(int d0, int d1) {
134 int d[] = {d0, d1};
135 return filled(d, 2, 1.f);
136}
137Tensor *TF::ones3(int d0, int d1, int d2) {
138 int d[] = {d0, d1, d2};
139 return filled(d, 3, 1.f);
140}
141Tensor *TF::ones4(int d0, int d1, int d2, int d3) {
142 int d[] = {d0, d1, d2, d3};
143 return filled(d, 4, 1.f);
144}
145Tensor *TF::ones5(int d0, int d1, int d2, int d3, int d4) {
146 int d[] = {d0, d1, d2, d3, d4};
147 return filled(d, 5, 1.f);
148}
149Tensor *TF::ones6(int d0, int d1, int d2, int d3, int d4, int d5) {
150 int d[] = {d0, d1, d2, d3, d4, d5};
151 return filled(d, 6, 1.f);
152}
153
154Tensor *TF::fill1(int d0, float value) {
155 int d[] = {d0};
156 return filled(d, 1, value);
157}
158Tensor *TF::fill2(int d0, int d1, float value) {
159 int d[] = {d0, d1};
160 return filled(d, 2, value);
161}
162Tensor *TF::fill3(int d0, int d1, int d2, float value) {
163 int d[] = {d0, d1, d2};
164 return filled(d, 3, value);
165}
166Tensor *TF::fill4(int d0, int d1, int d2, int d3, float value) {
167 int d[] = {d0, d1, d2, d3};
168 return filled(d, 4, value);
169}
170
172 int d[] = {1};
173 return filled(d, 1, value);
174}
175
177 if (n <= 0) throw Exception("TF.arange: n must be > 0");
178 if (tracing()) throw Exception("TF.arange: not supported while tracing (use inputs/constants)");
179 auto *t = new Tensor(n);
180 for (int i = 0; i < n; ++i) t->set1(i, float(i));
181 return t;
182}
183
184Tensor *TF::linspace(float start, float end, int n) {
185 if (n <= 0) throw Exception("TF.linspace: n must be > 0");
186 if (tracing()) throw Exception("TF.linspace: not supported while tracing");
187 auto *t = new Tensor(n);
188 if (n == 1) {
189 t->set1(0, start);
190 return t;
191 }
192 float step = (end - start) / float(n - 1);
193 for (int i = 0; i < n; ++i) t->set1(i, start + step * float(i));
194 return t;
195}
196
198 if (n <= 0) throw Exception("TF.eye: n must be > 0");
199 if (Func *f = tracing()) {
200 auto *eager = new Tensor(n, n);
201 for (int i = 0; i < n; ++i) eager->set2(i, i, 1.f);
202 int id = f->ensureNode(eager);
203 delete eager;
204 return Tensor::makeSymbolic(&f->graph(), id, f->graph().node(id).dims,
205 f->graph().node(id).rank);
206 }
207 auto *t = new Tensor(n, n);
208 for (int i = 0; i < n; ++i) t->set2(i, i, 1.f);
209 return t;
210}
211
213 if (tracing()) throw Exception("TF.randomUniform: not supported while tracing");
214 auto *t = zeros1(d0);
215 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextUniform());
216 return t;
217}
218
219Tensor *TF::randomUniform2(int d0, int d1) {
220 if (tracing()) throw Exception("TF.randomUniform: not supported while tracing");
221 auto *t = zeros2(d0, d1);
222 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextUniform());
223 return t;
224}
225
226Tensor *TF::randomUniform3(int d0, int d1, int d2) {
227 if (tracing()) throw Exception("TF.randomUniform: not supported while tracing");
228 auto *t = zeros3(d0, d1, d2);
229 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextUniform());
230 return t;
231}
232
233Tensor *TF::randomUniform4(int d0, int d1, int d2, int d3) {
234 if (tracing()) throw Exception("TF.randomUniform: not supported while tracing");
235 auto *t = zeros4(d0, d1, d2, d3);
236 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextUniform());
237 return t;
238}
239
241 if (tracing()) throw Exception("TF.randomNormal: not supported while tracing");
242 auto *t = zeros1(d0);
243 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextGaussian());
244 return t;
245}
246
247Tensor *TF::randomNormal2(int d0, int d1) {
248 if (tracing()) throw Exception("TF.randomNormal: not supported while tracing");
249 auto *t = zeros2(d0, d1);
250 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextGaussian());
251 return t;
252}
253
254Tensor *TF::randomNormal3(int d0, int d1, int d2) {
255 if (tracing()) throw Exception("TF.randomNormal: not supported while tracing");
256 auto *t = zeros3(d0, d1, d2);
257 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextGaussian());
258 return t;
259}
260
261Tensor *TF::randomNormal4(int d0, int d1, int d2, int d3) {
262 if (tracing()) throw Exception("TF.randomNormal: not supported while tracing");
263 auto *t = zeros4(d0, d1, d2, d3);
264 for (int i = 0; i < t->getSize(); ++i) t->set(i, nextGaussian());
265 return t;
266}
267
268#define EVE_TF_UNARY(name, method, opType) \
269 Tensor *TF::name(Tensor *a) { \
270 if (!a) throw Exception("TF." #name ": null"); \
271 if (Func *f = tracing()) return f->emitUnary(opType, a); \
272 a->ensureEager(#name); \
273 return a->method(); \
274 }
275
276EVE_TF_UNARY(neg, neg, OpType::Neg)
277EVE_TF_UNARY(abs, abs, OpType::Abs)
278EVE_TF_UNARY(sqrt, sqrt, OpType::Sqrt)
279EVE_TF_UNARY(exp, exp, OpType::Exp)
280EVE_TF_UNARY(log, log, OpType::Log)
281EVE_TF_UNARY(sin, sin, OpType::Sin)
282EVE_TF_UNARY(cos, cos, OpType::Cos)
283EVE_TF_UNARY(tanh, tanh, OpType::Tanh)
284EVE_TF_UNARY(relu, relu, OpType::Relu)
285EVE_TF_UNARY(sigmoid, sigmoid, OpType::Sigmoid)
286EVE_TF_UNARY(gelu, gelu, OpType::Gelu)
287EVE_TF_UNARY(silu, silu, OpType::Silu)
288
289#undef EVE_TF_UNARY
290
291#define EVE_TF_BINARY(name, method, opType) \
292 Tensor *TF::name(Tensor *a, Tensor *b) { \
293 if (!a || !b) throw Exception("TF." #name ": null"); \
294 if (Func *f = tracing()) return f->emitBinary(opType, a, b); \
295 a->ensureEager(#name); \
296 b->ensureEager(#name); \
297 return a->method(b); \
298 }
299
300EVE_TF_BINARY(add, add, OpType::Add)
301EVE_TF_BINARY(sub, sub, OpType::Sub)
302EVE_TF_BINARY(multiply, multiply, OpType::Multiply)
304
305#undef EVE_TF_BINARY
306
308 if (!a) throw Exception("TF.addScalar: null");
309 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::AddScalar, a, s);
310 return a->addScalar(s);
311}
313 if (!a) throw Exception("TF.subScalar: null");
314 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::SubScalar, a, s);
315 return a->subScalar(s);
316}
318 if (!a) throw Exception("TF.mulScalar: null");
319 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::MulScalar, a, s);
320 return a->mulScalar(s);
321}
323 if (!a) throw Exception("TF.divScalar: null");
324 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::DivScalar, a, s);
325 return a->divScalar(s);
326}
328 if (!a) throw Exception("TF.powScalar: null");
329 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::PowScalar, a, exp);
330 return a->powScalar(exp);
331}
332Tensor *TF::clamp(Tensor *a, float lo, float hi) {
333 if (!a) throw Exception("TF.clamp: null");
334 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::Clamp, a, lo, hi);
335 return a->clamp(lo, hi);
336}
338 if (!a) throw Exception("TF.maximumScalar: null");
339 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::MaximumScalar, a, s);
340 return a->maximumScalar(s);
341}
343 if (!a) throw Exception("TF.minimumScalar: null");
344 if (Func *f = tracing()) return f->emitUnaryScalar(OpType::MinimumScalar, a, s);
345 return a->minimumScalar(s);
346}
347
349 if (!a || !b) throw Exception("TF.matmul: null");
350 if (Func *f = tracing()) return f->emitMatMul(a, b);
351 return a->matmul(b);
352}
353
355 if (!a) throw Exception("TF.transpose: null");
356 if (Func *f = tracing()) return f->emitTranspose(a);
357 return a->transpose();
358}
359
360Tensor *TF::permute2(Tensor *a, int a0, int a1) {
361 if (!a) throw Exception("TF.permute2: null");
362 int order[] = {a0, a1};
363 if (Func *f = tracing()) return f->emitPermute(a, order, 2);
364 return a->permute(order, 2);
365}
366Tensor *TF::permute3(Tensor *a, int a0, int a1, int a2) {
367 if (!a) throw Exception("TF.permute3: null");
368 int order[] = {a0, a1, a2};
369 if (Func *f = tracing()) return f->emitPermute(a, order, 3);
370 return a->permute(order, 3);
371}
372Tensor *TF::permute4(Tensor *a, int a0, int a1, int a2, int a3) {
373 if (!a) throw Exception("TF.permute4: null");
374 int order[] = {a0, a1, a2, a3};
375 if (Func *f = tracing()) return f->emitPermute(a, order, 4);
376 return a->permute(order, 4);
377}
378Tensor *TF::permute5(Tensor *a, int a0, int a1, int a2, int a3, int a4) {
379 if (!a) throw Exception("TF.permute5: null");
380 int order[] = {a0, a1, a2, a3, a4};
381 if (Func *f = tracing()) return f->emitPermute(a, order, 5);
382 return a->permute(order, 5);
383}
384Tensor *TF::permute6(Tensor *a, int a0, int a1, int a2, int a3, int a4, int a5) {
385 if (!a) throw Exception("TF.permute6: null");
386 int order[] = {a0, a1, a2, a3, a4, a5};
387 if (Func *f = tracing()) return f->emitPermute(a, order, 6);
388 return a->permute(order, 6);
389}
390
392 if (!a) throw Exception("TF.reshape1: null");
393 int d[] = {d0};
394 if (Func *f = tracing()) return f->emitReshape(a, d, 1);
395 return a->reshape1(d0);
396}
397Tensor *TF::reshape2(Tensor *a, int d0, int d1) {
398 if (!a) throw Exception("TF.reshape2: null");
399 int d[] = {d0, d1};
400 if (Func *f = tracing()) return f->emitReshape(a, d, 2);
401 return a->reshape2(d0, d1);
402}
403Tensor *TF::reshape3(Tensor *a, int d0, int d1, int d2) {
404 if (!a) throw Exception("TF.reshape3: null");
405 int d[] = {d0, d1, d2};
406 if (Func *f = tracing()) return f->emitReshape(a, d, 3);
407 return a->reshape3(d0, d1, d2);
408}
409Tensor *TF::reshape4(Tensor *a, int d0, int d1, int d2, int d3) {
410 if (!a) throw Exception("TF.reshape4: null");
411 int d[] = {d0, d1, d2, d3};
412 if (Func *f = tracing()) return f->emitReshape(a, d, 4);
413 return a->reshape4(d0, d1, d2, d3);
414}
415Tensor *TF::reshape5(Tensor *a, int d0, int d1, int d2, int d3, int d4) {
416 if (!a) throw Exception("TF.reshape5: null");
417 int d[] = {d0, d1, d2, d3, d4};
418 if (Func *f = tracing()) return f->emitReshape(a, d, 5);
419 return a->reshape5(d0, d1, d2, d3, d4);
420}
421Tensor *TF::reshape6(Tensor *a, int d0, int d1, int d2, int d3, int d4, int d5) {
422 if (!a) throw Exception("TF.reshape6: null");
423 int d[] = {d0, d1, d2, d3, d4, d5};
424 if (Func *f = tracing()) return f->emitReshape(a, d, 6);
425 return a->reshape6(d0, d1, d2, d3, d4, d5);
426}
427
429 if (!a) throw Exception("TF.flatten: null");
430 int d[] = {a->getSize()};
431 if (Func *f = tracing()) return f->emitReshape(a, d, 1);
432 return a->flatten();
433}
434
436 if (!cond || !a || !b) throw Exception("TF.where: null");
437 if (Func *f = tracing()) return f->emitTernary(OpType::Where, cond, a, b);
438 if (cond->getRank() != a->getRank() || a->getRank() != b->getRank() ||
439 cond->getSize() != a->getSize() || a->getSize() != b->getSize())
440 throw Exception("TF.where: shape mismatch");
441 for (int i = 0; i < cond->getRank(); ++i) {
442 if (cond->getDim(i) != a->getDim(i) || a->getDim(i) != b->getDim(i))
443 throw Exception("TF.where: shape mismatch");
444 }
445 int dims[Tensor::kMaxRank] = {};
446 for (int i = 0; i < a->getRank(); ++i) dims[i] = a->getDim(i);
447 auto *out = new Tensor(dims, a->getRank());
448 for (int i = 0; i < a->getSize(); ++i)
449 out->set(i, cond->get(i) > 0.5f ? a->get(i) : b->get(i));
450 return out;
451}
452
453// --- neural / speech / terrain ops ---------------------------------------
454
456 if (!a) throw Exception("TF.softmax: null");
457 if (Func *f = tracing()) return f->emitSoftmax(a, axis, false);
458 a->ensureEager("softmax");
459 axis = normalizeAxis(axis, a->getRank());
460 int dims[Tensor::kMaxRank] = {};
461 for (int k = 0; k < a->getRank(); ++k) dims[k] = a->getDim(k);
462 auto *out = new Tensor(dims, a->getRank());
463 kernels::softmax(a->data(), dims, a->getRank(), axis, false, out->data());
464 return out;
465}
466
468 if (!a) throw Exception("TF.logSoftmax: null");
469 if (Func *f = tracing()) return f->emitSoftmax(a, axis, true);
470 a->ensureEager("logSoftmax");
471 axis = normalizeAxis(axis, a->getRank());
472 int dims[Tensor::kMaxRank] = {};
473 for (int k = 0; k < a->getRank(); ++k) dims[k] = a->getDim(k);
474 auto *out = new Tensor(dims, a->getRank());
475 kernels::softmax(a->data(), dims, a->getRank(), axis, true, out->data());
476 return out;
477}
478
480 if (!a) throw Exception("TF.layernorm: null");
481 if (Func *f = tracing()) return f->emitLayerNorm(a, nullptr, nullptr, eps);
482 a->ensureEager("layernorm");
483 const int cols = a->getDim(a->getRank() - 1);
484 const int rows = a->getSize() / cols;
485 int dims[Tensor::kMaxRank] = {};
486 for (int k = 0; k < a->getRank(); ++k) dims[k] = a->getDim(k);
487 auto *out = new Tensor(dims, a->getRank());
488 kernels::layernorm(a->data(), rows, cols, nullptr, nullptr, eps, out->data());
489 return out;
490}
491
493 if (!a || !scale || !bias) throw Exception("TF.layernormWB: null");
494 if (Func *f = tracing()) return f->emitLayerNorm(a, scale, bias, eps);
495 a->ensureEager("layernormWB");
496 const int cols = a->getDim(a->getRank() - 1);
497 if (scale->getSize() != cols || bias->getSize() != cols)
498 throw Exception("TF.layernormWB: scale/bias must match last dim");
499 const int rows = a->getSize() / cols;
500 int dims[Tensor::kMaxRank] = {};
501 for (int k = 0; k < a->getRank(); ++k) dims[k] = a->getDim(k);
502 auto *out = new Tensor(dims, a->getRank());
503 kernels::layernorm(a->data(), rows, cols, scale->data(), bias->data(), eps, out->data());
504 return out;
505}
506
507Tensor *TF::rmsnorm(Tensor *a, float eps) {
508 if (!a) throw Exception("TF.rmsnorm: null");
509 if (Func *f = tracing()) return f->emitRMSNorm(a, nullptr, eps);
510 a->ensureEager("rmsnorm");
511 const int cols = a->getDim(a->getRank() - 1);
512 const int rows = a->getSize() / cols;
513 int dims[Tensor::kMaxRank] = {};
514 for (int k = 0; k < a->getRank(); ++k) dims[k] = a->getDim(k);
515 auto *out = new Tensor(dims, a->getRank());
516 kernels::rmsnorm(a->data(), rows, cols, nullptr, eps, out->data());
517 return out;
518}
519
521 if (!a || !scale) throw Exception("TF.rmsnormW: null");
522 if (Func *f = tracing()) return f->emitRMSNorm(a, scale, eps);
523 a->ensureEager("rmsnormW");
524 const int cols = a->getDim(a->getRank() - 1);
525 if (scale->getSize() != cols) throw Exception("TF.rmsnormW: scale must match last dim");
526 const int rows = a->getSize() / cols;
527 int dims[Tensor::kMaxRank] = {};
528 for (int k = 0; k < a->getRank(); ++k) dims[k] = a->getDim(k);
529 auto *out = new Tensor(dims, a->getRank());
530 kernels::rmsnorm(a->data(), rows, cols, scale->data(), eps, out->data());
531 return out;
532}
533
534Tensor *TF::conv1d(Tensor *x, Tensor *w, int stride, int pad) {
535 return conv1dBias(x, w, nullptr, stride, pad);
536}
537
538Tensor *TF::conv1dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad) {
539 if (!x || !w) throw Exception("TF.conv1d: null");
540 if (Func *f = tracing()) return f->emitConv1d(x, w, bias, stride, pad);
541 if (x->getRank() != 3 || w->getRank() != 3) throw Exception("TF.conv1d: rank 3 required");
542 if (x->getDim(1) != w->getDim(1)) throw Exception("TF.conv1d: channel mismatch");
543 if (bias && bias->getSize() != w->getDim(0)) throw Exception("TF.conv1d: bias mismatch");
544 const int OL = convOutSize(x->getDim(2), w->getDim(2), stride, pad);
545 auto *out = new Tensor(x->getDim(0), w->getDim(0), OL);
546 int xd[3] = {x->getDim(0), x->getDim(1), x->getDim(2)};
547 int wd[3] = {w->getDim(0), w->getDim(1), w->getDim(2)};
548 kernels::conv1d(x->data(), xd, w->data(), wd, bias ? bias->data() : nullptr, stride, pad,
549 out->data());
550 return out;
551}
552
553Tensor *TF::conv2d(Tensor *x, Tensor *w, int stride, int pad) {
554 return conv2dBias(x, w, nullptr, stride, pad);
555}
556
557Tensor *TF::conv2dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad) {
558 if (!x || !w) throw Exception("TF.conv2d: null");
559 if (Func *f = tracing()) return f->emitConv2d(x, w, bias, stride, pad);
560 if (x->getRank() != 4 || w->getRank() != 4) throw Exception("TF.conv2d: rank 4 required");
561 if (x->getDim(1) != w->getDim(1)) throw Exception("TF.conv2d: channel mismatch");
562 if (bias && bias->getSize() != w->getDim(0)) throw Exception("TF.conv2d: bias mismatch");
563 const int OH = convOutSize(x->getDim(2), w->getDim(2), stride, pad);
564 const int OW = convOutSize(x->getDim(3), w->getDim(3), stride, pad);
565 auto *out = new Tensor(x->getDim(0), w->getDim(0), OH, OW);
566 int xd[4] = {x->getDim(0), x->getDim(1), x->getDim(2), x->getDim(3)};
567 int wd[4] = {w->getDim(0), w->getDim(1), w->getDim(2), w->getDim(3)};
568 kernels::conv2d(x->data(), xd, w->data(), wd, bias ? bias->data() : nullptr, stride, pad,
569 out->data());
570 return out;
571}
572
573Tensor *TF::maxpool2d(Tensor *x, int ksize, int stride, int pad) {
574 if (!x) throw Exception("TF.maxpool2d: null");
575 if (Func *f = tracing()) return f->emitPool(OpType::MaxPool2d, x, ksize, stride, pad);
576 if (x->getRank() != 4) throw Exception("TF.maxpool2d: rank 4 required");
577 const int OH = convOutSize(x->getDim(2), ksize, stride, pad);
578 const int OW = convOutSize(x->getDim(3), ksize, stride, pad);
579 auto *out = new Tensor(x->getDim(0), x->getDim(1), OH, OW);
580 int xd[4] = {x->getDim(0), x->getDim(1), x->getDim(2), x->getDim(3)};
581 kernels::maxpool2d(x->data(), xd, ksize, stride, pad, out->data());
582 return out;
583}
584
585Tensor *TF::avgpool2d(Tensor *x, int ksize, int stride, int pad) {
586 if (!x) throw Exception("TF.avgpool2d: null");
587 if (Func *f = tracing()) return f->emitPool(OpType::AvgPool2d, x, ksize, stride, pad);
588 if (x->getRank() != 4) throw Exception("TF.avgpool2d: rank 4 required");
589 const int OH = convOutSize(x->getDim(2), ksize, stride, pad);
590 const int OW = convOutSize(x->getDim(3), ksize, stride, pad);
591 auto *out = new Tensor(x->getDim(0), x->getDim(1), OH, OW);
592 int xd[4] = {x->getDim(0), x->getDim(1), x->getDim(2), x->getDim(3)};
593 kernels::avgpool2d(x->data(), xd, ksize, stride, pad, out->data());
594 return out;
595}
596
597Tensor *TF::embedding(Tensor *table, Tensor *indices) {
598 if (!table || !indices) throw Exception("TF.embedding: null");
599 if (Func *f = tracing()) return f->emitEmbedding(table, indices);
600 if (table->getRank() != 2) throw Exception("TF.embedding: table rank 2 required");
601 int dims[Tensor::kMaxRank] = {};
602 for (int k = 0; k < indices->getRank(); ++k) dims[k] = indices->getDim(k);
603 dims[indices->getRank()] = table->getDim(1);
604 auto *out = new Tensor(dims, indices->getRank() + 1);
605 if (table->isQuantized()) {
606 const std::vector<float> tf32 = table->dequantized();
607 kernels::embedding(tf32.data(), table->getDim(0), table->getDim(1), indices->data(),
608 indices->getSize(), out->data());
609 } else {
610 kernels::embedding(table->data(), table->getDim(0), table->getDim(1), indices->data(),
611 indices->getSize(), out->data());
612 }
613 return out;
614}
615
616Tensor *TF::quantizeWeight(Tensor *a, const std::string &dtype, int group) {
617 if (!a) throw Exception("TF.quantizeWeight: null");
618 if (tracing()) throw Exception("TF.quantizeWeight: quantize eager weights before tracing");
620 if (!parseDType(dtype, dt) || !q::isQuantDType(dt))
621 throw Exception("TF.quantizeWeight: expected fp16/fp8/fp4/int8/int4, got '%s'",
622 dtype.c_str());
623 a->ensureEager("quantizeWeight");
624 if (a->isQuantized()) throw Exception("TF.quantizeWeight: input is already quantized");
625 q::QuantPayload p = q::quantize(a->data(), a->getSize(), dt, group);
626 auto *out = new Tensor(dt, a->getRank() > 0 ? a->dims_ : nullptr, a->getRank());
627 out->bytes_ = std::move(p.bytes);
628 out->qScales_ = std::move(p.scales);
629 out->qGroup_ = p.group;
630 return out;
631}
632
634 Tensor *ins[] = {a, b};
635 return concatN(ins, 2, axis);
636}
637
639 Tensor *ins[] = {a, b, c};
640 return concatN(ins, 3, axis);
641}
642
644 Tensor *ins[] = {a, b, c, d};
645 return concatN(ins, 4, axis);
646}
647
648namespace {
649
650Tensor *concatEager(Tensor *const *ins, int n, int axis) {
651 for (int k = 0; k < n; ++k)
652 if (!ins[k]) throw Exception("TF.concat: null");
653 const int rank = ins[0]->getRank();
654 axis = normalizeAxis(axis, rank);
655 int dims[Tensor::kMaxRank] = {};
656 for (int k = 0; k < rank; ++k) {
657 if (k == axis) {
658 int total = 0;
659 for (int t = 0; t < n; ++t) total += ins[t]->getDim(k);
660 dims[k] = total;
661 } else {
662 dims[k] = ins[0]->getDim(k);
663 for (int t = 1; t < n; ++t)
664 if (ins[t]->getDim(k) != dims[k]) throw Exception("TF.concat: dims mismatch");
665 }
666 }
667 auto *out = new Tensor(dims, rank);
668 const float *ptrs[4] = {};
669 int inDims[4][Tensor::kMaxRank] = {};
670 const int *dimsPtr[4] = {};
671 int inRanks[4] = {};
672 for (int k = 0; k < n; ++k) {
673 ptrs[k] = ins[k]->data();
674 for (int d = 0; d < rank; ++d) inDims[k][d] = ins[k]->getDim(d);
675 dimsPtr[k] = inDims[k];
676 inRanks[k] = rank;
677 }
678 kernels::concat(ptrs, dimsPtr, inRanks, n, axis, out->data(), dims, rank);
679 return out;
680}
681
682} // namespace
683
684Tensor *TF::concatN(Tensor *const *ins, int n, int axis) {
685 if (Func *f = tracing()) return f->emitConcat(const_cast<const Tensor *const *>(ins), n, axis);
686 return concatEager(ins, n, axis);
687}
688
689Tensor *TF::slice(Tensor *a, int axis, int begin, int end) {
690 if (!a) throw Exception("TF.slice: null");
691 if (Func *f = tracing()) return f->emitSlice(a, axis, begin, end);
692 a->ensureEager("slice");
693 axis = normalizeAxis(axis, a->getRank());
694 if (begin < 0 || end < begin || end > a->getDim(axis))
695 throw Exception("TF.slice: range out of bounds");
696 int srcDims[Tensor::kMaxRank] = {};
697 int dims[Tensor::kMaxRank] = {};
698 for (int k = 0; k < a->getRank(); ++k) {
699 srcDims[k] = a->getDim(k);
700 dims[k] = a->getDim(k);
701 }
702 dims[axis] = end - begin;
703 auto *out = new Tensor(dims, a->getRank());
704 kernels::sliceOp(a->data(), srcDims, a->getRank(), axis, begin, end, out->data(), dims,
705 a->getRank());
706 return out;
707}
708
709#define EVE_TF_AXIS_REDUCE(name, opType) \
710 Tensor *TF::name(Tensor *a, int axis, int keepDims) { \
711 if (!a) throw Exception("TF." #name ": null"); \
712 if (Func *f = tracing()) return f->emitReduce(opType, a, axis, keepDims != 0); \
713 a->ensureEager(#name); \
714 axis = normalizeAxis(axis, a->getRank()); \
715 int srcDims[Tensor::kMaxRank] = {}; \
716 for (int k = 0; k < a->getRank(); ++k) srcDims[k] = a->getDim(k); \
717 int od[Tensor::kMaxRank] = {}; \
718 int outRank = 0; \
719 reduceOutDims(srcDims, a->getRank(), axis, keepDims != 0, od, outRank); \
720 auto *out = new Tensor(od, outRank); \
721 kernels::reduceAxis(opType, a->data(), srcDims, a->getRank(), axis, out->data(), od, \
722 outRank); \
723 return out; \
724 }
725
730
731#undef EVE_TF_AXIS_REDUCE
732
733Tensor *TF::argmax(Tensor *a, int axis, int keepDims) {
734 if (!a) throw Exception("TF.argmax: null");
735 if (Func *f = tracing()) return f->emitArgMax(a, axis, keepDims != 0);
736 a->ensureEager("argmax");
737 axis = normalizeAxis(axis, a->getRank());
738 int srcDims[Tensor::kMaxRank] = {};
739 for (int k = 0; k < a->getRank(); ++k) srcDims[k] = a->getDim(k);
740 int od[Tensor::kMaxRank] = {};
741 int outRank = 0;
742 reduceOutDims(srcDims, a->getRank(), axis, keepDims != 0, od, outRank);
743 auto *out = new Tensor(DType::Int32, od, outRank);
744 kernels::argmax(a->data(), srcDims, a->getRank(), axis, out->data(), od, outRank);
745 return out;
746}
747
748Tensor *TF::cast(Tensor *a, const std::string &dtype) {
749 if (!a) throw Exception("TF.cast: null");
751 if (!parseDType(dtype, dt)) throw Exception("TF.cast: unknown dtype '%s'", dtype.c_str());
752 if (Func *f = tracing()) return f->emitCast(a, dt);
753 a->ensureEager("cast");
754 int dims[Tensor::kMaxRank] = {};
755 for (int k = 0; k < a->getRank(); ++k) dims[k] = a->getDim(k);
756 auto *out = new Tensor(dt, dims, a->getRank());
757 std::memcpy(out->data(), a->data(), sizeof(float) * static_cast<size_t>(a->getSize()));
758 return out;
759}
760
762 return sdpaMasked(q, k, v, nullptr, scale);
763}
764
766 if (!q || !k || !v) throw Exception("TF.sdpa: null");
767 if (Func *f = tracing()) return f->emitSdpa(q, k, v, mask, scale);
768 if (q->getRank() != 4 || k->getRank() != 4 || v->getRank() != 4)
769 throw Exception("TF.sdpa: rank 4 required");
770 if (q->getDim(0) != k->getDim(0) || q->getDim(1) != k->getDim(1) ||
771 q->getDim(3) != k->getDim(3) || k->getDim(2) != v->getDim(2) ||
772 q->getDim(3) != v->getDim(3))
773 throw Exception("TF.sdpa: q/k/v shape mismatch");
774 if (mask && (mask->getRank() != 4 || mask->getDim(0) != q->getDim(0) ||
775 mask->getDim(1) != q->getDim(1) || mask->getDim(2) != q->getDim(2) ||
776 mask->getDim(3) != k->getDim(2)))
777 throw Exception("TF.sdpa: mask shape mismatch");
778 auto *out = new Tensor(q->getDim(0), q->getDim(1), q->getDim(2), q->getDim(3));
779 kernels::sdpa(q->data(), k->data(), v->data(), mask ? mask->data() : nullptr, q->getDim(0),
780 q->getDim(1), q->getDim(2), k->getDim(2), q->getDim(3), scale, out->data());
781 return out;
782}
783
784Tensor *TF::resize2d(Tensor *a, int outW, int outH, int mode) {
785 if (!a) throw Exception("TF.resize2d: null");
786 if (Func *f = tracing()) return f->emitResize2d(a, outH, outW, mode);
787 if (a->getRank() != 4) throw Exception("TF.resize2d: rank 4 required");
788 if (outW <= 0 || outH <= 0) throw Exception("TF.resize2d: bad output size");
789 auto *out = new Tensor(a->getDim(0), a->getDim(1), outH, outW);
790 int xd[4] = {a->getDim(0), a->getDim(1), a->getDim(2), a->getDim(3)};
791 kernels::resize2d(a->data(), xd, outW, outH, mode, out->data());
792 return out;
793}
794
796 if (!a) throw Exception("TF.reduceSum: null");
797 if (tracing()) throw Exception("TF.reduceSum: not supported while tracing");
798 a->ensureEager("reduceSum");
799 float gpuResult = 0.f;
800 if (a->getSize() >= kGpuReduceMinSize && gpuReduce(a->data(), a->getSize(), 0, gpuResult))
801 return gpuResult;
802 return a->reduceSum();
803}
805 if (!a) throw Exception("TF.reduceMean: null");
806 if (tracing()) throw Exception("TF.reduceMean: not supported while tracing");
807 a->ensureEager("reduceMean");
808 if (a->getSize() <= 0) return 0.f;
809 return reduceSum(a) / float(a->getSize());
810}
812 if (!a) throw Exception("TF.reduceMin: null");
813 if (tracing()) throw Exception("TF.reduceMin: not supported while tracing");
814 a->ensureEager("reduceMin");
815 float gpuResult = 0.f;
816 if (a->getSize() >= kGpuReduceMinSize && gpuReduce(a->data(), a->getSize(), 1, gpuResult))
817 return gpuResult;
818 return a->reduceMin();
819}
821 if (!a) throw Exception("TF.reduceMax: null");
822 if (tracing()) throw Exception("TF.reduceMax: not supported while tracing");
823 a->ensureEager("reduceMax");
824 float gpuResult = 0.f;
825 if (a->getSize() >= kGpuReduceMinSize && gpuReduce(a->data(), a->getSize(), 2, gpuResult))
826 return gpuResult;
827 return a->reduceMax();
828}
829
830void TF::expose(ssq::Table &table) {
831 auto cls = table.addClass(name, TF::create, false);
832 expose(cls);
833
834 auto ten = table.addClass<Tensor>(
835 "Tensor", std::function<Tensor *()>([]() -> Tensor * { return nullptr; }), true);
836
837 ten.addFunc("isSymbolic", &Tensor::isSymbolic);
838 ten.addFunc("isEager", &Tensor::isEager);
839 ten.addFunc("getRank", &Tensor::getRank);
840 ten.addFunc("getSize", &Tensor::getSize);
841 ten.addFunc("getDim", &Tensor::getDim);
842 ten.addFunc("getDim0", &Tensor::getDim0);
843 ten.addFunc("getDim1", &Tensor::getDim1);
844 ten.addFunc("getDim2", &Tensor::getDim2);
845 ten.addFunc("getDim3", &Tensor::getDim3);
846 ten.addFunc("getDim4", &Tensor::getDim4);
847 ten.addFunc("getDim5", &Tensor::getDim5);
848 ten.addFunc("getDevice", &Tensor::getDevice);
849 ten.addFunc("getDtype", &Tensor::getDtype);
850 ten.addFunc("isQuantized", &Tensor::isQuantized);
851
852 ten.addFunc("get", &Tensor::get);
853 ten.addFunc("set", &Tensor::set);
854 ten.addFunc("get1", &Tensor::get1);
855 ten.addFunc("set1", &Tensor::set1);
856 ten.addFunc("get2", &Tensor::get2);
857 ten.addFunc("set2", &Tensor::set2);
858 ten.addFunc("get3", &Tensor::get3);
859 ten.addFunc("set3", &Tensor::set3);
860 ten.addFunc("get4", &Tensor::get4);
861 ten.addFunc("set4", &Tensor::set4);
862 ten.addFunc("get5", &Tensor::get5);
863 ten.addFunc("set5", &Tensor::set5);
864 ten.addFunc("get6", &Tensor::get6);
865 ten.addFunc("set6", &Tensor::set6);
866
867 ten.addFunc("fill", &Tensor::fill);
868 ten.addFunc("copyFrom", &Tensor::copyFrom);
869 ten.addFunc("clone", &Tensor::clone);
870
871 ten.addFunc("add", &Tensor::add);
872 ten.addFunc("sub", &Tensor::sub);
873 ten.addFunc("multiply", &Tensor::multiply);
874 ten.addFunc("div", &Tensor::div);
875 ten.addFunc("addScalar", &Tensor::addScalar);
876 ten.addFunc("subScalar", &Tensor::subScalar);
877 ten.addFunc("mulScalar", &Tensor::mulScalar);
878 ten.addFunc("divScalar", &Tensor::divScalar);
879 ten.addFunc("neg", &Tensor::neg);
880 ten.addFunc("abs", &Tensor::abs);
881 ten.addFunc("sqrt", &Tensor::sqrt);
882 ten.addFunc("exp", &Tensor::exp);
883 ten.addFunc("log", &Tensor::log);
884 ten.addFunc("sin", &Tensor::sin);
885 ten.addFunc("cos", &Tensor::cos);
886 ten.addFunc("tanh", &Tensor::tanh);
887 ten.addFunc("relu", &Tensor::relu);
888 ten.addFunc("sigmoid", &Tensor::sigmoid);
889 ten.addFunc("gelu", &Tensor::gelu);
890 ten.addFunc("silu", &Tensor::silu);
891 ten.addFunc("powScalar", &Tensor::powScalar);
892 ten.addFunc("clamp", &Tensor::clamp);
893 ten.addFunc("maximumScalar", &Tensor::maximumScalar);
894 ten.addFunc("minimumScalar", &Tensor::minimumScalar);
895
896 ten.addFunc("addInPlace", &Tensor::addInPlace);
897 ten.addFunc("multiplyInPlace", &Tensor::multiplyInPlace);
898 ten.addFunc("addScalarInPlace", &Tensor::addScalarInPlace);
899 ten.addFunc("mulScalarInPlace", &Tensor::mulScalarInPlace);
900 ten.addFunc("reluInPlace", &Tensor::reluInPlace);
901
902 ten.addFunc("reduceSum", &Tensor::reduceSum);
903 ten.addFunc("reduceMean", &Tensor::reduceMean);
904 ten.addFunc("reduceMin", &Tensor::reduceMin);
905 ten.addFunc("reduceMax", &Tensor::reduceMax);
906 ten.addFunc("dot", &Tensor::dot);
907
908 ten.addFunc("matmul", &Tensor::matmul);
909 ten.addFunc("transpose", &Tensor::transpose);
910 ten.addFunc("reshape1", &Tensor::reshape1);
911 ten.addFunc("reshape2", &Tensor::reshape2);
912 ten.addFunc("reshape3", &Tensor::reshape3);
913 ten.addFunc("reshape4", &Tensor::reshape4);
914 ten.addFunc("reshape5", &Tensor::reshape5);
915 ten.addFunc("reshape6", &Tensor::reshape6);
916 ten.addFunc("flatten", &Tensor::flatten);
917
918 auto fn = table.addClass<Func>(
919 "Func", std::function<Func *()>([]() -> Func * { return nullptr; }), true);
920 fn.addFunc("input1", &Func::input1);
921 fn.addFunc("input2", &Func::input2);
922 fn.addFunc("input3", &Func::input3);
923 fn.addFunc("input4", &Func::input4);
924 fn.addFunc("input5", &Func::input5);
925 fn.addFunc("input6", &Func::input6);
926 fn.addFunc("setOutput", &Func::setOutput);
927 fn.addFunc("compile", &Func::compile);
928
929 auto cf = table.addClass<CompiledFunction>(
930 "CompiledFunction",
931 std::function<CompiledFunction *()>([]() -> CompiledFunction * { return nullptr; }), true);
932 cf.addFunc("run0", &CompiledFunction::run0);
933 cf.addFunc("run1", &CompiledFunction::run1);
934 cf.addFunc("run2", &CompiledFunction::run2);
935 cf.addFunc("run3", &CompiledFunction::run3);
936 cf.addFunc("run4", &CompiledFunction::run4);
937 cf.addFunc("run5", &CompiledFunction::run5);
938 cf.addFunc("run6", &CompiledFunction::run6);
939 cf.addFunc("getPlaceholderCount", &CompiledFunction::getPlaceholderCount);
940 cf.addFunc("getDevice", &CompiledFunction::getDevice);
941}
942
943void TF::expose(ssq::Class &cls) {
944 cls.addFunc("getName", &TF::getName);
945 cls.addFunc("func", &TF::func);
946 cls.addFunc("quantizeWeight", &TF::quantizeWeight);
947
948 cls.addFunc("zeros1", &TF::zeros1);
949 cls.addFunc("zeros2", &TF::zeros2);
950 cls.addFunc("zeros3", &TF::zeros3);
951 cls.addFunc("zeros4", &TF::zeros4);
952 cls.addFunc("zeros5", &TF::zeros5);
953 cls.addFunc("zeros6", &TF::zeros6);
954 cls.addFunc("ones1", &TF::ones1);
955 cls.addFunc("ones2", &TF::ones2);
956 cls.addFunc("ones3", &TF::ones3);
957 cls.addFunc("ones4", &TF::ones4);
958 cls.addFunc("ones5", &TF::ones5);
959 cls.addFunc("ones6", &TF::ones6);
960 cls.addFunc("fill1", &TF::fill1);
961 cls.addFunc("fill2", &TF::fill2);
962 cls.addFunc("fill3", &TF::fill3);
963 cls.addFunc("fill4", &TF::fill4);
964 cls.addFunc("constantScalar", &TF::constantScalar);
965 cls.addFunc("arange", &TF::arange);
966 cls.addFunc("linspace", &TF::linspace);
967 cls.addFunc("eye", &TF::eye);
968 cls.addFunc("randomUniform1", &TF::randomUniform1);
969 cls.addFunc("randomUniform2", &TF::randomUniform2);
970 cls.addFunc("randomUniform3", &TF::randomUniform3);
971 cls.addFunc("randomUniform4", &TF::randomUniform4);
972 cls.addFunc("randomNormal1", &TF::randomNormal1);
973 cls.addFunc("randomNormal2", &TF::randomNormal2);
974 cls.addFunc("randomNormal3", &TF::randomNormal3);
975 cls.addFunc("randomNormal4", &TF::randomNormal4);
976 cls.addFunc("rand1", &TF::rand1);
977 cls.addFunc("rand2", &TF::rand2);
978 cls.addFunc("rand3", &TF::rand3);
979 cls.addFunc("rand4", &TF::rand4);
980 cls.addFunc("randn1", &TF::randn1);
981 cls.addFunc("randn2", &TF::randn2);
982 cls.addFunc("randn3", &TF::randn3);
983 cls.addFunc("randn4", &TF::randn4);
984 cls.addFunc("setRandomSeed", &TF::setRandomSeed);
985 cls.addFunc("getRandomSeed", &TF::getRandomSeed);
986
987 cls.addFunc("add", &TF::add);
988 cls.addFunc("sub", &TF::sub);
989 cls.addFunc("multiply", &TF::multiply);
990 cls.addFunc("div", &TF::div);
991 cls.addFunc("addScalar", &TF::addScalar);
992 cls.addFunc("subScalar", &TF::subScalar);
993 cls.addFunc("mulScalar", &TF::mulScalar);
994 cls.addFunc("divScalar", &TF::divScalar);
995 cls.addFunc("neg", &TF::neg);
996 cls.addFunc("abs", &TF::abs);
997 cls.addFunc("sqrt", &TF::sqrt);
998 cls.addFunc("exp", &TF::exp);
999 cls.addFunc("log", &TF::log);
1000 cls.addFunc("sin", &TF::sin);
1001 cls.addFunc("cos", &TF::cos);
1002 cls.addFunc("tanh", &TF::tanh);
1003 cls.addFunc("relu", &TF::relu);
1004 cls.addFunc("sigmoid", &TF::sigmoid);
1005 cls.addFunc("gelu", &TF::gelu);
1006 cls.addFunc("silu", &TF::silu);
1007 cls.addFunc("powScalar", &TF::powScalar);
1008 cls.addFunc("clamp", &TF::clamp);
1009 cls.addFunc("maximumScalar", &TF::maximumScalar);
1010 cls.addFunc("minimumScalar", &TF::minimumScalar);
1011 cls.addFunc("matmul", &TF::matmul);
1012 cls.addFunc("transpose", &TF::transpose);
1013 cls.addFunc("permute2", &TF::permute2);
1014 cls.addFunc("permute3", &TF::permute3);
1015 cls.addFunc("permute4", &TF::permute4);
1016 cls.addFunc("permute5", &TF::permute5);
1017 cls.addFunc("permute6", &TF::permute6);
1018 cls.addFunc("reshape1", &TF::reshape1);
1019 cls.addFunc("reshape2", &TF::reshape2);
1020 cls.addFunc("reshape3", &TF::reshape3);
1021 cls.addFunc("reshape4", &TF::reshape4);
1022 cls.addFunc("reshape5", &TF::reshape5);
1023 cls.addFunc("reshape6", &TF::reshape6);
1024 cls.addFunc("flatten", &TF::flatten);
1025 cls.addFunc("where", &TF::where);
1026 cls.addFunc("reduceSum", &TF::reduceSum);
1027 cls.addFunc("reduceMean", &TF::reduceMean);
1028 cls.addFunc("reduceMin", &TF::reduceMin);
1029 cls.addFunc("reduceMax", &TF::reduceMax);
1030
1031 cls.addFunc("softmax", &TF::softmax);
1032 cls.addFunc("logSoftmax", &TF::logSoftmax);
1033 cls.addFunc("layernorm", &TF::layernorm);
1034 cls.addFunc("layernormWB", &TF::layernormWB);
1035 cls.addFunc("rmsnorm", &TF::rmsnorm);
1036 cls.addFunc("rmsnormW", &TF::rmsnormW);
1037 cls.addFunc("conv1d", &TF::conv1d);
1038 cls.addFunc("conv1dBias", &TF::conv1dBias);
1039 cls.addFunc("conv2d", &TF::conv2d);
1040 cls.addFunc("conv2dBias", &TF::conv2dBias);
1041 cls.addFunc("maxpool2d", &TF::maxpool2d);
1042 cls.addFunc("avgpool2d", &TF::avgpool2d);
1043 cls.addFunc("embedding", &TF::embedding);
1044 cls.addFunc("concat2", &TF::concat2);
1045 cls.addFunc("concat3", &TF::concat3);
1046 cls.addFunc("concat4", &TF::concat4);
1047 cls.addFunc("slice", &TF::slice);
1048 cls.addFunc("sumAxis", &TF::sumAxis);
1049 cls.addFunc("meanAxis", &TF::meanAxis);
1050 cls.addFunc("minAxis", &TF::minAxis);
1051 cls.addFunc("maxAxis", &TF::maxAxis);
1052 cls.addFunc("argmax", &TF::argmax);
1053 cls.addFunc("cast", &TF::cast);
1054 cls.addFunc("sdpa", &TF::sdpa);
1055 cls.addFunc("sdpaMasked", &TF::sdpaMasked);
1056 cls.addFunc("resize2d", &TF::resize2d);
1057}
1058
1059} // namespace eve::tensor
uint32_t seed
std::string value
HSQOBJECT cls
Definition ECS.cpp:21
int x
Definition Grass.cpp:135
glm::vec3 n
Definition Grass.cpp:64
int w
const FusedGroup & group
uint32_t a
uint32_t b
uint32_t c
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:24
float f
glm::vec4 p[6]
const char * name
Definition RockMesh.cpp:21
SettlementPipeline::Stage fn
int d
int v
#define EVE_TF_BINARY(name, method, opType)
Definition TF.cpp:291
#define EVE_TF_UNARY(name, method, opType)
Definition TF.cpp:268
#define EVE_TF_AXIS_REDUCE(name, opType)
Definition TF.cpp:709
float scale
Definition TreeMesh.cpp:122
float step
Definition TreeMesh.cpp:196
uint32_t s
Definition Weather.cpp:28
virtual std::string getName() const =0
Tensor * run1(Tensor *in0)
Definition Graph.cpp:613
Tensor * run2(Tensor *in0, Tensor *in1)
Definition Graph.cpp:618
Tensor * run5(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3, Tensor *in4)
Definition Graph.cpp:633
Tensor * run4(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3)
Definition Graph.cpp:628
std::string getDevice() const
Definition Graph.h:205
int getPlaceholderCount() const
Definition Graph.h:204
Tensor * run3(Tensor *in0, Tensor *in1, Tensor *in2)
Definition Graph.cpp:623
Tensor * run6(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3, Tensor *in4, Tensor *in5)
Definition Graph.cpp:638
Trace builder — TF2 tf.function analogue (tf.func in scripts). While active, TF ops record into this ...
Definition Graph.h:125
class CompiledFunction * compile()
Definition Graph.cpp:583
Tensor * input6(int d0, int d1, int d2, int d3, int d4, int d5)
Definition Graph.cpp:118
Tensor * input4(int d0, int d1, int d2, int d3)
Definition Graph.cpp:106
Tensor * input1(int d0)
Definition Graph.cpp:88
Tensor * input5(int d0, int d1, int d2, int d3, int d4)
Definition Graph.cpp:112
void setOutput(Tensor *t)
Definition Graph.cpp:124
Tensor * input2(int d0, int d1)
Definition Graph.cpp:94
Tensor * input3(int d0, int d1, int d2)
Definition Graph.cpp:100
TF2-like namespace module. Script: tf <- eve.TF(); Default eager; tf.func() traces a graph for compil...
Definition TF.h:18
Tensor * randn4(int d0, int d1, int d2, int d3)
Definition TF.h:74
Tensor * maxAxis(Tensor *a, int axis, int keepDims)
Tensor * transpose(Tensor *a)
Definition TF.cpp:354
Tensor * minimumScalar(Tensor *a, float s)
Definition TF.cpp:342
Tensor * layernormWB(Tensor *a, Tensor *scale, Tensor *bias, float eps)
Definition TF.cpp:492
Tensor * reshape2(Tensor *a, int d0, int d1)
Definition TF.cpp:397
Tensor * quantizeWeight(Tensor *a, const std::string &dtype, int group=0)
Definition TF.cpp:616
Tensor * neg(Tensor *a)
Tensor * rand3(int d0, int d1, int d2)
Definition TF.h:67
Tensor * layernorm(Tensor *a, float eps)
Definition TF.cpp:479
Tensor * divScalar(Tensor *a, float s)
Definition TF.cpp:322
Tensor * maxpool2d(Tensor *x, int ksize, int stride, int pad)
Definition TF.cpp:573
Tensor * randomNormal1(int d0)
Definition TF.cpp:240
void popTrace(Func *f)
Definition TF.cpp:77
Tensor * argmax(Tensor *a, int axis, int keepDims)
Definition TF.cpp:733
Tensor * addScalar(Tensor *a, float s)
Definition TF.cpp:307
Tensor * softmax(Tensor *a, int axis)
Definition TF.cpp:455
Tensor * permute3(Tensor *a, int a0, int a1, int a2)
Definition TF.cpp:366
Tensor * linspace(float start, float end, int n)
Definition TF.cpp:184
Tensor * resize2d(Tensor *a, int outW, int outH, int mode)
Definition TF.cpp:784
Tensor * fill3(int d0, int d1, int d2, float value)
Definition TF.cpp:162
Tensor * add(Tensor *a, Tensor *b)
Tensor * concatN(Tensor *const *ins, int n, int axis)
Definition TF.cpp:684
Tensor * multiply(Tensor *a, Tensor *b)
Tensor * zeros1(int d0)
Definition TF.cpp:104
void setRandomSeed(uint32_t seed)
Definition TF.cpp:66
Tensor * relu(Tensor *a)
Tensor * embedding(Tensor *table, Tensor *indices)
Definition TF.cpp:597
Tensor * avgpool2d(Tensor *x, int ksize, int stride, int pad)
Definition TF.cpp:585
Tensor * rand4(int d0, int d1, int d2, int d3)
Definition TF.h:68
float reduceMin(Tensor *a)
Definition TF.cpp:811
Tensor * tanh(Tensor *a)
uint32_t getRandomSeed() const
Definition TF.cpp:71
Tensor * zeros6(int d0, int d1, int d2, int d3, int d4, int d5)
Definition TF.cpp:124
Tensor * fill4(int d0, int d1, int d2, int d3, float value)
Definition TF.cpp:166
Tensor * exp(Tensor *a)
Tensor * ones1(int d0)
Definition TF.cpp:129
Tensor * sigmoid(Tensor *a)
Tensor * clamp(Tensor *a, float lo, float hi)
Definition TF.cpp:332
float reduceMean(Tensor *a)
Definition TF.cpp:804
float reduceSum(Tensor *a)
Definition TF.cpp:795
Tensor * gelu(Tensor *a)
Tensor * reshape5(Tensor *a, int d0, int d1, int d2, int d3, int d4)
Definition TF.cpp:415
Tensor * ones2(int d0, int d1)
Definition TF.cpp:133
Tensor * sumAxis(Tensor *a, int axis, int keepDims)
Tensor * ones3(int d0, int d1, int d2)
Definition TF.cpp:137
Tensor * log(Tensor *a)
Tensor * abs(Tensor *a)
Tensor * randn2(int d0, int d1)
Definition TF.h:72
Tensor * sqrt(Tensor *a)
Tensor * conv1d(Tensor *x, Tensor *w, int stride, int pad)
Definition TF.cpp:534
Tensor * randomNormal4(int d0, int d1, int d2, int d3)
Definition TF.cpp:261
Tensor * rand2(int d0, int d1)
Definition TF.h:66
Tensor * meanAxis(Tensor *a, int axis, int keepDims)
void pushTrace(Func *f)
Definition TF.cpp:73
Tensor * conv1dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad)
Definition TF.cpp:538
Tensor * randomUniform1(int d0)
Definition TF.cpp:212
Tensor * minAxis(Tensor *a, int axis, int keepDims)
Tensor * flatten(Tensor *a)
Definition TF.cpp:428
Tensor * fill2(int d0, int d1, float value)
Definition TF.cpp:158
Tensor * randomUniform4(int d0, int d1, int d2, int d3)
Definition TF.cpp:233
float reduceMax(Tensor *a)
Definition TF.cpp:820
Tensor * concat3(Tensor *a, Tensor *b, Tensor *c, int axis)
Definition TF.cpp:638
Tensor * reshape1(Tensor *a, int d0)
Definition TF.cpp:391
Tensor * randomUniform2(int d0, int d1)
Definition TF.cpp:219
Tensor * sdpa(Tensor *q, Tensor *k, Tensor *v, float scale)
Definition TF.cpp:761
Tensor * rand1(int d0)
Definition TF.h:65
Tensor * sub(Tensor *a, Tensor *b)
Tensor * eye(int n)
Definition TF.cpp:197
Tensor * zeros4(int d0, int d1, int d2, int d3)
Definition TF.cpp:116
Tensor * slice(Tensor *a, int axis, int begin, int end)
Definition TF.cpp:689
Tensor * arange(int n)
Definition TF.cpp:176
Tensor * reshape4(Tensor *a, int d0, int d1, int d2, int d3)
Definition TF.cpp:409
Tensor * maximumScalar(Tensor *a, float s)
Definition TF.cpp:337
Tensor * rmsnorm(Tensor *a, float eps)
Definition TF.cpp:507
Tensor * randomUniform3(int d0, int d1, int d2)
Definition TF.cpp:226
Tensor * zeros5(int d0, int d1, int d2, int d3, int d4)
Definition TF.cpp:120
Tensor * randn3(int d0, int d1, int d2)
Definition TF.h:73
Tensor * matmul(Tensor *a, Tensor *b)
Definition TF.cpp:348
Tensor * zeros2(int d0, int d1)
Definition TF.cpp:108
Tensor * sin(Tensor *a)
Func * func()
Definition TF.cpp:95
Tensor * cos(Tensor *a)
Tensor * ones6(int d0, int d1, int d2, int d3, int d4, int d5)
Definition TF.cpp:149
Tensor * sdpaMasked(Tensor *q, Tensor *k, Tensor *v, Tensor *mask, float scale)
Definition TF.cpp:765
Tensor * powScalar(Tensor *a, float exp)
Definition TF.cpp:327
Tensor * reshape6(Tensor *a, int d0, int d1, int d2, int d3, int d4, int d5)
Definition TF.cpp:421
Tensor * reshape3(Tensor *a, int d0, int d1, int d2)
Definition TF.cpp:403
Tensor * div(Tensor *a, Tensor *b)
Tensor * randomNormal2(int d0, int d1)
Definition TF.cpp:247
Tensor * constantScalar(float value)
Definition TF.cpp:171
Tensor * logSoftmax(Tensor *a, int axis)
Definition TF.cpp:467
Tensor * concat4(Tensor *a, Tensor *b, Tensor *c, Tensor *d, int axis)
Definition TF.cpp:643
Tensor * silu(Tensor *a)
Tensor * rmsnormW(Tensor *a, Tensor *scale, float eps)
Definition TF.cpp:520
Tensor * zeros3(int d0, int d1, int d2)
Definition TF.cpp:112
Tensor * conv2dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad)
Definition TF.cpp:557
Tensor * conv2d(Tensor *x, Tensor *w, int stride, int pad)
Definition TF.cpp:553
Tensor * where(Tensor *cond, Tensor *a, Tensor *b)
Definition TF.cpp:435
Tensor * ones4(int d0, int d1, int d2, int d3)
Definition TF.cpp:141
Tensor * permute4(Tensor *a, int a0, int a1, int a2, int a3)
Definition TF.cpp:372
Tensor * ones5(int d0, int d1, int d2, int d3, int d4)
Definition TF.cpp:145
Tensor * permute5(Tensor *a, int a0, int a1, int a2, int a3, int a4)
Definition TF.cpp:378
Tensor * permute6(Tensor *a, int a0, int a1, int a2, int a3, int a4, int a5)
Definition TF.cpp:384
Tensor * mulScalar(Tensor *a, float s)
Definition TF.cpp:317
Tensor * subScalar(Tensor *a, float s)
Definition TF.cpp:312
Func * tracing() const
Definition TF.cpp:91
Tensor * randn1(int d0)
Definition TF.h:71
Tensor * concat2(Tensor *a, Tensor *b, int axis)
Definition TF.cpp:633
Tensor * cast(Tensor *a, const std::string &dtype)
Definition TF.cpp:748
Tensor * fill1(int d0, float value)
Definition TF.cpp:154
Tensor * randomNormal3(int d0, int d1, int d2)
Definition TF.cpp:254
Tensor * permute2(Tensor *a, int a0, int a1)
Definition TF.cpp:360
float32 / int32 tensor (rank 1–6), row-major. Eager: owns a buffer. Symbolic: node in a Func graph (n...
Definition Tensor.h:43
Tensor * tanh() const
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
std::string getDtype() const
Definition Tensor.h:77
float reduceSum() const
归约:求和 / 均值 / 最小 / 最大。
Definition Tensor.cpp:437
Tensor * sin() const
int getDim4() const
Definition Tensor.h:74
bool isQuantized() const
Definition Tensor.h:82
void fill(float value)
Definition Tensor.cpp:267
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
Tensor * log() const
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
int getDim2() const
Definition Tensor.h:72
float get1(int i0) const
Definition Tensor.cpp:218
float get4(int i0, int i1, int i2, int i3) const
Definition Tensor.cpp:242
Tensor * sigmoid() const
int getDim3() const
Definition Tensor.h:73
std::vector< float > dequantized() const
Definition Tensor.cpp:210
Tensor * abs() const
std::string getDevice() const
Definition Tensor.h:76
void mulScalarInPlace(float s)
Definition Tensor.cpp:424
int getSize() const
Definition Tensor.h:68
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 * neg() const
Tensor * reshape2(int d0, int d1) const
Definition Tensor.cpp:569
float * data()
原始数据指针(eager)。
Definition Tensor.cpp:185
Tensor * relu() const
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
Tensor * exp() const
Tensor * gelu() 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
bool isSymbolic() const
Definition Tensor.h:62
int getDim1() const
Definition Tensor.h:71
int getDim0() const
Definition Tensor.h:70
Tensor * powScalar(float exp) const
Definition Tensor.cpp:350
Tensor * subScalar(float s) const
Definition Tensor.cpp:332
int getRank() const
Definition Tensor.h:67
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 * sqrt() const
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
Tensor * silu() const
bool isEager() const
Definition Tensor.h:63
void multiplyInPlace(const Tensor *other)
Definition Tensor.cpp:409
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
int getDim5() const
Definition Tensor.h:75
Tensor * addScalar(float s) const
Definition Tensor.cpp:326
float reduceMean() const
Definition Tensor.cpp:444
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
Tensor * cos() const
void maxpool2d(const float *in, const int *dims, int ksize, int stride, int pad, float *out)
void softmax(const float *in, const int *dims, int rank, int axis, bool logMode, float *out)
void conv2d(const float *x, const int *xDims, const float *w, const int *wDims, const float *bias, int stride, int pad, float *out)
void sdpa(const float *q, const float *k, const float *v, const float *mask, int B, int H, int T, int S, int D, float scale, float *out)
void sliceOp(const float *in, const int *inDims, int inRank, int axis, int begin, int end, float *out, const int *outDims, int outRank)
void embedding(const float *table, int vocab, int dim, const float *indices, int count, float *out)
void avgpool2d(const float *in, const int *dims, int ksize, int stride, int pad, float *out)
void argmax(const float *in, const int *dims, int rank, int axis, float *out, const int *outDims, int outRank)
void layernorm(const float *in, int rows, int cols, const float *scale, const float *bias, float eps, float *out)
void rmsnorm(const float *in, int rows, int cols, const float *scale, float eps, float *out)
void concat(const float *const *ins, const int *const *inDims, const int *inRanks, int n, int axis, float *out, const int *outDims, int outRank)
void conv1d(const float *x, const int *xDims, const float *w, const int *wDims, const float *bias, int stride, int pad, float *out)
void resize2d(const float *in, const int *inDims, int outW, int outH, int mode, float *out)
QuantPayload quantize(const float *src, int count, DType dt, int group)
Definition Quant.h:216
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
bool gpuReduce(const float *data, int size, int op, float &outResult)
GPU-accelerated reduction for large eager tensors. op: 0 = sum, 1 = min, 2 = max. Returns false (call...