src/api/native_tensor_batched.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // native_tensor_batched.cpp — bodies for the restored "batched" group. | ||
| 2 | // | ||
| 3 | // Ported from the QuickJS binding (bro-quickjs-oracle | ||
| 4 | // src/js/tensor_bindings.cpp, `nngpu::` namespace) onto the op signatures that | ||
| 5 | // exist today under include/brotensor/ops/. A native is called straight from | ||
| 6 | // generated code, so nothing may unwind out of one: every body that reaches | ||
| 7 | // into brotensor is wrapped in BROTENSOR_API_TRY / BROTENSOR_API_CATCH, which | ||
| 8 | // records the message for js/tensor_batched.js to throw after the call. | ||
| 9 | |||
| 10 | #include "native_tensor_batched_decl.h" | ||
| 11 | #include "api_internal.h" | ||
| 12 | #include "native_register.h" | ||
| 13 | #include "native_tensor_extra_util.h" | ||
| 14 | |||
| 15 | #include <cstdint> | ||
| 16 | #include <string> | ||
| 17 | #include <vector> | ||
| 18 | |||
| 19 | using namespace brotensor::api; | ||
| 20 | using brotensor::Tensor; | ||
| 21 | using brotensor::Dtype; | ||
| 22 | |||
| 23 | // gather_rows / scatter_rows_add take Idx as an (M,1) INT32 tensor whose | ||
| 24 | // VALUES address rows on the device, unchecked by the kernels. The native | ||
| 25 | // reads the indices back, range-checks them, and hands the op an INT32 | ||
| 26 | // operand (the tensor itself, or an INT32 copy of a whole-number FP32 one — | ||
| 27 | // GpuTensor.prototype.upload always lands FP32). See native_tensor_extra_util.h. | ||
| 28 | |||
| 29 | namespace { | ||
| 30 | |||
| 31 | 124 | Tensor* T(void* p) { return toTensor(p); } | |
| 32 | |||
| 33 | // X_BD is (B, W.cols). | ||
| 34 | 12 | bool needBatchIn(const char* L, const Tensor* W, const Tensor* X) { | |
| 35 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
|
12 | if (X->cols != W->cols) { |
| 36 |
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(L) + ": X_BD must be (B, " + std::to_string(W->cols) + ") to match W's in-dim"); |
| 37 | 2 | return false; | |
| 38 | } | ||
| 39 | 10 | return true; | |
| 40 | 12 | } | |
| 41 | |||
| 42 | } // namespace | ||
| 43 | |||
| 44 | extern "C" { | ||
| 45 | |||
| 46 | // ---- batched forwards ------------------------------------------------------ | ||
| 47 | |||
| 48 | // W may be FP32/FP16/BF16; bias, X and Y are FP32. | ||
| 49 | 6 | void bro_tensor_linearForwardBatched(void* W, void* bias, void* X_BD, void* Y_BD) { | |
| 50 | 6 | const char* L = "linearForwardBatched"; | |
| 51 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
|
6 | if (!need(L, {W, bias, X_BD, Y_BD}) || !needBatchIn(L, T(W), T(X_BD))) return; |
| 52 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
4 | if (!needMask(L, T(bias), T(W)->rows, "bias") || !needMask(L, T(X_BD), 0, "X_BD")) return; |
| 53 | BROTENSOR_API_TRY | ||
| 54 |
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 | brotensor::linear_forward_batched(*toTensor(W), *toTensor(bias), *toTensor(X_BD), *toTensor(Y_BD)); |
| 55 |
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(L) |
| 56 | 6 | } | |
| 57 | |||
| 58 | 4 | void bro_tensor_linearForwardBatchedFp16(void* W, uint64_t bias_bits, void* X_BD, void* Y_BD) { | |
| 59 | 4 | const char* L = "linearForwardBatchedFp16"; | |
| 60 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | if (!need(L, {W, X_BD, Y_BD}) || !needBatchIn(L, T(W), T(X_BD))) return; |
| 61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!needOperands(L, T(W), {{"X_BD", T(X_BD), 0}, {"bias", tensorFromValue(bias_bits), T(W)->rows}})) return; |
| 62 | BROTENSOR_API_TRY | ||
| 63 |
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 | brotensor::linear_forward_batched_fp16(*toTensor(W), tensorFromValue(bias_bits), |
| 64 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | *toTensor(X_BD), *toTensor(Y_BD)); |
| 65 |
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(L) |
| 66 | 4 | } | |
| 67 | |||
| 68 | 2 | void bro_tensor_reluForwardBatched(void* X_BD, void* Y_BD) { | |
| 69 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!need("reluForwardBatched", {X_BD, Y_BD})) return; |
| 70 | BROTENSOR_API_TRY | ||
| 71 |
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::relu_forward_batched(*toTensor(X_BD), *toTensor(Y_BD)); |
| 72 |
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("reluForwardBatched") |
| 73 | 2 | } | |
| 74 | |||
| 75 | 2 | void bro_tensor_tanhForwardBatched(void* X_BD, void* Y_BD) { | |
| 76 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!need("tanhForwardBatched", {X_BD, Y_BD})) return; |
| 77 | BROTENSOR_API_TRY | ||
| 78 |
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::tanh_forward_batched(*toTensor(X_BD), *toTensor(Y_BD)); |
| 79 |
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("tanhForwardBatched") |
| 80 | 2 | } | |
| 81 | |||
| 82 | 4 | void bro_tensor_addInplaceBatched(void* Y_BD, void* X_BD) { | |
| 83 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!need("addInplaceBatched", {Y_BD, X_BD}) || !needPair("addInplaceBatched", "X_BD", T(X_BD), T(Y_BD))) return; |
| 84 | BROTENSOR_API_TRY | ||
| 85 |
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::add_inplace_batched(*toTensor(Y_BD), *toTensor(X_BD)); |
| 86 |
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("addInplaceBatched") |
| 87 | 4 | } | |
| 88 | |||
| 89 | // ---- batched-training backwards -------------------------------------------- | ||
| 90 | |||
| 91 | 2 | void bro_tensor_linearBackwardBatched(void* W, void* X_BD, void* dY_BD, void* dX_BD, void* dW, void* dB) { | |
| 92 | 2 | const char* L = "linearBackwardBatched"; | |
| 93 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need(L, {W, X_BD, dY_BD, dX_BD, dW, dB}) || !needBatchIn(L, T(W), T(X_BD))) return; |
| 94 | 2 | const Tensor* w = T(W); | |
| 95 | // dW / dB accumulate — "caller zeros". | ||
| 96 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6 | if (!needOperands(L, w, {{"X_BD", T(X_BD), 0}, {"dY_BD", T(dY_BD), elems({T(X_BD)->rows, w->rows})}, |
| 97 | 4 | {"dW", T(dW), elems({w->rows, w->cols})}, {"dB", T(dB), w->rows}})) return; | |
| 98 | BROTENSOR_API_TRY | ||
| 99 |
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::linear_backward_batched(*toTensor(W), *toTensor(X_BD), *toTensor(dY_BD), |
| 100 |
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(dX_BD), *toTensor(dW), *toTensor(dB)); |
| 101 |
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("linearBackwardBatched") |
| 102 | 2 | } | |
| 103 | |||
| 104 | 2 | void bro_tensor_reluBackwardBatched(void* X_BD, void* dY_BD, void* dX_BD) { | |
| 105 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need("reluBackwardBatched", {X_BD, dY_BD, dX_BD}) || |
| 106 | 2 | !needPair("reluBackwardBatched", "dY_BD", T(dY_BD), T(X_BD))) return; | |
| 107 | BROTENSOR_API_TRY | ||
| 108 |
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::relu_backward_batched(*toTensor(X_BD), *toTensor(dY_BD), *toTensor(dX_BD)); |
| 109 |
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("reluBackwardBatched") |
| 110 | 2 | } | |
| 111 | |||
| 112 | 2 | void bro_tensor_tanhBackwardBatched(void* Y_BD, void* dY_BD, void* dX_BD) { | |
| 113 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | if (!need("tanhBackwardBatched", {Y_BD, dY_BD, dX_BD}) || |
| 114 | 2 | !needPair("tanhBackwardBatched", "dY_BD", T(dY_BD), T(Y_BD))) return; | |
| 115 | BROTENSOR_API_TRY | ||
| 116 |
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::tanh_backward_batched(*toTensor(Y_BD), *toTensor(dY_BD), *toTensor(dX_BD)); |
| 117 |
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("tanhBackwardBatched") |
| 118 | 2 | } | |
| 119 | |||
| 120 | // ---- row gather / scatter / top-k ------------------------------------------ | ||
| 121 | |||
| 122 | 10 | void bro_tensor_gatherRows(void* X, void* Idx, void* Y) { | |
| 123 | 10 | const char* L = "gatherRows"; | |
| 124 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (!need(L, {X, Idx, Y})) return; |
| 125 | 10 | const Tensor* idx = T(Idx); | |
| 126 | BROTENSOR_API_TRY | ||
| 127 | 10 | std::vector<int32_t> vals; | |
| 128 |
3/6✓ 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.
|
10 | if (!extra::hostInt32(L, "Idx", idx, idx->size(), vals)) return; |
| 129 |
5/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 taken 6 times.
✓ Branch 7 taken 4 times.
|
10 | if (!extra::needIndicesIn(L, "Idx", vals, idx->size(), 0, T(X)->rows)) return; |
| 130 | 6 | Tensor scratch; | |
| 131 |
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 taken 6 times.
✗ Branch 7 not taken.
|
6 | brotensor::gather_rows(*toTensor(X), extra::int32Operand(*idx, vals, scratch), *toTensor(Y)); |
| 132 |
2/15✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 6 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.
|
10 | BROTENSOR_API_CATCH(L) |
| 133 | 10 | } | |
| 134 | |||
| 135 | // dY is (M, C) with M = Idx's length; every index names one of dX's R rows. | ||
| 136 | 4 | void bro_tensor_scatterRowsAdd(void* dY, void* Idx, int32_t R, void* dX) { | |
| 137 | 4 | const char* L = "scatterRowsAdd"; | |
| 138 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | if (!need(L, {dY, Idx, dX}) || !needNonNegative(L, {R})) return; |
| 139 | 4 | const Tensor* idx = T(Idx); | |
| 140 | 4 | const Tensor* dy = T(dY); | |
| 141 | BROTENSOR_API_TRY | ||
| 142 | 4 | std::vector<int32_t> vals; | |
| 143 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | if (!extra::hostInt32(L, "Idx", idx, dy->rows, vals)) return; |
| 144 |
3/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!extra::needIndicesIn(L, "Idx", vals, dy->rows, 0, R)) return; |
| 145 | 2 | Tensor scratch; | |
| 146 |
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::scatter_rows_add(*toTensor(dY), extra::int32Operand(*idx, vals, scratch), R, *toTensor(dX)); |
| 147 |
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(L) |
| 148 | 4 | } | |
| 149 | |||
| 150 | 6 | void bro_tensor_topKRows(void* X, int32_t k, void* Vals, void* Idx) { | |
| 151 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (!need("topKRows", {X, Vals, Idx})) return; |
| 152 | BROTENSOR_API_TRY | ||
| 153 |
5/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 taken 4 times.
✓ Branch 7 taken 2 times.
|
6 | brotensor::top_k_rows(*toTensor(X), k, *toTensor(Vals), *toTensor(Idx)); |
| 154 |
5/12✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ 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 not taken.
✗ Branch 11 not taken.
|
6 | BROTENSOR_API_CATCH("topKRows") |
| 155 | 8 | } | |
| 156 | |||
| 157 | // ---- batched LayerNorm with training caches -------------------------------- | ||
| 158 | |||
| 159 | 2 | void bro_tensor_layernormForwardBatchedWithCaches(void* X, void* gamma, void* beta, void* Y, void* Xhat, void* Mean, void* Rstd, double eps) { | |
| 160 | 2 | const char* L = "layernormForwardBatchedWithCaches"; | |
| 161 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!need(L, {X, gamma, beta, Y, Xhat, Mean, Rstd})) return; |
| 162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!needOperands(L, T(X), {{"gamma", T(gamma), T(X)->cols}, {"beta", T(beta), T(X)->cols}})) return; |
| 163 | BROTENSOR_API_TRY | ||
| 164 |
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::layernorm_forward_batched_with_caches(*toTensor(X), *toTensor(gamma), *toTensor(beta), |
| 165 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | *toTensor(Y), *toTensor(Xhat), |
| 166 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | *toTensor(Mean), *toTensor(Rstd), |
| 167 | 2 | static_cast<float>(eps)); | |
| 168 |
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("layernormForwardBatchedWithCaches") |
| 169 | 2 | } | |
| 170 | |||
| 171 | 2 | void bro_tensor_layernormBackwardBatchedWithCaches(void* dY, void* Xhat, void* gamma, void* Rstd, void* dX, void* dGamma, void* dBeta) { | |
| 172 | 2 | const char* L = "layernormBackwardBatchedWithCaches"; | |
| 173 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!need(L, {dY, Xhat, gamma, Rstd, dX, dGamma, dBeta})) return; |
| 174 | // dY/Xhat (R,D); gamma, dGamma, dBeta (D,) — the last two accumulate; Rstd (R,1) FP32. | ||
| 175 | 2 | const Tensor* dy = T(dY); | |
| 176 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (!needPair(L, "Xhat", T(Xhat), dy)) return; |
| 177 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
4 | if (!needOperands(L, dy, {{"gamma", T(gamma), dy->cols}, {"dGamma", T(dGamma), dy->cols}, |
| 178 | 2 | {"dBeta", T(dBeta), dy->cols}})) return; | |
| 179 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (!needMask(L, T(Rstd), dy->rows, "Rstd")) return; |
| 180 | BROTENSOR_API_TRY | ||
| 181 |
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::layernorm_backward_batched_with_caches(*toTensor(dY), *toTensor(Xhat), *toTensor(gamma), |
| 182 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | *toTensor(Rstd), *toTensor(dX), |
| 183 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | *toTensor(dGamma), *toTensor(dBeta)); |
| 184 |
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("layernormBackwardBatchedWithCaches") |
| 185 | 2 | } | |
| 186 | |||
| 187 | } // extern "C" | ||
| 188 | |||
| 189 | namespace brotensor::api { | ||
| 190 | |||
| 191 | 3 | bool registerTensorNatives_batched(std::string* error) { | |
| 192 | using namespace brotensor::api::reg; | ||
| 193 | 3 | return | |
| 194 | 6 | fn("__bro_native.tensor.linearForwardBatched", p(&bro_tensor_linearForwardBatched), "void", | |
| 195 |
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}, error) && |
| 196 | 6 | fn("__bro_native.tensor.linearForwardBatchedFp16", p(&bro_tensor_linearForwardBatchedFp16), "void", | |
| 197 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kDyn, kTensorCls, kTensorCls}, error) && |
| 198 | 6 | fn("__bro_native.tensor.reluForwardBatched", p(&bro_tensor_reluForwardBatched), "void", | |
| 199 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls}, error) && |
| 200 | 6 | fn("__bro_native.tensor.tanhForwardBatched", p(&bro_tensor_tanhForwardBatched), "void", | |
| 201 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls}, error) && |
| 202 | 6 | fn("__bro_native.tensor.addInplaceBatched", p(&bro_tensor_addInplaceBatched), "void", | |
| 203 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls}, error) && |
| 204 | 6 | fn("__bro_native.tensor.linearBackwardBatched", p(&bro_tensor_linearBackwardBatched), "void", | |
| 205 |
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, kTensorCls, kTensorCls}, error) && |
| 206 | 6 | fn("__bro_native.tensor.reluBackwardBatched", p(&bro_tensor_reluBackwardBatched), "void", | |
| 207 |
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) && |
| 208 | 6 | fn("__bro_native.tensor.tanhBackwardBatched", p(&bro_tensor_tanhBackwardBatched), "void", | |
| 209 |
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) && |
| 210 | 6 | fn("__bro_native.tensor.gatherRows", p(&bro_tensor_gatherRows), "void", | |
| 211 |
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) && |
| 212 | 6 | fn("__bro_native.tensor.scatterRowsAdd", p(&bro_tensor_scatterRowsAdd), "void", | |
| 213 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, kTensorCls, "i32", kTensorCls}, error) && |
| 214 | 6 | fn("__bro_native.tensor.topKRows", p(&bro_tensor_topKRows), "void", | |
| 215 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | {kTensorCls, "i32", kTensorCls, kTensorCls}, error) && |
| 216 | 6 | fn("__bro_native.tensor.layernormForwardBatchedWithCaches", p(&bro_tensor_layernormForwardBatchedWithCaches), "void", | |
| 217 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
6 | {kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, "f64"}, error) && |
| 218 | 6 | fn("__bro_native.tensor.layernormBackwardBatchedWithCaches", p(&bro_tensor_layernormBackwardBatchedWithCaches), "void", | |
| 219 | 3 | {kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls}, error); | |
| 220 | } | ||
| 221 | |||
| 222 | } // namespace brotensor::api | ||
| 223 |