GCC Code Coverage Report


Directory: brotensor/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 90.1% 237 / 0 / 263
Functions: 100.0% 16 / 0 / 16
Branches: 36.8% 256 / 0 / 696

src/api/native_tensor_extra_conv.cpp
Line Branch Exec Source
1 // native_tensor_extra_conv.cpp — the image / convolution half of the
2 // never-bound ops: the StyleGAN3-R set (bias_act, upfirdn2d, modulated_conv2d,
3 // filtered_lrelu, forward + backward each), torchvision-style deformable
4 // conv2d, the DC-AE 2x pixel-shuffle upsample and the DiT unpatchify.
5 //
6 // Same mechanism as native_tensor_extra.cpp: every NCHW operand is checked
7 // against N*C*H*W (and every derived output extent against the int the ops
8 // size tensors with) before the op runs. Accumulated gradients (dB, dW) are
9 // read by the op, so they are checked like inputs.
10
11 #include "native_tensor_extra_decl.h"
12 #include "native_tensor_extra_util.h"
13 #include "api_internal.h"
14 #include "native_register.h"
15
16 #include <string>
17
18 using namespace brotensor::api;
19 using namespace brotensor::api::extra;
20
21 namespace {
22
23 // upfirdn2d's output extent along one axis:
24 // ((in*up + pad0 + pad1) - f) / down + 1, which needs the padded input to
25 // cover the filter.
26 44 bool firExtent(const char* lb, const char* axis, int64_t in, int64_t up, int64_t down, int64_t pad0, int64_t pad1,
27 int64_t f, int64_t& out) {
28 44 const int64_t padded = in * up + pad0 + pad1;
29
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if (padded < f) {
30 ✗ setError(std::string(lb) + ": the padded " + axis + " extent " + std::to_string(padded) +
31 ✗ " is smaller than the filter (" + std::to_string(f) + ")");
32 ✗ return false;
33 }
34 44 out = (padded - f) / down + 1;
35 44 return needExtent(lb, axis, out);
36 44 }
37
38 // The upfirdn2d argument block shared by the forward and backward: N, C, H, W
39 // positive, up/down >= 1, f (fH, fW) of X's dtype. Answers the output extents.
40 10 bool firArgs(const char* lb, brotensor::Tensor* X, const char* xn, brotensor::Tensor* f,
41 int32_t N, int32_t C, int32_t H, int32_t W, int32_t fH, int32_t fW,
42 int32_t upX, int32_t upY, int32_t downX, int32_t downY,
43 int32_t padX0, int32_t padX1, int32_t padY0, int32_t padY1, int64_t& Ho, int64_t& Wo) {
44
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (!needFloat(lb, xn, X) || !needSameDtype(lb, "f", f, X)) return false;
45
6/12
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 10 times.
10 if (N < 1 || C < 1 || H < 1 || W < 1 || fH < 1 || fW < 1) {
46 ✗ setError(std::string(lb) + ": N, C, H, W, fH and fW must be >= 1");
47 ✗ return false;
48 }
49
4/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
10 if (upX < 1 || upY < 1 || downX < 1 || downY < 1) {
50 ✗ setError(std::string(lb) + ": up / down factors must be >= 1");
51 ✗ return false;
52 }
53
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (f->rows != fH || f->cols != fW) {
54 ✗ setError(std::string(lb) + ": f must be (fH, fW) = (" + std::to_string(fH) + ", " + std::to_string(fW) + ")");
55 ✗ return false;
56 }
57
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
20 return firExtent(lb, "H_out", H, upY, downY, padY0, padY1, fH, Ho) &&
58
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 firExtent(lb, "W_out", W, upX, downX, padX0, padX1, fW, Wo) &&
59 10 needExtent(lb, "C*H_out*W_out", prod({C, Ho, Wo}));
60 10 }
61
62 // modulated_conv2d's shared argument block: X (N, C_in*H*W), W (C_out,
63 // C_in*kH*kW), s (N, C_in) of one float dtype; answers H_out / W_out.
64 14 bool modConvArgs(const char* lb, brotensor::Tensor* X, brotensor::Tensor* Wt, brotensor::Tensor* s,
65 int32_t N, int32_t Cin, int32_t H, int32_t Wd, int32_t Cout, int32_t kH, int32_t kW,
66 int32_t padH, int32_t padW, int64_t& Ho, int64_t& Wo) {
67
3/6
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
14 if (!needFloat(lb, "X", X) || !needSameDtype(lb, "W", Wt, X) || !needSameDtype(lb, "s", s, X)) return false;
68
9/18
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 14 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 14 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 14 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 14 times.
14 if (N < 1 || Cin < 1 || H < 1 || Wd < 1 || Cout < 1 || kH < 1 || kW < 1 || padH < 0 || padW < 0) {
69 ✗ setError(std::string(lb) + ": dims and kernel must be >= 1, padding >= 0");
70 ✗ return false;
71 }
72 14 Ho = static_cast<int64_t>(H) + 2 * static_cast<int64_t>(padH) - (kH - 1);
73 14 Wo = static_cast<int64_t>(Wd) + 2 * static_cast<int64_t>(padW) - (kW - 1);
74
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
28 return needExtent(lb, "H_out", Ho) && needExtent(lb, "W_out", Wo) &&
75
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 needExtent(lb, "C_out*H_out*W_out", prod({Cout, Ho, Wo})) &&
76
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 needElems(lb, "X", X, prod({N, Cin, H, Wd})) &&
77
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
12 needElems(lb, "W", Wt, prod({Cout, Cin, kH, kW})) &&
78 10 needElems(lb, "s", s, prod({N, Cin}));
79 14 }
80
81 // filtered_lrelu's shared argument block. Answers the post-upsample extents
82 // (Hu, Wu — the up_buf grid) and the output extents (Ho, Wo).
83 8 bool flreluArgs(const char* lb, brotensor::Tensor* X, brotensor::Tensor* fu, brotensor::Tensor* fd,
84 brotensor::Tensor* b, int32_t N, int32_t C, int32_t H, int32_t W, int32_t up, int32_t down,
85 int32_t padX0, int32_t padX1, int32_t padY0, int32_t padY1,
86 int64_t& Hu, int64_t& Wu, int64_t& Ho, int64_t& Wo) {
87
3/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
8 if (!needFloat(lb, "X", X) || !needSameDtype(lb, "fu", fu, X) || !needSameDtype(lb, "fd", fd, X)) return false;
88
6/12
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
8 if (N < 1 || C < 1 || H < 1 || W < 1 || up < 1 || down < 1) {
89 ✗ setError(std::string(lb) + ": N, C, H, W, up and down must be >= 1");
90 ✗ return false;
91 }
92
2/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8 if (fu->empty() || fd->empty()) { setError(std::string(lb) + ": fu and fd must be non-empty filters"); return false; }
93
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
8 if (!needElems(lb, "X", X, prod({N, C, H, W})) || !optElems(lb, "b", b, C, X)) return false;
94
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 if (!firExtent(lb, "upsampled H", H, up, 1, padY0, padY1, fu->rows, Hu) ||
95
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 !firExtent(lb, "upsampled W", W, up, 1, padX0, padX1, fu->cols, Wu) ||
96
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 !needExtent(lb, "C*H_up*W_up", prod({C, Hu, Wu})) ||
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 !firExtent(lb, "H_out", Hu, 1, down, 0, 0, fd->rows, Ho) ||
98 6 !firExtent(lb, "W_out", Wu, 1, down, 0, 0, fd->cols, Wo)) return false;
99 6 return true;
100 8 }
101
102 } // namespace
103
104 extern "C" {
105
106 // ---- bias_act ----------------------------------------------------------------
107
108 6 void bro_tensor_biasActForward(void* X, uint64_t b_bits, int32_t N, int32_t C, int32_t HW, int32_t act,
109 double alpha, double gain, double clamp, void* Y) {
110 6 constexpr const char* lb = "biasActForward";
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!need(lb, {X, Y})) return;
112 6 auto* x = toTensor(X);
113 6 auto* b = tensorFromValue(b_bits);
114
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (!needFloat(lb, "X", x) || !needRange(lb, "act", act, 0, 1)) return;
115
3/10
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
6 if (N < 1 || C < 1 || HW < 1) { setError(std::string(lb) + ": N, C and HW must be >= 1"); return; }
116
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
6 if (!needElems(lb, "X", x, prod({N, C, HW})) || !optElems(lb, "b", b, C, x)) return;
117 BROTENSOR_API_TRY
118
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 brotensor::bias_act_forward(*x, b, N, C, HW, act, static_cast<float>(alpha), static_cast<float>(gain),
119
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 static_cast<float>(clamp), *toTensor(Y));
120
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2 BROTENSOR_API_CATCH(lb)
121 6 }
122
123 4 void bro_tensor_biasActBackward(void* dY, void* X, uint64_t b_bits, int32_t N, int32_t C, int32_t HW, int32_t act,
124 double alpha, double gain, double clamp, void* dX, uint64_t dB_bits) {
125 4 constexpr const char* lb = "biasActBackward";
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!need(lb, {dY, X, dX})) return;
127 4 auto* dy = toTensor(dY);
128 4 auto* x = toTensor(X);
129 4 auto* b = tensorFromValue(b_bits);
130 4 auto* dB = tensorFromValue(dB_bits);
131
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if (!needFloat(lb, "X", x) || !needSameDtype(lb, "dY", dy, x) || !needRange(lb, "act", act, 0, 1)) return;
132
3/10
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
4 if (N < 1 || C < 1 || HW < 1) { setError(std::string(lb) + ": N, C and HW must be >= 1"); return; }
133 4 const int64_t n = prod({N, C, HW});
134
5/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
4 if (!needElems(lb, "X", x, n) || !needElems(lb, "dY", dy, n) || !optElems(lb, "b", b, C, x) ||
135 4 !optElems(lb, "dB", dB, C, x)) return;
136 BROTENSOR_API_TRY
137
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 brotensor::bias_act_backward(*dy, *x, b, N, C, HW, act, static_cast<float>(alpha), static_cast<float>(gain),
138
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 static_cast<float>(clamp), *toTensor(dX), dB);
139
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2 BROTENSOR_API_CATCH(lb)
140 4 }
141
142 // ---- upfirdn2d ---------------------------------------------------------------
143
144 6 void bro_tensor_upfirdn2dForward(void* X, void* f, int32_t N, int32_t C, int32_t H, int32_t W, int32_t fH,
145 int32_t fW, int32_t upX, int32_t upY, int32_t downX, int32_t downY,
146 int32_t padX0, int32_t padX1, int32_t padY0, int32_t padY1, bool flipFilter,
147 double gain, void* Y) {
148 6 constexpr const char* lb = "upfirdn2dForward";
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!need(lb, {X, f, Y})) return;
150 6 int64_t Ho = 0, Wo = 0;
151
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
18 if (!firArgs(lb, toTensor(X), "X", toTensor(f), N, C, H, W, fH, fW, upX, upY, downX, downY,
152
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
12 padX0, padX1, padY0, padY1, Ho, Wo) ||
153 8 !needElems(lb, "X", toTensor(X), prod({N, C, H, W}))) return;
154 BROTENSOR_API_TRY
155
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 brotensor::upfirdn2d_forward(*toTensor(X), *toTensor(f), N, C, H, W, fH, fW, upX, upY, downX, downY,
156
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 padX0, padX1, padY0, padY1, flipFilter, static_cast<float>(gain), *toTensor(Y));
157
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
4 BROTENSOR_API_CATCH(lb)
158 6 }
159
160 4 void bro_tensor_upfirdn2dBackward(void* dY, void* f, int32_t N, int32_t C, int32_t H, int32_t W, int32_t fH,
161 int32_t fW, int32_t upX, int32_t upY, int32_t downX, int32_t downY,
162 int32_t padX0, int32_t padX1, int32_t padY0, int32_t padY1, bool flipFilter,
163 double gain, void* dX) {
164 4 constexpr const char* lb = "upfirdn2dBackward";
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!need(lb, {dY, f, dX})) return;
166 4 int64_t Ho = 0, Wo = 0;
167
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
12 if (!firArgs(lb, toTensor(dY), "dY", toTensor(f), N, C, H, W, fH, fW, upX, upY, downX, downY,
168
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 padX0, padX1, padY0, padY1, Ho, Wo) ||
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 !needExtent(lb, "C*H*W", prod({C, H, W})) ||
170 6 !needElems(lb, "dY", toTensor(dY), prod({N, C, Ho, Wo}))) return;
171 BROTENSOR_API_TRY
172
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 brotensor::upfirdn2d_backward(*toTensor(dY), *toTensor(f), N, C, H, W, fH, fW, upX, upY, downX, downY,
173 2 padX0, padX1, padY0, padY1, flipFilter, static_cast<float>(gain),
174
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 *toTensor(dX));
175
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2 BROTENSOR_API_CATCH(lb)
176 4 }
177
178 // ---- modulated_conv2d --------------------------------------------------------
179
180 8 void bro_tensor_modulatedConv2dForward(void* X, void* W, void* s, int32_t N, int32_t Cin, int32_t H, int32_t Wd,
181 int32_t Cout, int32_t kH, int32_t kW, int32_t padH, int32_t padW,
182 bool demodulate, double eps, void* dcoef, void* Y) {
183 8 constexpr const char* lb = "modulatedConv2dForward";
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!need(lb, {X, W, s, dcoef, Y})) return;
185 8 int64_t Ho = 0, Wo = 0;
186
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (!modConvArgs(lb, toTensor(X), toTensor(W), toTensor(s), N, Cin, H, Wd, Cout, kH, kW, padH, padW, Ho, Wo))
187 4 return;
188 BROTENSOR_API_TRY
189
4/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
8 brotensor::modulated_conv2d_forward(*toTensor(X), *toTensor(W), *toTensor(s), N, Cin, H, Wd, Cout, kH, kW,
190
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 padH, padW, demodulate, static_cast<float>(eps), *toTensor(dcoef),
191
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 *toTensor(Y));
192
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
4 BROTENSOR_API_CATCH(lb)
193 8 }
194
195 6 void bro_tensor_modulatedConv2dBackward(void* X, void* W, void* s, void* dcoef, void* dY, int32_t N, int32_t Cin,
196 int32_t H, int32_t Wd, int32_t Cout, int32_t kH, int32_t kW, int32_t padH,
197 int32_t padW, bool demodulate, double eps, void* dX, uint64_t dW_bits,
198 void* ds) {
199 6 constexpr const char* lb = "modulatedConv2dBackward";
200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!need(lb, {X, W, s, dcoef, dY, dX, ds})) return;
201 6 int64_t Ho = 0, Wo = 0;
202 6 auto* x = toTensor(X);
203
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (!modConvArgs(lb, x, toTensor(W), toTensor(s), N, Cin, H, Wd, Cout, kH, kW, padH, padW, Ho, Wo)) return;
204
3/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
12 if (!needDtype(lb, "dcoef", toTensor(dcoef), brotensor::Dtype::FP32) ||
205
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 !needElems(lb, "dcoef", toTensor(dcoef), prod({N, Cout})) ||
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 !needSameDtype(lb, "dY", toTensor(dY), x) || !needElems(lb, "dY", toTensor(dY), prod({N, Cout, Ho, Wo})))
207 4 return;
208 // dW accumulates, so a committed one is read: check it. null or an empty
209 // tensor skips the weight gradient.
210 2 auto* dW = tensorFromValue(dW_bits);
211
4/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
4 if (dW && !dW->empty() && (!needSameDtype(lb, "dW", dW, x) || !needElems(lb, "dW", dW, prod({Cout, Cin, kH, kW}))))
212 ✗ return;
213 BROTENSOR_API_TRY
214 2 brotensor::Tensor skip;
215
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 brotensor::Tensor& dWref = (dW && !dW->empty()) ? *dW : skip;
216
5/10
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
4 brotensor::modulated_conv2d_backward(*x, *toTensor(W), *toTensor(s), *toTensor(dcoef), *toTensor(dY), N, Cin,
217 2 H, Wd, Cout, kH, kW, padH, padW, demodulate, static_cast<float>(eps),
218
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 *toTensor(dX), dWref, *toTensor(ds));
219
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2 BROTENSOR_API_CATCH(lb)
220 6 }
221
222 // ---- filtered_lrelu ----------------------------------------------------------
223
224 4 void bro_tensor_filteredLreluForward(void* X, void* fu, void* fd, uint64_t b_bits, int32_t N, int32_t C, int32_t H,
225 int32_t W, int32_t up, int32_t down, int32_t padX0, int32_t padX1,
226 int32_t padY0, int32_t padY1, double gain, double slope, double clamp,
227 void* upBuf, void* actBuf, void* Y) {
228 4 constexpr const char* lb = "filteredLreluForward";
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!need(lb, {X, fu, fd, upBuf, actBuf, Y})) return;
230 4 int64_t Hu = 0, Wu = 0, Ho = 0, Wo = 0;
231 4 auto* b = tensorFromValue(b_bits);
232
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (!flreluArgs(lb, toTensor(X), toTensor(fu), toTensor(fd), b, N, C, H, W, up, down, padX0, padX1, padY0, padY1,
233 2 Hu, Wu, Ho, Wo)) return;
234 BROTENSOR_API_TRY
235
4/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
4 brotensor::filtered_lrelu_forward(*toTensor(X), *toTensor(fu), *toTensor(fd), b, N, C, H, W, up, down,
236 2 padX0, padX1, padY0, padY1, static_cast<float>(gain),
237
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 static_cast<float>(slope), static_cast<float>(clamp), *toTensor(upBuf),
238
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 *toTensor(actBuf), *toTensor(Y));
239
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2 BROTENSOR_API_CATCH(lb)
240 4 }
241
242 4 void bro_tensor_filteredLreluBackward(void* dY, void* X, void* fu, void* fd, uint64_t b_bits, int32_t N, int32_t C,
243 int32_t H, int32_t W, int32_t up, int32_t down, int32_t padX0, int32_t padX1,
244 int32_t padY0, int32_t padY1, double gain, double slope, double clamp,
245 uint64_t upBuf_bits, void* dX, uint64_t dB_bits) {
246 4 constexpr const char* lb = "filteredLreluBackward";
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!need(lb, {dY, X, fu, fd, dX})) return;
248 4 int64_t Hu = 0, Wu = 0, Ho = 0, Wo = 0;
249 4 auto* x = toTensor(X);
250 4 auto* b = tensorFromValue(b_bits);
251
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!flreluArgs(lb, x, toTensor(fu), toTensor(fd), b, N, C, H, W, up, down, padX0, padX1, padY0, padY1,
252 ✗ Hu, Wu, Ho, Wo)) return;
253
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 if (!needSameDtype(lb, "dY", toTensor(dY), x) || !needElems(lb, "dY", toTensor(dY), prod({N, C, Ho, Wo}))) return;
254 // up_buf is optional (an empty one is recomputed from X); a committed one
255 // is read over the whole post-upsample grid.
256 2 auto* ub = tensorFromValue(upBuf_bits);
257
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
2 if (ub && !ub->empty() && (!needSameDtype(lb, "upBuf", ub, x) || !needElems(lb, "upBuf", ub, prod({N, C, Hu, Wu}))))
258 ✗ return;
259 2 auto* dB = tensorFromValue(dB_bits);
260
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!optElems(lb, "dB", dB, C, x)) return;
261 BROTENSOR_API_TRY
262 2 brotensor::Tensor none;
263
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 const brotensor::Tensor& upRef = (ub && !ub->empty()) ? *ub : none;
264
4/8
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 brotensor::filtered_lrelu_backward(*toTensor(dY), *x, *toTensor(fu), *toTensor(fd), b, N, C, H, W, up, down,
265 2 padX0, padX1, padY0, padY1, static_cast<float>(gain),
266 2 static_cast<float>(slope), static_cast<float>(clamp), upRef,
267
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 *toTensor(dX), dB);
268
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2 BROTENSOR_API_CATCH(lb)
269 4 }
270
271 // ---- deformable conv2d -------------------------------------------------------
272
273 10 void bro_tensor_deformConv2dForward(void* X, void* offset, uint64_t mask_bits, void* Wt, uint64_t bias_bits,
274 int32_t N, int32_t Cin, int32_t H, int32_t W, int32_t Cout, int32_t kH,
275 int32_t kW, int32_t sH, int32_t sW, int32_t pH, int32_t pW, int32_t dH,
276 int32_t dW, int32_t groups, int32_t deformGroups, void* Y) {
277 10 constexpr const char* lb = "deformConv2dForward";
278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!need(lb, {X, offset, Wt, Y})) return;
279 10 auto* x = toTensor(X);
280 10 auto* off = toTensor(offset);
281 10 auto* w = toTensor(Wt);
282 10 auto* mask = tensorFromValue(mask_bits);
283 10 auto* bias = tensorFromValue(bias_bits);
284
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
10 if (!needFloat(lb, "X", x) || !needSameDtype(lb, "offset", off, x) || !needSameDtype(lb, "Wt", w, x)) return;
285
11/22
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 10 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 10 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 10 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 10 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 10 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 10 times.
20 if (N < 1 || Cin < 1 || H < 1 || W < 1 || Cout < 1 || kH < 1 || kW < 1 || sH < 1 || sW < 1 || pH < 0 ||
286
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 pW < 0 || dH < 1 || dW < 1) {
287 ✗ setError(std::string(lb) + ": dims, kernel, stride and dilation must be >= 1, padding >= 0");
288 ✗ return;
289 }
290
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
10 if (groups < 1 || Cin % groups != 0 || Cout % groups != 0) {
291 ✗ setError(std::string(lb) + ": groups must divide C_in and C_out");
292 ✗ return;
293 }
294
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (deformGroups < 1 || Cin % deformGroups != 0) {
295 ✗ setError(std::string(lb) + ": deformGroups must divide C_in");
296 ✗ return;
297 }
298 10 const int64_t Ho = (static_cast<int64_t>(H) + 2 * pH - static_cast<int64_t>(dH) * (kH - 1) - 1) / sH + 1;
299 10 const int64_t Wo = (static_cast<int64_t>(W) + 2 * pW - static_cast<int64_t>(dW) * (kW - 1) - 1) / sW + 1;
300
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
10 if (!needExtent(lb, "H_out", Ho) || !needExtent(lb, "W_out", Wo) ||
301 10 !needExtent(lb, "C_out*H_out*W_out", prod({Cout, Ho, Wo}))) return;
302 10 const int64_t taps = prod({deformGroups, kH, kW});
303
3/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 6 times.
20 if (!needElems(lb, "X", x, prod({N, Cin, H, W})) ||
304
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 !needElems(lb, "offset", off, prod({N, 2, taps, Ho, Wo})) ||
305
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 !optElems(lb, "mask", mask, prod({N, taps, Ho, Wo}), x) ||
306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 !needElems(lb, "Wt", w, prod({Cout, Cin / groups, kH, kW})) ||
307 10 !optElems(lb, "bias", bias, Cout, x)) return;
308 BROTENSOR_API_TRY
309
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 brotensor::deform_conv2d_forward(*x, *off, mask, *w, bias, N, Cin, H, W, Cout, kH, kW, sH, sW, pH, pW, dH, dW,
310
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 groups, deformGroups, *toTensor(Y));
311
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
6 BROTENSOR_API_CATCH(lb)
312 10 }
313
314 // ---- pixel-shuffle upsample + unpatchify -------------------------------------
315
316 6 void bro_tensor_pixelShuffleUpsample2xForward(void* X, int32_t N, int32_t Cin, int32_t H, int32_t W, int32_t Cout,
317 void* Y) {
318 6 constexpr const char* lb = "pixelShuffleUpsample2xForward";
319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!need(lb, {X, Y})) return;
320 6 auto* x = toTensor(X);
321
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (!needFloat(lb, "X", x)) return;
322
6/12
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
6 if (N < 1 || Cin < 1 || H < 1 || W < 1 || Cout < 1 || (4 * static_cast<int64_t>(Cout)) % Cin != 0) {
323 ✗ setError(std::string(lb) + ": dims must be >= 1 and C_in must divide 4*C_out");
324 ✗ return;
325 }
326
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
6 if (!needElems(lb, "X", x, prod({N, Cin, H, W})) || !needExtent(lb, "C_out*2H*2W", prod({Cout, 2 * int64_t(H), 2 * int64_t(W)})))
327 2 return;
328 BROTENSOR_API_TRY
329
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 brotensor::pixel_shuffle_upsample_2x_forward(*x, N, Cin, H, W, Cout, *toTensor(Y));
330
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
4 BROTENSOR_API_CATCH(lb)
331 6 }
332
333 6 void bro_tensor_patchUnpackForward(void* tokens, int32_t hp, int32_t wp, int32_t P, int32_t Ctotal, int32_t Ckeep,
334 bool channelMajor, void* Y) {
335 6 constexpr const char* lb = "patchUnpackForward";
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!need(lb, {tokens, Y})) return;
337 6 auto* t = toTensor(tokens);
338
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (!needFloat(lb, "tokens", t)) return;
339
6/12
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
6 if (hp < 1 || wp < 1 || P < 1 || Ctotal < 1 || Ckeep < 1 || Ckeep > Ctotal) {
340 ✗ setError(std::string(lb) + ": hp, wp, P, C_total must be >= 1 and 1 <= C_keep <= C_total");
341 ✗ return;
342 }
343 6 const int64_t rowWidth = prod({P, P, Ctotal});
344
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
6 if (t->cols != rowWidth || t->rows < static_cast<int64_t>(hp) * wp) {
345
5/10
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
4 setError(std::string(lb) + ": tokens must be (hp*wp, P*P*C_total) = (" + std::to_string(int64_t(hp) * wp) +
346
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 ", " + std::to_string(rowWidth) + ")");
347 2 return;
348 }
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!needExtent(lb, "C_keep*(hp*P)*(wp*P)", prod({Ckeep, hp, P, wp, P}))) return;
350 BROTENSOR_API_TRY
351
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 brotensor::patch_unpack_forward(*t, hp, wp, P, Ctotal, Ckeep, channelMajor, *toTensor(Y));
352
0/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
4 BROTENSOR_API_CATCH(lb)
353 6 }
354
355 } // extern "C"
356
357 namespace brotensor::api {
358
359 3 bool registerTensorNatives_extra_conv(std::string* error) {
360 using namespace brotensor::api::reg;
361 3 const char* T = kTensorCls;
362 3 return
363 6 fn("__bro_native.tensor.biasActForward", p(&bro_tensor_biasActForward), "void",
364
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 {T, kDyn, "i32", "i32", "i32", "i32", "f64", "f64", "f64", T}, error) &&
365 6 fn("__bro_native.tensor.biasActBackward", p(&bro_tensor_biasActBackward), "void",
366
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 {T, T, kDyn, "i32", "i32", "i32", "i32", "f64", "f64", "f64", T, kDyn}, error) &&
367 6 fn("__bro_native.tensor.upfirdn2dForward", p(&bro_tensor_upfirdn2dForward), "void",
368 6 {T, T, "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32",
369
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 "i32", "i32", "i32", "i32", "bool", "f64", T}, error) &&
370 6 fn("__bro_native.tensor.upfirdn2dBackward", p(&bro_tensor_upfirdn2dBackward), "void",
371 6 {T, T, "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32",
372
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 "i32", "i32", "i32", "i32", "bool", "f64", T}, error) &&
373 6 fn("__bro_native.tensor.modulatedConv2dForward", p(&bro_tensor_modulatedConv2dForward), "void",
374
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 {T, T, T, "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "bool", "f64", T, T}, error) &&
375 6 fn("__bro_native.tensor.modulatedConv2dBackward", p(&bro_tensor_modulatedConv2dBackward), "void",
376 9 {T, T, T, T, T, "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "bool", "f64",
377
4/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
12 T, kDyn, T}, error) &&
378 6 fn("__bro_native.tensor.filteredLreluForward", p(&bro_tensor_filteredLreluForward), "void",
379 12 {T, T, T, kDyn, "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32",
380
5/10
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
15 "f64", "f64", "f64", T, T, T}, error) &&
381 6 fn("__bro_native.tensor.filteredLreluBackward", p(&bro_tensor_filteredLreluBackward), "void",
382 6 {T, T, T, T, kDyn, "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32",
383
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 "f64", "f64", "f64", kDyn, T, kDyn}, error) &&
384 6 fn("__bro_native.tensor.deformConv2dForward", p(&bro_tensor_deformConv2dForward), "void",
385 6 {T, T, kDyn, T, kDyn, "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32",
386
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 "i32", "i32", "i32", "i32", T}, error) &&
387 6 fn("__bro_native.tensor.pixelShuffleUpsample2xForward", p(&bro_tensor_pixelShuffleUpsample2xForward), "void",
388
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 {T, "i32", "i32", "i32", "i32", "i32", T}, error) &&
389 6 fn("__bro_native.tensor.patchUnpackForward", p(&bro_tensor_patchUnpackForward), "void",
390 3 {T, "i32", "i32", "i32", "i32", "i32", "bool", T}, error);
391 }
392
393 } // namespace brotensor::api
394