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.
Files changed (49) hide show
  1. rns_engine-0.9.0/CAPACITY_PLANNING.md +178 -0
  2. rns_engine-0.9.0/CUDA_PARALLEL_LANES.md +100 -0
  3. rns_engine-0.9.0/MANIFEST.in +8 -0
  4. {rns_engine-0.7.0/src/rns_engine.egg-info → rns_engine-0.9.0}/PKG-INFO +153 -17
  5. rns_engine-0.9.0/PRE_CUDA_READINESS.md +72 -0
  6. {rns_engine-0.7.0 → rns_engine-0.9.0}/README.md +152 -16
  7. rns_engine-0.9.0/benchmarks/weighted_int32_baseline.py +423 -0
  8. rns_engine-0.9.0/colab/T4_EXACT_GEMM_BRINGUP.ipynb +152 -0
  9. {rns_engine-0.7.0 → rns_engine-0.9.0}/pyproject.toml +4 -1
  10. rns_engine-0.9.0/src/rns_engine/__init__.py +179 -0
  11. rns_engine-0.9.0/src/rns_engine/capacity.py +390 -0
  12. rns_engine-0.9.0/src/rns_engine/coefficients.py +179 -0
  13. rns_engine-0.9.0/src/rns_engine/cuda_contract.py +281 -0
  14. rns_engine-0.9.0/src/rns_engine/exact_gemm.py +340 -0
  15. rns_engine-0.9.0/src/rns_engine/lane_plan.py +66 -0
  16. rns_engine-0.9.0/src/rns_engine/pre_cuda.py +221 -0
  17. rns_engine-0.9.0/src/rns_engine/rail_planning.py +318 -0
  18. rns_engine-0.9.0/src/rns_engine/wide.py +339 -0
  19. {rns_engine-0.7.0 → rns_engine-0.9.0/src/rns_engine.egg-info}/PKG-INFO +153 -17
  20. rns_engine-0.9.0/src/rns_engine.egg-info/SOURCES.txt +45 -0
  21. rns_engine-0.9.0/src/rns_engine.egg-info/entry_points.txt +2 -0
  22. rns_engine-0.9.0/tests/test_capacity.py +161 -0
  23. rns_engine-0.9.0/tests/test_coefficients.py +110 -0
  24. rns_engine-0.9.0/tests/test_cuda_contract.py +56 -0
  25. rns_engine-0.9.0/tests/test_exact_gemm.py +83 -0
  26. rns_engine-0.9.0/tests/test_pre_cuda.py +45 -0
  27. rns_engine-0.9.0/tests/test_pre_cuda_assets.py +30 -0
  28. rns_engine-0.9.0/tests/test_rail_planning.py +170 -0
  29. rns_engine-0.9.0/tests/test_wide.py +109 -0
  30. rns_engine-0.7.0/src/rns_engine/__init__.py +0 -98
  31. rns_engine-0.7.0/src/rns_engine.egg-info/SOURCES.txt +0 -22
  32. {rns_engine-0.7.0 → rns_engine-0.9.0}/LICENSE +0 -0
  33. {rns_engine-0.7.0 → rns_engine-0.9.0}/setup.cfg +0 -0
  34. {rns_engine-0.7.0 → rns_engine-0.9.0}/setup.py +0 -0
  35. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/_core.cpp +0 -0
  36. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/_weighted.cpp +0 -0
  37. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/engine.py +0 -0
  38. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/signed.py +0 -0
  39. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine/weighted.py +0 -0
  40. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/dependency_links.txt +0 -0
  41. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/not-zip-safe +0 -0
  42. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/requires.txt +0 -0
  43. {rns_engine-0.7.0 → rns_engine-0.9.0}/src/rns_engine.egg-info/top_level.txt +0 -0
  44. {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_packaging.py +0 -0
  45. {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_rns.py +0 -0
  46. {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_session.py +0 -0
  47. {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_signed.py +0 -0
  48. {rns_engine-0.7.0 → rns_engine-0.9.0}/tests/test_weighted.py +0 -0
  49. {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.
@@ -0,0 +1,8 @@
1
+ include LICENSE
2
+ include README.md
3
+ include CAPACITY_PLANNING.md
4
+ include PRE_CUDA_READINESS.md
5
+ include CUDA_PARALLEL_LANES.md
6
+ recursive-include benchmarks *.py
7
+ recursive-include colab *.ipynb
8
+ recursive-include tests *.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rns_engine
3
- Version: 0.7.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 provides the fused direct bridge for digit-plane, chunked-GEMM, and Tensor Core pipelines.
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 current 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.
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 the new weighted INT32 orchestration path.
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.7.0
408
-
409
- - fused native weighted signed INT32 partial accumulation
410
- - one compiled pass for magnitude collection, positional weighting, and four-rail accumulation
411
- - staged reference body retained for exact fused-versus-staged A/B benchmarking
412
- - exact arbitrary-precision positional weights
413
- - per-term magnitude receipts and strict no-wrap certification
414
- - canonical modular and uniqueness-gated signed decode paths
415
- - canonical centered signed encoding and decoding
416
- - exact dot-product and GEMM output-bound receipts
417
- - `SignedSession` high-level API
418
- - four-rail native engine (`127 × 8191 × 65536 × 524287`)
419
- - AVX2, OpenMP, and auto-dispatch kernel families
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.