GCC Code Coverage Report


Directory: brotensor/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 137 / 0 / 137
Functions: 100.0% 14 / 0 / 14
Branches: 42.2% 164 / 0 / 389

src/api/native_tensor_attn2.cpp
Line Branch Exec Source
1 // Native bodies for the second attention family (see
2 // native_tensor_attn2_decl.h): decomposed 2D rel-pos self-attention (global +
3 // windowed), packed variable-length flash attention, the gated delta rule and
4 // M-RoPE. js/tensor_attn2.js checks argument types; a body checks the index
5 // streams' values (see IdxStream), calls, and records any thrown violation.
6
7 #include "native_tensor_attn2_decl.h"
8 #include "api_internal.h"
9 #include "native_register.h"
10 #include "native_tensor_extra_util.h"
11
12 #include <string>
13 #include <vector>
14
15 using namespace brotensor::api;
16 using brotensor::Tensor;
17
18 namespace {
19
20 74 Tensor* T(void* p) { return toTensor(p); }
21
22 // The varlen / M-RoPE ops take `const int32_t*` streams (device pointers on
23 // CUDA/Metal, host on CPU) whose VALUES address rows of the other operands,
24 // and the kernels trust them. A stream is an optional GpuTensor holding INT32
25 // (uploadInt32) or whole-number FP32 (upload); the native reads it back,
26 // checks every value, and hands the op INT32 storage — the tensor's own, or
27 // an INT32 copy held in `scratch` (reading FP32 storage as INT32 would turn
28 // 1.0f into 1065353216).
29 58 struct IdxStream {
30 std::vector<int32_t> vals;
31 Tensor scratch;
32 58 const int32_t* ptr = nullptr;
33 };
34
35 // Reads `n` values of the stream in `bits` into `s`; a null stream leaves
36 // s.ptr null (the op decides whether that is allowed).
37 28 bool readStream(const char* L, const char* name, uint64_t bits, int64_t n, IdxStream& s) {
38 28 const Tensor* t = tensorFromValue(bits);
39
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (!t) return true;
40
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 2 times.
28 if (!extra::hostInt32(L, name, t, n, s.vals)) return false;
41 26 s.ptr = static_cast<const int32_t*>(extra::int32Operand(*t, s.vals, s.scratch).data);
42 26 return true;
43 28 }
44
45 // cu_seqlens: batch+1 non-decreasing prefix sums inside [0, total], each
46 // sequence at most maxLen long (the GPU kernels size their tiles from it).
47 20 bool needCuSeq(const char* L, const char* name, uint64_t bits, int32_t batch, int64_t total, int32_t maxLen,
48 IdxStream& s) {
49
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (batch <= 0) return true;
50
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
20 if (!tensorFromValue(bits)) {
51
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(L) + ": " + name + " is required when batch > 0");
52 2 return false;
53 }
54
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (!readStream(L, name, bits, static_cast<int64_t>(batch) + 1, s)) return false;
55
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
18 if (!extra::needIndicesIn(L, name, s.vals, static_cast<int64_t>(batch) + 1, 0, total + 1)) return false;
56
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 12 times.
42 for (int32_t b = 0; b < batch; ++b) {
57 30 const int64_t len = static_cast<int64_t>(s.vals[b + 1]) - s.vals[b];
58
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 2 times.
30 if (len < 0 || len > maxLen) {
59
8/16
✓ 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.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
12 setError(std::string(L) + ": " + name + " sequence " + std::to_string(b) + " has length " +
60
5/10
✓ 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.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
8 std::to_string(len) + " (must be in [0, " + std::to_string(maxLen) + "])");
61 4 return false;
62 }
63 26 }
64 12 return true;
65 20 }
66
67 // An M-RoPE position stream for an axis of width d: length L, every value a
68 // row of that axis's cos/sin tables.
69 18 bool needPosStream(const char* L, const char* name, uint64_t bits, int32_t d, int64_t rows, const Tensor* cosT,
70 const Tensor* sinT, IdxStream& s) {
71
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
18 if (d <= 0) return true;
72
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
12 if (!tensorFromValue(bits)) {
73
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(L) + ": " + name + " is required when its axis width is > 0");
74 2 return false;
75 }
76
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 if (!readStream(L, name, bits, rows, s)) return false;
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 const int64_t maxPos = cosT->rows < sinT->rows ? cosT->rows : sinT->rows;
78 8 return extra::needIndicesIn(L, name, s.vals, rows, 0, maxPos);
79 18 }
80
81 } // namespace
82
83 extern "C" {
84
85 // ---- SAM / ViTDet decomposed 2D rel-pos self-attention ---------------------
86
87 4 void bro_tensor_selfAttentionDecomposedRelPosForward(void* X, void* Wq, uint64_t bq_bits, void* Wk, uint64_t bk_bits,
88 void* Wv, uint64_t bv_bits, void* Wo, uint64_t bo_bits,
89 void* relPosH, void* relPosW,
90 int32_t numHeads, int32_t gridH, int32_t gridW, double scale,
91 void* O) {
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!need("selfAttentionDecomposedRelPosForward", {X, Wq, Wk, Wv, Wo, relPosH, relPosW, O})) return;
93 BROTENSOR_API_TRY
94
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 brotensor::self_attention_decomposed_rel_pos_forward(
95
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 *toTensor(X),
96
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wq), tensorFromValue(bq_bits),
97
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wk), tensorFromValue(bk_bits),
98
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wv), tensorFromValue(bv_bits),
99
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wo), tensorFromValue(bo_bits),
100
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(relPosH), *toTensor(relPosW),
101
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 numHeads, gridH, gridW, static_cast<float>(scale), *toTensor(O));
102
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("selfAttentionDecomposedRelPosForward")
103 4 }
104
105 4 void bro_tensor_selfAttentionDecomposedRelPosWindowedForward(void* X, void* Wq, uint64_t bq_bits, void* Wk, uint64_t bk_bits,
106 void* Wv, uint64_t bv_bits, void* Wo, uint64_t bo_bits,
107 void* relPosH, void* relPosW,
108 int32_t numHeads, int32_t gridH, int32_t gridW,
109 int32_t window, double scale, void* O) {
110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!need("selfAttentionDecomposedRelPosWindowedForward", {X, Wq, Wk, Wv, Wo, relPosH, relPosW, O})) return;
111 BROTENSOR_API_TRY
112
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 brotensor::self_attention_decomposed_rel_pos_windowed_forward(
113
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 *toTensor(X),
114
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wq), tensorFromValue(bq_bits),
115
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wk), tensorFromValue(bk_bits),
116
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wv), tensorFromValue(bv_bits),
117
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(Wo), tensorFromValue(bo_bits),
118
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(relPosH), *toTensor(relPosW),
119
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 numHeads, gridH, gridW, window, static_cast<float>(scale), *toTensor(O));
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.
4 BROTENSOR_API_CATCH("selfAttentionDecomposedRelPosWindowedForward")
121 4 }
122
123 // ---- packed variable-length flash attention (Qwen-VL window attention) -----
124
125 12 void bro_tensor_flashAttentionVarlenForward(void* Q, void* K, void* V, uint64_t cuSeqQ_bits, uint64_t cuSeqK_bits,
126 int32_t batch, int32_t maxQ, int32_t maxK,
127 int32_t numHeads, int32_t headDim, bool causal, void* O) {
128 12 const char* L = "flashAttentionVarlenForward";
129
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if (!need(L, {Q, K, V, O}) || !needNonNegative(L, {batch, maxQ, maxK})) return;
130 BROTENSOR_API_TRY
131 12 IdxStream cq, ck;
132
5/8
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
16 if (!needCuSeq(L, "cuSeqQ", cuSeqQ_bits, batch, T(Q)->rows, maxQ, cq) ||
133
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
12 !needCuSeq(L, "cuSeqK", cuSeqK_bits, batch, T(K)->rows, maxK, ck)) return;
134
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::flash_attention_varlen_forward(*toTensor(Q), *toTensor(K), *toTensor(V),
135 4 cq.ptr, ck.ptr,
136 4 batch, maxQ, maxK, numHeads, headDim, causal,
137
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 *toTensor(O));
138
2/15
✗ 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 taken 8 times.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
12 BROTENSOR_API_CATCH(L)
139 12 }
140
141 2 void bro_tensor_flashAttentionVarlenBackward(void* Q, void* K, void* V, void* O, void* dO,
142 uint64_t cuSeqQ_bits, uint64_t cuSeqK_bits,
143 int32_t batch, int32_t maxQ, int32_t maxK,
144 int32_t numHeads, int32_t headDim, bool causal,
145 void* dQ, void* dK, void* dV) {
146 2 const char* L = "flashAttentionVarlenBackward";
147
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (!need(L, {Q, K, V, O, dO, dQ, dK, dV}) || !needNonNegative(L, {batch, maxQ, maxK})) return;
148
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (!needPair(L, "O", T(O), T(Q)) || !needPair(L, "dO", T(dO), T(Q))) return;
149 BROTENSOR_API_TRY
150 2 IdxStream cq, ck;
151
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 if (!needCuSeq(L, "cuSeqQ", cuSeqQ_bits, batch, T(Q)->rows, maxQ, cq) ||
152
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 !needCuSeq(L, "cuSeqK", cuSeqK_bits, batch, T(K)->rows, maxK, ck)) return;
153
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::flash_attention_varlen_backward(*toTensor(Q), *toTensor(K), *toTensor(V),
154
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 *toTensor(O), *toTensor(dO),
155 2 cq.ptr, ck.ptr,
156 2 batch, maxQ, maxK, numHeads, headDim, causal,
157
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(dQ), *toTensor(dK), *toTensor(dV));
158
1/15
✗ 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.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
2 BROTENSOR_API_CATCH(L)
159 2 }
160
161 // ---- gated delta rule (linear attention — Qwen3-Next) ---------------------
162
163 4 void bro_tensor_gatedDeltaRuleChunked(void* Q, void* K, void* V, void* aRaw, void* beta, void* logA,
164 int32_t numHeads, int32_t d_k, int32_t d_v, void* state, void* O) {
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!need("gatedDeltaRuleChunked", {Q, K, V, aRaw, beta, logA, state, O})) return;
166 BROTENSOR_API_TRY
167
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::gated_delta_rule_chunked(*toTensor(Q), *toTensor(K), *toTensor(V),
168
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 *toTensor(aRaw), *toTensor(beta), *toTensor(logA),
169
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 numHeads, d_k, d_v, *toTensor(state), *toTensor(O));
170
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("gatedDeltaRuleChunked")
171 4 }
172
173 6 void bro_tensor_gatedDeltaRuleStep(void* Q, void* K, void* V, void* aRaw, void* beta, void* logA,
174 int32_t numHeads, int32_t d_k, int32_t d_v, void* state, void* O) {
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!need("gatedDeltaRuleStep", {Q, K, V, aRaw, beta, logA, state, O})) return;
176 BROTENSOR_API_TRY
177
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.
12 brotensor::gated_delta_rule_step(*toTensor(Q), *toTensor(K), *toTensor(V),
178
3/6
✓ 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.
6 *toTensor(aRaw), *toTensor(beta), *toTensor(logA),
179
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 numHeads, d_k, d_v, *toTensor(state), *toTensor(O));
180
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("gatedDeltaRuleStep")
181 6 }
182
183 // ---- M-RoPE (Qwen-VL multimodal rotary) -----------------------------------
184
185 10 void bro_tensor_ropeApplyMrope(void* X, void* cosT, void* sinT, void* cosH, void* sinH, void* cosW, void* sinW,
186 uint64_t posT_bits, uint64_t posH_bits, uint64_t posW_bits,
187 int32_t headDim, int32_t numHeads, int32_t d_t, int32_t d_h, int32_t d_w,
188 void* Y) {
189 10 const char* L = "ropeApplyMrope";
190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!need(L, {X, cosT, sinT, cosH, sinH, cosW, sinW, Y})) return;
191 10 const int64_t rows = T(X)->rows;
192 BROTENSOR_API_TRY
193 10 IdxStream pt, ph, pw;
194
6/10
✓ 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 4 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
14 if (!needPosStream(L, "posT", posT_bits, d_t, rows, T(cosT), T(sinT), pt) ||
195
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.
4 !needPosStream(L, "posH", posH_bits, d_h, rows, T(cosH), T(sinH), ph) ||
196
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.
10 !needPosStream(L, "posW", posW_bits, d_w, rows, T(cosW), T(sinW), pw)) return;
197
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 brotensor::rope_apply_mrope(*toTensor(X),
198
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(cosT), *toTensor(sinT),
199
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(cosH), *toTensor(sinH),
200
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 *toTensor(cosW), *toTensor(sinW),
201 4 pt.ptr, ph.ptr, pw.ptr,
202
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 headDim, numHeads, d_t, d_h, d_w, *toTensor(Y));
203
2/15
✗ 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 taken 6 times.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
10 BROTENSOR_API_CATCH(L)
204 10 }
205
206 } // extern "C"
207
208 namespace brotensor::api {
209
210 3 bool registerTensorNatives_attn2(std::string* error) {
211 using namespace brotensor::api::reg;
212 3 return
213 6 fn("__bro_native.tensor.selfAttentionDecomposedRelPosForward", p(&bro_tensor_selfAttentionDecomposedRelPosForward), "void",
214 3 {kTensorCls, kTensorCls, kDyn, kTensorCls, kDyn, kTensorCls, kDyn, kTensorCls, kDyn,
215
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", "i32", "f64", kTensorCls}, error) &&
216 6 fn("__bro_native.tensor.selfAttentionDecomposedRelPosWindowedForward", p(&bro_tensor_selfAttentionDecomposedRelPosWindowedForward), "void",
217 3 {kTensorCls, kTensorCls, kDyn, kTensorCls, kDyn, kTensorCls, kDyn, kTensorCls, kDyn,
218
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", "i32", "i32", "f64", kTensorCls}, error) &&
219 6 fn("__bro_native.tensor.flashAttentionVarlenForward", p(&bro_tensor_flashAttentionVarlenForward), "void",
220
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 {kTensorCls, kTensorCls, kTensorCls, kDyn, kDyn, "i32", "i32", "i32", "i32", "i32", "bool", kTensorCls}, error) &&
221 6 fn("__bro_native.tensor.flashAttentionVarlenBackward", p(&bro_tensor_flashAttentionVarlenBackward), "void",
222 3 {kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kDyn, kDyn,
223
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 "i32", "i32", "i32", "i32", "i32", "bool", kTensorCls, kTensorCls, kTensorCls}, error) &&
224 6 fn("__bro_native.tensor.gatedDeltaRuleChunked", p(&bro_tensor_gatedDeltaRuleChunked), "void",
225 3 {kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls,
226
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 "i32", "i32", "i32", kTensorCls, kTensorCls}, error) &&
227 6 fn("__bro_native.tensor.gatedDeltaRuleStep", p(&bro_tensor_gatedDeltaRuleStep), "void",
228 3 {kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls,
229
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 "i32", "i32", "i32", kTensorCls, kTensorCls}, error) &&
230 6 fn("__bro_native.tensor.ropeApplyMrope", p(&bro_tensor_ropeApplyMrope), "void",
231 3 {kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls, kTensorCls,
232 3 kDyn, kDyn, kDyn, "i32", "i32", "i32", "i32", "i32", kTensorCls}, error);
233 }
234
235 } // namespace brotensor::api
236