betterwithage commited on
Commit
7e533ce
·
verified ·
1 Parent(s): 7ccac9b

Add Kernel Hub build/torch-universal + torch-cpu for get_kernel (yarqa-attn, version 1, GitHub 098d19b)

Browse files
build/torch-cpu/metadata.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "yarqa-attn",
3
+ "version": 1,
4
+ "summary": "SZL original compartment/plug-flow attention with SHA3 receipts (CPU)",
5
+ "license": "Apache-2.0",
6
+ "universal": true,
7
+ "python-depends": [],
8
+ "id": "_yarqa_attn_cpu_010",
9
+ "backend": {
10
+ "type": "cpu"
11
+ }
12
+ }
build/torch-cpu/yarqa_attn/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 SZL Holdings
3
+ """yarqa-attn public API. Compartment / plug-flow attention. Not a Flash/Flex/paged stack."""
4
+
5
+ from ._chain import ReceiptChain
6
+ from .attn import canal_bounds, compartment_mask, selfcheck, yarqa_attn
7
+
8
+ __all__ = [
9
+ "ReceiptChain",
10
+ "canal_bounds",
11
+ "compartment_mask",
12
+ "selfcheck",
13
+ "yarqa_attn",
14
+ ]
15
+ __version__ = "0.1.0"
build/torch-cpu/yarqa_attn/_chain.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 SZL Holdings
3
+ """SHA3-256 receipt chain for partition boundaries and attention output."""
4
+ from __future__ import annotations
5
+
6
+ import hashlib
7
+ import json
8
+ from typing import Any, List, Optional, Tuple
9
+
10
+ GENESIS = "0" * 64
11
+
12
+
13
+ def _canon(obj: Any) -> bytes:
14
+ return json.dumps(obj, sort_keys=True, separators=(",", ":")).encode("utf-8")
15
+
16
+
17
+ def sha3_hex(body: bytes) -> str:
18
+ return hashlib.sha3_256(body).hexdigest()
19
+
20
+
21
+ class ReceiptChain:
22
+ """Linked SHA3-256 receipts. Genesis prev is 64 zero hex digits."""
23
+
24
+ def __init__(self) -> None:
25
+ self._rows: List[dict] = []
26
+
27
+ def emit(self, payload: dict) -> str:
28
+ prev = self._rows[-1]["digest"] if self._rows else GENESIS
29
+ body = dict(payload)
30
+ body["seq"] = len(self._rows)
31
+ body["prev"] = prev
32
+ digest = sha3_hex(_canon(body))
33
+ row = {**body, "digest": digest}
34
+ self._rows.append(row)
35
+ return digest
36
+
37
+ def verify(self) -> Tuple[bool, int, int]:
38
+ prev = GENESIS
39
+ for i, row in enumerate(self._rows):
40
+ body = {k: v for k, v in row.items() if k != "digest"}
41
+ if row.get("prev") != prev or sha3_hex(_canon(body)) != row.get("digest"):
42
+ return False, i, i
43
+ prev = row["digest"]
44
+ return True, len(self._rows), -1
45
+
46
+ def head(self) -> Optional[str]:
47
+ return self._rows[-1]["digest"] if self._rows else None
48
+
49
+ def __len__(self) -> int:
50
+ return len(self._rows)
build/torch-cpu/yarqa_attn/attn.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 SZL Holdings
3
+ """Compartment / plug-flow attention. Original SZL cut.
4
+
5
+ Named attn.py (not _ops.py): kernel-builder generates
6
+ torch-ext/<python_name>/_ops.py with add_op_namespace_prefix.
7
+
8
+ CPU only. No Dao hopper, Sage csrc, vLLM paged .cu, cuDNN FMHA,
9
+ TRT cubins, CuTeDSL, or flex_attention.py.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import ctypes
14
+ from typing import List, Optional
15
+
16
+ import torch
17
+ import torch.nn.functional as F
18
+
19
+ from ._chain import ReceiptChain, sha3_hex
20
+
21
+ PATH = "torch_compartment"
22
+ LAMBDA = "Conjecture 1"
23
+ _ATOL = 1.0e-5
24
+ _RTOL = 1.0e-5
25
+
26
+
27
+ def canal_bounds(seq_len: int, n_canals: int) -> List[int]:
28
+ """Exclusive endpoints of contiguous canals. Remainder goes to earlier canals."""
29
+ if not isinstance(n_canals, int) or isinstance(n_canals, bool):
30
+ raise TypeError("n_canals must be an int")
31
+ if seq_len < 1:
32
+ raise ValueError("seq_len must be >= 1")
33
+ if n_canals < 1:
34
+ raise ValueError("n_canals must be >= 1")
35
+ if n_canals > seq_len:
36
+ raise ValueError("n_canals cannot exceed sequence length")
37
+ base, rem = divmod(seq_len, n_canals)
38
+ bounds = [0]
39
+ for i in range(n_canals):
40
+ width = base + (1 if i < rem else 0)
41
+ bounds.append(bounds[-1] + width)
42
+ return bounds
43
+
44
+
45
+ def compartment_mask(seq_len: int, n_canals: int, *, device=None) -> torch.Tensor:
46
+ """Boolean keep-mask: True where query and key sit in the same canal."""
47
+ bounds = canal_bounds(seq_len, n_canals)
48
+ mask = torch.zeros(seq_len, seq_len, dtype=torch.bool, device=device)
49
+ for s, e in zip(bounds, bounds[1:]):
50
+ mask[s:e, s:e] = True
51
+ return mask
52
+
53
+
54
+ def _require_cpu(*tensors: torch.Tensor) -> None:
55
+ for t in tensors:
56
+ if t.device.type != "cpu":
57
+ raise RuntimeError(
58
+ "YARQA-ATTN v0 is CPU-only. GPU cubins are not claimed. "
59
+ "This is not a Flash/Flex/paged stack."
60
+ )
61
+
62
+
63
+ def _validate_qkv(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> None:
64
+ if q.ndim != 4 or k.ndim != 4 or v.ndim != 4:
65
+ raise ValueError("q, k, v must be rank-4 (batch, heads, seq, dim)")
66
+ if q.shape != k.shape or q.shape != v.shape:
67
+ raise ValueError("q, k, v must share shape (batch, heads, seq, dim) in v0")
68
+ if q.dtype != k.dtype or q.dtype != v.dtype:
69
+ raise ValueError("q, k, v dtype must match")
70
+
71
+
72
+ def _within_canal(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor:
73
+ try:
74
+ return F.scaled_dot_product_attention(
75
+ q, k, v, dropout_p=0.0, is_causal=False
76
+ )
77
+ except Exception:
78
+ scale = q.shape[-1] ** -0.5
79
+ scores = torch.matmul(q, k.transpose(-2, -1)) * scale
80
+ probs = torch.softmax(scores, dim=-1)
81
+ return torch.matmul(probs, v)
82
+
83
+
84
+ def _block_diag_reference(
85
+ q: torch.Tensor, k: torch.Tensor, v: torch.Tensor, n_canals: int
86
+ ) -> torch.Tensor:
87
+ """Naive full-attn-within-compartment: one SDPA with a block-diagonal keep-mask."""
88
+ seq = q.shape[2]
89
+ mask = compartment_mask(seq, n_canals, device=q.device)
90
+ return F.scaled_dot_product_attention(
91
+ q, k, v, attn_mask=mask, dropout_p=0.0, is_causal=False
92
+ )
93
+
94
+
95
+ def _output_digest(y: torch.Tensor) -> str:
96
+ """SHA3-256 of contiguous float32 IEEE bytes. Numpy is not required.
97
+
98
+ GitHub CPU torch wheels often ship without numpy; a numpy conversion is a defect here.
99
+ """
100
+ x = y.detach().to(dtype=torch.float32, device="cpu").contiguous()
101
+ nbytes = int(x.numel()) * int(x.element_size())
102
+ if nbytes == 0:
103
+ return sha3_hex(b"")
104
+ buf = (ctypes.c_char * nbytes).from_address(x.data_ptr())
105
+ return sha3_hex(bytes(buf))
106
+
107
+
108
+ def yarqa_attn(
109
+ q: torch.Tensor,
110
+ k: torch.Tensor,
111
+ v: torch.Tensor,
112
+ n_canals: int,
113
+ *,
114
+ chain: Optional[ReceiptChain] = None,
115
+ ) -> torch.Tensor:
116
+ """Attend inside each contiguous canal; concatenate along seq.
117
+
118
+ Not Flash tiled fusion, not Flex score_mod, not paged KV gather.
119
+ """
120
+ _require_cpu(q, k, v)
121
+ _validate_qkv(q, k, v)
122
+ seq = int(q.shape[2])
123
+ bounds = canal_bounds(seq, n_canals)
124
+ pieces = []
125
+ for start, end in zip(bounds, bounds[1:]):
126
+ pieces.append(
127
+ _within_canal(
128
+ q[:, :, start:end, :],
129
+ k[:, :, start:end, :],
130
+ v[:, :, start:end, :],
131
+ )
132
+ )
133
+ y = torch.cat(pieces, dim=2)
134
+ if chain is not None:
135
+ chain.emit(
136
+ {
137
+ "op": "yarqa_partition",
138
+ "path": PATH,
139
+ "n_canals": n_canals,
140
+ "bounds": list(bounds),
141
+ "q_shape": list(q.shape),
142
+ "dtype": str(q.dtype).replace("torch.", ""),
143
+ "lambda": LAMBDA,
144
+ }
145
+ )
146
+ chain.emit(
147
+ {
148
+ "op": "yarqa_output",
149
+ "path": PATH,
150
+ "n_canals": n_canals,
151
+ "output_digest": _output_digest(y),
152
+ "out_shape": list(y.shape),
153
+ "lambda": LAMBDA,
154
+ }
155
+ )
156
+ return y
157
+
158
+
159
+ def _tamper_breaks(chain: ReceiptChain) -> bool:
160
+ if not chain._rows:
161
+ return False
162
+ saved = chain._rows[0].get("bounds")
163
+ chain._rows[0]["bounds"] = [0, 0]
164
+ ok, _, first = chain.verify()
165
+ chain._rows[0]["bounds"] = saved
166
+ return (not ok) and first == 0
167
+
168
+
169
+ def _actually_splits(q, k, v, n_canals: int, y: torch.Tensor) -> bool:
170
+ if n_canals <= 1:
171
+ return False
172
+ y_one = yarqa_attn(q, k, v, 1)
173
+ if torch.allclose(y, y_one, atol=_ATOL, rtol=_RTOL):
174
+ return False
175
+ bounds = canal_bounds(int(q.shape[2]), n_canals)
176
+ widths = [e - s for s, e in zip(bounds, bounds[1:])]
177
+ return len(widths) == n_canals and min(widths) >= 1
178
+
179
+
180
+ def selfcheck() -> dict:
181
+ torch.manual_seed(20260828)
182
+ q = torch.randn(2, 4, 16, 32)
183
+ k = torch.randn(2, 4, 16, 32)
184
+ v = torch.randn(2, 4, 16, 32)
185
+ n_canals = 4
186
+ chain = ReceiptChain()
187
+ y = yarqa_attn(q, k, v, n_canals, chain=chain)
188
+ ref = _block_diag_reference(q, k, v, n_canals)
189
+ err = float((y - ref).abs().max().item())
190
+ ok_chain, depth, brk = chain.verify()
191
+ split = _actually_splits(q, k, v, n_canals, y)
192
+ tamper = _tamper_breaks(chain)
193
+ ok = bool(
194
+ err < _ATOL
195
+ and ok_chain
196
+ and depth == 2
197
+ and brk == -1
198
+ and split
199
+ and tamper
200
+ )
201
+ return {
202
+ "ok": ok,
203
+ "max_abs_vs_compartment_ref": err,
204
+ "chain_ok": ok_chain,
205
+ "chain_depth": depth,
206
+ "chain_break": brk,
207
+ "tamper_detected": tamper,
208
+ "split": split,
209
+ "n_canals": n_canals,
210
+ "path": PATH,
211
+ "lambda": LAMBDA,
212
+ "python": "present",
213
+ "note": (
214
+ "CPU correctness vs naive within-compartment attn; "
215
+ "no speedup claimed; GPU cubins not claimed; not import-LIVE"
216
+ ),
217
+ }
build/torch-universal/metadata.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "yarqa-attn",
3
+ "version": 1,
4
+ "summary": "SZL original compartment/plug-flow attention with SHA3 receipts (CPU)",
5
+ "license": "Apache-2.0",
6
+ "universal": true,
7
+ "python-depends": [],
8
+ "id": "_yarqa_attn_universal_010",
9
+ "backend": {
10
+ "type": "cpu"
11
+ }
12
+ }
build/torch-universal/yarqa_attn/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 SZL Holdings
3
+ """yarqa-attn public API. Compartment / plug-flow attention. Not a Flash/Flex/paged stack."""
4
+
5
+ from ._chain import ReceiptChain
6
+ from .attn import canal_bounds, compartment_mask, selfcheck, yarqa_attn
7
+
8
+ __all__ = [
9
+ "ReceiptChain",
10
+ "canal_bounds",
11
+ "compartment_mask",
12
+ "selfcheck",
13
+ "yarqa_attn",
14
+ ]
15
+ __version__ = "0.1.0"
build/torch-universal/yarqa_attn/_chain.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 SZL Holdings
3
+ """SHA3-256 receipt chain for partition boundaries and attention output."""
4
+ from __future__ import annotations
5
+
6
+ import hashlib
7
+ import json
8
+ from typing import Any, List, Optional, Tuple
9
+
10
+ GENESIS = "0" * 64
11
+
12
+
13
+ def _canon(obj: Any) -> bytes:
14
+ return json.dumps(obj, sort_keys=True, separators=(",", ":")).encode("utf-8")
15
+
16
+
17
+ def sha3_hex(body: bytes) -> str:
18
+ return hashlib.sha3_256(body).hexdigest()
19
+
20
+
21
+ class ReceiptChain:
22
+ """Linked SHA3-256 receipts. Genesis prev is 64 zero hex digits."""
23
+
24
+ def __init__(self) -> None:
25
+ self._rows: List[dict] = []
26
+
27
+ def emit(self, payload: dict) -> str:
28
+ prev = self._rows[-1]["digest"] if self._rows else GENESIS
29
+ body = dict(payload)
30
+ body["seq"] = len(self._rows)
31
+ body["prev"] = prev
32
+ digest = sha3_hex(_canon(body))
33
+ row = {**body, "digest": digest}
34
+ self._rows.append(row)
35
+ return digest
36
+
37
+ def verify(self) -> Tuple[bool, int, int]:
38
+ prev = GENESIS
39
+ for i, row in enumerate(self._rows):
40
+ body = {k: v for k, v in row.items() if k != "digest"}
41
+ if row.get("prev") != prev or sha3_hex(_canon(body)) != row.get("digest"):
42
+ return False, i, i
43
+ prev = row["digest"]
44
+ return True, len(self._rows), -1
45
+
46
+ def head(self) -> Optional[str]:
47
+ return self._rows[-1]["digest"] if self._rows else None
48
+
49
+ def __len__(self) -> int:
50
+ return len(self._rows)
build/torch-universal/yarqa_attn/attn.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2026 SZL Holdings
3
+ """Compartment / plug-flow attention. Original SZL cut.
4
+
5
+ Named attn.py (not _ops.py): kernel-builder generates
6
+ torch-ext/<python_name>/_ops.py with add_op_namespace_prefix.
7
+
8
+ CPU only. No Dao hopper, Sage csrc, vLLM paged .cu, cuDNN FMHA,
9
+ TRT cubins, CuTeDSL, or flex_attention.py.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import ctypes
14
+ from typing import List, Optional
15
+
16
+ import torch
17
+ import torch.nn.functional as F
18
+
19
+ from ._chain import ReceiptChain, sha3_hex
20
+
21
+ PATH = "torch_compartment"
22
+ LAMBDA = "Conjecture 1"
23
+ _ATOL = 1.0e-5
24
+ _RTOL = 1.0e-5
25
+
26
+
27
+ def canal_bounds(seq_len: int, n_canals: int) -> List[int]:
28
+ """Exclusive endpoints of contiguous canals. Remainder goes to earlier canals."""
29
+ if not isinstance(n_canals, int) or isinstance(n_canals, bool):
30
+ raise TypeError("n_canals must be an int")
31
+ if seq_len < 1:
32
+ raise ValueError("seq_len must be >= 1")
33
+ if n_canals < 1:
34
+ raise ValueError("n_canals must be >= 1")
35
+ if n_canals > seq_len:
36
+ raise ValueError("n_canals cannot exceed sequence length")
37
+ base, rem = divmod(seq_len, n_canals)
38
+ bounds = [0]
39
+ for i in range(n_canals):
40
+ width = base + (1 if i < rem else 0)
41
+ bounds.append(bounds[-1] + width)
42
+ return bounds
43
+
44
+
45
+ def compartment_mask(seq_len: int, n_canals: int, *, device=None) -> torch.Tensor:
46
+ """Boolean keep-mask: True where query and key sit in the same canal."""
47
+ bounds = canal_bounds(seq_len, n_canals)
48
+ mask = torch.zeros(seq_len, seq_len, dtype=torch.bool, device=device)
49
+ for s, e in zip(bounds, bounds[1:]):
50
+ mask[s:e, s:e] = True
51
+ return mask
52
+
53
+
54
+ def _require_cpu(*tensors: torch.Tensor) -> None:
55
+ for t in tensors:
56
+ if t.device.type != "cpu":
57
+ raise RuntimeError(
58
+ "YARQA-ATTN v0 is CPU-only. GPU cubins are not claimed. "
59
+ "This is not a Flash/Flex/paged stack."
60
+ )
61
+
62
+
63
+ def _validate_qkv(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> None:
64
+ if q.ndim != 4 or k.ndim != 4 or v.ndim != 4:
65
+ raise ValueError("q, k, v must be rank-4 (batch, heads, seq, dim)")
66
+ if q.shape != k.shape or q.shape != v.shape:
67
+ raise ValueError("q, k, v must share shape (batch, heads, seq, dim) in v0")
68
+ if q.dtype != k.dtype or q.dtype != v.dtype:
69
+ raise ValueError("q, k, v dtype must match")
70
+
71
+
72
+ def _within_canal(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor:
73
+ try:
74
+ return F.scaled_dot_product_attention(
75
+ q, k, v, dropout_p=0.0, is_causal=False
76
+ )
77
+ except Exception:
78
+ scale = q.shape[-1] ** -0.5
79
+ scores = torch.matmul(q, k.transpose(-2, -1)) * scale
80
+ probs = torch.softmax(scores, dim=-1)
81
+ return torch.matmul(probs, v)
82
+
83
+
84
+ def _block_diag_reference(
85
+ q: torch.Tensor, k: torch.Tensor, v: torch.Tensor, n_canals: int
86
+ ) -> torch.Tensor:
87
+ """Naive full-attn-within-compartment: one SDPA with a block-diagonal keep-mask."""
88
+ seq = q.shape[2]
89
+ mask = compartment_mask(seq, n_canals, device=q.device)
90
+ return F.scaled_dot_product_attention(
91
+ q, k, v, attn_mask=mask, dropout_p=0.0, is_causal=False
92
+ )
93
+
94
+
95
+ def _output_digest(y: torch.Tensor) -> str:
96
+ """SHA3-256 of contiguous float32 IEEE bytes. Numpy is not required.
97
+
98
+ GitHub CPU torch wheels often ship without numpy; a numpy conversion is a defect here.
99
+ """
100
+ x = y.detach().to(dtype=torch.float32, device="cpu").contiguous()
101
+ nbytes = int(x.numel()) * int(x.element_size())
102
+ if nbytes == 0:
103
+ return sha3_hex(b"")
104
+ buf = (ctypes.c_char * nbytes).from_address(x.data_ptr())
105
+ return sha3_hex(bytes(buf))
106
+
107
+
108
+ def yarqa_attn(
109
+ q: torch.Tensor,
110
+ k: torch.Tensor,
111
+ v: torch.Tensor,
112
+ n_canals: int,
113
+ *,
114
+ chain: Optional[ReceiptChain] = None,
115
+ ) -> torch.Tensor:
116
+ """Attend inside each contiguous canal; concatenate along seq.
117
+
118
+ Not Flash tiled fusion, not Flex score_mod, not paged KV gather.
119
+ """
120
+ _require_cpu(q, k, v)
121
+ _validate_qkv(q, k, v)
122
+ seq = int(q.shape[2])
123
+ bounds = canal_bounds(seq, n_canals)
124
+ pieces = []
125
+ for start, end in zip(bounds, bounds[1:]):
126
+ pieces.append(
127
+ _within_canal(
128
+ q[:, :, start:end, :],
129
+ k[:, :, start:end, :],
130
+ v[:, :, start:end, :],
131
+ )
132
+ )
133
+ y = torch.cat(pieces, dim=2)
134
+ if chain is not None:
135
+ chain.emit(
136
+ {
137
+ "op": "yarqa_partition",
138
+ "path": PATH,
139
+ "n_canals": n_canals,
140
+ "bounds": list(bounds),
141
+ "q_shape": list(q.shape),
142
+ "dtype": str(q.dtype).replace("torch.", ""),
143
+ "lambda": LAMBDA,
144
+ }
145
+ )
146
+ chain.emit(
147
+ {
148
+ "op": "yarqa_output",
149
+ "path": PATH,
150
+ "n_canals": n_canals,
151
+ "output_digest": _output_digest(y),
152
+ "out_shape": list(y.shape),
153
+ "lambda": LAMBDA,
154
+ }
155
+ )
156
+ return y
157
+
158
+
159
+ def _tamper_breaks(chain: ReceiptChain) -> bool:
160
+ if not chain._rows:
161
+ return False
162
+ saved = chain._rows[0].get("bounds")
163
+ chain._rows[0]["bounds"] = [0, 0]
164
+ ok, _, first = chain.verify()
165
+ chain._rows[0]["bounds"] = saved
166
+ return (not ok) and first == 0
167
+
168
+
169
+ def _actually_splits(q, k, v, n_canals: int, y: torch.Tensor) -> bool:
170
+ if n_canals <= 1:
171
+ return False
172
+ y_one = yarqa_attn(q, k, v, 1)
173
+ if torch.allclose(y, y_one, atol=_ATOL, rtol=_RTOL):
174
+ return False
175
+ bounds = canal_bounds(int(q.shape[2]), n_canals)
176
+ widths = [e - s for s, e in zip(bounds, bounds[1:])]
177
+ return len(widths) == n_canals and min(widths) >= 1
178
+
179
+
180
+ def selfcheck() -> dict:
181
+ torch.manual_seed(20260828)
182
+ q = torch.randn(2, 4, 16, 32)
183
+ k = torch.randn(2, 4, 16, 32)
184
+ v = torch.randn(2, 4, 16, 32)
185
+ n_canals = 4
186
+ chain = ReceiptChain()
187
+ y = yarqa_attn(q, k, v, n_canals, chain=chain)
188
+ ref = _block_diag_reference(q, k, v, n_canals)
189
+ err = float((y - ref).abs().max().item())
190
+ ok_chain, depth, brk = chain.verify()
191
+ split = _actually_splits(q, k, v, n_canals, y)
192
+ tamper = _tamper_breaks(chain)
193
+ ok = bool(
194
+ err < _ATOL
195
+ and ok_chain
196
+ and depth == 2
197
+ and brk == -1
198
+ and split
199
+ and tamper
200
+ )
201
+ return {
202
+ "ok": ok,
203
+ "max_abs_vs_compartment_ref": err,
204
+ "chain_ok": ok_chain,
205
+ "chain_depth": depth,
206
+ "chain_break": brk,
207
+ "tamper_detected": tamper,
208
+ "split": split,
209
+ "n_canals": n_canals,
210
+ "path": PATH,
211
+ "lambda": LAMBDA,
212
+ "python": "present",
213
+ "note": (
214
+ "CPU correctness vs naive within-compartment attn; "
215
+ "no speedup claimed; GPU cubins not claimed; not import-LIVE"
216
+ ),
217
+ }