26 if (tracing_ && owner_) owner_->
popTrace(
this);
34 for (
int i = 0; i < rank; ++i)
n.dims[i] = dims[i];
39Tensor *Func::makeSymbolicFromNode(
int nodeId) {
42 t->setDtype(
static_cast<DType>(
n.dtype));
48GraphNode makeInputNode(Graph &
graph,
OpType type,
const int *dims,
int rank,
int slot) {
53 for (
int i = 0; i < rank; ++i)
n.dims[i] = dims[i];
55 n.placeholderSlot = slot;
59int normalizeAxisChecked(
int axis,
int rank) {
60 if (axis < 0)
axis += rank;
61 if (axis < 0 || axis >= rank)
throw eve::Exception(
"Func: axis out of range");
65int convOutSize(
int inSize,
int kernel,
int stride,
int pad) {
66 const int out = (inSize + 2 *
pad - kernel) / stride + 1;
67 if (out <= 0)
throw eve::Exception(
"Func: conv output size must be > 0");
76 return makeSymbolicFromNode(
id);
82 return makeSymbolicFromNode(
id);
86 int d[] = {d0, d1, d2};
88 return makeSymbolicFromNode(
id);
92 int d[] = {d0, d1, d2, d3};
94 return makeSymbolicFromNode(
id);
98 int d[] = {d0, d1, d2, d3, d4};
100 return makeSymbolicFromNode(
id);
104 int d[] = {d0, d1, d2, d3, d4, d5};
106 return makeSymbolicFromNode(
id);
116 if (
t->isSymbolic()) {
117 if (
t->graph() != &graph_)
throw eve::Exception(
"Func: tensor from another graph");
120 t->ensureEager(
"capture");
122 if (
t->isQuantized()) {
123 n.constBytes =
t->qBytes();
124 n.constScales =
t->qScales();
125 n.qGroup =
t->qGroup();
127 n.constData.assign(
t->data(),
t->data() +
t->getSize());
129 n.dtype =
static_cast<int>(
t->dtype_);
130 return graph_.
addNode(std::move(
n));
135 n.constData.assign(
static_cast<size_t>(
n.size),
value);
136 int id = graph_.
addNode(std::move(
n));
137 return makeSymbolicFromNode(
id);
142 const auto &src = graph_.
node(ix);
143 auto n = makeShapeNode(
type, src.dims, src.rank);
146 int id = graph_.
addNode(std::move(
n));
147 return makeSymbolicFromNode(
id);
152 const auto &src = graph_.
node(ix);
153 auto n = makeShapeNode(
type, src.dims, src.rank);
158 int id = graph_.
addNode(std::move(
n));
159 return makeSymbolicFromNode(
id);
165 const auto &na = graph_.
node(ia);
166 const auto &nb = graph_.
node(ib);
171 auto n = makeShapeNode(
type, od, orank);
174 int id = graph_.
addNode(std::move(
n));
175 return makeSymbolicFromNode(
id);
182 const auto &na = graph_.
node(ia);
183 auto n = makeShapeNode(
type, na.dims, na.rank);
187 int id = graph_.
addNode(std::move(
n));
188 return makeSymbolicFromNode(
id);
194 const auto &na = graph_.
node(ia);
195 const auto &nb = graph_.
node(ib);
196 if (na.rank == 2 && nb.rank == 2) {
197 if (na.dims[1] != nb.dims[0])
throw eve::Exception(
"Func.matmul: inner dims mismatch");
198 int od[] = {na.dims[0], nb.dims[1]};
202 int id = graph_.
addNode(std::move(
n));
203 return makeSymbolicFromNode(
id);
205 if (na.rank == 3 && nb.rank == 3) {
206 if (na.dims[0] != nb.dims[0] || na.dims[2] != nb.dims[1])
208 int od[] = {na.dims[0], na.dims[1], nb.dims[2]};
212 int id = graph_.
addNode(std::move(
n));
213 return makeSymbolicFromNode(
id);
220 const auto &src = graph_.
node(ix);
221 if (src.rank != 2)
throw eve::Exception(
"Func.transpose: rank 2 required");
222 int order[] = {1, 0};
228 const auto &src = graph_.
node(ix);
229 if (rank != src.rank)
throw eve::Exception(
"Func.permute: rank mismatch");
231 for (
int k = 0; k < rank; ++k) {
234 od[k] = src.dims[
order[k]];
238 for (
int k = 0; k < rank; ++k)
n.perm[k] =
order[k];
240 int id = graph_.
addNode(std::move(
n));
241 return makeSymbolicFromNode(
id);
246 const auto &src = graph_.
node(ix);
248 if (newSize != src.size)
throw eve::Exception(
"Func.reshape: size mismatch");
252 int id = graph_.
addNode(std::move(
n));
253 return makeSymbolicFromNode(
id);
258 const auto &src = graph_.
node(ix);
259 axis = normalizeAxisChecked(axis, src.rank);
263 int id = graph_.
addNode(std::move(
n));
264 return makeSymbolicFromNode(
id);
269void checkParamVector(
const GraphNode &src,
int cols,
const char *what) {
279 const auto &src = graph_.
node(ix);
287 checkParamVector(graph_.
node(is),
cols,
"layernorm scale");
292 checkParamVector(graph_.
node(ib),
cols,
"layernorm bias");
295 int id = graph_.
addNode(std::move(
n));
296 return makeSymbolicFromNode(
id);
301 const auto &src = graph_.
node(ix);
309 checkParamVector(graph_.
node(is),
cols,
"rmsnorm scale");
312 int id = graph_.
addNode(std::move(
n));
313 return makeSymbolicFromNode(
id);
320 const auto &
nx = graph_.
node(ix);
321 const auto &nw = graph_.
node(iw);
322 if (
nx.rank != 3 || nw.rank != 3)
throw eve::Exception(
"Func.conv1d: rank 3 required");
323 if (
nx.dims[1] != nw.dims[1])
throw eve::Exception(
"Func.conv1d: channel mismatch");
324 const int OL = convOutSize(
nx.dims[2], nw.dims[2], stride,
pad);
325 int od[] = {
nx.dims[0], nw.dims[0], OL};
333 const auto &nb = graph_.
node(ib);
334 if (nb.rank != 1 || nb.dims[0] !=
n.dims[1])
throw eve::Exception(
"Func.conv1d: bias shape mismatch");
337 int id = graph_.
addNode(std::move(
n));
338 return makeSymbolicFromNode(
id);
345 const auto &
nx = graph_.
node(ix);
346 const auto &nw = graph_.
node(iw);
347 if (
nx.rank != 4 || nw.rank != 4)
throw eve::Exception(
"Func.conv2d: rank 4 required");
348 if (
nx.dims[1] != nw.dims[1])
throw eve::Exception(
"Func.conv2d: channel mismatch");
349 const int OH = convOutSize(
nx.dims[2], nw.dims[2], stride,
pad);
350 const int OW = convOutSize(
nx.dims[3], nw.dims[3], stride,
pad);
351 int od[] = {
nx.dims[0], nw.dims[0], OH, OW};
359 const auto &nb = graph_.
node(ib);
360 if (nb.rank != 1 || nb.dims[0] !=
n.dims[1])
throw eve::Exception(
"Func.conv2d: bias shape mismatch");
363 int id = graph_.
addNode(std::move(
n));
364 return makeSymbolicFromNode(
id);
369 const auto &src = graph_.
node(ix);
371 const int OH = convOutSize(src.
dims[2], ksize, stride,
pad);
372 const int OW = convOutSize(src.
dims[3], ksize, stride,
pad);
373 int od[] = {src.
dims[0], src.
dims[1], OH, OW};
374 auto n = makeShapeNode(
type, od, 4);
379 int id = graph_.
addNode(std::move(
n));
380 return makeSymbolicFromNode(
id);
386 const auto &nt = graph_.
node(it);
387 const auto &ni = graph_.
node(ii);
388 if (nt.rank != 2)
throw eve::Exception(
"Func.embedding: table rank 2 required");
392 for (
int k = 0; k < ni.rank; ++k) od[k] = ni.dims[k];
393 od[ni.rank] = nt.dims[1];
397 int id = graph_.
addNode(std::move(
n));
398 return makeSymbolicFromNode(
id);
402 if (!ins || n < 2 || n > 4)
throw eve::Exception(
"Func.concat: 2..4 inputs required");
407 for (
int k = 0; k <
n; ++k) {
409 if (ns[k]->rank != ns[0]->rank)
412 axis = normalizeAxisChecked(axis, ns[0]->rank);
414 for (
int k = 0; k < ns[0]->
rank; ++k) {
417 for (
int t = 0;
t <
n; ++
t) total += ns[
t]->dims[k];
420 od[k] = ns[0]->
dims[k];
421 for (
int t = 1;
t <
n; ++
t)
422 if (ns[
t]->dims[k] != od[k])
429 if (
n > 2)
g.in2 =
ids[2];
430 if (
n > 3)
g.in3 =
ids[3];
432 int id = graph_.
addNode(std::move(
g));
433 return makeSymbolicFromNode(
id);
438 const auto &src = graph_.
node(ix);
439 axis = normalizeAxisChecked(axis, src.
rank);
440 if (
begin < 0 || end < begin || end > src.
dims[axis])
443 for (
int k = 0; k < src.
rank; ++k) od[k] = src.
dims[k];
450 int id = graph_.
addNode(std::move(
n));
451 return makeSymbolicFromNode(
id);
456 const auto &src = graph_.
node(ix);
457 axis = normalizeAxisChecked(axis, src.
rank);
459 int orank = src.
rank;
460 for (
int k = 0; k < src.
rank; ++k) od[k] = src.
dims[k];
467 for (
int k = axis; k < orank - 1; ++k) od[k] = od[k + 1];
472 auto n = makeShapeNode(
type, od, orank);
475 n.i1 = keepDims ? 1 : 0;
476 int id = graph_.
addNode(std::move(
n));
477 return makeSymbolicFromNode(
id);
482 const auto &src = graph_.
node(ix);
483 axis = normalizeAxisChecked(axis, src.
rank);
485 int orank = src.
rank;
486 for (
int k = 0; k < src.
rank; ++k) od[k] = src.
dims[k];
493 for (
int k = axis; k < orank - 1; ++k) od[k] = od[k + 1];
501 n.i1 = keepDims ? 1 : 0;
503 int id = graph_.
addNode(std::move(
n));
504 return makeSymbolicFromNode(
id);
509 const auto &src = graph_.
node(ix);
512 n.dtype =
static_cast<int>(dtype);
513 int id = graph_.
addNode(std::move(
n));
514 return makeSymbolicFromNode(
id);
523 const auto &nq = graph_.
node(iq);
524 const auto &nk = graph_.
node(ik);
525 const auto &nv = graph_.
node(iv);
526 if (nq.rank != 4 || nk.rank != 4 || nv.rank != 4)
528 if (nq.dims[0] != nk.dims[0] || nq.dims[1] != nk.dims[1] ||
529 nq.dims[3] != nk.dims[3] || nk.dims[2] != nv.dims[2] || nq.dims[3] != nv.dims[3])
537 const auto &nm = graph_.
node(im);
538 if (nm.rank != 4 || nm.dims[0] != nq.dims[0] || nm.dims[1] != nq.dims[1] ||
539 nm.dims[2] != nq.dims[2] || nm.dims[3] != nk.dims[2])
543 int id = graph_.
addNode(std::move(
n));
544 return makeSymbolicFromNode(
id);
549 const auto &src = graph_.
node(ix);
551 if (outH <= 0 || outW <= 0)
throw eve::Exception(
"Func.resize2d: bad output size");
552 int od[] = {src.
dims[0], src.
dims[1], outH, outW};
556 int id = graph_.
addNode(std::move(
n));
557 return makeSymbolicFromNode(
id);
568 if (outputNode_ < 0)
throw eve::Exception(
"Func.compile: setOutput required");
577 cf->graph_ =
fn->graph();
578 cf->outputNode_ =
fn->outputNode();
579 cf->placeholderCount_ =
fn->placeholderCount();
581 cf->optimized_ = std::make_unique<OptimizedGraph>(
optimizeGraph(cf->graph_, cf->outputNode_));
582 cf->order_ = cf->optimized_->order;
589 cf->gpuProgram_.reset();
591 if (cf->gpuProgram_) cf->device_ =
"gpu";
599 return runWithFeeds(feeds, 1);
603 Tensor *feeds[] = {in0, in1};
604 return runWithFeeds(feeds, 2);
608 Tensor *feeds[] = {in0, in1, in2};
609 return runWithFeeds(feeds, 3);
613 Tensor *feeds[] = {in0, in1, in2, in3};
614 return runWithFeeds(feeds, 4);
618 Tensor *feeds[] = {in0, in1, in2, in3, in4};
619 return runWithFeeds(feeds, 5);
624 Tensor *feeds[] = {in0, in1, in2, in3, in4, in5};
625 return runWithFeeds(feeds, 6);
628Tensor *CompiledFunction::runWithFeeds(
Tensor *
const *feeds,
int nFeeds) {
629 if (nFeeds != placeholderCount_)
630 throw eve::Exception(
"CompiledFunction.run: expected %d feeds, got %d", placeholderCount_,
632 for (
int i = 0; i < nFeeds; ++i) {
633 if (!feeds[i])
throw eve::Exception(
"CompiledFunction.run: null feed");
640 for (
int i = 0; i <
n; ++i) {
641 const auto &nd = graph_.
node(i);
644 if (slot < 0 || slot >= nFeeds)
throw eve::Exception(
"CompiledFunction: bad placeholder slot");
645 Tensor *feed = feeds[slot];
646 if (feed->getRank() != nd.rank || feed->getSize() != nd.size)
648 for (
int a = 0;
a < nd.rank; ++
a)
649 if (feed->getDim(
a) != nd.dims[
a])
653 const auto &outN = graph_.
node(outputNode_);
656 std::vector<const float *> ptrs(
static_cast<size_t>(nFeeds));
657 for (
int i = 0; i < nFeeds; ++i) ptrs[static_cast<size_t>(i)] = feeds[i]->
data();
658 std::vector<float> result = gpuProgram_->run(ptrs);
659 auto *out =
new Tensor(
static_cast<DType>(outN.dtype), outN.dims, outN.rank);
660 if (
int(result.size()) != out->getSize())
661 throw eve::Exception(
"CompiledFunction: gpu output size mismatch");
662 std::memcpy(out->data(), result.data(),
sizeof(
float) *
static_cast<size_t>(out->getSize()));
666 std::vector<std::vector<float>> bufs(
static_cast<size_t>(
n));
667 for (
int i = 0; i <
n; ++i) {
668 const auto &nd = graph_.
node(i);
670 Tensor *feed = feeds[nd.placeholderSlot];
671 bufs[
static_cast<size_t>(i)].assign(feed->data(), feed->data() + feed->getSize());
676 auto *out =
new Tensor(
static_cast<DType>(outN.dtype), outN.dims, outN.rank);
677 const auto &src = bufs[
static_cast<size_t>(outputNode_)];
678 if (
int(src.
size()) != out->getSize())
680 std::memcpy(out->data(), src.data(),
sizeof(
float) *
static_cast<size_t>(out->getSize()));
684void CompiledFunction::executeNode(
int nodeId, std::vector<std::vector<float>> &bufs)
const {
686 auto &out = bufs[
static_cast<size_t>(
nodeId)];
687 const auto in = [&](
int id) ->
const std::vector<float> & {
688 return bufs[
static_cast<size_t>(
id)];
695 if (!nd.constBytes.empty()) {
696 out.assign(
static_cast<size_t>(nd.size), 0.f);
698 nd.constScales.data(), nd.qGroup, nd.size, out.data());
707 const auto &na = graph_.
node(nd.in0);
708 const auto &nb = graph_.
node(nd.in1);
709 out.resize(
static_cast<size_t>(nd.size));
710 kernels::binaryOp(nd.type, in(nd.in0).data(), na.dims, na.rank, in(nd.in1).data(),
711 nb.dims, nb.rank, out.data(), nd.dims, nd.rank);
734 out.resize(
static_cast<size_t>(nd.size));
735 kernels::unaryOp(nd.type, in(nd.in0).data(), nd.size, out.data(), nd.s0, nd.s1);
739 const auto &
c = in(nd.in0);
740 const auto &
a = in(nd.in1);
741 const auto &
b = in(nd.in2);
742 out.resize(
static_cast<size_t>(nd.size));
743 for (
int i = 0; i < nd.size; ++i)
744 out[
static_cast<size_t>(i)] =
745 c[
static_cast<size_t>(i)] > 0.5f ?
a[
static_cast<size_t>(i)]
746 :
b[
static_cast<size_t>(i)];
750 const auto &
A = graph_.
node(nd.in0);
751 const auto &
B = graph_.
node(nd.in1);
752 const auto &
a = in(nd.in0);
753 const auto &
b = in(nd.in1);
754 out.assign(
static_cast<size_t>(nd.size), 0.f);
756 const int m =
A.dims[0], k =
A.dims[1],
n =
B.dims[1];
757 for (
int i = 0; i <
m; ++i) {
758 for (
int j = 0; j <
n; ++j) {
760 for (
int t = 0;
t < k; ++
t)
761 acc +=
double(
a[
static_cast<size_t>(i * k +
t)]) *
762 double(
b[
static_cast<size_t>(
t *
n + j)]);
763 out[
static_cast<size_t>(i *
n + j)] =
float(acc);
767 const int batch =
A.dims[0],
m =
A.dims[1], k =
A.dims[2],
n =
B.dims[2];
768 for (
int bb = 0; bb < batch; ++bb) {
769 const float *ap =
a.data() + size_t(bb) *
m * k;
770 const float *bp =
b.data() + size_t(bb) * k *
n;
771 float *cp = out.data() + size_t(bb) *
m *
n;
772 for (
int i = 0; i <
m; ++i)
773 for (
int j = 0; j <
n; ++j) {
775 for (
int t = 0;
t < k; ++
t) acc +=
double(ap[i * k +
t]) * double(bp[
t *
n + j]);
776 cp[i *
n + j] = float(acc);
784 const auto &
X = graph_.
node(nd.in0);
785 out.resize(
static_cast<size_t>(nd.size));
787 for (
int k = 0; k < nd.rank; ++k)
799 out.resize(
static_cast<size_t>(nd.size));
805 out.resize(
static_cast<size_t>(nd.size));
806 const int cols = nd.dims[nd.rank - 1];
809 nd.in1 >= 0 ? in(nd.in1).data() : nullptr,
810 nd.in2 >= 0 ? in(nd.in2).data() : nullptr, nd.s0, out.data());
814 out.resize(
static_cast<size_t>(nd.size));
815 const int cols = nd.dims[nd.rank - 1];
818 nd.in1 >= 0 ? in(nd.in1).data() : nullptr, nd.s0, out.data());
823 out.resize(
static_cast<size_t>(nd.size));
824 const auto &
X = graph_.
node(nd.in0);
825 const auto &
W = graph_.
node(nd.in1);
828 nd.in2 >= 0 ? in(nd.in2).data() : nullptr, nd.
i0, nd.
i1, out.data());
831 nd.in2 >= 0 ? in(nd.in2).data() : nullptr, nd.
i0, nd.
i1, out.data());
836 out.resize(
static_cast<size_t>(nd.size));
837 const auto &
X = graph_.
node(nd.in0);
845 out.resize(
static_cast<size_t>(nd.size));
846 const auto &T = graph_.
node(nd.in0);
847 const auto &I = graph_.
node(nd.in1);
853 out.resize(
static_cast<size_t>(nd.size));
854 const float *ins[4] = {};
855 const int *dims[4] = {};
858 if (nd.in3 >= 0)
n = 4;
859 else if (nd.in2 >= 0)
n = 3;
860 const int ids[4] = {nd.in0, nd.in1, nd.in2, nd.in3};
861 for (
int k = 0; k <
n; ++k) {
862 ins[k] = in(
ids[k]).data();
870 out.resize(
static_cast<size_t>(nd.size));
871 const auto &
X = graph_.
node(nd.in0);
880 out.resize(
static_cast<size_t>(nd.size));
881 const auto &
X = graph_.
node(nd.in0);
887 out.resize(
static_cast<size_t>(nd.size));
888 const auto &
X = graph_.
node(nd.in0);
894 out.resize(
static_cast<size_t>(nd.size));
895 const auto &Q = graph_.
node(nd.in0);
896 const auto &K = graph_.
node(nd.in1);
897 const int B = Q.dims[0], H = Q.dims[1], T = Q.dims[2], D = Q.dims[3];
898 const int S = K.dims[2];
899 kernels::sdpa(in(nd.in0).data(), in(nd.in1).data(), in(nd.in2).data(),
900 nd.in3 >= 0 ? in(nd.in3).data() : nullptr,
B, H, T, S, D, nd.s0,
905 out.resize(
static_cast<size_t>(nd.size));
906 const auto &
X = graph_.
node(nd.in0);
std::array< double, 10 > q
std::vector< std::uint32_t > indices
std::array< float, 3 > scale
std::map< std::string, std::vector< std::string > > graph
EVENGINE_API_FOUNDATION public API.
Optimized / scheduled graph ready to run with feeds.
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.
CompiledFunction()
Compiled function.
~CompiledFunction()
Compiled function.
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.
static CompiledFunction * fromFunc(Func *fn)
From func.
Trace builder — TF2 tf.function analogue (tf.func in scripts). While active, TF ops record into this ...
Tensor * emitReduce(OpType type, const Tensor *x, int axis, bool keepDims)
Emit reduce.
Tensor * emitCast(const Tensor *x, DType dtype)
Emit cast.
Tensor * emitPermute(const Tensor *x, const int *order, int rank)
Emit permute.
class CompiledFunction * compile()
Compiles compile.
Tensor * input6(int d0, int d1, int d2, int d3, int d4, int d5)
Input 6.
Tensor * emitResize2d(const Tensor *x, int outH, int outW, int mode)
Emit resize 2 d.
Tensor * input4(int d0, int d1, int d2, int d3)
Input 4.
Tensor * emitConcat(const Tensor *const *ins, int n, int axis)
Emit concat.
Tensor * input1(int d0)
Input 1.
Tensor * input5(int d0, int d1, int d2, int d3, int d4)
Input 5.
Tensor * emitPool(OpType type, const Tensor *x, int ksize, int stride, int pad)
Emit pool.
Tensor * emitSdpa(const Tensor *q, const Tensor *k, const Tensor *v, const Tensor *mask, float scale)
Emit sdpa.
Tensor * emitBinary(OpType type, const Tensor *a, const Tensor *b)
Emit binary.
Tensor * emitSoftmax(const Tensor *x, int axis, bool logMode)
Emit softmax.
Tensor * emitConv1d(const Tensor *x, const Tensor *w, const Tensor *bias, int stride, int pad)
Emit conv 1 d.
Tensor * emitTernary(OpType type, const Tensor *a, const Tensor *b, const Tensor *c)
Emit ternary.
Tensor * emitFill(const int *dims, int rank, float value)
Emit fill.
void setOutput(Tensor *t)
Sets the output.
Tensor * emitEmbedding(const Tensor *table, const Tensor *indices)
Emit embedding.
Tensor * emitConv2d(const Tensor *x, const Tensor *w, const Tensor *bias, int stride, int pad)
Emit conv 2 d.
Tensor * emitArgMax(const Tensor *x, int axis, bool keepDims)
Emit arg max.
Tensor * emitMatMul(const Tensor *a, const Tensor *b)
Emit mat mul.
Tensor * emitUnaryScalar(OpType type, const Tensor *x, float s0, float s1=0.f)
Emit unary scalar.
Tensor * input2(int d0, int d1)
Input 2.
Tensor * emitReshape(const Tensor *x, const int *dims, int rank)
Emit reshape.
Tensor * emitSlice(const Tensor *x, int axis, int begin, int end)
Emit slice.
Tensor * emitUnary(OpType type, const Tensor *x)
Emit unary.
Tensor * emitTranspose(const Tensor *x)
Emit transpose.
Tensor * input3(int d0, int d1, int d2)
Input 3.
int ensureNode(const Tensor *t)
Ensure tensor is a node in this graph (Const-capture if eager).
Tensor * emitLayerNorm(const Tensor *x, const Tensor *scale, const Tensor *bias, float eps)
Emit layer norm.
Tensor * emitRMSNorm(const Tensor *x, const Tensor *scale, float eps)
Emit rms norm.
static GpuProgram * tryBuild(const Graph &graph, const OptimizedGraph &opt, int outputNode)
Try build.
int addNode(GraphNode node)
Adds node.
const GraphNode & node(int id) const
Node.
int nodeCount() const
Node count.
static int product(const int *dims, int rank)
Product.
TF2-like namespace module. Script: tf <- eve.TF(); Default eager; tf.func() traces a graph for compil...
void popTrace(Func *f)
Pops trace.
void pushTrace(Func *f)
Pushes trace.
float32 / int32 tensor (rank 1–6), row-major. Eager: owns a buffer. Symbolic: node in a Func graph (n...
void ensureEager(const char *op) const
Ensure eager.
static constexpr int kMaxRank
float * data()
原始数据指针(eager)。
static Tensor * makeSymbolic(Graph *graph, int nodeId, const int *dims, int rank)
Symbolic handle into a graph node.
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 binaryOp(OpType type, const float *a, const int *aDims, int aRank, const float *b, const int *bDims, int bRank, float *out, const int *outDims, int outRank)
Binary op.
void permute(const float *in, const int *inDims, int rank, const int *order, float *out, const int *outDims)
Permute.
void reduceAxis(OpType type, const float *in, const int *dims, int rank, int axis, float *out, const int *outDims, int outRank)
Reduce axis.
bool broadcastShape(const int *aDims, int aRank, const int *bDims, int bRank, int *outDims, int &outRank)
Broadcast shape.
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 unaryOp(OpType type, const float *in, int count, float *out, float s0, float s1)
Unary op.
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.
void dequantizeAll(DType dt, const uint8_t *bytes, const float *scales, int group, int count, float *out)
Dequantize all.
DType
Tensor element types.
@ ScaledDotProductAttention
OptimizedGraph optimizeGraph(const Graph &graph, int outputNode)
Optimize graph.
SettlementPipeline::Stage fn
int dims[Tensor::kMaxRank]