rns-engine 0.7.0__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rns_engine-0.9.0/CAPACITY_PLANNING.md +178 -0
- rns_engine-0.9.0/CUDA_PARALLEL_LANES.md +100 -0
- rns_engine-0.9.0/MANIFEST.in +8 -0
- {rns_engine-0.7.0/src/rns_engine.egg-info → rns_engine-0.9.0}/PKG-INFO +153 -17
- rns_engine-0.9.0/PRE_CUDA_READINESS.md +72 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/README.md +152 -16
- rns_engine-0.9.0/benchmarks/weighted_int32_baseline.py +423 -0
- rns_engine-0.9.0/colab/T4_EXACT_GEMM_BRINGUP.ipynb +152 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/pyproject.toml +4 -1
- rns_engine-0.9.0/src/rns_engine/__init__.py +179 -0
- rns_engine-0.9.0/src/rns_engine/capacity.py +390 -0
- rns_engine-0.9.0/src/rns_engine/coefficients.py +179 -0
- rns_engine-0.9.0/src/rns_engine/cuda_contract.py +281 -0
- rns_engine-0.9.0/src/rns_engine/exact_gemm.py +340 -0
- rns_engine-0.9.0/src/rns_engine/lane_plan.py +66 -0
- rns_engine-0.9.0/src/rns_engine/pre_cuda.py +221 -0
- rns_engine-0.9.0/src/rns_engine/rail_planning.py +318 -0
- rns_engine-0.9.0/src/rns_engine/wide.py +339 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0/src/rns_engine.egg-info}/PKG-INFO +153 -17
- rns_engine-0.9.0/src/rns_engine.egg-info/SOURCES.txt +45 -0
- rns_engine-0.9.0/src/rns_engine.egg-info/entry_points.txt +2 -0
- rns_engine-0.9.0/tests/test_capacity.py +161 -0
- rns_engine-0.9.0/tests/test_coefficients.py +110 -0
- rns_engine-0.9.0/tests/test_cuda_contract.py +56 -0
- rns_engine-0.9.0/tests/test_exact_gemm.py +83 -0
- rns_engine-0.9.0/tests/test_pre_cuda.py +45 -0
- rns_engine-0.9.0/tests/test_pre_cuda_assets.py +30 -0
- rns_engine-0.9.0/tests/test_rail_planning.py +170 -0
- rns_engine-0.9.0/tests/test_wide.py +109 -0
- rns_engine-0.7.0/src/rns_engine/__init__.py +0 -98
- rns_engine-0.7.0/src/rns_engine.egg-info/SOURCES.txt +0 -22
- {rns_engine-0.7.0 → rns_engine-0.9.0}/LICENSE +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/setup.cfg +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/setup.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/_core.cpp +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/_weighted.cpp +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/engine.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/signed.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/weighted.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/dependency_links.txt +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/not-zip-safe +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/requires.txt +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/top_level.txt +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_packaging.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_rns.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_session.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_signed.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_weighted.py +0 -0
- {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_weighted_benchmark.py +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Exact GEMM Capacity Planning
|
|
2
|
+
|
|
3
|
+
`rns_engine` keeps two different safety questions separate:
|
|
4
|
+
|
|
5
|
+
1. **Local accumulator safety:** does each raw grouped digit-plane coefficient fit the native signed accumulator, such as INT32?
|
|
6
|
+
2. **Global reconstruction safety:** after positional weights are applied, does the final wide result fit uniquely inside the RNS modulus product?
|
|
7
|
+
|
|
8
|
+
A workload can pass the first test and fail the second. Version 0.8 provides exact integer-only receipts for both.
|
|
9
|
+
|
|
10
|
+
## Local grouped-coefficient safety
|
|
11
|
+
|
|
12
|
+
For positional digit planes,
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
A = sum(A_i * radix**i)
|
|
16
|
+
B = sum(B_j * radix**j)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
raw coefficient `k` is:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
R_k = sum_{i+j=k} GEMM(A_i, B_j)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If the GEMM inner dimension is `K`, and plane entries obey magnitude bounds `L_i` and `R_j`, then:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
abs(R_k) <= sum_{i+j=k} K * L_i * R_j
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Use:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import rns_engine as rns
|
|
35
|
+
|
|
36
|
+
local = rns.plan_grouped_coefficient_capacity(
|
|
37
|
+
inner_dimension=5120,
|
|
38
|
+
left_digit_abs_bounds=[127] * 8,
|
|
39
|
+
right_digit_abs_bounds=[127] * 8,
|
|
40
|
+
accumulator_bits=32,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
print(local.coefficient_pair_counts)
|
|
44
|
+
print(local.coefficient_abs_bounds)
|
|
45
|
+
print(local.max_abs_bound)
|
|
46
|
+
print(local.minimum_signed_accumulator_bits)
|
|
47
|
+
local.require_safe()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For eight full-magnitude INT8 planes at `K=5120`:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
largest grouped coefficient = 660,643,840
|
|
54
|
+
minimum signed width = 31 bits
|
|
55
|
+
INT32 status = safe
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This proves the grouped Tensor Core or native INT32 outputs can remain exact locally.
|
|
59
|
+
|
|
60
|
+
## Global RNS reconstruction safety
|
|
61
|
+
|
|
62
|
+
The reconstructed operands obey:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
left_value_bound = sum(L_i * radix**i)
|
|
66
|
+
right_value_bound = sum(R_j * radix**j)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
One final GEMM output obeys:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
abs(C) <= K * left_value_bound * right_value_bound + addend_bound
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
A symmetric signed interval `[-bound, bound]` requires modulus:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
minimum_modulus = 2 * bound + 1
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Use:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
wide = rns.plan_digit_plane_gemm_capacity(
|
|
85
|
+
inner_dimension=5120,
|
|
86
|
+
radix=128,
|
|
87
|
+
left_digit_abs_bounds=[127] * 8,
|
|
88
|
+
right_digit_abs_bounds=[127] * 8,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
print(wide.max_abs_bound)
|
|
92
|
+
print(wide.capacity.minimum_required_modulus)
|
|
93
|
+
print(wide.capacity.required_modulus_bits)
|
|
94
|
+
print(wide.capacity.additional_bits_required)
|
|
95
|
+
print(wide.current_unique)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
For eight full radix-128 planes per operand:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
operand magnitude bound = 128**8 - 1
|
|
102
|
+
required signed modulus = 126 bits
|
|
103
|
+
current additional deficit = 71 product bits
|
|
104
|
+
current four-rail result = modular-only in the worst case
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
So the same workload is locally INT32-safe but not globally unique in the current four-rail RNS range.
|
|
108
|
+
|
|
109
|
+
## Proposed additional rails
|
|
110
|
+
|
|
111
|
+
Candidate CRT moduli can be tested explicitly:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
base = rns.plan_digit_plane_gemm_capacity(
|
|
115
|
+
5120,
|
|
116
|
+
128,
|
|
117
|
+
[127] * 8,
|
|
118
|
+
[127] * 8,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
candidate = base.capacity.minimum_single_coprime_modulus
|
|
122
|
+
|
|
123
|
+
expanded = rns.plan_digit_plane_gemm_capacity(
|
|
124
|
+
5120,
|
|
125
|
+
128,
|
|
126
|
+
[127] * 8,
|
|
127
|
+
[127] * 8,
|
|
128
|
+
additional_moduli=[candidate],
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
expanded.require_unique()
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Every proposed modulus must be greater than one and coprime with the existing modulus product and every earlier candidate.
|
|
135
|
+
|
|
136
|
+
`minimum_single_coprime_modulus` answers only the mathematical capacity question. It does **not** claim that the returned modulus is fast to reduce, appropriate for a GPU, or the best hardware rail. Reduction cost, storage width, vectorization, and reconstruction cost must be benchmarked separately.
|
|
137
|
+
|
|
138
|
+
## General weighted-sum planning
|
|
139
|
+
|
|
140
|
+
For arbitrary exact weighted partial bounds:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
plan = rns.plan_weighted_sum_capacity(
|
|
144
|
+
weights=[1, 128, 128**2],
|
|
145
|
+
term_abs_bounds=[100, 200, 300],
|
|
146
|
+
addend_abs_bound=7,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
print(plan.max_abs_bound)
|
|
150
|
+
print(plan.current_unique)
|
|
151
|
+
print(plan.modulus_shortfall)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
For a known result bound directly:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
plan = rns.plan_signed_capacity(max_abs_bound=10**30)
|
|
158
|
+
print(plan.minimum_required_modulus)
|
|
159
|
+
print(plan.additional_bits_required)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## What these receipts prove
|
|
163
|
+
|
|
164
|
+
They prove conservative worst-case capacity from the supplied exact integer bounds. They can certify:
|
|
165
|
+
|
|
166
|
+
- grouped coefficient safety for a chosen signed accumulator width;
|
|
167
|
+
- the exact final-result magnitude bound;
|
|
168
|
+
- whether the current RNS product gives unique signed reconstruction;
|
|
169
|
+
- how much modulus product is missing;
|
|
170
|
+
- whether explicit proposed CRT rails close that deficit lawfully.
|
|
171
|
+
|
|
172
|
+
They do not prove:
|
|
173
|
+
|
|
174
|
+
- that the supplied input bounds describe a real dataset tightly;
|
|
175
|
+
- that a proposed modulus is computationally efficient;
|
|
176
|
+
- GPU, CUDA, or Tensor Core speed;
|
|
177
|
+
- that worst-case capacity is necessary for a narrower application distribution;
|
|
178
|
+
- that adding rails is cheaper than chunking, rescaling, or changing the digit representation.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Parallel Learning Lanes for CUDA Rail and Kernel Search
|
|
2
|
+
|
|
3
|
+
The CUDA search uses a shared-prior / bounded-divergence / teaching-boundary architecture.
|
|
4
|
+
|
|
5
|
+
## Shared prior
|
|
6
|
+
|
|
7
|
+
Every lane receives the same immutable evidence body:
|
|
8
|
+
|
|
9
|
+
- identical input matrices and exact shared scales;
|
|
10
|
+
- identical radix-128 digit planes;
|
|
11
|
+
- identical required grouped INT32 outputs;
|
|
12
|
+
- identical seven-rail residue targets;
|
|
13
|
+
- identical direct Python-big-integer answer;
|
|
14
|
+
- identical capacity and no-wrap receipts;
|
|
15
|
+
- identical warmup count and measurement protocol.
|
|
16
|
+
|
|
17
|
+
No lane may redefine correctness.
|
|
18
|
+
|
|
19
|
+
## Independent lanes
|
|
20
|
+
|
|
21
|
+
Initial lanes should differ in one controlled design choice:
|
|
22
|
+
|
|
23
|
+
- `lane-smallest-product`: extra Mersenne exponents `(11, 29, 31)`;
|
|
24
|
+
- `lane-balanced`: extra Mersenne exponents `(23, 24, 25)`;
|
|
25
|
+
- reduction-kernel variants inside each lawful profile;
|
|
26
|
+
- reconstruction ordering variants;
|
|
27
|
+
- grouped-coefficient launch/packing variants.
|
|
28
|
+
|
|
29
|
+
Inside one benchmark epoch, lanes may tune independently. Their outputs remain comparable because the shared fixture and proof laws are frozen.
|
|
30
|
+
|
|
31
|
+
## Hard-law firewall
|
|
32
|
+
|
|
33
|
+
Before performance evidence is accepted, every lane must pass:
|
|
34
|
+
|
|
35
|
+
1. exact grouped-partial equality;
|
|
36
|
+
2. exact residue equality on every rail;
|
|
37
|
+
3. exact centered reconstruction;
|
|
38
|
+
4. pairwise coprimality;
|
|
39
|
+
5. local INT32 safety;
|
|
40
|
+
6. global signed uniqueness;
|
|
41
|
+
7. deterministic fixture identity.
|
|
42
|
+
|
|
43
|
+
A fast failing lane has no score. GCD is not learned or approximated.
|
|
44
|
+
|
|
45
|
+
## Teaching boundary
|
|
46
|
+
|
|
47
|
+
At a fixed trial boundary:
|
|
48
|
+
|
|
49
|
+
- pool lawful integer evidence: failure counts, bytes moved, launch counts, register-spill counts, and completed output counts;
|
|
50
|
+
- preserve timing samples with their provenance rather than averaging incompatible runs blindly;
|
|
51
|
+
- select one coherent kernel/configuration body as the next teacher;
|
|
52
|
+
- retain alternate lawful bodies in an archive to prevent premature monoculture.
|
|
53
|
+
|
|
54
|
+
The first deterministic selection tuple is:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
(correctness_failures,
|
|
58
|
+
validation_failures,
|
|
59
|
+
median_elapsed_ns,
|
|
60
|
+
bytes_moved,
|
|
61
|
+
launch_count,
|
|
62
|
+
lane_id)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Correctness and validation fields must both be zero before timing matters. `lane_id` is the fixed tie-break.
|
|
66
|
+
|
|
67
|
+
## Epoch rule
|
|
68
|
+
|
|
69
|
+
An epoch is a fixed number of completed repetitions on a fixed matrix shape, never wall-clock duration. This keeps work membership reproducible even though elapsed time is measured.
|
|
70
|
+
|
|
71
|
+
Suggested initial epoch:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
5 warmups + 21 measured repetitions per shape/profile
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The next shared prior contains the winning complete kernel body plus pooled benchmark evidence. It does not average coupled CUDA source, register layouts, or launch strategies into a synthetic kernel that no lane tested.
|
|
78
|
+
|
|
79
|
+
## What can merge and what must be selected
|
|
80
|
+
|
|
81
|
+
Merge lawfully:
|
|
82
|
+
|
|
83
|
+
- exact pass/fail counts;
|
|
84
|
+
- operation counts;
|
|
85
|
+
- byte counts;
|
|
86
|
+
- launch counts;
|
|
87
|
+
- fixture hashes;
|
|
88
|
+
- hardware metadata;
|
|
89
|
+
- independent timing samples with provenance.
|
|
90
|
+
|
|
91
|
+
Select coherently:
|
|
92
|
+
|
|
93
|
+
- CUDA kernel source;
|
|
94
|
+
- tile shape;
|
|
95
|
+
- register layout;
|
|
96
|
+
- reduction strategy;
|
|
97
|
+
- reconstruction order;
|
|
98
|
+
- rail profile.
|
|
99
|
+
|
|
100
|
+
The rule is: merge evidence; select a complete executable body.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rns_engine
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Exact RNS engine with session/cache API.
|
|
5
5
|
Author: Evan Wesley
|
|
6
6
|
License-Expression: AGPL-3.0-only
|
|
@@ -194,7 +194,7 @@ out = session.decode_signed(session.add(a, b))
|
|
|
194
194
|
|
|
195
195
|
## Weighted INT32 partial accumulation
|
|
196
196
|
|
|
197
|
-
Version 0.7
|
|
197
|
+
Version 0.7 introduced the fused direct bridge for digit-plane, chunked-GEMM, and Tensor Core pipelines.
|
|
198
198
|
|
|
199
199
|
Give the engine signed INT32 partial outputs with shape:
|
|
200
200
|
|
|
@@ -246,7 +246,7 @@ Important details:
|
|
|
246
246
|
- `decode_modular()` always returns the canonical residue in `[0, M)`.
|
|
247
247
|
- Empty term sets produce an exact zero result.
|
|
248
248
|
|
|
249
|
-
The
|
|
249
|
+
The implementation uses one fused native `_weighted` call to read signed INT32 partials, collect exact per-term magnitude bounds, apply positional weights modulo `M`, and accumulate all four rails. The pre-fusion staged encode → scale → add body remains available internally as an exact reference for A/B tests. Local AVX2 diagnostics measured roughly 2.1×–2.9× speedup at one million outputs and larger gains on tiny many-term cases; those figures are hardware-specific CPU evidence, not CUDA, Tensor Core, or universal performance claims.
|
|
250
250
|
|
|
251
251
|
A precomputed receipt can also be created without materializing partial arrays:
|
|
252
252
|
|
|
@@ -260,6 +260,103 @@ certificate.require_unique()
|
|
|
260
260
|
|
|
261
261
|
---
|
|
262
262
|
|
|
263
|
+
## Exact GEMM capacity planning
|
|
264
|
+
|
|
265
|
+
Version 0.8 separates two different safety questions that must not be conflated:
|
|
266
|
+
|
|
267
|
+
1. Does each grouped raw digit-plane coefficient fit the native signed accumulator?
|
|
268
|
+
2. Does the final radix-weighted result fit uniquely inside the global RNS modulus product?
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
import rns_engine as rns
|
|
272
|
+
|
|
273
|
+
local = rns.plan_grouped_coefficient_capacity(
|
|
274
|
+
inner_dimension=5120,
|
|
275
|
+
left_digit_abs_bounds=[127] * 8,
|
|
276
|
+
right_digit_abs_bounds=[127] * 8,
|
|
277
|
+
accumulator_bits=32,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
global_plan = rns.plan_digit_plane_gemm_capacity(
|
|
281
|
+
inner_dimension=5120,
|
|
282
|
+
radix=128,
|
|
283
|
+
left_digit_abs_bounds=[127] * 8,
|
|
284
|
+
right_digit_abs_bounds=[127] * 8,
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
assert local.max_abs_bound == 660_643_840
|
|
288
|
+
assert local.safe
|
|
289
|
+
assert local.minimum_signed_accumulator_bits == 31
|
|
290
|
+
|
|
291
|
+
assert global_plan.capacity.required_modulus_bits == 126
|
|
292
|
+
assert global_plan.capacity.additional_bits_required == 71
|
|
293
|
+
assert not global_plan.current_unique
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
That workload is locally safe in INT32 but globally modular-only in the current four-rail range. The planner can also validate explicit proposed CRT moduli and rejects candidates that are not pairwise coprime with the existing product.
|
|
297
|
+
|
|
298
|
+
See [`CAPACITY_PLANNING.md`](CAPACITY_PLANNING.md) for the exact laws, examples, and limits of what the receipts prove.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Pre-CUDA exact shared-scale GEMM
|
|
303
|
+
|
|
304
|
+
Version 0.9 adds the complete CPU-side oracle and integration contract for the future CUDA/T4 body. Before using GPU credits, run:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
rns-pre-cuda --report readiness.json --fixture t4_fixture.json
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
A green receipt proves:
|
|
311
|
+
|
|
312
|
+
- both seven-rail profiles are pairwise coprime and close the 126-bit target;
|
|
313
|
+
- radix-128 signed digit planes round-trip exactly;
|
|
314
|
+
- grouped plane GEMMs fit INT32 for the frozen witness;
|
|
315
|
+
- weighted seven-rail reconstruction equals direct Python-big-integer GEMM;
|
|
316
|
+
- shared rational scales multiply exactly with no denominator GEMM;
|
|
317
|
+
- the portable CUDA fixture and full backend verifier agree.
|
|
318
|
+
|
|
319
|
+
The future CUDA backend must implement both methods in the contract:
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
class ExactPipelineBackend:
|
|
323
|
+
def grouped_partials(self, left_planes, right_planes):
|
|
324
|
+
... # INT8 Tensor Core / cuBLASLt grouped coefficients
|
|
325
|
+
|
|
326
|
+
def weighted_rails(self, grouped_partials, weights, moduli):
|
|
327
|
+
... # GPU seven-rail modular weighting and accumulation
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
The verifier refuses a backend that produces correct GEMM partials but silently falls back to CPU RNS. See [`PRE_CUDA_READINESS.md`](PRE_CUDA_READINESS.md), [`CUDA_PARALLEL_LANES.md`](CUDA_PARALLEL_LANES.md), and [`colab/T4_EXACT_GEMM_BRINGUP.ipynb`](colab/T4_EXACT_GEMM_BRINGUP.ipynb).
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
import numpy as np
|
|
334
|
+
import rns_engine as rns
|
|
335
|
+
|
|
336
|
+
left = rns.SharedScaleMatrix(
|
|
337
|
+
np.array([[2**40 + 3, -17], [29, 2**35 - 5]], dtype=object),
|
|
338
|
+
scale=6,
|
|
339
|
+
)
|
|
340
|
+
right = rns.SharedScaleMatrix(
|
|
341
|
+
np.array([[31, -(2**30) + 9], [2**33 + 1, 43]], dtype=object),
|
|
342
|
+
scale=35,
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
receipt = rns.exact_shared_scale_gemm(
|
|
346
|
+
left,
|
|
347
|
+
right,
|
|
348
|
+
config=rns.WideRNSConfig.balanced_seven_rail(),
|
|
349
|
+
left_plane_count=8,
|
|
350
|
+
right_plane_count=8,
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
assert receipt.exact_match
|
|
354
|
+
assert receipt.output_scale == 210
|
|
355
|
+
result = receipt.as_matrix()
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
263
360
|
## Core API
|
|
264
361
|
|
|
265
362
|
### Rail operations
|
|
@@ -285,6 +382,41 @@ certificate.require_unique()
|
|
|
285
382
|
- `WeightedInt32Result.decode_signed(require_unique=True)`
|
|
286
383
|
- `WeightedInt32Result.decode_modular()`
|
|
287
384
|
|
|
385
|
+
### Capacity planning
|
|
386
|
+
|
|
387
|
+
- `plan_signed_capacity(max_abs_bound, additional_moduli=())`
|
|
388
|
+
- `plan_weighted_sum_capacity(weights, term_abs_bounds, addend_abs_bound=0, additional_moduli=())`
|
|
389
|
+
- `plan_digit_plane_gemm_capacity(inner_dimension, radix, left_digit_abs_bounds, right_digit_abs_bounds, ...)`
|
|
390
|
+
- `plan_grouped_coefficient_capacity(inner_dimension, left_digit_abs_bounds, right_digit_abs_bounds, accumulator_bits=32)`
|
|
391
|
+
- `SignedCapacityPlan`
|
|
392
|
+
- `DigitPlaneGemmCapacityPlan`
|
|
393
|
+
- `GroupedCoefficientCapacityPlan`
|
|
394
|
+
|
|
395
|
+
### Wide reference and pre-CUDA APIs
|
|
396
|
+
|
|
397
|
+
- `WideRNSConfig.current()`
|
|
398
|
+
- `WideRNSConfig.smallest_product_seven_rail()`
|
|
399
|
+
- `WideRNSConfig.balanced_seven_rail()`
|
|
400
|
+
- `accumulate_weighted_int32_wide(...)`
|
|
401
|
+
- `SharedScaleMatrix`
|
|
402
|
+
- `exact_integer_matmul(...)`
|
|
403
|
+
- `decompose_signed_radix(...)` / `reconstruct_signed_radix(...)`
|
|
404
|
+
- `grouped_plane_gemm(...)` / `reconstruct_grouped_partials(...)`
|
|
405
|
+
- `exact_shared_scale_gemm(...)`
|
|
406
|
+
- `CudaGemmFixture`
|
|
407
|
+
- `CpuExactPipelineBackend`
|
|
408
|
+
- `build_cuda_gemm_fixture(...)`
|
|
409
|
+
- `verify_backend(...)`
|
|
410
|
+
- `run_pre_cuda_readiness()`
|
|
411
|
+
- `build_default_pre_cuda_fixture()`
|
|
412
|
+
|
|
413
|
+
### Parallel rail-lane planning
|
|
414
|
+
|
|
415
|
+
- `build_parallel_rail_prior(capacity)`
|
|
416
|
+
- `RailLearningLane`
|
|
417
|
+
- `ParallelRailPrior`
|
|
418
|
+
- `search_mersenne_rails_for_capacity(...)`
|
|
419
|
+
|
|
288
420
|
### Scalar-broadcast encoded operations
|
|
289
421
|
|
|
290
422
|
- `mul_u64(...)`
|
|
@@ -359,7 +491,7 @@ Workload: `affine_repeat_u64_io(x, 1_000_003, 7, iterations=1000)`
|
|
|
359
491
|
- OpenMP with one thread: **82.80 billion ops/sec**
|
|
360
492
|
- OpenMP with two threads: **94.86 billion ops/sec**
|
|
361
493
|
|
|
362
|
-
These measurements cover the existing affine kernels, not
|
|
494
|
+
These measurements cover the existing affine kernels, not weighted INT32 reconstruction or the pure-Python capacity planners.
|
|
363
495
|
|
|
364
496
|
---
|
|
365
497
|
|
|
@@ -404,19 +536,23 @@ rns.HAS_AVX2
|
|
|
404
536
|
|
|
405
537
|
## Current release
|
|
406
538
|
|
|
407
|
-
### v0.
|
|
408
|
-
|
|
409
|
-
-
|
|
410
|
-
-
|
|
411
|
-
-
|
|
412
|
-
- exact
|
|
413
|
-
-
|
|
414
|
-
-
|
|
415
|
-
-
|
|
416
|
-
-
|
|
417
|
-
-
|
|
418
|
-
-
|
|
419
|
-
-
|
|
539
|
+
### v0.9.0
|
|
540
|
+
|
|
541
|
+
- configurable correctness-first CRT oracle for arbitrary pairwise-coprime rails
|
|
542
|
+
- two lawful seven-rail profiles closing the 126-bit eight-plane target
|
|
543
|
+
- exact signed radix-128 decomposition and reconstruction
|
|
544
|
+
- exact grouped digit-plane GEMM coefficients with strict INT32 overflow refusal
|
|
545
|
+
- exact shared-scale rational GEMM with integer numerator and scale receipts
|
|
546
|
+
- portable JSON CUDA fixture containing inputs, planes, partials, rails, and answer
|
|
547
|
+
- full backend contract requiring both grouped partials and GPU rail accumulation
|
|
548
|
+
- deterministic pre-CUDA readiness command and frozen witness
|
|
549
|
+
- parallel rail-lane shared-prior plan with hard correctness firewall
|
|
550
|
+
- Colab/T4 bring-up notebook with one isolated CUDA integration point
|
|
551
|
+
- exact Mersenne rail-set search and local/global capacity planners
|
|
552
|
+
- fused native four-rail weighted signed INT32 accumulation
|
|
553
|
+
- canonical centered signed encoding and no-wrap certificates
|
|
554
|
+
|
|
555
|
+
The seven-rail body in 0.9 is a CPU correctness oracle, not a native CUDA or production-speed wide RNS kernel.
|
|
420
556
|
|
|
421
557
|
---
|
|
422
558
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Pre-CUDA Readiness Contract
|
|
2
|
+
|
|
3
|
+
Do not spend GPU credits until this repository's complete CPU-side readiness gate passes:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
rns-pre-cuda
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The command emits one JSON receipt and exits nonzero if any required condition fails.
|
|
10
|
+
|
|
11
|
+
## What must already be proven
|
|
12
|
+
|
|
13
|
+
The gate verifies all of the following without CUDA:
|
|
14
|
+
|
|
15
|
+
1. The eight-plane radix-128 target at `K=5120` needs a 126-bit signed modulus.
|
|
16
|
+
2. The existing four rails are short by 71 product bits.
|
|
17
|
+
3. Under a 31-bit-per-extra-rail ceiling, three added rails are mathematically necessary.
|
|
18
|
+
4. Both retained seven-rail profiles are pairwise coprime and close the capacity deficit:
|
|
19
|
+
- smallest-product exponents `(11, 29, 31)`;
|
|
20
|
+
- balanced exponents `(23, 24, 25)`.
|
|
21
|
+
5. Both profiles round-trip centered signed values, including their exact signed boundaries.
|
|
22
|
+
6. Wide rail addition and multiplication agree with Python big integers.
|
|
23
|
+
7. Signed radix-128 digit planes reconstruct their source integers exactly.
|
|
24
|
+
8. Grouped plane GEMMs reconstruct the direct Python-big-integer GEMM exactly.
|
|
25
|
+
9. Every grouped coefficient fits signed INT32 for the tested fixture.
|
|
26
|
+
10. Shared-scale rational GEMM preserves the exact numerator and multiplies scale metadata exactly.
|
|
27
|
+
11. The portable CUDA fixture survives a JSON round trip.
|
|
28
|
+
12. A backend must reproduce both:
|
|
29
|
+
- grouped INT32 coefficient matrices;
|
|
30
|
+
- weighted seven-rail residues.
|
|
31
|
+
13. Final centered reconstruction must equal the direct big-integer witness.
|
|
32
|
+
|
|
33
|
+
## What remains for the T4
|
|
34
|
+
|
|
35
|
+
Once the gate is green, the only intentionally missing body is the CUDA implementation of the backend contract:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
class ExactPipelineBackend:
|
|
39
|
+
def grouped_partials(left_planes, right_planes):
|
|
40
|
+
... # INT8 Tensor Core / cuBLASLt body
|
|
41
|
+
|
|
42
|
+
def weighted_rails(grouped_partials, weights, moduli):
|
|
43
|
+
... # CUDA modular weighting and seven-rail accumulation
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The verifier, fixtures, scales, exact witnesses, range receipts, candidate rail profiles, and failure rules already exist.
|
|
47
|
+
|
|
48
|
+
## What a green gate does not prove
|
|
49
|
+
|
|
50
|
+
A green CPU gate does not prove:
|
|
51
|
+
|
|
52
|
+
- T4 Tensor Core execution;
|
|
53
|
+
- CUDA correctness;
|
|
54
|
+
- GPU reduction efficiency;
|
|
55
|
+
- FP16 parity or superiority;
|
|
56
|
+
- that either candidate rail profile is the fastest GPU profile;
|
|
57
|
+
- arbitrary per-element rational denominators.
|
|
58
|
+
|
|
59
|
+
Those claims require the T4 run.
|
|
60
|
+
|
|
61
|
+
## First T4 success condition
|
|
62
|
+
|
|
63
|
+
The first GPU milestone is not speed. It is exact equivalence:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
CUDA grouped partials == CPU grouped partials
|
|
67
|
+
CUDA seven rails == CPU seven rails
|
|
68
|
+
CUDA decoded numerator == direct Python integer GEMM
|
|
69
|
+
CUDA output scale == left scale * right scale
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Only after that witness passes should timing begin.
|