Skip to main content

Exact RNS engine with session/cache API.

Project description

rns_engine

Exact 4-rail integer arithmetic via a Residue Number System (RNS), with AVX2 and optional OpenMP acceleration.

No floating point. No approximation. Exact results modulo the engine's dynamic range.


What it does

Standard Python integers are exact but slow. NumPy arrays are fast, but fixed-width integer arithmetic can overflow and float-based pipelines drift. rns_engine gives you exact modular arithmetic within a fixed dynamic range by decomposing values across four coprime rails:

  • 127
  • 8191
  • 65536
  • 524287

Arithmetic is performed independently on each rail, then reconstructed with Garner-style CRT.

Dynamic range: [0, 35,742,890,181,197,824)

127 × 8191 × 65536 × 524287 = 35,742,890,181,197,824

Install

pip install rns_engine

AVX2 note

HAS_AVX2 is a build-time property of the compiled extension, not runtime CPU detection. On supported x86_64 builds, the core can use AVX2 acceleration.


Quick start

import numpy as np
import rns_engine as rns

a = np.array([123456789, 999999999], dtype=np.uint64)
b = np.array([987654321, 111111111], dtype=np.uint64)

ea = rns.encode(a)
eb = rns.encode(b)

out_add = rns.decode(*rns.add(*ea, *eb))
out_mul = rns.decode(*rns.mul(*ea, *eb))

# Chain multiple exact operations in residue space, decode once at the end
s1 = rns.add(*ea, *eb)
s2 = rns.mul(*s1, *eb)
s3 = rns.sub(*s2, *ea)
out = rns.decode(*s3)

Session quick start

import numpy as np
import rns_engine as rns

s = rns.Session(cache_capacity=32)
x = np.array([1, 2, 3, 4], dtype=np.uint64)

# Cache-aware encode
ex = s.encode(x)

# Chain exact ops without decoding between steps
res = s.mul(s.add(ex, ex), ex)
out = s.decode(res)

# Single exact affine step
one = s.one_shot_affine(x, multiplier=1_000_003, addend=7)

# Repeated exact affine loop: stay in residue space, decode once
hot = s.hot_loop_affine(x, multiplier=1_000_003, addend=7, iterations=1000)

Core API

Encoded rail API

  • rns.encode(x)(r0, r1, r2, r3)
  • rns.decode(r0, r1, r2, r3)uint64[]
  • rns.add(*ea, *eb)
  • rns.sub(*ea, *eb)
  • rns.mul(*ea, *eb)
  • rns.div_(*ea, *eb)
  • rns.fma(*ea, *eb, *ec)
  • rns.op(*ea, *eb, code) where 0=add 1=mul 2=sub 3=div

Scalar-broadcast encoded API

These avoid materializing full constant arrays in Python:

  • rns.mul_u64(*ea, multiplier)
  • rns.fma_u64(*ea, multiplier, addend)
  • rns.affine_repeat_u64(*ea, multiplier, addend, iterations)

Raw fused uint64 API

These perform encode → exact op → decode in one native call:

  • rns.add_u64_io(x, addend)
  • rns.sub_u64_io(x, subtrahend)
  • rns.mul_u64_io(x, multiplier)
  • rns.fma_u64_io(x, multiplier, addend)
  • rns.affine_repeat_u64_io(x, multiplier, addend, iterations)

OpenMP variants:

  • rns.add_u64_io_omp(...)
  • rns.sub_u64_io_omp(...)
  • rns.mul_u64_io_omp(...)
  • rns.fma_u64_io_omp(...)
  • rns.affine_repeat_u64_io_omp(...)

Auto-dispatch variants:

  • rns.add_u64_auto(...)
  • rns.sub_u64_auto(...)
  • rns.mul_u64_auto(...)
  • rns.fma_u64_auto(...)
  • rns.affine_repeat_u64_auto(...)

High-level API

  • rns.Session
  • rns.SessionCache
  • rns.EncodedArray

Division constraint

Division requires the divisor to be invertible on all four rails:

  • b % 127 != 0
  • b % 8191 != 0
  • b must be odd (for mod 65536)
  • b % 524287 != 0

A safe sanitizer looks like this:

import numpy as np
import rns_engine as rns

M = int(rns.M)

