src/api/native_tensor_extra.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // native_tensor_extra.cpp — the brotensor ops that never had a JS binding: | ||
| 2 | // the elementwise / reduction / index half, the INT32 upload + download pair | ||
| 3 | // the index-taking ops need, and the group's registration entry point (which | ||
| 4 | // chains native_tensor_extra_nn.cpp and native_tensor_extra_conv.cpp). | ||
| 5 | // | ||
| 6 | // Everything here is a free function on `bro.tensor`; js/tensor_extra.js is | ||
| 7 | // the wrapper half that validates arguments and reads the error slot back. | ||
| 8 | // Every body checks each operand against the dims it is handed before the op | ||
| 9 | // runs (the ops trust their caller's dims; from JS that trust is an | ||
| 10 | // out-of-bounds read or write) — see native_tensor_extra_util.h. | ||
| 11 | |||
| 12 | #include "native_tensor_extra_decl.h" | ||
| 13 | #include "native_tensor_extra_util.h" | ||
| 14 | #include "api_internal.h" | ||
| 15 | #include "native_register.h" | ||
| 16 | |||
| 17 | #include <cmath> | ||
| 18 | #include <cstring> | ||
| 19 | #include <string> | ||
| 20 | #include <vector> | ||
| 21 | |||
| 22 | using namespace brotensor::api; | ||
| 23 | using namespace brotensor::api::extra; | ||
| 24 | |||
| 25 | namespace brotensor::api::extra { | ||
| 26 | |||
| 27 | 68 | bool hostInt32(const char* label, const char* name, const brotensor::Tensor* t, int64_t n, | |
| 28 | std::vector<int32_t>& out) { | ||
| 29 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 66 times.
|
68 | if (!needElems(label, name, t, n)) return false; |
| 30 | 66 | out.clear(); | |
| 31 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
|
66 | if (t->empty()) return true; |
| 32 | 66 | const brotensor::Tensor host = t->to(brotensor::Device::CPU); | |
| 33 |
1/2✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
|
66 | const auto count = static_cast<size_t>(host.size()); |
| 34 |
1/2✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
|
66 | out.resize(count); |
| 35 |
2/2✓ Branch 0 taken 44 times.
✓ Branch 1 taken 22 times.
|
66 | if (host.dtype == brotensor::Dtype::INT32) { |
| 36 |
1/2✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
|
44 | std::memcpy(out.data(), host.host_raw(), count * sizeof(int32_t)); |
| 37 | 44 | return true; | |
| 38 | } | ||
| 39 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | if (host.dtype == brotensor::Dtype::FP32) { |
| 40 |
1/2✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
|
22 | const float* f = host.host_f32(); |
| 41 |
2/2✓ Branch 0 taken 46 times.
✓ Branch 1 taken 20 times.
|
66 | for (size_t i = 0; i < count; ++i) { |
| 42 | 46 | const float v = f[i]; | |
| 43 |
4/6✓ Branch 0 taken 44 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
|
46 | if (!(v == std::floor(v)) || v < -2147483648.0f || v >= 2147483648.0f) { |
| 44 |
8/16✓ 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.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
|
2 | setError(std::string(label) + ": " + name + "[" + std::to_string(i) + |
| 45 | "] is not a whole number that fits INT32"); | ||
| 46 | 2 | return false; | |
| 47 | } | ||
| 48 | 44 | out[i] = static_cast<int32_t>(v); | |
| 49 | 44 | } | |
| 50 | 20 | return true; | |
| 51 | } | ||
| 52 | ✗ | setError(std::string(label) + ": " + name + " is " + dtypeToString(host.dtype) + ", expected int32 (or whole-number fp32)"); | |
| 53 | ✗ | return false; | |
| 54 | 68 | } | |
| 55 | |||
| 56 | 48 | const brotensor::Tensor& int32Operand(const brotensor::Tensor& t, const std::vector<int32_t>& vals, | |
| 57 | brotensor::Tensor& scratch) { | ||
| 58 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 14 times.
|
48 | if (t.dtype == brotensor::Dtype::INT32) return t; |
| 59 | 28 | scratch = brotensor::Tensor::from_raw_bytes_on(t.device, vals.data(), t.rows, t.cols, | |
| 60 | 14 | brotensor::Dtype::INT32, vals.size() * sizeof(int32_t)); | |
| 61 | 14 | return scratch; | |
| 62 | 48 | } | |
| 63 | |||
| 64 | 50 | bool needIndicesIn(const char* label, const char* name, const std::vector<int32_t>& vals, int64_t n, | |
| 65 | int64_t lo, int64_t hi) { | ||
| 66 |
4/4✓ Branch 0 taken 36 times.
✓ Branch 1 taken 120 times.
✓ Branch 2 taken 120 times.
✓ Branch 3 taken 36 times.
|
156 | for (int64_t i = 0; i < n && i < static_cast<int64_t>(vals.size()); ++i) { |
| 67 | 120 | const int64_t v = vals[static_cast<size_t>(i)]; | |
| 68 |
4/4✓ Branch 0 taken 118 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 106 times.
|
120 | if (v < lo || v >= hi) { |
| 69 |
10/20✓ 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 taken 14 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 14 times.
✗ Branch 19 not taken.
|
28 | setError(std::string(label) + ": " + name + "[" + std::to_string(i) + "] = " + std::to_string(v) + |
| 70 |
6/12✓ 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.
|
14 | " is outside [" + std::to_string(lo) + ", " + std::to_string(hi) + ")"); |
| 71 | 14 | return false; | |
| 72 | } | ||
| 73 | 106 | } | |
| 74 | 36 | return true; | |
| 75 | 50 | } | |
| 76 | |||
| 77 | } // namespace brotensor::api::extra | ||
| 78 | |||
| 79 | namespace { | ||
| 80 | |||
| 81 | thread_local std::vector<int32_t> tl_download_i32; | ||
| 82 | |||
| 83 | 12 | void emptyBuffer(bronze_native_buffer* out) { | |
| 84 | 12 | out->data = nullptr; | |
| 85 | 12 | out->length = 0; | |
| 86 | 12 | out->release = nullptr; | |
| 87 | 12 | out->ctx = nullptr; | |
| 88 | 12 | } | |
| 89 | |||
| 90 | // The FP32-only elementwise pair shape: x FP32, dY the same size. | ||
| 91 | 14 | bool fp32Pair(const char* label, void* x, const char* xn, void* dY) { | |
| 92 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | if (!need(label, {x, dY})) return false; |
| 93 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
28 | return needDtype(label, xn, toTensor(x), brotensor::Dtype::FP32) && |
| 94 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | needDtype(label, "dY", toTensor(dY), brotensor::Dtype::FP32) && |
| 95 | 14 | needSameSize(label, "dY", toTensor(dY), toTensor(x)); | |
| 96 | 14 | } | |
| 97 | |||
| 98 | } // namespace | ||
| 99 | |||
| 100 | extern "C" { | ||
| 101 | |||
| 102 | // ---- INT32 upload / download ----------------------------------------------- | ||
| 103 | |||
| 104 | 50 | void bro_tensor_uploadInt32(void* self, const int32_t* data, uint32_t data_len) { | |
| 105 | 50 | auto* t = toTensor(self); | |
| 106 |
2/4✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 50 times.
|
50 | if (!t || !data) { |
| 107 | ✗ | setError("uploadInt32: not a GpuTensor / Int32Array"); | |
| 108 | ✗ | return; | |
| 109 | } | ||
| 110 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
|
50 | if (data_len > static_cast<uint32_t>(INT_MAX)) { |
| 111 | ✗ | setError("uploadInt32: too many elements"); | |
| 112 | ✗ | return; | |
| 113 | } | ||
| 114 | 50 | int r = t->rows, c = t->cols; | |
| 115 |
1/2✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
|
50 | if (static_cast<int64_t>(r) * c != static_cast<int64_t>(data_len)) { |
| 116 | ✗ | r = static_cast<int>(data_len); | |
| 117 | ✗ | c = 1; | |
| 118 | ✗ | } | |
| 119 | BROTENSOR_API_TRY | ||
| 120 | // The typed-array view is only valid for this call: copy it into the | ||
| 121 | // tensor before anything else runs. | ||
| 122 |
3/6✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
|
50 | *t = brotensor::Tensor::from_raw_bytes_on(brotensor::default_device(), data, r, c, |
| 123 | brotensor::Dtype::INT32, | ||
| 124 | 50 | static_cast<size_t>(data_len) * sizeof(int32_t)); | |
| 125 |
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.
|
50 | BROTENSOR_API_CATCH("uploadInt32") |
| 126 | 50 | } | |
| 127 | |||
| 128 | 12 | void bro_tensor_downloadInt32(void* self, bronze_native_buffer* out) { | |
| 129 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | if (!out) return; |
| 130 | 12 | emptyBuffer(out); | |
| 131 | 12 | auto* t = toTensor(self); | |
| 132 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | if (!t) { |
| 133 | ✗ | setError("downloadInt32: not a GpuTensor"); | |
| 134 | ✗ | return; | |
| 135 | } | ||
| 136 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (t->empty()) return; |
| 137 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
|
12 | if (t->dtype != brotensor::Dtype::INT32) { |
| 138 |
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 | setError(std::string("downloadInt32: tensor is ") + dtypeToString(t->dtype) + ", expected int32"); |
| 139 | 2 | return; | |
| 140 | } | ||
| 141 | BROTENSOR_API_TRY | ||
| 142 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | const brotensor::Tensor host = t->to(brotensor::Device::CPU); |
| 143 |
2/4✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
10 | tl_download_i32.resize(static_cast<size_t>(host.size())); |
| 144 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | std::memcpy(tl_download_i32.data(), host.host_raw(), tl_download_i32.size() * sizeof(int32_t)); |
| 145 | 10 | out->data = tl_download_i32.data(); | |
| 146 | 10 | out->length = static_cast<uint32_t>(tl_download_i32.size()); | |
| 147 |
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.
|
10 | BROTENSOR_API_CATCH("downloadInt32") |
| 148 | 12 | } | |
| 149 | |||
| 150 | // ---- bias adds + axpby ----------------------------------------------------- | ||
| 151 | |||
| 152 | 6 | void bro_tensor_addChannelBiasInplace(void* y, void* bias, int32_t C, int32_t L) { | |
| 153 | 6 | constexpr const char* lb = "addChannelBiasInplace"; | |
| 154 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (!need(lb, {y, bias})) return; |
| 155 | 6 | auto* Y = toTensor(y); | |
| 156 | 6 | auto* B = toTensor(bias); | |
| 157 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | if (!needFloat(lb, "y", Y) || !needSameDtype(lb, "bias", B, Y)) return; |
| 158 | 6 | const int64_t n = prod({C, L}); | |
| 159 |
1/6✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
6 | if (n < 0) { setError(std::string(lb) + ": negative C or L"); return; } |
| 160 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
|
6 | if (n != Y->size()) { |
| 161 |
8/16✓ 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.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
|
2 | setError(std::string(lb) + ": y holds " + std::to_string(Y->size()) + " elements, C*L is " + std::to_string(n)); |
| 162 | 2 | return; | |
| 163 | } | ||
| 164 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (!needElems(lb, "bias", B, C)) return; |
| 165 | BROTENSOR_API_TRY | ||
| 166 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | brotensor::add_channel_bias_inplace(*Y, *B, C, L); |
| 167 |
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) |
| 168 | 6 | } | |
| 169 | |||
| 170 | 4 | void bro_tensor_addRowBiasInplace(void* y, void* bias) { | |
| 171 | 4 | constexpr const char* lb = "addRowBiasInplace"; | |
| 172 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!need(lb, {y, bias})) return; |
| 173 | 4 | auto* Y = toTensor(y); | |
| 174 | 4 | auto* B = toTensor(bias); | |
| 175 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | if (!needFloat(lb, "Y", Y) || !needSameDtype(lb, "bias", B, Y)) return; |
| 176 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (B->size() != Y->cols) { |
| 177 |
7/14✓ 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.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
|
6 | setError(std::string(lb) + ": bias holds " + std::to_string(B->size()) + " elements, Y has " + |
| 178 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | std::to_string(Y->cols) + " columns"); |
| 179 | 2 | return; | |
| 180 | } | ||
| 181 | BROTENSOR_API_TRY | ||
| 182 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | brotensor::add_row_bias_inplace(*Y, *B); |
| 183 |
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) |
| 184 | 4 | } | |
| 185 | |||
| 186 | 4 | void bro_tensor_axpbyInplace(void* y, void* x, double a, double b) { | |
| 187 | 4 | constexpr const char* lb = "axpbyInplace"; | |
| 188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!need(lb, {y, x})) return; |
| 189 | 4 | auto* Y = toTensor(y); | |
| 190 | 4 | auto* X = toTensor(x); | |
| 191 |
4/6✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | if (!needFloat(lb, "y", Y) || !needSameDtype(lb, "x", X, Y) || !needSameSize(lb, "x", X, Y)) return; |
| 192 | BROTENSOR_API_TRY | ||
| 193 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | brotensor::axpby_inplace(*Y, *X, static_cast<float>(a), static_cast<float>(b)); |
| 194 |
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) |
| 195 | 4 | } | |
| 196 | |||
| 197 | // ---- sin / cos / rsqrt (FP32 elementwise) ---------------------------------- | ||
| 198 | |||
| 199 | 2 | void bro_tensor_sinForward(void* x, void* y) { | |
| 200 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need("sinForward", {x, y}) || !needDtype("sinForward", "x", toTensor(x), brotensor::Dtype::FP32)) return; |
| 201 | BROTENSOR_API_TRY | ||
| 202 |
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::sin_forward(*toTensor(x), *toTensor(y)); |
| 203 |
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("sinForward") |
| 204 | 2 | } | |
| 205 | |||
| 206 | 4 | void bro_tensor_sinBackward(void* x, void* dY, void* dX) { | |
| 207 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!need("sinBackward", {dX}) || !fp32Pair("sinBackward", x, "x", dY)) return; |
| 208 | BROTENSOR_API_TRY | ||
| 209 |
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::sin_backward(*toTensor(x), *toTensor(dY), *toTensor(dX)); |
| 210 |
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("sinBackward") |
| 211 | 4 | } | |
| 212 | |||
| 213 | 4 | void bro_tensor_cosForward(void* x, void* y) { | |
| 214 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!need("cosForward", {x, y}) || !needDtype("cosForward", "x", toTensor(x), brotensor::Dtype::FP32)) return; |
| 215 | BROTENSOR_API_TRY | ||
| 216 |
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::cos_forward(*toTensor(x), *toTensor(y)); |
| 217 |
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("cosForward") |
| 218 | 4 | } | |
| 219 | |||
| 220 | 2 | void bro_tensor_cosBackward(void* x, void* dY, void* dX) { | |
| 221 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need("cosBackward", {dX}) || !fp32Pair("cosBackward", x, "x", dY)) return; |
| 222 | BROTENSOR_API_TRY | ||
| 223 |
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::cos_backward(*toTensor(x), *toTensor(dY), *toTensor(dX)); |
| 224 |
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("cosBackward") |
| 225 | 2 | } | |
| 226 | |||
| 227 | 2 | void bro_tensor_rsqrtForward(void* x, void* y) { | |
| 228 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need("rsqrtForward", {x, y}) || !needDtype("rsqrtForward", "x", toTensor(x), brotensor::Dtype::FP32)) return; |
| 229 | BROTENSOR_API_TRY | ||
| 230 |
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::rsqrt_forward(*toTensor(x), *toTensor(y)); |
| 231 |
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("rsqrtForward") |
| 232 | 2 | } | |
| 233 | |||
| 234 | 4 | void bro_tensor_rsqrtBackward(void* y, void* dY, void* dX) { | |
| 235 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!need("rsqrtBackward", {dX}) || !fp32Pair("rsqrtBackward", y, "y", dY)) return; |
| 236 | BROTENSOR_API_TRY | ||
| 237 |
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::rsqrt_backward(*toTensor(y), *toTensor(dY), *toTensor(dX)); |
| 238 |
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("rsqrtBackward") |
| 239 | 4 | } | |
| 240 | |||
| 241 | // ---- pixel norm -------------------------------------------------------------- | ||
| 242 | |||
| 243 | 2 | void bro_tensor_pixelNormForward(void* X, double eps, void* Y) { | |
| 244 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need("pixelNormForward", {X, Y}) || |
| 245 | 2 | !needDtype("pixelNormForward", "X", toTensor(X), brotensor::Dtype::FP32)) return; | |
| 246 | BROTENSOR_API_TRY | ||
| 247 |
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::pixel_norm_forward(*toTensor(X), static_cast<float>(eps), *toTensor(Y)); |
| 248 |
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("pixelNormForward") |
| 249 | 2 | } | |
| 250 | |||
| 251 | 4 | void bro_tensor_pixelNormBackward(void* X, void* dY, double eps, void* dX) { | |
| 252 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!need("pixelNormBackward", {dX}) || !fp32Pair("pixelNormBackward", X, "X", dY)) return; |
| 253 | BROTENSOR_API_TRY | ||
| 254 |
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::pixel_norm_backward(*toTensor(X), *toTensor(dY), static_cast<float>(eps), *toTensor(dX)); |
| 255 |
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("pixelNormBackward") |
| 256 | 4 | } | |
| 257 | |||
| 258 | // ---- thresholds + row counts ------------------------------------------------- | ||
| 259 | |||
| 260 | 4 | void bro_tensor_thresholdU8(void* X, double t, void* Y) { | |
| 261 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!need("thresholdU8", {X, Y}) || !needFloat("thresholdU8", "X", toTensor(X))) return; |
| 262 | BROTENSOR_API_TRY | ||
| 263 |
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::threshold_u8(*toTensor(X), static_cast<float>(t), *toTensor(Y)); |
| 264 |
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("thresholdU8") |
| 265 | 4 | } | |
| 266 | |||
| 267 | 2 | void bro_tensor_rowsCountAbove(void* X, double tLo, double tHi, void* counts) { | |
| 268 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need("rowsCountAbove", {X, counts}) || !needFloat("rowsCountAbove", "X", toTensor(X))) return; |
| 269 | BROTENSOR_API_TRY | ||
| 270 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | brotensor::rows_count_above(*toTensor(X), static_cast<float>(tLo), static_cast<float>(tHi), |
| 271 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | *toTensor(counts)); |
| 272 |
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("rowsCountAbove") |
| 273 | 2 | } | |
| 274 | |||
| 275 | // ---- softmax --------------------------------------------------------------- | ||
| 276 | |||
| 277 | 4 | void bro_tensor_softmaxRowsForward(void* X, void* Y, int32_t rows, int32_t cols) { | |
| 278 | 4 | constexpr const char* lb = "softmaxRowsForward"; | |
| 279 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!need(lb, {X, Y})) return; |
| 280 | 4 | auto* x = toTensor(X); | |
| 281 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!needFloat(lb, "X", x) || !needElems(lb, "X", x, prod({rows, cols}))) return; |
| 282 | BROTENSOR_API_TRY | ||
| 283 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | brotensor::softmax_rows_forward(*x, *toTensor(Y), rows, cols); |
| 284 |
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) |
| 285 | 4 | } | |
| 286 | |||
| 287 | 8 | double bro_tensor_softmaxXent(void* logits, void* target, void* probs, void* dLogits, uint64_t mask_bits) { | |
| 288 | 8 | constexpr const char* lb = "softmaxXent"; | |
| 289 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (!need(lb, {logits, target, probs, dLogits})) return 0.0; |
| 290 | 8 | auto* L = toTensor(logits); | |
| 291 | 8 | auto* T = toTensor(target); | |
| 292 |
4/6✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 6 times.
|
8 | if (!needDtype(lb, "logits", L, brotensor::Dtype::FP32) || !needDtype(lb, "target", T, brotensor::Dtype::FP32) || |
| 293 | 8 | !needSameSize(lb, "target", T, L)) return 0.0; | |
| 294 | 6 | auto* M = tensorFromValue(mask_bits); | |
| 295 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | if (!optF32Elems(lb, "mask", M, L->size())) return 0.0; |
| 296 | BROTENSOR_API_TRY | ||
| 297 |
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.
|
8 | return brotensor::softmax_xent(*L, *T, *toTensor(probs), *toTensor(dLogits), |
| 298 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | M ? static_cast<const float*>(M->data) : nullptr); |
| 299 | ✗ | BROTENSOR_API_CATCH(lb) | |
| 300 | ✗ | return 0.0; | |
| 301 | 8 | } | |
| 302 | |||
| 303 | // ---- strided copy + row scatter ---------------------------------------------- | ||
| 304 | |||
| 305 | 6 | void bro_tensor_copyD2DStrided(void* src, int32_t srcOff, int32_t srcPitch, void* dst, int32_t dstOff, | |
| 306 | int32_t dstPitch, int32_t width, int32_t height) { | ||
| 307 | 6 | constexpr const char* lb = "copyD2DStrided"; | |
| 308 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (!need(lb, {src, dst})) return; |
| 309 | 6 | auto* S = toTensor(src); | |
| 310 | 6 | auto* D = toTensor(dst); | |
| 311 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (!needSameDtype(lb, "dst", D, S)) return; |
| 312 |
4/8✓ 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 not taken.
✓ Branch 7 taken 6 times.
|
6 | if (width < 0 || height < 0 || srcOff < 0 || dstOff < 0) { |
| 313 | ✗ | setError(std::string(lb) + ": offsets, width and height must be non-negative"); | |
| 314 | ✗ | return; | |
| 315 | } | ||
| 316 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | if (srcPitch < width || dstPitch < width) { |
| 317 | ✗ | setError(std::string(lb) + ": pitch must be >= width"); | |
| 318 | ✗ | return; | |
| 319 | } | ||
| 320 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | if (width == 0 || height == 0) return; |
| 321 | 6 | const int64_t srcNeed = static_cast<int64_t>(srcOff) + static_cast<int64_t>(height - 1) * srcPitch + width; | |
| 322 | 6 | const int64_t dstNeed = static_cast<int64_t>(dstOff) + static_cast<int64_t>(height - 1) * dstPitch + width; | |
| 323 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
6 | if (!needElems(lb, "src", S, srcNeed) || !needElems(lb, "dst", D, dstNeed)) return; |
| 324 | BROTENSOR_API_TRY | ||
| 325 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | brotensor::copy_d2d_strided(*S, srcOff, srcPitch, *D, dstOff, dstPitch, width, height); |
| 326 |
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) |
| 327 | 6 | } | |
| 328 | |||
| 329 | 8 | void bro_tensor_scatterRows(void* Y, void* Idx, void* X) { | |
| 330 | 8 | constexpr const char* lb = "scatterRows"; | |
| 331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (!need(lb, {Y, Idx, X})) return; |
| 332 | 8 | auto* y = toTensor(Y); | |
| 333 | 8 | auto* x = toTensor(X); | |
| 334 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
8 | if (!needFloat(lb, "Y", y) || !needSameDtype(lb, "X", x, y)) return; |
| 335 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
8 | if (x->empty()) { setError(std::string(lb) + ": X must be allocated (it is updated in place)"); return; } |
| 336 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (x->cols != y->cols) { |
| 337 | ✗ | setError(std::string(lb) + ": X has " + std::to_string(x->cols) + " columns, Y has " + std::to_string(y->cols)); | |
| 338 | ✗ | return; | |
| 339 | } | ||
| 340 | 8 | auto* I = toTensor(Idx); | |
| 341 |
3/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
8 | if (I->rows != y->rows || I->cols != 1) { |
| 342 |
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.
|
2 | setError(std::string(lb) + ": Idx must be (" + std::to_string(y->rows) + ", 1), one row index per Y row"); |
| 343 | 2 | return; | |
| 344 | } | ||
| 345 | BROTENSOR_API_TRY | ||
| 346 | 6 | std::vector<int32_t> idx; | |
| 347 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
6 | if (!hostInt32(lb, "Idx", I, y->rows, idx)) return; |
| 348 |
3/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
|
6 | if (!needIndicesIn(lb, "Idx", idx, y->rows, 0, x->rows)) return; |
| 349 | 4 | brotensor::Tensor scratch; | |
| 350 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | brotensor::scatter_rows(*y, int32Operand(*I, idx, scratch), *x); |
| 351 |
2/15✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✗ 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.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
6 | BROTENSOR_API_CATCH(lb) |
| 352 | 8 | } | |
| 353 | |||
| 354 | // ---- segment softmax statistics ------------------------------------------------ | ||
| 355 | |||
| 356 | 4 | void bro_tensor_segmentSoftmaxStats(void* logits, void* segOffsets, void* out) { | |
| 357 | 4 | constexpr const char* lb = "segmentSoftmaxStats"; | |
| 358 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!need(lb, {logits, segOffsets, out})) return; |
| 359 | 4 | auto* L = toTensor(logits); | |
| 360 | 4 | auto* O = toTensor(segOffsets); | |
| 361 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (!needFloat(lb, "logits", L)) return; |
| 362 |
2/8✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
4 | if (O->cols != 1 || O->rows < 1) { setError(std::string(lb) + ": segOffsets must be (S+1, 1)"); return; } |
| 363 | BROTENSOR_API_TRY | ||
| 364 | 4 | std::vector<int32_t> off; | |
| 365 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | if (!hostInt32(lb, "segOffsets", O, O->rows, off)) return; |
| 366 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | const int64_t K = L->size(); |
| 367 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
|
12 | for (size_t s = 0; s < off.size(); ++s) { |
| 368 |
5/6✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
|
10 | const bool bad = off[s] < 0 || off[s] > K || (s > 0 && off[s] < off[s - 1]); |
| 369 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
|
10 | if (bad) { |
| 370 |
6/12✓ 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.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
|
4 | setError(std::string(lb) + ": segOffsets must be non-decreasing within [0, " + std::to_string(K) + |
| 371 |
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.
|
2 | "]; entry " + std::to_string(s) + " is " + std::to_string(off[s])); |
| 372 | 2 | return; | |
| 373 | } | ||
| 374 | 8 | } | |
| 375 | 2 | brotensor::Tensor scratch; | |
| 376 |
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::segment_softmax_stats(*L, int32Operand(*O, off, scratch), *toTensor(out)); |
| 377 |
2/15✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ 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.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
4 | BROTENSOR_API_CATCH(lb) |
| 378 | 4 | } | |
| 379 | |||
| 380 | // ---- masked-diffusion token selection ------------------------------------------ | ||
| 381 | |||
| 382 | 6 | void bro_tensor_maskedDiffusionScores(void* logits, void* tokens, int32_t T, int32_t C, int32_t V, | |
| 383 | int32_t maskId, double guidanceScale, double layerPenalty, | ||
| 384 | double positionTemperature, double classTemperature, | ||
| 385 | double classTopFrac, uint64_t seed_bits, | ||
| 386 | void* pred, void* scores, void* confidence) { | ||
| 387 | 6 | constexpr const char* lb = "maskedDiffusionScores"; | |
| 388 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (!need(lb, {logits, tokens, pred, scores, confidence})) return; |
| 389 |
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 (T < 1 || C < 1 || V < 1) { setError(std::string(lb) + ": T, C and V must be >= 1"); return; } |
| 390 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (!needRange(lb, "maskId", maskId, 0, static_cast<int64_t>(V) - 1)) return; |
| 391 | 6 | auto* L = toTensor(logits); | |
| 392 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | const int64_t R = guidanceScale != 0.0 ? 2 * static_cast<int64_t>(T) : T; |
| 393 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
|
6 | if (!needDtype(lb, "logits", L, brotensor::Dtype::FP32) || !needElems(lb, "logits", L, prod({R, C, V}))) return; |
| 394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!needExtent(lb, "C*T", prod({C, T}))) return; |
| 395 | 4 | const uint64_t seed = bronze::embed::toUint64(bronze::Value{seed_bits}); | |
| 396 | BROTENSOR_API_TRY | ||
| 397 | 4 | std::vector<int32_t> tok; | |
| 398 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | auto* tk = toTensor(tokens); |
| 399 |
4/6✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
|
4 | if (!hostInt32(lb, "tokens", tk, prod({C, T}), tok)) return; |
| 400 | 2 | brotensor::Tensor scratch; | |
| 401 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | const brotensor::Tensor& tokI = int32Operand(*tk, tok, scratch); |
| 402 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | brotensor::masked_diffusion_scores(*L, tokI, T, C, V, maskId, static_cast<float>(guidanceScale), |
| 403 | 2 | static_cast<float>(layerPenalty), | |
| 404 | 2 | static_cast<float>(positionTemperature), | |
| 405 | 2 | static_cast<float>(classTemperature), | |
| 406 | 2 | static_cast<float>(classTopFrac), seed, | |
| 407 |
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 | *toTensor(pred), *toTensor(scores), *toTensor(confidence)); |
| 408 |
2/15✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ 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.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
4 | BROTENSOR_API_CATCH(lb) |
| 409 | 6 | } | |
| 410 | |||
| 411 | 6 | void bro_tensor_maskedDiffusionCommit(void* pred, void* idx, int32_t k, int32_t step, void* tokens, | |
| 412 | void* unmaskStep) { | ||
| 413 | 6 | constexpr const char* lb = "maskedDiffusionCommit"; | |
| 414 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (!need(lb, {pred, idx, tokens, unmaskStep})) return; |
| 415 | 6 | auto* P = toTensor(pred); | |
| 416 | 6 | auto* Tk = toTensor(tokens); | |
| 417 | 6 | auto* U = toTensor(unmaskStep); | |
| 418 |
3/6✓ 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.
|
6 | if (!needDtype(lb, "pred", P, brotensor::Dtype::INT32) || !needDtype(lb, "tokens", Tk, brotensor::Dtype::INT32) || |
| 419 | 6 | !needDtype(lb, "unmaskStep", U, brotensor::Dtype::INT32)) return; | |
| 420 |
3/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
6 | if (!needSameSize(lb, "tokens", Tk, P) || !needSameSize(lb, "unmaskStep", U, P)) return; |
| 421 |
1/6✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
4 | if (k < 0) { setError(std::string(lb) + ": k must be >= 0"); return; } |
| 422 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (k == 0) return; |
| 423 | BROTENSOR_API_TRY | ||
| 424 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | auto* I = toTensor(idx); |
| 425 | 4 | brotensor::Tensor scratch; | |
| 426 | 4 | const brotensor::Tensor* use = I; | |
| 427 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (I->dtype == brotensor::Dtype::INT32) { |
| 428 |
3/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!needElems(lb, "idx", I, k)) return; |
| 429 | 2 | } else { | |
| 430 | ✗ | std::vector<int32_t> vals; | |
| 431 | ✗ | if (!hostInt32(lb, "idx", I, k, vals)) return; | |
| 432 | ✗ | use = &int32Operand(*I, vals, scratch); | |
| 433 | ✗ | } | |
| 434 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | brotensor::masked_diffusion_commit(*P, *use, k, step, *Tk, *U); |
| 435 |
2/15✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ 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.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
4 | BROTENSOR_API_CATCH(lb) |
| 436 | 6 | } | |
| 437 | |||
| 438 | } // extern "C" | ||
| 439 | |||
| 440 | namespace brotensor::api { | ||
| 441 | |||
| 442 | 3 | bool registerTensorNatives_extra(std::string* error) { | |
| 443 | using namespace brotensor::api::reg; | ||
| 444 | 3 | return | |
| 445 | 6 | fn("__bro_native.tensor.uploadInt32", p(&bro_tensor_uploadInt32), "void", | |
| 446 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, "i32[]"}, error) && |
| 447 | 6 | fn("__bro_native.tensor.downloadInt32", p(&bro_tensor_downloadInt32), "i32[]", | |
| 448 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls}, error) && |
| 449 | 6 | fn("__bro_native.tensor.addChannelBiasInplace", p(&bro_tensor_addChannelBiasInplace), "void", | |
| 450 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, "i32", "i32"}, error) && |
| 451 | 6 | fn("__bro_native.tensor.addRowBiasInplace", p(&bro_tensor_addRowBiasInplace), "void", | |
| 452 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls}, error) && |
| 453 | 6 | fn("__bro_native.tensor.axpbyInplace", p(&bro_tensor_axpbyInplace), "void", | |
| 454 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, "f64", "f64"}, error) && |
| 455 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | fn("__bro_native.tensor.sinForward", p(&bro_tensor_sinForward), "void", {kTensorCls, kTensorCls}, error) && |
| 456 | 6 | fn("__bro_native.tensor.sinBackward", p(&bro_tensor_sinBackward), "void", | |
| 457 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, kTensorCls}, error) && |
| 458 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | fn("__bro_native.tensor.cosForward", p(&bro_tensor_cosForward), "void", {kTensorCls, kTensorCls}, error) && |
| 459 | 6 | fn("__bro_native.tensor.cosBackward", p(&bro_tensor_cosBackward), "void", | |
| 460 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, kTensorCls}, error) && |
| 461 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | fn("__bro_native.tensor.rsqrtForward", p(&bro_tensor_rsqrtForward), "void", {kTensorCls, kTensorCls}, error) && |
| 462 | 6 | fn("__bro_native.tensor.rsqrtBackward", p(&bro_tensor_rsqrtBackward), "void", | |
| 463 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, kTensorCls}, error) && |
| 464 | 6 | fn("__bro_native.tensor.pixelNormForward", p(&bro_tensor_pixelNormForward), "void", | |
| 465 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, "f64", kTensorCls}, error) && |
| 466 | 6 | fn("__bro_native.tensor.pixelNormBackward", p(&bro_tensor_pixelNormBackward), "void", | |
| 467 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, "f64", kTensorCls}, error) && |
| 468 | 6 | fn("__bro_native.tensor.thresholdU8", p(&bro_tensor_thresholdU8), "void", | |
| 469 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, "f64", kTensorCls}, error) && |
| 470 | 6 | fn("__bro_native.tensor.rowsCountAbove", p(&bro_tensor_rowsCountAbove), "void", | |
| 471 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, "f64", "f64", kTensorCls}, error) && |
| 472 | 6 | fn("__bro_native.tensor.softmaxRowsForward", p(&bro_tensor_softmaxRowsForward), "void", | |
| 473 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, "i32", "i32"}, error) && |
| 474 | 6 | fn("__bro_native.tensor.softmaxXent", p(&bro_tensor_softmaxXent), "f64", | |
| 475 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, kTensorCls, kTensorCls, kDyn}, error) && |
| 476 | 6 | fn("__bro_native.tensor.copyD2DStrided", p(&bro_tensor_copyD2DStrided), "void", | |
| 477 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, "i32", "i32", kTensorCls, "i32", "i32", "i32", "i32"}, error) && |
| 478 | 6 | fn("__bro_native.tensor.scatterRows", p(&bro_tensor_scatterRows), "void", | |
| 479 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, kTensorCls}, error) && |
| 480 | 6 | fn("__bro_native.tensor.segmentSoftmaxStats", p(&bro_tensor_segmentSoftmaxStats), "void", | |
| 481 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, kTensorCls}, error) && |
| 482 | 6 | fn("__bro_native.tensor.maskedDiffusionScores", p(&bro_tensor_maskedDiffusionScores), "void", | |
| 483 | 3 | {kTensorCls, kTensorCls, "i32", "i32", "i32", "i32", "f64", "f64", "f64", "f64", "f64", kDyn, | |
| 484 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | kTensorCls, kTensorCls, kTensorCls}, error) && |
| 485 | 6 | fn("__bro_native.tensor.maskedDiffusionCommit", p(&bro_tensor_maskedDiffusionCommit), "void", | |
| 486 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, "i32", "i32", kTensorCls, kTensorCls}, error) && |
| 487 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | registerTensorNatives_extra_nn(error) && |
| 488 | 3 | registerTensorNatives_extra_conv(error); | |
| 489 | } | ||
| 490 | |||
| 491 | } // namespace brotensor::api | ||
| 492 |