10#include <simplesquirrel/simplesquirrel.hpp>
20constexpr int kGpuReduceMinSize = 1 << 14;
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");
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");
34void reduceOutDims(
const int *dims,
int rank,
int axis,
int keepDims,
int *out,
int &outRank) {
36 for (
int k = 0; k < rank; ++k) out[k] = dims[k];
39 }
else if (rank == 1) {
42 for (
int k = axis; k < rank - 1; ++k) out[k] = out[k + 1];
54float TF::nextUniform()
const {
55 rngState_ = rngState_ * 1664525u + 1013904223u;
56 return float(rngState_ >> 8) * (1.f / 16777216.f);
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);
74 if (
f) traceStack_.push_back(
f);
78 if (traceStack_.empty())
return;
79 if (traceStack_.back() ==
f) {
80 traceStack_.pop_back();
83 for (
auto it = traceStack_.begin(); it != traceStack_.end(); ++it) {
85 traceStack_.erase(it);
92 return traceStack_.empty() ? nullptr : traceStack_.back();
97Tensor *TF::filled(
const int *dims,
int rank,
float value) {
99 auto *t =
new Tensor(dims, rank);
106 return filled(
d, 1, 0.f);
110 return filled(
d, 2, 0.f);
113 int d[] = {d0, d1, d2};
114 return filled(
d, 3, 0.f);
117 int d[] = {d0, d1, d2, d3};
118 return filled(
d, 4, 0.f);
121 int d[] = {d0, d1, d2, d3, d4};
122 return filled(
d, 5, 0.f);
125 int d[] = {d0, d1, d2, d3, d4, d5};
126 return filled(
d, 6, 0.f);
131 return filled(
d, 1, 1.f);
135 return filled(
d, 2, 1.f);
138 int d[] = {d0, d1, d2};
139 return filled(
d, 3, 1.f);
142 int d[] = {d0, d1, d2, d3};
143 return filled(
d, 4, 1.f);
146 int d[] = {d0, d1, d2, d3, d4};
147 return filled(
d, 5, 1.f);
150 int d[] = {d0, d1, d2, d3, d4, d5};
151 return filled(
d, 6, 1.f);
156 return filled(
d, 1,
value);
160 return filled(
d, 2,
value);
163 int d[] = {d0, d1, d2};
164 return filled(
d, 3,
value);
167 int d[] = {d0, d1, d2, d3};
168 return filled(
d, 4,
value);
173 return filled(
d, 1,
value);
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)");
180 for (
int i = 0; i <
n; ++i) t->set1(i,
float(i));
185 if (
n <= 0)
throw Exception(
"TF.linspace: n must be > 0");
192 float step = (end - start) /
float(
n - 1);
193 for (
int i = 0; i <
n; ++i) t->set1(i, start +
step *
float(i));
198 if (
n <= 0)
throw Exception(
"TF.eye: n must be > 0");
201 for (
int i = 0; i <
n; ++i) eager->set2(i, i, 1.f);
202 int id =
f->ensureNode(eager);
205 f->graph().node(
id).rank);
208 for (
int i = 0; i <
n; ++i) t->set2(i, i, 1.f);
213 if (
tracing())
throw Exception(
"TF.randomUniform: not supported while tracing");
215 for (
int i = 0; i < t->getSize(); ++i) t->set(i, nextUniform());
220 if (
tracing())
throw Exception(
"TF.randomUniform: not supported while tracing");
222 for (
int i = 0; i < t->getSize(); ++i) t->set(i, nextUniform());
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());
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());
241 if (
tracing())
throw Exception(
"TF.randomNormal: not supported while tracing");
243 for (
int i = 0; i < t->getSize(); ++i) t->set(i, nextGaussian());
248 if (
tracing())
throw Exception(
"TF.randomNormal: not supported while tracing");
250 for (
int i = 0; i < t->getSize(); ++i) t->set(i, nextGaussian());
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());
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());
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(); \
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); \
308 if (!
a)
throw Exception(
"TF.addScalar: null");
310 return a->addScalar(
s);
313 if (!
a)
throw Exception(
"TF.subScalar: null");
315 return a->subScalar(
s);
318 if (!
a)
throw Exception(
"TF.mulScalar: null");
320 return a->mulScalar(
s);
323 if (!
a)
throw Exception(
"TF.divScalar: null");
325 return a->divScalar(
s);
328 if (!
a)
throw Exception(
"TF.powScalar: null");
330 return a->powScalar(
exp);
335 return a->clamp(lo, hi);
338 if (!
a)
throw Exception(
"TF.maximumScalar: null");
340 return a->maximumScalar(
s);
343 if (!
a)
throw Exception(
"TF.minimumScalar: null");
345 return a->minimumScalar(
s);
355 if (!
a)
throw Exception(
"TF.transpose: null");
357 return a->transpose();
362 int order[] = {a0, a1};
364 return a->permute(order, 2);
368 int order[] = {a0, a1, a2};
370 return a->permute(order, 3);
374 int order[] = {a0, a1, a2, a3};
376 return a->permute(order, 4);
380 int order[] = {a0, a1, a2, a3, a4};
382 return a->permute(order, 5);
386 int order[] = {a0, a1, a2, a3, a4, a5};
388 return a->permute(order, 6);
395 return a->reshape1(d0);
401 return a->reshape2(d0, d1);
405 int d[] = {d0, d1, d2};
407 return a->reshape3(d0, d1, d2);
411 int d[] = {d0, d1, d2, d3};
413 return a->reshape4(d0, d1, d2, d3);
417 int d[] = {d0, d1, d2, d3, d4};
419 return a->reshape5(d0, d1, d2, d3, d4);
423 int d[] = {d0, d1, d2, d3, d4, d5};
425 return a->reshape6(d0, d1, d2, d3, d4, d5);
430 int d[] = {
a->getSize()};
436 if (!cond || !
a || !
b)
throw Exception(
"TF.where: null");
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");
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));
458 a->ensureEager(
"softmax");
459 axis = normalizeAxis(axis,
a->getRank());
461 for (
int k = 0; k <
a->getRank(); ++k) dims[k] =
a->getDim(k);
462 auto *out =
new Tensor(dims,
a->getRank());
468 if (!
a)
throw Exception(
"TF.logSoftmax: null");
470 a->ensureEager(
"logSoftmax");
471 axis = normalizeAxis(axis,
a->getRank());
473 for (
int k = 0; k <
a->getRank(); ++k) dims[k] =
a->getDim(k);
474 auto *out =
new Tensor(dims,
a->getRank());
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;
486 for (
int k = 0; k <
a->getRank(); ++k) dims[k] =
a->getDim(k);
487 auto *out =
new Tensor(dims,
a->getRank());
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;
501 for (
int k = 0; k <
a->getRank(); ++k) dims[k] =
a->getDim(k);
502 auto *out =
new Tensor(dims,
a->getRank());
510 a->ensureEager(
"rmsnorm");
511 const int cols =
a->getDim(
a->getRank() - 1);
512 const int rows =
a->getSize() / cols;
514 for (
int k = 0; k <
a->getRank(); ++k) dims[k] =
a->getDim(k);
515 auto *out =
new Tensor(dims,
a->getRank());
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;
528 for (
int k = 0; k <
a->getRank(); ++k) dims[k] =
a->getDim(k);
529 auto *out =
new Tensor(dims,
a->getRank());
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)};
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)};
574 if (!
x)
throw Exception(
"TF.maxpool2d: null");
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)};
586 if (!
x)
throw Exception(
"TF.avgpool2d: null");
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)};
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");
602 for (
int k = 0; k < indices->
getRank(); ++k) dims[k] = indices->
getDim(k);
606 const std::vector<float> tf32 = table->
dequantized();
608 indices->
getSize(), out->data());
611 indices->
getSize(), out->data());
617 if (!
a)
throw Exception(
"TF.quantizeWeight: null");
618 if (
tracing())
throw Exception(
"TF.quantizeWeight: quantize eager weights before tracing");
621 throw Exception(
"TF.quantizeWeight: expected fp16/fp8/fp4/int8/int4, got '%s'",
623 a->ensureEager(
"quantizeWeight");
624 if (
a->isQuantized())
throw Exception(
"TF.quantizeWeight: input is already quantized");
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;
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);
656 for (
int k = 0; k < rank; ++k) {
659 for (
int t = 0; t <
n; ++t) total += ins[t]->getDim(k);
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");
667 auto *out =
new Tensor(dims, rank);
668 const float *ptrs[4] = {};
670 const int *dimsPtr[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];
686 return concatEager(ins,
n, axis);
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");
698 for (
int k = 0; k <
a->getRank(); ++k) {
699 srcDims[k] =
a->getDim(k);
700 dims[k] =
a->getDim(k);
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,
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] = {}; \
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, \
731#undef EVE_TF_AXIS_REDUCE
735 if (
Func *
f =
tracing())
return f->emitArgMax(
a, axis, keepDims != 0);
736 a->ensureEager(
"argmax");
737 axis = normalizeAxis(axis,
a->getRank());
739 for (
int k = 0; k <
a->getRank(); ++k) srcDims[k] =
a->getDim(k);
742 reduceOutDims(srcDims,
a->getRank(), axis, keepDims != 0, od, outRank);
744 kernels::argmax(
a->data(), srcDims,
a->getRank(), axis, out->data(), od, outRank);
753 a->ensureEager(
"cast");
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()));
766 if (!q || !k || !
v)
throw Exception(
"TF.sdpa: null");
769 throw Exception(
"TF.sdpa: rank 4 required");
773 throw Exception(
"TF.sdpa: q/k/v shape mismatch");
777 throw Exception(
"TF.sdpa: mask shape mismatch");
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)};
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))
802 return a->reduceSum();
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;
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))
818 return a->reduceMin();
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))
827 return a->reduceMax();
830void TF::expose(ssq::Table &table) {
831 auto cls = table.addClass(
name, TF::create,
false);
834 auto ten = table.addClass<
Tensor>(
835 "Tensor", std::function<Tensor *()>([]() ->
Tensor * {
return nullptr; }),
true);
918 auto fn = table.addClass<Func>(
919 "Func", std::function<Func *()>([]() -> Func * {
return nullptr; }),
true);
929 auto cf = table.addClass<CompiledFunction>(
931 std::function<CompiledFunction *()>([]() -> CompiledFunction * {
return nullptr; }),
true);
943void TF::expose(ssq::Class &
cls) {
#define Module_IMPL(ModuleName, newExpr)
SettlementPipeline::Stage fn
#define EVE_TF_BINARY(name, method, opType)
#define EVE_TF_UNARY(name, method, opType)
#define EVE_TF_AXIS_REDUCE(name, opType)
virtual std::string getName() const =0
Tensor * run1(Tensor *in0)
Tensor * run2(Tensor *in0, Tensor *in1)
Tensor * run5(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3, Tensor *in4)
Tensor * run4(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3)
std::string getDevice() const
int getPlaceholderCount() const
Tensor * run3(Tensor *in0, Tensor *in1, Tensor *in2)
Tensor * run6(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3, Tensor *in4, Tensor *in5)
Trace builder — TF2 tf.function analogue (tf.func in scripts). While active, TF ops record into this ...
class CompiledFunction * compile()
Tensor * input6(int d0, int d1, int d2, int d3, int d4, int d5)
Tensor * input4(int d0, int d1, int d2, int d3)
Tensor * input5(int d0, int d1, int d2, int d3, int d4)
void setOutput(Tensor *t)
Tensor * input2(int d0, int d1)
Tensor * input3(int d0, int d1, int d2)
TF2-like namespace module. Script: tf <- eve.TF(); Default eager; tf.func() traces a graph for compil...
Tensor * randn4(int d0, int d1, int d2, int d3)
Tensor * maxAxis(Tensor *a, int axis, int keepDims)
Tensor * transpose(Tensor *a)
Tensor * minimumScalar(Tensor *a, float s)
Tensor * layernormWB(Tensor *a, Tensor *scale, Tensor *bias, float eps)
Tensor * reshape2(Tensor *a, int d0, int d1)
Tensor * quantizeWeight(Tensor *a, const std::string &dtype, int group=0)
Tensor * rand3(int d0, int d1, int d2)
Tensor * layernorm(Tensor *a, float eps)
Tensor * divScalar(Tensor *a, float s)
Tensor * maxpool2d(Tensor *x, int ksize, int stride, int pad)
Tensor * randomNormal1(int d0)
Tensor * argmax(Tensor *a, int axis, int keepDims)
Tensor * addScalar(Tensor *a, float s)
Tensor * softmax(Tensor *a, int axis)
Tensor * permute3(Tensor *a, int a0, int a1, int a2)
Tensor * linspace(float start, float end, int n)
Tensor * resize2d(Tensor *a, int outW, int outH, int mode)
Tensor * fill3(int d0, int d1, int d2, float value)
Tensor * add(Tensor *a, Tensor *b)
Tensor * concatN(Tensor *const *ins, int n, int axis)
Tensor * multiply(Tensor *a, Tensor *b)
void setRandomSeed(uint32_t seed)
Tensor * embedding(Tensor *table, Tensor *indices)
Tensor * avgpool2d(Tensor *x, int ksize, int stride, int pad)
Tensor * rand4(int d0, int d1, int d2, int d3)
float reduceMin(Tensor *a)
uint32_t getRandomSeed() const
Tensor * zeros6(int d0, int d1, int d2, int d3, int d4, int d5)
Tensor * fill4(int d0, int d1, int d2, int d3, float value)
Tensor * sigmoid(Tensor *a)
Tensor * clamp(Tensor *a, float lo, float hi)
float reduceMean(Tensor *a)
float reduceSum(Tensor *a)
Tensor * reshape5(Tensor *a, int d0, int d1, int d2, int d3, int d4)
Tensor * ones2(int d0, int d1)
Tensor * sumAxis(Tensor *a, int axis, int keepDims)
Tensor * ones3(int d0, int d1, int d2)
Tensor * randn2(int d0, int d1)
Tensor * conv1d(Tensor *x, Tensor *w, int stride, int pad)
Tensor * randomNormal4(int d0, int d1, int d2, int d3)
Tensor * rand2(int d0, int d1)
Tensor * meanAxis(Tensor *a, int axis, int keepDims)
Tensor * conv1dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad)
Tensor * randomUniform1(int d0)
Tensor * minAxis(Tensor *a, int axis, int keepDims)
Tensor * flatten(Tensor *a)
Tensor * fill2(int d0, int d1, float value)
Tensor * randomUniform4(int d0, int d1, int d2, int d3)
float reduceMax(Tensor *a)
Tensor * concat3(Tensor *a, Tensor *b, Tensor *c, int axis)
Tensor * reshape1(Tensor *a, int d0)
Tensor * randomUniform2(int d0, int d1)
Tensor * sdpa(Tensor *q, Tensor *k, Tensor *v, float scale)
Tensor * sub(Tensor *a, Tensor *b)
Tensor * zeros4(int d0, int d1, int d2, int d3)
Tensor * slice(Tensor *a, int axis, int begin, int end)
Tensor * reshape4(Tensor *a, int d0, int d1, int d2, int d3)
Tensor * maximumScalar(Tensor *a, float s)
Tensor * rmsnorm(Tensor *a, float eps)
Tensor * randomUniform3(int d0, int d1, int d2)
Tensor * zeros5(int d0, int d1, int d2, int d3, int d4)
Tensor * randn3(int d0, int d1, int d2)
Tensor * matmul(Tensor *a, Tensor *b)
Tensor * zeros2(int d0, int d1)
Tensor * ones6(int d0, int d1, int d2, int d3, int d4, int d5)
Tensor * sdpaMasked(Tensor *q, Tensor *k, Tensor *v, Tensor *mask, float scale)
Tensor * powScalar(Tensor *a, float exp)
Tensor * reshape6(Tensor *a, int d0, int d1, int d2, int d3, int d4, int d5)
Tensor * reshape3(Tensor *a, int d0, int d1, int d2)
Tensor * div(Tensor *a, Tensor *b)
Tensor * randomNormal2(int d0, int d1)
Tensor * constantScalar(float value)
Tensor * logSoftmax(Tensor *a, int axis)
Tensor * concat4(Tensor *a, Tensor *b, Tensor *c, Tensor *d, int axis)
Tensor * rmsnormW(Tensor *a, Tensor *scale, float eps)
Tensor * zeros3(int d0, int d1, int d2)
Tensor * conv2dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad)
Tensor * conv2d(Tensor *x, Tensor *w, int stride, int pad)
Tensor * where(Tensor *cond, Tensor *a, Tensor *b)
Tensor * ones4(int d0, int d1, int d2, int d3)
Tensor * permute4(Tensor *a, int a0, int a1, int a2, int a3)
Tensor * ones5(int d0, int d1, int d2, int d3, int d4)
Tensor * permute5(Tensor *a, int a0, int a1, int a2, int a3, int a4)
Tensor * permute6(Tensor *a, int a0, int a1, int a2, int a3, int a4, int a5)
Tensor * mulScalar(Tensor *a, float s)
Tensor * subScalar(Tensor *a, float s)
Tensor * concat2(Tensor *a, Tensor *b, int axis)
Tensor * cast(Tensor *a, const std::string &dtype)
Tensor * fill1(int d0, float value)
Tensor * randomNormal3(int d0, int d1, int d2)
Tensor * permute2(Tensor *a, int a0, int a1)
float32 / int32 tensor (rank 1–6), row-major. Eager: owns a buffer. Symbolic: node in a Func graph (n...
Tensor * mulScalar(float s) const
Tensor * reshape5(int d0, int d1, int d2, int d3, int d4) const
Tensor * sub(const Tensor *other) const
std::string getDtype() const
float reduceSum() const
归约:求和 / 均值 / 最小 / 最大。
Tensor * add(const Tensor *other) const
Eager 逐元素运算(符号张量会抛异常)。
void copyFrom(const Tensor *other)
void set3(int i0, int i1, int i2, float value)
void addScalarInPlace(float s)
static constexpr int kMaxRank
Tensor * reshape4(int d0, int d1, int d2, int d3) const
float get3(int i0, int i1, int i2) const
float get4(int i0, int i1, int i2, int i3) const
std::vector< float > dequantized() const
std::string getDevice() const
void mulScalarInPlace(float s)
float get5(int i0, int i1, int i2, int i3, int i4) const
Tensor * reshape6(int d0, int d1, int d2, int d3, int d4, int d5) const
Tensor * reshape2(int d0, int d1) const
float * data()
原始数据指针(eager)。
Tensor * clamp(float lo, float hi) const
Tensor * reshape1(int d0) const
float dot(const Tensor *other) const
float get6(int i0, int i1, int i2, int i3, int i4, int i5) const
Tensor * divScalar(float s) const
Tensor * multiply(const Tensor *other) const
float get2(int i0, int i1) const
Tensor * powScalar(float exp) const
Tensor * subScalar(float s) const
void set1(int i0, float value)
int getDim(int axis) const
Tensor * transpose() const
void set(int flatIndex, float value)
void set4(int i0, int i1, int i2, int i3, float value)
float get(int flatIndex) const
Tensor * maximumScalar(float s) const
Tensor * div(const Tensor *other) const
static Tensor * makeSymbolic(Graph *graph, int nodeId, const int *dims, int rank)
Symbolic handle into a graph node.
void set2(int i0, int i1, float value)
Tensor * reshape3(int d0, int d1, int d2) const
void multiplyInPlace(const Tensor *other)
Tensor * matmul(const Tensor *other) const
矩阵乘法 / 转置 / 变形。
Tensor * minimumScalar(float s) const
Tensor * addScalar(float s) const
void addInPlace(const Tensor *other)
Eager 原地运算。
void set6(int i0, int i1, int i2, int i3, int i4, int i5, float value)
void set5(int i0, int i1, int i2, int i3, int i4, float value)
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)
bool isQuantDType(DType dt)
bool parseDType(const std::string &name, DType &out)
DType
Tensor element types.
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...