axosim 0.1.0__py3-none-any.whl

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 (53) hide show
  1. axosim/__init__.py +222 -0
  2. axosim/_fused_lite.py +221 -0
  3. axosim/activity.py +451 -0
  4. axosim/adaptation.py +169 -0
  5. axosim/architecture_frontier.py +192 -0
  6. axosim/autoresearch.py +2119 -0
  7. axosim/axobench_iteration.py +417 -0
  8. axosim/axomamba.py +192 -0
  9. axosim/block_forecast.py +847 -0
  10. axosim/checkpoint.py +430 -0
  11. axosim/cli.py +660 -0
  12. axosim/connected_population.py +949 -0
  13. axosim/connectome.py +3011 -0
  14. axosim/connectors.py +363 -0
  15. axosim/data.py +750 -0
  16. axosim/deployment.py +414 -0
  17. axosim/diagnostics.py +505 -0
  18. axosim/evaluate.py +194 -0
  19. axosim/experiments.py +235 -0
  20. axosim/history_scan.py +167 -0
  21. axosim/inference_benchmark.py +229 -0
  22. axosim/interfaces.py +470 -0
  23. axosim/kaggle_download.py +258 -0
  24. axosim/mamba_official.py +1973 -0
  25. axosim/mamba_pytorch.py +233 -0
  26. axosim/metrics.py +38 -0
  27. axosim/model.py +81 -0
  28. axosim/model_family.py +130 -0
  29. axosim/neuronio_raw.py +240 -0
  30. axosim/official/__init__.py +48 -0
  31. axosim/official/constants.py +12 -0
  32. axosim/official/expressive_leaky_memory_neuron.py +262 -0
  33. axosim/official/modeling_utils.py +74 -0
  34. axosim/official/training.py +37 -0
  35. axosim/p4_surrogate.py +761 -0
  36. axosim/population.py +2270 -0
  37. axosim/population_tuning.py +263 -0
  38. axosim/rnn_variants.py +321 -0
  39. axosim/setup_workflow.py +188 -0
  40. axosim/simulation_contract.py +437 -0
  41. axosim/structured.py +414 -0
  42. axosim/support_surrogate.py +535 -0
  43. axosim/synapse.py +135 -0
  44. axosim/temporal_core.py +1234 -0
  45. axosim/train.py +762 -0
  46. axosim-0.1.0.dist-info/METADATA +515 -0
  47. axosim-0.1.0.dist-info/RECORD +53 -0
  48. axosim-0.1.0.dist-info/WHEEL +5 -0
  49. axosim-0.1.0.dist-info/entry_points.txt +4 -0
  50. axosim-0.1.0.dist-info/licenses/LICENSE +202 -0
  51. axosim-0.1.0.dist-info/licenses/LICENSES/ELM-MIT.txt +21 -0
  52. axosim-0.1.0.dist-info/licenses/NOTICE +16 -0
  53. axosim-0.1.0.dist-info/top_level.txt +1 -0
