neurosush 0.3.1__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 (134) hide show
  1. neurosush-0.3.1/.github/dependabot.yml +20 -0
  2. neurosush-0.3.1/.github/workflows/bench.yml +29 -0
  3. neurosush-0.3.1/.github/workflows/ci.yml +93 -0
  4. neurosush-0.3.1/.github/workflows/release.yml +95 -0
  5. neurosush-0.3.1/.gitignore +21 -0
  6. neurosush-0.3.1/.pre-commit-config.yaml +17 -0
  7. neurosush-0.3.1/CHANGELOG.md +93 -0
  8. neurosush-0.3.1/CITATION.cff +22 -0
  9. neurosush-0.3.1/CONTRIBUTING.md +76 -0
  10. neurosush-0.3.1/LICENSE +21 -0
  11. neurosush-0.3.1/PKG-INFO +499 -0
  12. neurosush-0.3.1/README.md +461 -0
  13. neurosush-0.3.1/benchmarks/baseline.json +25 -0
  14. neurosush-0.3.1/benchmarks/compare.py +63 -0
  15. neurosush-0.3.1/benchmarks/dense_stdp.py +93 -0
  16. neurosush-0.3.1/benchmarks/suite.py +131 -0
  17. neurosush-0.3.1/docs/ARCHITECTURE.md +187 -0
  18. neurosush-0.3.1/examples/object_recognition.py +60 -0
  19. neurosush-0.3.1/examples/sequence_prediction.py +93 -0
  20. neurosush-0.3.1/examples/two_patterns.py +139 -0
  21. neurosush-0.3.1/experiments/README.md +12 -0
  22. neurosush-0.3.1/experiments/sequence_learning.py +144 -0
  23. neurosush-0.3.1/pyproject.toml +102 -0
  24. neurosush-0.3.1/scripts/check.sh +9 -0
  25. neurosush-0.3.1/scripts/release_check.py +83 -0
  26. neurosush-0.3.1/src/neurosush/__init__.py +3 -0
  27. neurosush-0.3.1/src/neurosush/checkpoint.py +149 -0
  28. neurosush-0.3.1/src/neurosush/core/__init__.py +1 -0
  29. neurosush-0.3.1/src/neurosush/core/behavior.py +37 -0
  30. neurosush-0.3.1/src/neurosush/core/buffers.py +139 -0
  31. neurosush-0.3.1/src/neurosush/core/network.py +344 -0
  32. neurosush-0.3.1/src/neurosush/core/order.py +30 -0
  33. neurosush-0.3.1/src/neurosush/data.py +122 -0
  34. neurosush-0.3.1/src/neurosush/encoding.py +139 -0
  35. neurosush-0.3.1/src/neurosush/filters.py +168 -0
  36. neurosush-0.3.1/src/neurosush/htm/__init__.py +5 -0
  37. neurosush-0.3.1/src/neurosush/htm/_state.py +23 -0
  38. neurosush-0.3.1/src/neurosush/htm/active_dendrites.py +75 -0
  39. neurosush-0.3.1/src/neurosush/htm/classifier.py +45 -0
  40. neurosush-0.3.1/src/neurosush/htm/encoders.py +142 -0
  41. neurosush-0.3.1/src/neurosush/htm/grid_cells.py +153 -0
  42. neurosush-0.3.1/src/neurosush/htm/objects.py +148 -0
  43. neurosush-0.3.1/src/neurosush/htm/sdr.py +109 -0
  44. neurosush-0.3.1/src/neurosush/htm/spatial_pooler.py +237 -0
  45. neurosush-0.3.1/src/neurosush/htm/temporal_memory.py +337 -0
  46. neurosush-0.3.1/src/neurosush/modulation.py +63 -0
  47. neurosush-0.3.1/src/neurosush/neurons/__init__.py +1 -0
  48. neurosush-0.3.1/src/neurosush/neurons/axon.py +48 -0
  49. neurosush-0.3.1/src/neurosush/neurons/competition.py +195 -0
  50. neurosush-0.3.1/src/neurosush/neurons/dendrite.py +152 -0
  51. neurosush-0.3.1/src/neurosush/neurons/dynamics.py +87 -0
  52. neurosush-0.3.1/src/neurosush/neurons/homeostasis.py +128 -0
  53. neurosush-0.3.1/src/neurosush/neurons/inputs.py +57 -0
  54. neurosush-0.3.1/src/neurosush/neurons/models.py +243 -0
  55. neurosush-0.3.1/src/neurosush/predictive_coding.py +166 -0
  56. neurosush-0.3.1/src/neurosush/py.typed +0 -0
  57. neurosush-0.3.1/src/neurosush/recording.py +77 -0
  58. neurosush-0.3.1/src/neurosush/structure/__init__.py +1 -0
  59. neurosush-0.3.1/src/neurosush/structure/column.py +58 -0
  60. neurosush-0.3.1/src/neurosush/structure/connect.py +37 -0
  61. neurosush-0.3.1/src/neurosush/structure/layer.py +122 -0
  62. neurosush-0.3.1/src/neurosush/structure/sequence.py +209 -0
  63. neurosush-0.3.1/src/neurosush/structure/spec.py +267 -0
  64. neurosush-0.3.1/src/neurosush/synapses/__init__.py +1 -0
  65. neurosush-0.3.1/src/neurosush/synapses/bounds.py +60 -0
  66. neurosush-0.3.1/src/neurosush/synapses/constraints.py +118 -0
  67. neurosush-0.3.1/src/neurosush/synapses/currents.py +506 -0
  68. neurosush-0.3.1/src/neurosush/synapses/init.py +192 -0
  69. neurosush-0.3.1/src/neurosush/synapses/plasticity.py +486 -0
  70. neurosush-0.3.1/src/neurosush/synapses/segment_learning.py +274 -0
  71. neurosush-0.3.1/src/neurosush/synapses/segments.py +164 -0
  72. neurosush-0.3.1/src/neurosush/synapses/traces.py +80 -0
  73. neurosush-0.3.1/src/neurosush/transforms.py +146 -0
  74. neurosush-0.3.1/tests/conftest.py +12 -0
  75. neurosush-0.3.1/tests/core/__init__.py +1 -0
  76. neurosush-0.3.1/tests/core/test_behavior.py +51 -0
  77. neurosush-0.3.1/tests/core/test_buffers.py +170 -0
  78. neurosush-0.3.1/tests/core/test_network.py +225 -0
  79. neurosush-0.3.1/tests/htm/__init__.py +1 -0
  80. neurosush-0.3.1/tests/htm/test_active_dendrites.py +128 -0
  81. neurosush-0.3.1/tests/htm/test_classifier.py +43 -0
  82. neurosush-0.3.1/tests/htm/test_encoders.py +94 -0
  83. neurosush-0.3.1/tests/htm/test_examples.py +27 -0
  84. neurosush-0.3.1/tests/htm/test_grid_cells.py +152 -0
  85. neurosush-0.3.1/tests/htm/test_objects.py +173 -0
  86. neurosush-0.3.1/tests/htm/test_sdr.py +116 -0
  87. neurosush-0.3.1/tests/htm/test_spatial_pooler.py +268 -0
  88. neurosush-0.3.1/tests/htm/test_temporal_memory.py +236 -0
  89. neurosush-0.3.1/tests/neurons/__init__.py +1 -0
  90. neurosush-0.3.1/tests/neurons/test_axon_dendrite.py +200 -0
  91. neurosush-0.3.1/tests/neurons/test_competition.py +112 -0
  92. neurosush-0.3.1/tests/neurons/test_dynamics.py +74 -0
  93. neurosush-0.3.1/tests/neurons/test_homeostasis.py +125 -0
  94. neurosush-0.3.1/tests/neurons/test_inputs.py +70 -0
  95. neurosush-0.3.1/tests/neurons/test_minicolumns.py +80 -0
  96. neurosush-0.3.1/tests/neurons/test_models.py +141 -0
  97. neurosush-0.3.1/tests/structure/__init__.py +1 -0
  98. neurosush-0.3.1/tests/structure/test_layers.py +126 -0
  99. neurosush-0.3.1/tests/structure/test_sequence.py +30 -0
  100. neurosush-0.3.1/tests/structure/test_spec.py +170 -0
  101. neurosush-0.3.1/tests/synapses/__init__.py +1 -0
  102. neurosush-0.3.1/tests/synapses/test_currents_pure.py +97 -0
  103. neurosush-0.3.1/tests/synapses/test_init.py +132 -0
  104. neurosush-0.3.1/tests/synapses/test_inputs.py +197 -0
  105. neurosush-0.3.1/tests/synapses/test_learning.py +200 -0
  106. neurosush-0.3.1/tests/synapses/test_plasticity_pure.py +206 -0
  107. neurosush-0.3.1/tests/synapses/test_segment_learning.py +225 -0
  108. neurosush-0.3.1/tests/synapses/test_segments.py +169 -0
  109. neurosush-0.3.1/tests/synapses/test_traces_constraints.py +230 -0
  110. neurosush-0.3.1/tests/test_batching.py +224 -0
  111. neurosush-0.3.1/tests/test_benchmarks.py +53 -0
  112. neurosush-0.3.1/tests/test_checkpoint.py +146 -0
  113. neurosush-0.3.1/tests/test_data.py +119 -0
  114. neurosush-0.3.1/tests/test_encoding.py +157 -0
  115. neurosush-0.3.1/tests/test_filters.py +103 -0
  116. neurosush-0.3.1/tests/test_gpu.py +75 -0
  117. neurosush-0.3.1/tests/test_integration.py +37 -0
  118. neurosush-0.3.1/tests/test_modulation.py +38 -0
  119. neurosush-0.3.1/tests/test_package.py +7 -0
  120. neurosush-0.3.1/tests/test_predictive_coding.py +169 -0
  121. neurosush-0.3.1/tests/test_readme.py +19 -0
  122. neurosush-0.3.1/tests/test_recording.py +79 -0
  123. neurosush-0.3.1/tests/test_release_check.py +109 -0
  124. neurosush-0.3.1/tests/test_transforms.py +132 -0
  125. neurosush-0.3.1/tests/validation/__init__.py +1 -0
  126. neurosush-0.3.1/tests/validation/common.py +53 -0
  127. neurosush-0.3.1/tests/validation/test_connectivity_math.py +226 -0
  128. neurosush-0.3.1/tests/validation/test_encoding_math.py +110 -0
  129. neurosush-0.3.1/tests/validation/test_neuron_math.py +183 -0
  130. neurosush-0.3.1/tests/validation/test_plasticity_math.py +212 -0
  131. neurosush-0.3.1/tests/validation/test_reward_math.py +151 -0
  132. neurosush-0.3.1/tests/validation/test_segment_math.py +254 -0
  133. neurosush-0.3.1/tests/validation/test_sequence_learning.py +97 -0
  134. neurosush-0.3.1/tests/validation/test_sequence_math.py +168 -0
