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 |