7std::optional<RuntimeTensor>
executeMisc(
const Node&
n,
const std::vector<const RuntimeTensor*>& in,
13 auto low =
make(
x.element, {}, std::vector<float>{-std::numeric_limits<float>::infinity()}),
14 high =
make(
x.element, {}, std::vector<float>{std::numeric_limits<float>::infinity()});
15 const auto&
a = in.size() > 1 && in[1] ? *in[1] : low;
16 const auto&
b = in.size() > 2 && in[2] ? *in[2] : high;
17 if (
a.element !=
x.element ||
b.element !=
x.element ||
count(
a.shape) != 1 ||
count(
b.shape) != 1)
18 throw Failure(
"Clip bounds must be matching scalars");
21 for (
auto&
f :
v)
f = std::min(std::max(
f, read<float>(
a, 0)), read<float>(
b, 0));
22 return make(
x.element,
x.shape,
v);
24 if (
n.op ==
"CumSum") {
26 if (
count(
at.shape) != 1)
throw Failure(
"CumSum axis must be scalar");
30 const bool reverse =
attr(
n,
"reverse", 0) != 0, exclusive =
attr(
n,
"exclusive", 0) != 0;
31 size_t outer = 1, inner = 1;
32 for (
int j = 0; j <
a; ++j) outer *=
x.shape[j];
33 for (
size_t j =
a + 1; j <
x.shape.size(); ++j) inner *=
x.shape[j];
37 s <<
"uint base=i/" << inner <<
"u*" << inner *
width <<
"u+i%" << inner
38 <<
"u;precise float sum=0.0;for(uint j=0;j<" <<
width <<
"u;++j){uint index=base+"
39 << (reverse ?
"(" + std::to_string(
width - 1) +
"u-j)" :
"j") <<
"*" << inner <<
"u;"
40 << (exclusive ?
"y[index]=sum;sum+=x0[index];" :
"sum+=x0[index];y[index]=sum;") <<
"}";
44 for (
size_t o = 0; o < outer; ++o)
45 for (
size_t i = 0; i < inner; ++i) {
47 for (int64_t j = 0; j <
width; ++j) {
48 size_t p = (o *
width + (reverse ?
width - 1 - j : j)) * inner + i;
49 const float v = out[
p];
59 return make(
x.element,
x.shape, out);
63 if (pads.size() != 2 *
x.shape.size())
throw Failure(
"Pad rank mismatch");
65 const auto mode =
n.attrs.contains(
"mode") ?
n.attrs.at(
"mode").text :
"constant";
66 for (
size_t j = 0; j <
shape.size(); ++j) {
67 if (pads[j] < -INT32_MAX || pads[j] > INT32_MAX || pads[j +
shape.size()] < -INT32_MAX ||
68 pads[j +
shape.size()] > INT32_MAX)
69 throw Failure(
"Pad extent out of range");
71 if (mode !=
"constant" &&
x.shape[j] <= 0)
72 throw Failure(
"Edge/reflect padding requires nonempty dimensions");
73 if (mode ==
"reflect" && (pads[j] >=
x.shape[j] || pads[j +
shape.size()] >=
x.shape[j]))
74 throw Failure(
"Reflect padding exceeds input dimension");
77 std::vector<uint8_t> fill(
size, 0);
78 if (in.size() > 2 && in[2]) {
80 throw Failure(
"Pad value dtype/shape mismatch");
85 size_t rest = i,
source = 0, stride = 1;
87 for (
size_t j =
shape.size(); j > 0; --j) {
88 int64_t
p =
static_cast<int64_t
>(rest %
shape[j - 1]) - pads[j - 1];
90 if (p < 0 || p >=
x.shape[j - 1]) {
91 if (mode ==
"constant")
93 else if (mode ==
"edge")
94 p = std::clamp(
p, int64_t(0),
x.shape[j - 1] - 1);
96 p =
p < 0 ? -
p : 2 *
x.shape[j - 1] - 2 -
p;
98 if (!outside)
source +=
p * stride;
99 stride *=
x.shape[j - 1];
101 std::memcpy(out.bytes.data() + i *
size, outside ? fill.data() :
x.bytes.data() +
source *
size,
size);