Adaptive Precision
June 27, 2026 · View on GitHub
Per-layer adaptive bitstream length and per-synapse bit-width planning for mixed-precision SC networks.
assign_lengths— auto-select bitstream length per layer from Hoeffding or sensitivity bounds.assign_synapse_precisions— choose integer bit widths and stochastic bitstream lengths per synapse.auto_tune_synapse_precisions— emit the public precision-plan manifest for a percent error target.write_precision_formal_evidence_bundle— write bounded SVA/SBY/JSON evidence scaffolding for a precision plan.
from sc_neurocore.compiler.adaptive_precision import assign_lengths
sc_neurocore.compiler.adaptive_precision is in the scoped public-docstring
policy. Its dedicated adaptive-precision tests are strict typed and cover
layer-length assignment, sensitivity analysis, per-synapse planning, manifest
stability, row validation, and formal-evidence bundle writing at 100% isolated
facade coverage.
LayerPrecision and SynapsePrecision are validated row contracts behind the
public manifest. Layer rows reject negative indices, empty names, non-positive
or non-power-of-two bitstream lengths, and non-finite or negative error and
sensitivity values. Synapse rows reject negative coordinates, empty layer names,
non-positive bit widths or bitstream lengths, invalid component bounds, and
total error bounds that do not cover the quantisation plus stochastic
components.
The layer and synapse planners now fail closed before row emission. assign_lengths
rejects unsupported methods, mismatched layer_names, invalid target/length
bounds, empty layers, non-finite weights, and tensors outside the documented
1D/2D contract. assign_synapse_precisions rejects invalid target, bit-width,
length, and confidence bounds, mismatched names or sensitivity maps, empty or
non-finite weight layers, and non-finite or negative sensitivity maps. One
dimensional layer and sensitivity vectors remain supported and are serialized as
single-output rows.
The polyglot adaptive-precision mirrors are validated with the Python row contract:
- Rust:
src/sc_neurocore/accel/rust/safety/adaptive_precision.rscompiles as a Rust test binary and exercises layer/synapse contract checks. - Julia:
src/sc_neurocore/accel/julia/compiler/adaptive_precision.jlexposesLayerPrecisionState,SynapsePrecisionState,to_dict, and validation helpers. - Mojo:
src/sc_neurocore/accel/mojo/kernels/adaptive_precision.mojoruns the same layer and synapse validation smoke path.
Local non-isolated benchmark and validation evidence is stored in
benchmarks/results/bench_adaptive_precision_rows.json. On this workstation,
the 2026-06-27 artifact records 10,000 Python LayerPrecision row
constructor/serialization calls in 0.031964 s (312849.473 calls/s), 10,000
SynapsePrecision row constructor/serialization calls in 0.10749 s
(93031.712 calls/s), Rust compile status pass, Rust tests status pass,
Julia validation status pass, and Mojo validation status pass. The artifact
sets production_benchmark_claim to false; it is regression evidence, not a
production performance claim.
The 2026-06-27 planner validation slice did not change numeric planner
objectives or add a new backend benchmark. It added fail-closed validation and a
dedicated coverage gate:
tests/.coveragerc_adaptive_precision_planners, covering
length_planner.py and synapse_planner.py at 100% with the adaptive precision
planner tests.
2026-04-30 per-synapse precision plan
The adaptive precision module now includes a conservative per-synapse planner
for the roadmap auto-adaptive precision optimiser. It assigns integer
bit_width, SC bitstream_length, sensitivity, quantisation-error bound,
stochastic-error bound, and total bound for each synapse:
import numpy as np
from sc_neurocore.compiler.adaptive_precision import (
assign_synapse_precisions,
precision_plan_manifest,
)
weights = [np.array([[0.1, 0.8], [0.0, 0.4]])]
plan = assign_synapse_precisions(weights, target_error=0.05)
manifest = precision_plan_manifest(plan)
This is a deterministic planning surface, not a training-result claim. Bounds are intentionally conservative: quantisation is bounded by half an integer step scaled by sensitivity, and stochastic sampling uses the existing Hoeffding bitstream-length helper. Custom sensitivity maps can be supplied after an external sensitivity-analysis pass.
Adaptive runtime precision BFP metadata
compile_adaptive_precision(...) accepts fixed Q-format strings such as
Q8.8/Q16.16 and block-floating strings such as BFP16E3X32. When a
block-floating precision is supplied with lp_parameter_count or
hp_parameter_count, the generated manifest records the exact
block_exponent_layout: flattened row-major parameter count, block size,
exponent-vector length, and final partial-block size. Invalid negative
parameter counts fail before RTL emission.
This metadata is a compiler contract for downstream emitters. The generated
adaptive wrapper still emits fixed mantissa-width datapaths; shared exponents
remain explicit metadata until the target-specific BFP datapath is selected.
Every adaptive manifest carries adaptive_precision_emitter.v1, explicit
emitted_datapath_width, emitted_datapath_fraction,
exponent_stream_width, and exponent_vector_width fields. Fixed Q-format
paths set the exponent widths to zero and reject accidental
*_parameter_count inputs so a block-exponent layout cannot be silently
dropped before HDL/Rust emitter handoff.
::: sc_neurocore.compiler.adaptive_precision options: show_root_heading: true