def make_invertible_divisor(b):
    b = np.asarray(b, dtype=np.uint64) % np.uint64(M)
    b = np.where((b & np.uint64(1)) == 0, b + np.uint64(1), b)

    bad = (
        (b % np.uint64(127) == 0)
        | (b % np.uint64(8191) == 0)
        | (b % np.uint64(524287) == 0)
        | ((b & np.uint64(1)) == 0)
    )

    while np.any(bad):
        b = np.where(bad, (b + np.uint64(2)) % np.uint64(M), b)
        bad = (
            (b % np.uint64(127) == 0)
            | (b % np.uint64(8191) == 0)
            | (b % np.uint64(524287) == 0)
            | ((b & np.uint64(1)) == 0)
        )

    return b.astype(np.uint64)

Data model

  • input arrays to encode(...) are treated as uint64
  • values outside [0, M) are reduced mod M during encode
  • rails are returned as:
    • r0: uint16
    • r1: uint16
    • r2: uint16
    • r3: uint32
  • high-level EncodedArray objects store four read-only rails

Performance

Verified benchmark

Verified on Google Colab Linux x86_64, with:

  • AVX2 = True
  • omp_num_procs = 2
  • omp_max_threads = 2

Workloads were run against the installed wheel, not just an editable import.

Median throughput over 5 runs on 1,000,000 uint64 values:

Fused single-step affine

Workload: fma_u64_io(x, 1_000_003, 7)

  • fused fma_u64_io: 47.8 million values/sec
  • fma_u64_io_omp (1 thread): 80.7 million values/sec
  • fma_u64_io_omp (2 threads): 84.6 million values/sec

Repeated affine loop

Workload: affine_repeat_u64_io(x, 1_000_003, 7, iterations=1000)

  • affine_repeat_u64_io: 61.19 billion ops/sec
  • affine_repeat_u64_io_omp (1 thread): 82.80 billion ops/sec
  • affine_repeat_u64_io_omp (2 threads): 94.86 billion ops/sec

Verification status

  • correctness sanity checks passed
  • built wheel installed and executed successfully
  • full test suite passed: 49 / 49

Why RNS?

In a Residue Number System, addition and multiplication happen independently on each rail. There is no cross-rail carry propagation. That makes RNS attractive for:

  • exact modular arithmetic within a fixed dynamic range
  • SIMD-friendly kernels
  • repeated arithmetic pipelines where decode can be delayed
  • parallel execution

How it works

Encode

x -> (x mod 127, x mod 8191, x mod 65536, x mod 524287)

Operate

Each rail is processed independently.

Decode

Garner-style CRT reconstruction combines the four residues back into a uint64 value modulo M.

For the Mersenne moduli (127 = 2^7 - 1, 8191 = 2^13 - 1, 524287 = 2^19 - 1), the core uses fold-based reduction instead of general division.


Building from source

git clone https://github.com/playfularchitect/rns_engine.git
cd rns_engine
pip install -e .
pytest tests/ -v

Requirements:

  • Python 3.10+
  • C++17 compiler
  • NumPy
  • pybind11

Introspection

import rns_engine as rns

rns.info()

rns.M
rns.M0
rns.M1
rns.M2
rns.M3
rns.HAS_AVX2

Current release

v0.4.0rc1

  • 4-rail engine (127 × 8191 × 65536 × 524287)
  • AVX2-accelerated encoded kernels
  • fused fma(...)
  • scalar-broadcast encoded APIs: mul_u64, fma_u64, affine_repeat_u64
  • fused raw uint64 APIs: *_u64_io
  • OpenMP fused raw APIs: *_u64_io_omp
  • auto-dispatch raw APIs: *_u64_auto
  • high-level Session, SessionCache, and EncodedArray

License