@@ -0,0 +1,20 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ commit-message:
8
+ prefix: build
9
+ groups:
10
+ python:
11
+ patterns: ["*"]
12
+ - package-ecosystem: github-actions
13
+ directory: /
14
+ schedule:
15
+ interval: weekly
16
+ commit-message:
17
+ prefix: ci
18
+ groups:
19
+ actions:
20
+ patterns: ["*"]
@@ -0,0 +1,29 @@
1
+ name: Benchmarks
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 3 * * 1' # Mondays
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ benchmark:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v7
16
+ - uses: actions/setup-python@v7
17
+ with:
18
+ python-version: '3.12'
19
+ cache: pip
20
+ - run: pip install torch --index-url https://download.pytorch.org/whl/cpu
21
+ - run: pip install -e .
22
+ - run: python benchmarks/suite.py --out benchmark.json
23
+ - uses: actions/upload-artifact@v7
24
+ with:
25
+ name: benchmark
26
+ path: benchmark.json
27
+ - name: Compare with the baseline (fails when a case halves)
28
+ shell: bash # -eo pipefail: the comparison's exit code survives the pipe to tee
29
+ run: python benchmarks/compare.py benchmarks/baseline.json benchmark.json | tee -a "$GITHUB_STEP_SUMMARY"
@@ -0,0 +1,93 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+ workflow_call:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ concurrency:
14
+ group: ci-${{ github.ref }}
15
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
16
+
17
+ jobs:
18
+ lint:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v7
22
+ - uses: actions/setup-python@v7
23
+ with:
24
+ python-version: '3.12'
25
+ cache: pip
26
+ - run: pip install pre-commit
27
+ - run: pre-commit run --all-files --show-diff-on-failure
28
+
29
+ typecheck:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v7
33
+ - uses: actions/setup-python@v7
34
+ with:
35
+ python-version: '3.12'
36
+ cache: pip
37
+ - run: pip install torch --index-url https://download.pytorch.org/whl/cpu
38
+ - run: pip install "mypy>=1.10"
39
+ - run: mypy
40
+
41
+ test:
42
+ runs-on: ${{ matrix.os }}
43
+ strategy:
44
+ fail-fast: false
45
+ matrix:
46
+ os: [ubuntu-latest]
47
+ python: ['3.10', '3.11', '3.12', '3.13']
48
+ include:
49
+ - os: macos-latest
50
+ python: '3.12'
51
+ steps:
52
+ - uses: actions/checkout@v7
53
+ - uses: actions/setup-python@v7
54
+ with:
55
+ python-version: ${{ matrix.python }}
56
+ cache: pip
57
+ - if: runner.os == 'Linux'
58
+ run: pip install torch --index-url https://download.pytorch.org/whl/cpu
59
+ - if: runner.os == 'macOS'
60
+ run: pip install torch
61
+ - run: pip install -e ".[dev]"
62
+ - if: matrix.os == 'ubuntu-latest' && matrix.python == '3.12'
63
+ run: pytest --cov --cov-report=xml --cov-fail-under=90
64
+ - if: matrix.os != 'ubuntu-latest' || matrix.python != '3.12'
65
+ run: pytest
66
+ - uses: actions/upload-artifact@v7
67
+ if: matrix.os == 'ubuntu-latest' && matrix.python == '3.12'
68
+ with:
69
+ name: coverage
70
+ path: coverage.xml
71
+
72
+ build:
73
+ runs-on: ubuntu-latest
74
+ steps:
75
+ - uses: actions/checkout@v7
76
+ - uses: actions/setup-python@v7
77
+ with:
78
+ python-version: '3.12'
79
+ cache: pip
80
+ - run: pip install build twine
81
+ - run: python -m build
82
+ - run: twine check --strict dist/*
83
+ - name: Smoke test the wheel in a fresh environment
84
+ run: |
85
+ python -m venv "${RUNNER_TEMP}/wheel-venv"
86
+ "${RUNNER_TEMP}/wheel-venv/bin/python" -m pip install torch --index-url https://download.pytorch.org/whl/cpu
87
+ "${RUNNER_TEMP}/wheel-venv/bin/python" -m pip install dist/*.whl
88
+ cd "${RUNNER_TEMP}"
89
+ "${RUNNER_TEMP}/wheel-venv/bin/python" -c "import neurosush; print(neurosush.__version__)"
90
+ - uses: actions/upload-artifact@v7
91
+ with:
92
+ name: dist
93
+ path: dist/
@@ -0,0 +1,95 @@
1
+ name: Release
2
+
3
+ # A commit on main whose __version__ is a release version (for example 0.2.0) that has no
4
+ # GitHub release yet is released automatically: verify, full CI, GitHub release with the
5
+ # wheel and sdist, then PyPI once publishing is switched on. Pushing a tag vX.Y.Z by hand
6
+ # works too.
7
+
8
+ on:
9
+ push:
10
+ branches: [main]
11
+ tags: ['v*']
12
+ workflow_dispatch:
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ concurrency:
18
+ group: release
19
+ cancel-in-progress: false
20
+
21
+ jobs:
22
+ plan:
23
+ runs-on: ubuntu-latest
24
+ outputs:
25
+ release: ${{ steps.decide.outputs.release }}
26
+ tag: ${{ steps.decide.outputs.tag }}
27
+ steps:
28
+ - uses: actions/checkout@v7
29
+ - id: decide
30
+ env:
31
+ GH_TOKEN: ${{ github.token }}
32
+ run: |
33
+ version=$(python3 scripts/release_check.py --print-version)
34
+ tag="v${version}"
35
+ echo "tag=${tag}" >> "$GITHUB_OUTPUT"
36
+ if ! python3 scripts/release_check.py --is-release "$version"; then
37
+ echo "release=false" >> "$GITHUB_OUTPUT"; echo "${version} is a development version"
38
+ elif gh release view "$tag" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
39
+ echo "release=false" >> "$GITHUB_OUTPUT"; echo "${tag} is already released"
40
+ else
41
+ echo "release=true" >> "$GITHUB_OUTPUT"; echo "releasing ${tag}"
42
+ fi
43
+
44
+ verify:
45
+ needs: plan
46
+ if: needs.plan.outputs.release == 'true'
47
+ runs-on: ubuntu-latest
48
+ steps:
49
+ - uses: actions/checkout@v7
50
+ - run: python3 scripts/release_check.py --tag "${{ needs.plan.outputs.tag }}" --notes-out notes.md
51
+ - uses: actions/upload-artifact@v7
52
+ with:
53
+ name: notes
54
+
55
+ path: notes.md
56
+
57
+ ci:
58
+ needs: verify
59
+ uses: ./.github/workflows/ci.yml
60
+
61
+ github-release:
62
+ needs: [plan, ci]
63
+ runs-on: ubuntu-latest
64
+ permissions:
65
+ contents: write
66
+ steps:
67
+ - uses: actions/download-artifact@v8
68
+ with:
69
+ name: dist
70
+ path: dist/
71
+ - uses: actions/download-artifact@v8
72
+ with:
73
+ name: notes
74
+ - env:
75
+ GH_TOKEN: ${{ github.token }}
76
+ TAG: ${{ needs.plan.outputs.tag }}
77
+ run: >
78
+ gh release create "$TAG" dist/* --repo "$GITHUB_REPOSITORY" --target "$GITHUB_SHA"
79
+ --title "$TAG" --notes-file notes.md
80
+
81
+ pypi:
82
+ needs: github-release
83
+ # Switch on after adding this repository as a PyPI trusted publisher:
84
+ # Settings > Secrets and variables > Actions > Variables > PYPI_PUBLISH = true
85
+ if: vars.PYPI_PUBLISH == 'true'
86
+ runs-on: ubuntu-latest
87
+ environment: pypi
88
+ permissions:
89
+ id-token: write
90
+ steps:
91
+ - uses: actions/download-artifact@v8
92
+ with:
93
+ name: dist
94
+ path: dist/
95
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,21 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .eggs/
5
+ build/
6
+ dist/
7
+ .venv
8
+ .venv/
9
+ .pytest_cache/
10
+ .ruff_cache/
11
+ .coverage
12
+ coverage.xml
13
+ htmlcov/
14
+ .mypy_cache/
15
+ # local tooling, never committed
16
+ .worker/
17
+ .ref/
18
+ graphify-out/
19
+ .claude/
20
+ CLAUDE.md
21
+ AGENTS.md
@@ -0,0 +1,17 @@
1
+ # Install once with `pre-commit install`; the hooks then run on every commit.
2
+ repos:
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v6.0.0
5
+ hooks:
6
+ - id: trailing-whitespace
7
+ - id: end-of-file-fixer
8
+ - id: check-yaml
9
+ - id: check-toml
10
+ - id: check-merge-conflict
11
+ - id: check-added-large-files
12
+ - repo: https://github.com/astral-sh/ruff-pre-commit
13
+ rev: v0.16.8
14
+ hooks:
15
+ - id: ruff-check
16
+ args: [--fix]
17
+ - id: ruff-format
@@ -0,0 +1,93 @@
1
+ # Changelog
2
+
3
+ All notable changes to neuroSush are documented here, following the
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format.
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.3.1] - 2026-09-24
9
+
10
+ ### Added
11
+ - Package metadata for PyPI (summary, keywords, project links, classifiers) and
12
+ `CITATION.cff`.
13
+
14
+ ### Changed
15
+ - The README introduces the whole project, links absolutely (so it also works on PyPI), shows
16
+ the spiking sequence memory learning, and lists the limitations.
17
+
18
+ ## [0.3.0] - 2026-09-24
19
+
20
+ ### Added
21
+ - Spiking temporal memory: `ActiveSegments` (distal dendritic segments with NMDA-like
22
+ plateaus and a coincidence window) and `MinicolumnInhibition`; a layer built from them
23
+ activates exactly the cells `TemporalMemory` activates, checked by
24
+ `tests/validation/test_segment_math.py` and `test_sequence_math.py`.
25
+ - `SegmentLearning`: the temporal memory's learning in spike time, and `sequence_memory`,
26
+ which builds a spiking sequence memory layer with derived and checked timing. It learns
27
+ the same curves as `TemporalMemory` (`tests/validation/test_sequence_learning.py`).
28
+ - `experiments/sequence_learning.py`: the full learning curves, with parameters and seeds.
29
+ - `SpatialPooler.state_dict()`/`load_state_dict()` and the same for `TemporalMemory`
30
+ (including its random generator), so both resume exactly.
31
+ - More of `tests/validation`: conv2d, local2d, lateral and pooling currents and the conv and
32
+ local STDP rules against the dense synapse-by-synapse definition; reward-modulated STDP
33
+ against its closed form, and the distal reward problem (Izhikevich 2007).
34
+ - `benchmarks/suite.py` and `compare.py`, run weekly by the Benchmarks workflow: throughput
35
+ normalized by a calibration workload, compared with a baseline recorded on a GitHub
36
+ runner (a case that halves fails).
37
+
38
+ ### Fixed
39
+ - STDP computed in torch's default dtype instead of the traces' dtype, so a float64
40
+ network learned in float32 precision (and conv and local synapses got float32 updates).
41
+
42
+ ## [0.2.0] - 2026-09-24
43
+
44
+ ### Added
45
+ - `neurosush.htm`: SDR operations with exact match probabilities, scalar, random
46
+ distributed and category encoders, `SDRClassifier`, `SpatialPooler`, `TemporalMemory`,
47
+ grid cell modules, `ActiveDendrites`, and voting columns for object recognition.
48
+ - `neurosush.predictive_coding.PredictiveCodingNetwork`: hierarchical predictive coding with
49
+ learned weights, priors and variances.
50
+ - `examples/sequence_prediction.py` and `examples/object_recognition.py`.
51
+ - `Recorder`: records attributes of a network, neuron group or synapse group over time.
52
+ - `neurosush.checkpoint`: save and load the complete state of a network and resume it
53
+ exactly, batched or not.
54
+ - `Behavior.state_dict()`/`load_state_dict()`, and the same for delay buffers.
55
+ - Strict mypy type checking of the package (in `scripts/check.sh` and CI).
56
+ - `tests/validation`: the spiking core checked against the closed-form solutions of its
57
+ equations (LIF, exponential and adaptive LIF, traces, STDP, inhibitory STDP, homeostasis,
58
+ dopamine, Poisson encoders and delays).
59
+ - Tests marked `gpu` that compare CUDA and CPU runs, pre-commit hooks (also run by the CI
60
+ lint job), and Dependabot updates for pip and GitHub Actions.
61
+
62
+ ### Changed
63
+ - A synaptic input without `SpikeGather` is now an error; before, the synapse silently
64
+ delivered no current.
65
+ - `SpikeGather` needs an `Axon` only on the source; `syn.post_spike` is gathered when the
66
+ destination has one too (traces and plasticity need it and say so).
67
+ - `Axon` checks that the `dst_delay` of incoming synapses fits its history.
68
+ - A group shape in a JSON spec that is neither an int nor three ints raises `ValueError`.
69
+
70
+ ## [0.1.0] - 2026-09-24
71
+
72
+ ### Added
73
+ - Simulation core: `Network`, `NeuronGroup`, `SynapseGroup`, `Behavior` with an explicit
74
+ execution `Order`, delay buffers, and seeded randomness.
75
+ - Neurons: `LIF`, `ELIF`, `AdaptiveELIF` with pure dynamics, `Fire`, `KWTA`, `InherentNoise`,
76
+ `Axon` delays, `DendriteStructure` and `DendriteIntegration` (proximal, distal, apical),
77
+ `ActivityHomeostasis`, `VoltageHomeostasis`, and `SpikeInput`.
78
+ - Synapses: `WeightInit` (dense or sparse), `DelayInit`, dense, one-to-one, sparse, conv2d,
79
+ local2d, lateral and average-pooling inputs, `SpikeGather`, `Traces`, `STDP`, `RSTDP`,
80
+ `ISTDP`, `WeightClip`, `WeightNormalization`, `CurrentNormalization`.
81
+ - `Payoff` and `Dopamine` reward modulation.
82
+ - Poisson and latency encoders, DoG and Gabor kernels, grid masks, `LocationDataset` and
83
+ `spike_frames`.
84
+ - Cortical structures: layers with ports, `connect`, `CorticalColumn`, and JSON specs built
85
+ through a class registry.
86
+ - `examples/two_patterns.py`, which learns two input patterns with STDP.
87
+ - Fast paths: ring-buffer delays validated once, and event-driven in-place STDP for dense
88
+ synapses (5-6x faster on CPU); `benchmarks/dense_stdp.py` measures it.
89
+ - Batched simulation: `Network(batch_size=B)` and `spike_frames(..., batch_size=B)` run `B`
90
+ samples side by side with shared weights (about 23,000 sample-steps/s on a laptop GPU for
91
+ the 784 -> 400 benchmark).
92
+ - CI (lint, tests on Python 3.10 to 3.13, coverage, build) and a tag-driven release workflow
93
+ with PyPI trusted publishing.
@@ -0,0 +1,22 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use this software, please cite it as below, together with the papers of the models you use."
3
+ title: "neuroSush: brain-inspired computing on PyTorch"
4
+ type: software
5
+ authors:
6
+ - alias: sush
7
+ email: soroushdeimi@gmail.com
8
+ repository-code: "https://github.com/soroushdeimi/neuroSush"
9
+ license: MIT
10
+ abstract: >-
11
+ A PyTorch library that simulates spiking neural networks (integrate-and-fire neurons with
12
+ dendritic compartments and delays, STDP-family plasticity with dopamine modulation),
13
+ implements the Thousand Brains and hierarchical temporal memory models and hierarchical
14
+ predictive coding, and provides a spiking layer that computes the temporal memory. Every
15
+ model is validated against its mathematics.
16
+ keywords:
17
+ - spiking neural networks
18
+ - hierarchical temporal memory
19
+ - thousand brains theory
20
+ - predictive coding
21
+ - computational neuroscience
22
+ - pytorch
@@ -0,0 +1,76 @@
1
+ # Contributing
2
+
3
+ ## Development setup
4
+
5
+ Use Python 3.10 or newer. Create and activate a virtual environment, install CPU
6
+ PyTorch, then install the package with development dependencies:
7
+
8
+ ```bash
9
+ python -m venv .venv
10
+ source .venv/bin/activate
11
+ pip install torch --index-url https://download.pytorch.org/whl/cpu
12
+ pip install -e ".[dev]"
13
+ ```
14
+
15
+ On macOS, use `pip install torch` instead of the CPU index command.
16
+ Install the git hooks once; they fix whitespace and run ruff on every commit, as the CI
17
+ lint job does:
18
+
19
+ ```bash
20
+ pre-commit install
21
+ ```
22
+
23
+ Run the full check before committing:
24
+
25
+ ```bash
26
+ bash scripts/check.sh
27
+ ```
28
+
29
+ Tests marked `gpu` compare CUDA runs with the CPU. They are skipped on machines without a
30
+ CUDA device (including CI), so run them locally after changing tensor code:
31
+ `pytest -m gpu`.
32
+
33
+ ## Code and commits
34
+
35
+ Keep math in pure functions and behaviors thin. Test equations with hand-computed
36
+ values, and never mutate inputs in place. Add type hints to public functions and
37
+ use `from __future__ import annotations` in Python modules. Follow
38
+ `docs/ARCHITECTURE.md` for the simulation model and conventions.
39
+
40
+ Use Conventional Commits with a scope: `feat`, `fix`, `docs`, `test`, `build`,
41
+ `ci`, or `refactor`, for example `fix(neurons): validate time constants`.
42
+
43
+ ## Benchmarks
44
+
45
+ `python benchmarks/suite.py` times the main workloads (dense STDP, batched simulation,
46
+ spatial pooler and temporal memory learning). Each rate is also divided by a calibration
47
+ workload measured on the same machine, which removes most of the difference between
48
+ machines, though not all of it: the same code measured up to 27% apart on two GitHub
49
+ runners. The Benchmarks workflow runs the suite every Monday (or on demand) and compares it
50
+ with `benchmarks/baseline.json`; a case that loses half its normalized throughput fails
51
+ the run, and the table in the run summary shows every change.
52
+
53
+ To record or move the baseline after an intended change, download the `benchmark`
54
+ artifact of a Benchmarks run on GitHub and commit it as `benchmarks/baseline.json`; a
55
+ baseline from another machine is not comparable.
56
+
57
+ ## Releasing
58
+
59
+ Releases are automatic:
60
+
61
+ 1. Set `__version__` in `src/neurosush/__init__.py` to the release version.
62
+ 2. Move the Unreleased notes under `## [X.Y.Z] - YYYY-MM-DD`, keeping an
63
+ Unreleased section for future changes.
64
+ 3. Run `bash scripts/check.sh`, commit, and push to `main`.
65
+
66
+ On that push the Release workflow sees a release version without a GitHub
67
+ release, checks the version and changelog, runs the full CI, and creates the tag
68
+ `vX.Y.Z` and a GitHub release with the wheel, the sdist and the changelog notes.
69
+ Development versions (`X.Y.Z.devN`) are never released. Pushing a tag `vX.Y.Z`
70
+ by hand does the same.
71
+
72
+ PyPI publishing is a separate job that is off until it is set up once: add this
73
+ repository as a trusted publisher on PyPI (workflow `release.yml`, environment
74
+ `pypi`), create the `pypi` environment in the repository settings, and set the
75
+ repository variable `PYPI_PUBLISH` to `true`. After that every release is also
76
+ published to PyPI.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 sush
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.