axosim/__init__.py ADDED
@@ -0,0 +1,222 @@
1
+ """NeuronIO training and evaluation utilities for ELM / Branch-ELM experiments.
2
+
3
+ Keep the package import lightweight so data utilities can run in environments
4
+ that intentionally omit PyTorch.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Any
10
+
11
+ __all__ = [
12
+ "AXOSIM_POPULATION_PROFILE",
13
+ "MILLION_NEURON_REALTIME_CONTRACT",
14
+ "AxoMamba",
15
+ "AxoMambaConfig",
16
+ "AxoSimGRU",
17
+ "AxoSimLite",
18
+ "AxoSimMamba",
19
+ "AxoSimModelProfile",
20
+ "AxoSimPopulation",
21
+ "CudaGraphAdaptationStep",
22
+ "HomeostaticThresholdController",
23
+ "HistoryScanBackend",
24
+ "HistoryScanResult",
25
+ "AXOSIM_MODEL_PROFILES",
26
+ "BranchELM",
27
+ "BranchELMConfig",
28
+ "LargePopulationSimulationContract",
29
+ "MixedQuantizedNeuronBehaviorBank",
30
+ "PopulationInferenceProfile",
31
+ "ProceduralMorphologyConnectomeRouter",
32
+ "QuantizedSynapticEfficacyBank",
33
+ "compact_active_sources",
34
+ "dequantize_synaptic_efficacies",
35
+ "dequantize_mixed_neuron_behavior_parameters",
36
+ "quantize_synaptic_efficacies",
37
+ "quantize_mixed_neuron_behavior_parameters",
38
+ "create_axosim_profile",
39
+ "ConnectedPopulation",
40
+ "ExplicitConnectome",
41
+ "InputEvents",
42
+ "PopulationFrame",
43
+ "ProceduralConnectome",
44
+ "create_population",
45
+ "scan_histories",
46
+ "all_to_all",
47
+ "concatenate",
48
+ "fixed_indegree",
49
+ "fixed_probability",
50
+ "from_list",
51
+ "one_to_one",
52
+ ]
53
+
54
+
55
+ def __getattr__(name: str) -> Any:
56
+ if name in {
57
+ "all_to_all", "concatenate", "connectors", "fixed_indegree",
58
+ "fixed_probability", "from_list", "one_to_one",
59
+ }:
60
+ import importlib
61
+
62
+ connectors = importlib.import_module("axosim.connectors")
63
+ return connectors if name == "connectors" else getattr(connectors, name)
64
+ if name in {"HistoryScanBackend", "HistoryScanResult", "scan_histories"}:
65
+ from axosim.history_scan import HistoryScanBackend, HistoryScanResult, scan_histories
66
+
67
+ return {
68
+ "HistoryScanBackend": HistoryScanBackend,
69
+ "HistoryScanResult": HistoryScanResult,
70
+ "scan_histories": scan_histories,
71
+ }[name]
72
+ if name in {
73
+ "ConnectedPopulation", "ExplicitConnectome", "InputEvents",
74
+ "PopulationFrame", "ProceduralConnectome", "create_population",
75
+ }:
76
+ from axosim.connected_population import (
77
+ ConnectedPopulation, ExplicitConnectome, InputEvents,
78
+ PopulationFrame, ProceduralConnectome, create_population,
79
+ )
80
+
81
+ return {
82
+ "ConnectedPopulation": ConnectedPopulation,
83
+ "ExplicitConnectome": ExplicitConnectome,
84
+ "InputEvents": InputEvents,
85
+ "PopulationFrame": PopulationFrame,
86
+ "ProceduralConnectome": ProceduralConnectome,
87
+ "create_population": create_population,
88
+ }[name]
89
+ if name == "CudaGraphAdaptationStep":
90
+ from axosim.adaptation import CudaGraphAdaptationStep
91
+
92
+ return CudaGraphAdaptationStep
93
+ if name == "HomeostaticThresholdController":
94
+ from axosim.activity import HomeostaticThresholdController
95
+
96
+ return HomeostaticThresholdController
97
+ if name in {
98
+ "AxoSimGRU",
99
+ "AxoSimLite",
100
+ "AxoSimMamba",
101
+ "AxoSimPopulation",
102
+ }:
103
+ from axosim.interfaces import (
104
+ AxoSimGRU,
105
+ AxoSimLite,
106
+ AxoSimMamba,
107
+ AxoSimPopulation,
108
+ )
109
+
110
+ return {
111
+ "AxoSimGRU": AxoSimGRU,
112
+ "AxoSimLite": AxoSimLite,
113
+ "AxoSimMamba": AxoSimMamba,
114
+ "AxoSimPopulation": AxoSimPopulation,
115
+ }[name]
116
+ if name in {"AxoMamba", "AxoMambaConfig"}:
117
+ from axosim.axomamba import AxoMamba, AxoMambaConfig
118
+
119
+ return {"AxoMamba": AxoMamba, "AxoMambaConfig": AxoMambaConfig}[name]
120
+ if name in {
121
+ "AXOSIM_MODEL_PROFILES",
122
+ "AxoSimModelProfile",
123
+ "create_axosim_profile",
124
+ }:
125
+ from axosim.model_family import (
126
+ AXOSIM_MODEL_PROFILES,
127
+ AxoSimModelProfile,
128
+ create_axosim_profile,
129
+ )
130
+
131
+ return {
132
+ "AXOSIM_MODEL_PROFILES": AXOSIM_MODEL_PROFILES,
133
+ "AxoSimModelProfile": AxoSimModelProfile,
134
+ "create_axosim_profile": create_axosim_profile,
135
+ }[name]
136
+ if name in {"BranchELM", "BranchELMConfig"}:
137
+ from axosim.model import BranchELM, BranchELMConfig
138
+
139
+ return {"BranchELM": BranchELM, "BranchELMConfig": BranchELMConfig}[name]
140
+ if name in {
141
+ "AXOSIM_POPULATION_PROFILE",
142
+ "LargePopulationSimulationContract",
143
+ "MILLION_NEURON_REALTIME_CONTRACT",
144
+ "PopulationInferenceProfile",
145
+ }:
146
+ from axosim.simulation_contract import (
147
+ AXOSIM_POPULATION_PROFILE,
148
+ MILLION_NEURON_REALTIME_CONTRACT,
149
+ LargePopulationSimulationContract,
150
+ PopulationInferenceProfile,
151
+ )
152
+
153
+ return {
154
+ "AXOSIM_POPULATION_PROFILE": AXOSIM_POPULATION_PROFILE,
155
+ "LargePopulationSimulationContract": (
156
+ LargePopulationSimulationContract
157
+ ),
158
+ "PopulationInferenceProfile": PopulationInferenceProfile,
159
+ "MILLION_NEURON_REALTIME_CONTRACT": (
160
+ MILLION_NEURON_REALTIME_CONTRACT
161
+ ),
162
+ }[name]
163
+ if name in {
164
+ "QuantizedSynapticEfficacyBank",
165
+ "dequantize_synaptic_efficacies",
166
+ "quantize_synaptic_efficacies",
167
+ }:
168
+ from axosim.synapse import (
169
+ QuantizedSynapticEfficacyBank,
170
+ dequantize_synaptic_efficacies,
171
+ quantize_synaptic_efficacies,
172
+ )
173
+
174
+ return {
175
+ "QuantizedSynapticEfficacyBank": (
176
+ QuantizedSynapticEfficacyBank
177
+ ),
178
+ "dequantize_synaptic_efficacies": (
179
+ dequantize_synaptic_efficacies
180
+ ),
181
+ "quantize_synaptic_efficacies": (
182
+ quantize_synaptic_efficacies
183
+ ),
184
+ }[name]
185
+ if name in {
186
+ "ProceduralMorphologyConnectomeRouter",
187
+ "compact_active_sources",
188
+ }:
189
+ from axosim.connectome import (
190
+ ProceduralMorphologyConnectomeRouter,
191
+ compact_active_sources,
192
+ )
193
+
194
+ return {
195
+ "ProceduralMorphologyConnectomeRouter": (
196
+ ProceduralMorphologyConnectomeRouter
197
+ ),
198
+ "compact_active_sources": compact_active_sources,
199
+ }[name]
200
+ if name in {
201
+ "MixedQuantizedNeuronBehaviorBank",
202
+ "dequantize_mixed_neuron_behavior_parameters",
203
+ "quantize_mixed_neuron_behavior_parameters",
204
+ }:
205
+ from axosim.population import (
206
+ MixedQuantizedNeuronBehaviorBank,
207
+ dequantize_mixed_neuron_behavior_parameters,
208
+ quantize_mixed_neuron_behavior_parameters,
209
+ )
210
+
211
+ return {
212
+ "MixedQuantizedNeuronBehaviorBank": (
213
+ MixedQuantizedNeuronBehaviorBank
214
+ ),
215
+ "dequantize_mixed_neuron_behavior_parameters": (
216
+ dequantize_mixed_neuron_behavior_parameters
217
+ ),
218
+ "quantize_mixed_neuron_behavior_parameters": (
219
+ quantize_mixed_neuron_behavior_parameters
220
+ ),
221
+ }[name]
222
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
axosim/_fused_lite.py ADDED
@@ -0,0 +1,221 @@
1
+ """Installed fused Lite neuron step, extracted from validated iteration 572.
2
+
3
+ This kernel fuses recurrence and decoding only. Connected graph routing and
4
+ native scheduling are supplied by connected_population, not the historical
5
+ specialized million-neuron router. Adaptation values are passed directly with
6
+ unit scales; the facade does not silently quantize caller coefficients.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import torch
12
+ import triton
13
+ import triton.language as tl
14
+
15
+
16
+ @triton.jit
17
+ def _adaptive_support_step_kernel(
18
+ token,
19
+ previous_state,
20
+ adaptation,
21
+ adaptation_scales,
22
+ input_weight,
23
+ recurrent_weight,
24
+ state_bias,
25
+ shared_decay_logit,
26
+ output_weight,
27
+ skip_weight,
28
+ output_bias,
29
+ next_state,
30
+ output,
31
+ population: tl.constexpr,
32
+ token_width: tl.constexpr,
33
+ state_width: tl.constexpr,
34
+ adaptation_width: tl.constexpr,
35
+ outputs: tl.constexpr,
36
+ block_rows: tl.constexpr,
37
+ block_token: tl.constexpr,
38
+ block_state: tl.constexpr,
39
+ block_outputs: tl.constexpr,
40
+ ):
41
+ rows = tl.program_id(0) * block_rows + tl.arange(0, block_rows)
42
+ token_index = tl.arange(0, block_token)
43
+ state_index = tl.arange(0, block_state)
44
+ output_index = tl.arange(0, block_outputs)
45
+ row_mask = rows < population
46
+ token_mask = token_index < token_width
47
+ state_mask = state_index < state_width
48
+ output_mask = output_index < outputs
49
+ token_matrix_mask = row_mask[:, None] & token_mask[None, :]
50
+ state_matrix_mask = row_mask[:, None] & state_mask[None, :]
51
+ adaptation_base = rows[:, None] * adaptation_width
52
+
53
+ raw_token = tl.load(
54
+ token + rows[:, None] * token_width + token_index[None, :],
55
+ mask=token_matrix_mask,
56
+ other=0.0,
57
+ ).to(tl.float32)
58
+ token_offset = tl.load(
59
+ adaptation + adaptation_base + token_index[None, :],
60
+ mask=token_matrix_mask,
61
+ other=0,
62
+ ).to(tl.float32) * tl.load(adaptation_scales)
63
+ token_gain = tl.load(
64
+ adaptation + adaptation_base + token_width + token_index[None, :],
65
+ mask=token_matrix_mask,
66
+ other=0,
67
+ ).to(tl.float32) * tl.load(adaptation_scales + 1)
68
+ adapted_token = ((raw_token + token_offset) * (1.0 + token_gain)).to(tl.float16)
69
+
70
+ previous = tl.load(
71
+ previous_state + rows[:, None] * state_width + state_index[None, :],
72
+ mask=state_matrix_mask,
73
+ other=0.0,
74
+ ).to(tl.float32)
75
+ input_matrix = tl.load(
76
+ input_weight + state_index[:, None] * token_width + token_index[None, :],
77
+ mask=state_mask[:, None] & token_mask[None, :],
78
+ other=0.0,
79
+ ).to(tl.float16)
80
+ recurrent_matrix = tl.load(
81
+ recurrent_weight + state_index[:, None] * state_width + state_index[None, :],
82
+ mask=state_mask[:, None] & state_mask[None, :],
83
+ other=0.0,
84
+ ).to(tl.float16)
85
+ forcing = tl.dot(adapted_token, tl.trans(input_matrix))
86
+ recurrence = tl.dot(
87
+ previous.to(tl.float16),
88
+ tl.trans(recurrent_matrix),
89
+ )
90
+ state_adaptation_base = 2 * token_width
91
+ decay_delta = tl.load(
92
+ adaptation + adaptation_base + state_adaptation_base + state_index[None, :],
93
+ mask=state_matrix_mask,
94
+ other=0,
95
+ ).to(tl.float32) * tl.load(adaptation_scales + 2)
96
+ state_gain = tl.load(
97
+ adaptation
98
+ + adaptation_base
99
+ + state_adaptation_base
100
+ + state_width
101
+ + state_index[None, :],
102
+ mask=state_matrix_mask,
103
+ other=0,
104
+ ).to(tl.float32) * tl.load(adaptation_scales + 3)
105
+ state_offset = tl.load(
106
+ adaptation
107
+ + adaptation_base
108
+ + state_adaptation_base
109
+ + 2 * state_width
110
+ + state_index[None, :],
111
+ mask=state_matrix_mask,
112
+ other=0,
113
+ ).to(tl.float32) * tl.load(adaptation_scales + 4)
114
+ proposal_argument = (
115
+ forcing
116
+ + recurrence
117
+ + tl.load(
118
+ state_bias + state_index,
119
+ mask=state_mask,
120
+ other=0.0,
121
+ )[None, :]
122
+ + state_offset
123
+ )
124
+ proposal = 2.0 * tl.sigmoid(2.0 * proposal_argument) - 1.0
125
+ decay = tl.sigmoid(
126
+ tl.load(
127
+ shared_decay_logit + state_index,
128
+ mask=state_mask,
129
+ other=0.0,
130
+ )[None, :]
131
+ + decay_delta
132
+ )
133
+ state = decay * previous + (1.0 - decay) * proposal * (1.0 + state_gain)
134
+ tl.store(
135
+ next_state + rows[:, None] * state_width + state_index[None, :],
136
+ state,
137
+ mask=state_matrix_mask,
138
+ )
139
+
140
+ state_to_output = tl.load(
141
+ output_weight + output_index[:, None] * state_width + state_index[None, :],
142
+ mask=output_mask[:, None] & state_mask[None, :],
143
+ other=0.0,
144
+ ).to(tl.float16)
145
+ token_to_output = tl.load(
146
+ skip_weight + output_index[:, None] * token_width + token_index[None, :],
147
+ mask=output_mask[:, None] & token_mask[None, :],
148
+ other=0.0,
149
+ ).to(tl.float16)
150
+ decoded = tl.dot(
151
+ state.to(tl.float16),
152
+ tl.trans(state_to_output),
153
+ )
154
+ decoded += tl.dot(
155
+ adapted_token,
156
+ tl.trans(token_to_output),
157
+ )
158
+ decoded += tl.load(
159
+ output_bias + output_index,
160
+ mask=output_mask,
161
+ other=0.0,
162
+ )[None, :]
163
+ output_adaptation_base = state_adaptation_base + 3 * state_width
164
+ output_gain = tl.load(
165
+ adaptation + adaptation_base + output_adaptation_base + output_index[None, :],
166
+ mask=row_mask[:, None] & output_mask[None, :],
167
+ other=0,
168
+ ).to(tl.float32) * tl.load(adaptation_scales + 5)
169
+ output_offset = tl.load(
170
+ adaptation
171
+ + adaptation_base
172
+ + output_adaptation_base
173
+ + outputs
174
+ + output_index[None, :],
175
+ mask=row_mask[:, None] & output_mask[None, :],
176
+ other=0,
177
+ ).to(tl.float32) * tl.load(adaptation_scales + 6)
178
+ decoded = decoded * (1.0 + output_gain) + output_offset
179
+ tl.store(
180
+ output + rows[:, None] * outputs + output_index[None, :],
181
+ decoded,
182
+ mask=row_mask[:, None] & output_mask[None, :],
183
+ )
184
+
185
+
186
+ def fused_lite_step(model, token, state, coefficients):
187
+ """Return ``(next_state, forecasts)`` for contiguous FP16 CUDA tensors.
188
+
189
+ ``forecasts`` has shape ``(N, 4, 2)`` in native model coordinates.
190
+ Coefficients are direct packed runtime values, not quantized integer codes.
191
+ """
192
+ n, token_width = token.shape
193
+ state_width = state.shape[1]
194
+ next_state = torch.empty_like(state)
195
+ output = torch.empty((n, 8), dtype=token.dtype, device=token.device)
196
+ scales = torch.ones(7, dtype=torch.float32, device=token.device)
197
+ _adaptive_support_step_kernel[(triton.cdiv(n, 32),)](
198
+ token,
199
+ state,
200
+ coefficients,
201
+ scales,
202
+ model.support_input.weight,
203
+ model.support_recurrent.weight,
204
+ model.state_bias,
205
+ model.shared_decay_logit,
206
+ model.output_head.weight,
207
+ model.skip_head.weight,
208
+ model.output_head.bias,
209
+ next_state,
210
+ output,
211
+ population=n,
212
+ token_width=token_width,
213
+ state_width=state_width,
214
+ adaptation_width=model.cache_width,
215
+ outputs=8,
216
+ block_rows=32,
217
+ block_token=max(16, triton.next_power_of_2(token_width)),
218
+ block_state=max(16, triton.next_power_of_2(state_width)),
219
+ block_outputs=16,
220
+ )
221
+ return next_state, output.reshape(n, 4, 2)