AGPL-3.0-only
Copyright 2026 Evan Wesley

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rns_engine-0.4.0rc1.tar.gz (34.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rns_engine-0.4.0rc1-cp312-cp312-win_amd64.whl (131.7 kB view details)

Uploaded CPython 3.12Windows x86-64

rns_engine-0.4.0rc1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_x86_64.whl (169.2 kB view details)

Uploaded CPython 3.12macOS 11.0+ x86-64

rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_arm64.whl (173.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

rns_engine-0.4.0rc1-cp311-cp311-win_amd64.whl (129.7 kB view details)

Uploaded CPython 3.11Windows x86-64

rns_engine-0.4.0rc1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_x86_64.whl (166.4 kB view details)

Uploaded CPython 3.11macOS 11.0+ x86-64

rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_arm64.whl (172.7 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

rns_engine-0.4.0rc1-cp310-cp310-win_amd64.whl (130.0 kB view details)

Uploaded CPython 3.10Windows x86-64

rns_engine-0.4.0rc1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.9 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_x86_64.whl (165.5 kB view details)

Uploaded CPython 3.10macOS 11.0+ x86-64

rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_arm64.whl (171.4 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file rns_engine-0.4.0rc1.tar.gz.

File metadata

  • Download URL: rns_engine-0.4.0rc1.tar.gz
  • Upload date:
  • Size: 34.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rns_engine-0.4.0rc1.tar.gz
Algorithm Hash digest
SHA256 9df2c6f8072bc0451218ca5c7402b277b9c78b54ca57c1f3a13791a3520c5062
MD5 97db1f0ff70c5c371855f8639432732a
BLAKE2b-256 19fadee58fb2dd40d13c286da7ec60d2a153dc7bc1f241f18149987b78447d7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1.tar.gz:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f630b389d07a2db76d02e5e44666bfbf717d99886d6b888a48bb3f484cdfcdf5
MD5 c4e895e216896d650490a6a56bba894a
BLAKE2b-256 3e8e535ec7427ed6079aff648e7d18a1ec4e6be4404a2c14b228d0c25e8b2a15

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp312-cp312-win_amd64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b8cec121483eb203c3e0de16fe41d5511489bbd4d93a20b62927370aed1479e3
MD5 74ee1fae74ba88253e688760b40613d1
BLAKE2b-256 784238eb5052fe120b7e33930a1beb8b20f70ea9682e1f5730d3b0d138cdf388

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 2002d846304d697407a75466edbd5a8c084fd632f21efe72922c9499bc91248d
MD5 3cedf2eff18b76711cec8f73c21eea0b
BLAKE2b-256 4df193729123f60372cc3bf8c562d2c390e0ad344a105f90165b5ed058e04c6c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_x86_64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5e1ff0775daa29a1041e6a3ee51118f8d7752d49c2bc626614841456a6466fc1
MD5 bdb3350ce8229ad28c040ca9ef315300
BLAKE2b-256 fed921460b1bf638dd64a56f8d2b72e491c86121ecca77a8ff823bbf62a2f90f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 f921d06e395f78af7b5af8b115710512913b2b3306a1cc7ea8aa344990fc5a7e
MD5 e766a327d2204429dc2ca59f444904ce
BLAKE2b-256 090c5404094c9531798981a12e3c33220917496c9b75d0fee73785282bda69a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp311-cp311-win_amd64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 02958a43716d7e9bd57a2d0a276cbada5ce8634c3f78f8642c855f2739e70cbb
MD5 810b922213c71ab035de4a3b9460b2a7
BLAKE2b-256 2ba2e1faff05253ade9418f74b322ec6c9001f54b3773a3ae7454f7ad911b326

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 b0b476d83c01f4c13c693e6521e7b3c94bee2a83aebdf97b4aa9d1ff7c21737e
MD5 0232ee94fddfcf7de55a55dbb55f3331
BLAKE2b-256 85a671aef6047548667b38387f287e0589d9fc752e1c5352bf0f990ebecec722

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_x86_64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3871832bd21c30082c654e0faa0bdece8dd242e1bbb8f7c099c6f2f1f50dd05c
MD5 f0a06307e3a7138828735bc7eb93ea64
BLAKE2b-256 10f0433c555ee96bb2d642a093b2788ff83a829fed6f36db33a883f61ab9cb09

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 4089443d22cf946532db4fb2879d38a7313a8a67811ff4b4b609891eb541af79
MD5 a063a3f17a07440315b38fa63ba16018
BLAKE2b-256 4a898537fa103249c1cc85481123cca01786379b56563204d66f1c5bdd968ca8

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp310-cp310-win_amd64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 33f834d6af573b7df3b9538a1426f9060b8020498f8a3c4e6fc2773da8566772
MD5 8736f595e152839073ffc2f99decb11b
BLAKE2b-256 a7263ad11b82487002bff6ca24e2b03171bbee4476373736b4f204b01f68814a

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 0320527099c1d08a98b4823a25783645ac189cd54f2a1ed6f6c2937b3945998b
MD5 a5aab830ee23efd384b2e31ac29995fa
BLAKE2b-256 b553b69e21b18d8ee3c1aa65f0885d6d2111b639eb8909143df61fd508b4bf48

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_x86_64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 744f7c7abf99b5ce8c8d00bd8f0f1eef48afa6410ed1baf9c6e5144b4b9ce7e1
MD5 6dee67fe8b97188d4ddc9571d321edc8
BLAKE2b-256 db53f44d9d1839899b721ccc575508e1bcdd711b269dacb79ccdfeffc1bdf81a

See more details on using hashes here.

Provenance

The following attestation bundles were made for rns_engine-0.4.0rc1-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: build.yml on playfularchitect/rns_engine

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page