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");
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");
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");
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);
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);
498 throw Exception(
"TF.layernormWB: scale/bias must match last dim");
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);
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");
528 for (
int k = 0; k <
a->getRank(); ++k) dims[k] =
a->getDim(k);
529 auto *out =
new Tensor(dims,
a->getRank());
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)};
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)};
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);
603 dims[
indices->getRank()] = table->getDim(1);
605 if (table->isQuantized()) {
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);
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);
703 auto *out =
new Tensor(dims,
a->getRank());
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");
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) ||
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) ||
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));
780 q->getDim(1),
q->getDim(2), k->
getDim(2),
q->getDim(3),
scale, out->data());
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) {
building::EdgeCurveGroup group
std::array< double, 10 > q
std::vector< std::uint32_t > indices
std::array< float, 3 > scale
#define Module_IMPL(ModuleName, newExpr)
#define EVE_TF_BINARY(name, method, opType)
#define EVE_TF_UNARY(name, method, opType)
#define EVE_TF_AXIS_REDUCE(name, opType)
EVENGINE_API_FOUNDATION public API.
virtual std::string getName() const =0
Returns the name.
Tensor * run1(Tensor *in0)
Run 1.
Tensor * run2(Tensor *in0, Tensor *in1)
Run 2.
Tensor * run5(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3, Tensor *in4)
Run 5.
Tensor * run4(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3)
Run 4.
std::string getDevice() const
Returns the device.
int getPlaceholderCount() const
Returns the placeholder count.
Tensor * run3(Tensor *in0, Tensor *in1, Tensor *in2)
Run 3.
Tensor * run6(Tensor *in0, Tensor *in1, Tensor *in2, Tensor *in3, Tensor *in4, Tensor *in5)
Run 6.
Trace builder — TF2 tf.function analogue (tf.func in scripts). While active, TF ops record into this ...
class CompiledFunction * compile()
Compiles compile.
Tensor * input6(int d0, int d1, int d2, int d3, int d4, int d5)
Input 6.
Tensor * input4(int d0, int d1, int d2, int d3)
Input 4.
Tensor * input1(int d0)
Input 1.
Tensor * input5(int d0, int d1, int d2, int d3, int d4)
Input 5.
void setOutput(Tensor *t)
Sets the output.
Tensor * input2(int d0, int d1)
Input 2.
Tensor * input3(int d0, int d1, int d2)
Input 3.
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)
Randn 4.
Tensor * maxAxis(Tensor *a, int axis, int keepDims)
Max axis.
Tensor * transpose(Tensor *a)
Transpose.
Tensor * minimumScalar(Tensor *a, float s)
Minimum scalar.
Tensor * layernormWB(Tensor *a, Tensor *scale, Tensor *bias, float eps)
Layernorm wb.
Tensor * reshape2(Tensor *a, int d0, int d1)
Reshape 2.
Tensor * quantizeWeight(Tensor *a, const std::string &dtype, int group=0)
Quantize weight.
Tensor * neg(Tensor *a)
Neg.
Tensor * rand3(int d0, int d1, int d2)
Rand 3.
Tensor * layernorm(Tensor *a, float eps)
Layernorm.
Tensor * divScalar(Tensor *a, float s)
Div scalar.
Tensor * maxpool2d(Tensor *x, int ksize, int stride, int pad)
Maxpool 2 d.
Tensor * randomNormal1(int d0)
Random normal 1.
void popTrace(Func *f)
Pops trace.
Tensor * argmax(Tensor *a, int axis, int keepDims)
Argmax.
Tensor * addScalar(Tensor *a, float s)
Adds scalar.
Tensor * softmax(Tensor *a, int axis)
Softmax.
Tensor * permute3(Tensor *a, int a0, int a1, int a2)
Permute 3.
Tensor * linspace(float start, float end, int n)
Linspace.
Tensor * resize2d(Tensor *a, int outW, int outH, int mode)
Resize 2 d.
Tensor * fill3(int d0, int d1, int d2, float value)
Fill 3.
Tensor * add(Tensor *a, Tensor *b)
Adds add.
Tensor * concatN(Tensor *const *ins, int n, int axis)
Concat n.
Tensor * multiply(Tensor *a, Tensor *b)
Multiply.
Tensor * zeros1(int d0)
Zeros 1.
void setRandomSeed(uint32_t seed)
Sets the random seed.
Tensor * relu(Tensor *a)
Relu.
Tensor * embedding(Tensor *table, Tensor *indices)
Embedding.
Tensor * avgpool2d(Tensor *x, int ksize, int stride, int pad)
Avgpool 2 d.
Tensor * rand4(int d0, int d1, int d2, int d3)
Rand 4.
float reduceMin(Tensor *a)
Reduce min.
Tensor * tanh(Tensor *a)
Tanh.
uint32_t getRandomSeed() const
Returns the random seed.
Tensor * zeros6(int d0, int d1, int d2, int d3, int d4, int d5)
Zeros 6.
Tensor * fill4(int d0, int d1, int d2, int d3, float value)
Fill 4.
Tensor * exp(Tensor *a)
Exp.
Tensor * ones1(int d0)
Ones 1.
Tensor * sigmoid(Tensor *a)
Sigmoid.
Tensor * clamp(Tensor *a, float lo, float hi)
Clamp.
float reduceMean(Tensor *a)
Reduce mean.
float reduceSum(Tensor *a)
Reduce sum.
Tensor * gelu(Tensor *a)
Gelu.
Tensor * reshape5(Tensor *a, int d0, int d1, int d2, int d3, int d4)
Reshape 5.
Tensor * ones2(int d0, int d1)
Ones 2.
Tensor * sumAxis(Tensor *a, int axis, int keepDims)
Sum axis.
Tensor * ones3(int d0, int d1, int d2)
Ones 3.
Tensor * log(Tensor *a)
Log.
Tensor * abs(Tensor *a)
Abs.
Tensor * randn2(int d0, int d1)
Randn 2.
Tensor * sqrt(Tensor *a)
Sqrt.
Tensor * conv1d(Tensor *x, Tensor *w, int stride, int pad)
Conv 1 d.
Tensor * randomNormal4(int d0, int d1, int d2, int d3)
Random normal 4.
Tensor * rand2(int d0, int d1)
Rand 2.
Tensor * meanAxis(Tensor *a, int axis, int keepDims)
Mean axis.
void pushTrace(Func *f)
Pushes trace.
Tensor * conv1dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad)
Conv 1 d bias.
Tensor * randomUniform1(int d0)
Random uniform 1.
Tensor * minAxis(Tensor *a, int axis, int keepDims)
Min axis.
Tensor * flatten(Tensor *a)
Flatten.
Tensor * fill2(int d0, int d1, float value)
Fill 2.
Tensor * randomUniform4(int d0, int d1, int d2, int d3)
Random uniform 4.
float reduceMax(Tensor *a)
Reduce max.
Tensor * concat3(Tensor *a, Tensor *b, Tensor *c, int axis)
Concat 3.
Tensor * reshape1(Tensor *a, int d0)
Reshape 1.
Tensor * randomUniform2(int d0, int d1)
Random uniform 2.
Tensor * sdpa(Tensor *q, Tensor *k, Tensor *v, float scale)
Sdpa.
Tensor * rand1(int d0)
Rand 1.
Tensor * sub(Tensor *a, Tensor *b)
Sub.
Tensor * zeros4(int d0, int d1, int d2, int d3)
Zeros 4.
Tensor * slice(Tensor *a, int axis, int begin, int end)
Slice.
Tensor * arange(int n)
Arange.
Tensor * reshape4(Tensor *a, int d0, int d1, int d2, int d3)
Reshape 4.
Tensor * maximumScalar(Tensor *a, float s)
Maximum scalar.
Tensor * rmsnorm(Tensor *a, float eps)
Rmsnorm.
Tensor * randomUniform3(int d0, int d1, int d2)
Random uniform 3.
Tensor * zeros5(int d0, int d1, int d2, int d3, int d4)
Zeros 5.
Tensor * randn3(int d0, int d1, int d2)
Randn 3.
Tensor * matmul(Tensor *a, Tensor *b)
Matmul.
Tensor * zeros2(int d0, int d1)
Zeros 2.
Tensor * sin(Tensor *a)
Sin.
Tensor * cos(Tensor *a)
Cos.
Tensor * ones6(int d0, int d1, int d2, int d3, int d4, int d5)
Ones 6.
Tensor * sdpaMasked(Tensor *q, Tensor *k, Tensor *v, Tensor *mask, float scale)
Sdpa masked.
Tensor * powScalar(Tensor *a, float exp)
Pow scalar.
Tensor * reshape6(Tensor *a, int d0, int d1, int d2, int d3, int d4, int d5)
Reshape 6.
Tensor * reshape3(Tensor *a, int d0, int d1, int d2)
Reshape 3.
Tensor * div(Tensor *a, Tensor *b)
Div.
Tensor * randomNormal2(int d0, int d1)
Random normal 2.
Tensor * constantScalar(float value)
Constant scalar.
Tensor * logSoftmax(Tensor *a, int axis)
Log softmax.
Tensor * concat4(Tensor *a, Tensor *b, Tensor *c, Tensor *d, int axis)
Concat 4.
Tensor * silu(Tensor *a)
Silu.
Tensor * rmsnormW(Tensor *a, Tensor *scale, float eps)
Rmsnorm w.
Tensor * zeros3(int d0, int d1, int d2)
Zeros 3.
Tensor * conv2dBias(Tensor *x, Tensor *w, Tensor *bias, int stride, int pad)
Conv 2 d bias.
Tensor * conv2d(Tensor *x, Tensor *w, int stride, int pad)
Conv 2 d.
Tensor * where(Tensor *cond, Tensor *a, Tensor *b)
Where.
Tensor * ones4(int d0, int d1, int d2, int d3)
Ones 4.
Tensor * permute4(Tensor *a, int a0, int a1, int a2, int a3)
Permute 4.
Tensor * ones5(int d0, int d1, int d2, int d3, int d4)
Ones 5.
Tensor * permute5(Tensor *a, int a0, int a1, int a2, int a3, int a4)
Permute 5.
Tensor * permute6(Tensor *a, int a0, int a1, int a2, int a3, int a4, int a5)
Permute 6.
Tensor * mulScalar(Tensor *a, float s)
Mul scalar.
Tensor * subScalar(Tensor *a, float s)
Sub scalar.
Func * tracing() const
Tracing.
Tensor * randn1(int d0)
Randn 1.
Tensor * concat2(Tensor *a, Tensor *b, int axis)
Concat 2.
Tensor * cast(Tensor *a, const std::string &dtype)
Cast.
Tensor * fill1(int d0, float value)
Fill 1.
Tensor * randomNormal3(int d0, int d1, int d2)
Random normal 3.
Tensor * permute2(Tensor *a, int a0, int a1)
Permute 2.
float32 / int32 tensor (rank 1–6), row-major. Eager: owns a buffer. Symbolic: node in a Func graph (n...
Tensor * tanh() const
Tanh.
Tensor * mulScalar(float s) const
Mul scalar.
Tensor * reshape5(int d0, int d1, int d2, int d3, int d4) const
Reshape 5.
Tensor * sub(const Tensor *other) const
Sub.
std::string getDtype() const
Returns the dtype.
float reduceSum() const
归约:求和 / 均值 / 最小 / 最大。
int getDim4() const
Returns the dim 4.
bool isQuantized() const
True when quantized.
void fill(float value)
Fill.
Tensor * add(const Tensor *other) const
Eager 逐元素运算(符号张量会抛异常)。
void copyFrom(const Tensor *other)
Copies from.
void set3(int i0, int i1, int i2, float value)
Sets the 3.
float reduceMax() const
Reduce max.
void addScalarInPlace(float s)
Adds scalar in place.
static constexpr int kMaxRank
Tensor * reshape4(int d0, int d1, int d2, int d3) const
Reshape 4.
float get3(int i0, int i1, int i2) const
Returns the 3.
int getDim2() const
Returns the dim 2.
float get1(int i0) const
Returns the 1.
float get4(int i0, int i1, int i2, int i3) const
Returns the 4.
Tensor * sigmoid() const
Sigmoid.
int getDim3() const
Returns the dim 3.
std::string getDevice() const
Returns the device.
void mulScalarInPlace(float s)
Mul scalar in place.
int getSize() const
Byte length of the owned buffer.
float get5(int i0, int i1, int i2, int i3, int i4) const
Returns the 5.
Tensor * reshape6(int d0, int d1, int d2, int d3, int d4, int d5) const
Reshape 6.
Tensor * reshape2(int d0, int d1) const
Reshape 2.
float * data()
原始数据指针(eager)。
Tensor * relu() const
Relu.
Tensor * clamp(float lo, float hi) const
Clamp.
Tensor * reshape1(int d0) const
Reshape 1.
float dot(const Tensor *other) const
Dot.
Tensor * gelu() const
Gelu.
float get6(int i0, int i1, int i2, int i3, int i4, int i5) const
Returns the 6.
Tensor * divScalar(float s) const
Div scalar.
Tensor * multiply(const Tensor *other) const
Multiply.
float get2(int i0, int i1) const
Returns the 2.
bool isSymbolic() const
True when symbolic.
int getDim1() const
Returns the dim 1.
int getDim0() const
Returns the dim 0.
Tensor * powScalar(float exp) const
Pow scalar.
Tensor * subScalar(float s) const
Sub scalar.
int getRank() const
Returns the rank.
void set1(int i0, float value)
Sets the 1.
int getDim(int axis) const
Returns the dim.
Tensor * transpose() const
Transpose.
void set(int flatIndex, float value)
Sets the set.
Tensor * clone() const
Deep copy. @ownership Caller deletes.
void set4(int i0, int i1, int i2, int i3, float value)
Sets the 4.
float get(int flatIndex) const
Returns the get.
Tensor * maximumScalar(float s) const
Maximum scalar.
Tensor * sqrt() const
Sqrt.
Tensor * div(const Tensor *other) const
Div.
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)
Sets the 2.
Tensor * reshape3(int d0, int d1, int d2) const
Reshape 3.
Tensor * silu() const
Silu.
bool isEager() const
True when eager.
void multiplyInPlace(const Tensor *other)
Multiply in place.
void reluInPlace()
Relu in place.
Tensor * flatten() const
Flatten.
Tensor * matmul(const Tensor *other) const
矩阵乘法 / 转置 / 变形。
Tensor * minimumScalar(float s) const
Minimum scalar.
int getDim5() const
Returns the dim 5.
Tensor * addScalar(float s) const
Adds scalar.
float reduceMean() const
Reduce mean.
void addInPlace(const Tensor *other)
Eager 原地运算。
void set6(int i0, int i1, int i2, int i3, int i4, int i5, float value)
Sets the 6.
void set5(int i0, int i1, int i2, int i3, int i4, float value)
Sets the 5.
float reduceMin() const
Reduce min.
void maxpool2d(const float *in, const int *dims, int ksize, int stride, int pad, float *out)
Maxpool 2 d.
void conv2d(const float *x, const int *xDims, const float *w, const int *wDims, const float *bias, int stride, int pad, float *out)
Conv 2 d.
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)
Sdpa.
void sliceOp(const float *in, const int *inDims, int inRank, int axis, int begin, int end, float *out, const int *outDims, int outRank)
Slice op.
void embedding(const float *table, int vocab, int dim, const float *indices, int count, float *out)
Embedding.
void avgpool2d(const float *in, const int *dims, int ksize, int stride, int pad, float *out)
Avgpool 2 d.
void argmax(const float *in, const int *dims, int rank, int axis, float *out, const int *outDims, int outRank)
Argmax.
void layernorm(const float *in, int rows, int cols, const float *scale, const float *bias, float eps, float *out)
Layernorm.
void rmsnorm(const float *in, int rows, int cols, const float *scale, float eps, float *out)
Rmsnorm.
void softmax(const float *in, const int *dims, int rank, int axis, bool logMode, float *out)
Softmax.
void concat(const float *const *ins, const int *const *inDims, const int *inRanks, int n, int axis, float *out, const int *outDims, int outRank)
Concat.
void conv1d(const float *x, const int *xDims, const float *w, const int *wDims, const float *bias, int stride, int pad, float *out)
Conv 1 d.
void resize2d(const float *in, const int *inDims, int outW, int outH, int mode, float *out)
Resize 2 d.
int axis(int64_t a, size_t rank)
Axis.
QuantPayload quantize(const float *src, int count, DType dt, int group)
Quantize.
bool isQuantDType(DType dt)
True when quant d type.
bool parseDType(const std::string &name, DType &out)
Parse d type.
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...
SettlementPipeline::Stage fn