Repository navigation
DPointNet: integrate performance paths and safe automatic selection - #481
Conversation
Consolidate native projection, backward sharing, compact rate reduction, input replay and metadata improvements behind validated automatic capability checks. Preserve explicit overrides, canonical gradients, live coefficient mutation/restore safety and checkpoint compatibility. Document numerical and qualification boundaries, add shared GLIF extension contracts, and cover native execution, segmented replay, gradients, updates and restore. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Delay handling can break construction or bypass routing-memory limits, and guarded dispatch has incompatible Keras 3 device access.
3 open issues
What changed in this PR
Integrates DPointNet performance paths with bounded automatic selection, compatibility safeguards, and GLIF extension interfaces.
Changes:
- Adds joint projection, shared basis metadata, and optimized gradients.
- Reduces input, loss, and metadata overhead.
- Adds regression coverage and documents numerical boundaries.
| File | Description |
|---|---|
| tests/simulator/dpointnet/test_weight_regularization.py | Tests compact indexing and checkpoint compatibility. |
| tests/simulator/dpointnet/test_training.py | Checks iterator dtype selection. |
| tests/simulator/dpointnet/test_recurrent_accumulation.py | Tests gradient queue boundaries. |
| tests/simulator/dpointnet/test_projection_basis_sharing.py | Tests basis sharing and fallback. |
| tests/simulator/dpointnet/test_performance_auto.py | Tests automatic selection and live-coefficient safeguards. |
| tests/simulator/dpointnet/test_host_input_metadata.py | Tests dtype, placement, and checkpoints. |
| tests/simulator/dpointnet/test_graded_source_contract.py | Validates graded-source values and gradients. |
| tests/simulator/dpointnet/test_glif_extension_contracts.py | Tests current injection and shadow interfaces. |
| tests/simulator/dpointnet/test_compiled_rate_counts.py | Tests compiled counts and gradients. |
| tests/simulator/dpointnet/test_combined_sweep.py | Tests joint projection and restoration. |
| docs/autodocs/source/dpointnet_training.rst | Documents compiled count configuration. |
| docs/autodocs/source/dpointnet_performance.rst | Explains selection and numerical boundaries. |
| docs/autodocs/source/dpointnet_development.rst | Documents extension and gradient contracts. |
| bmtk/simulator/dpointnet/training.py | Selects native iterator output dtype. |
| bmtk/simulator/dpointnet/rnn_model.py | Prepares admission context and host indices. |
| bmtk/simulator/dpointnet/loss_functions/weight_regularization.py | Adds compact, checkpoint-compatible indexing. |
| bmtk/simulator/dpointnet/loss_functions/target_firing_rates.py | Adds compiled FP32 count reduction. |
| bmtk/simulator/dpointnet/data_iterator.py | Supports output dtype conversion. |
| bmtk/simulator/dpointnet/custom_ops/glif_state_ops.py | Hoists live coefficient guards. |
| bmtk/simulator/dpointnet/custom_ops/csr_spike_ops.py | Adds sharing and joint-projection wrappers. |
| bmtk/simulator/dpointnet/custom_ops/csr_spike_ops.cu.cc | Implements joint sweeps and warp-tiled gradients. |
| bmtk/simulator/dpointnet/custom_ops/csr_spike_ops.cc | Registers the combined-sweep operator. |
| bmtk/simulator/dpointnet/cell_models/glif3_cell.py | Integrates optimized paths and extension interfaces. |
| bmtk/simulator/dpointnet/acceleration.py | Adds bounded automatic projection selection. |
Review effort: Balanced
| network, inputs, *, dt, max_delay, standard_cell, single_replica, | ||
| ): | ||
| """Describe the high-level runner's static projection admission boundary.""" | ||
| history = max(1, int(max_delay / dt) + 1) |
There was a problem hiding this comment.
Fixed in 8e3ee6f. Uncapped (None, zero or negative) recurrent limits now resolve from the network's actual maximum delay before computing the conservative history bound; fractional steps round upward. Added direct-cell bound checks at dt=1/0.5 and high-level RNN construction regressions with acceleration disabled. All pass on actual Keras 3 and Keras 2.
| "source_rows_upper_bound": history * ( | ||
| int(network["n_nodes"]) + sum(int(item["n_inputs"]) for item in inputs.values()) | ||
| ), |
There was a problem hiding this comment.
Fixed in 8e3ee6f. The routing estimate now sums recurrent history plus each external population's independently delay-expanded width, without applying recurrent max_delay to inputs. Added your 4,096-neuron / 20,000-input / 1-and-500-ms example: auto rejects tile256 and selects tile2048. A 100,000-input variant exceeds the budget even at tile2048 and retains separate projection. Existing exact 512-MiB boundary tests also pass.
| ) | ||
| with tf.device("/CPU:0"): | ||
| guard_device = ( | ||
| self.recurrent_weight_values_compute.device |
There was a problem hiding this comment.
Fixed in 8e3ee6f by using recurrent_weight_values_compute.handle.device. Expanded preparation and native live-coefficient mutation/restore tests across frozen, per-type and per-edge recurrent weights, with FP32 and mixed precision coverage. The final focused RTX3090 run passes 207 tests (2 skips); CPU preparation regressions pass on both actual Keras 3 and Keras 2.
Resolve uncapped recurrent delay limits from connectivity and bound external input histories independently for the 512-MiB routing gate. Use compute-weight resource handles for guarded coefficient placement with Keras 3 frozen/per-type FP32 variables. Add delay, routing-budget, live-mutation and restore regressions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>


Summary
Consolidate the DPointNet performance improvements and shared GLIF extension contracts into one complete implementation, with native user/developer documentation and safe automatic selection rather than a manual accelerator overlay.
Compatibility and numerical boundaries
The separate-projection rounding repair from #480 remains intact. Joint projection deliberately sums compatible sources in FP32 before one output rounding, so it can change spikes and trajectories, including full-FP32 runs.
use_combined_current_sweep=falseretains separate projection;compiled_spike_counts=falseretains the ordinary rate reduction.Keep Poisson counts, causal delays, silent-source credit, canonical FP32 masters and exactly-once CSR gradient restoration. Refresh recurrent and named-input shadows after update/assignment/restore. Unsupported explicit requests raise rather than silently changing the selected method.
This is not an STP adapter, neuron-partition implementation, hybrid/distributed qualification, installation or convergence claim. Those integrations remain separate PRs.
Copilot review follow-up — 8e3ee6f
Addressed all three review comments:
max_delay=Noneor nonpositive) from network delays; conservatively round fractional delay steps upward.Validation of the production fixes:
git diff --checkpassed. Unchanged native operators match the original qualification hashes; no rebuild or dependency/environment mutation.rsttemplate. No new successful rendered-docs claim is made for this follow-up.Original implementation validation — 2892f86
All production, tests and documentation in the original implementation commit are byte-identical to the immutable qualification snapshot:
git diff --checkpassed. Flake8 was unavailable in the declared environment and was not installed.Bounded full-V1 performance qualification
RTX3090 / TF2.21, bio-trained 66,658-neuron network, 24,450,554 recurrent edges, 500 steps, exact checkpoint interval 25, counted-Poisson replay, three changing qualification updates and destructive complete restore. All 28 serial arms passed real native-path, precision, master/shadow, carry, restore and one-replay-upload gates. Each arm excludes three warmups and measures 20 synchronized updates.
The four same-static-options/default-2048 B32 control arms passed: candidate 2.384997s versus reference 2.384810s, paired ratios 1.000730/0.999428 and repeat drift below 0.21%. This is fresh admission of this integrated implementation; it does not relabel the historical failed tile controls.
The remaining 24 arms form six reference/auto/auto/reference groups:
Values are means of the two independent run medians/peaks. The B16/32 reference is the already-optimized pre-tile manual prototype, not unchanged upstream develop. The B1 reference uses tile256 and an externally safeguarded static coefficient promise; safe auto is 14.2%/17.6% longer because it retains live mutation safety. Auto must not silently enable that promise.
All repeat drifts are below 3%; every paired B16/32 candidate/reference ratio passes the 1.03 non-regression limit. Lifetime memory is not warm traced memory or driver reservation. Warm-memory changes are small/inconsistent, B1 lifetime peaks increase, and driver-reservation savings are not established.
These are independent-trajectory timing observations, not bitwise equivalence or convergence: the historical unchanged full-model baseline itself fails strict gradient repeatability. New GPU performance qualification is TF2.21/SM86 only; the actual TF2.13 suite is CPU-only. No universal-fastest or universal-memory-saving claim is made.