tnfr 3.0.3__py3-none-any.whl → 8.5.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.
Potentially problematic release.
This version of tnfr might be problematic. Click here for more details.
- tnfr/__init__.py +375 -56
- tnfr/__init__.pyi +33 -0
- tnfr/_compat.py +10 -0
- tnfr/_generated_version.py +34 -0
- tnfr/_version.py +49 -0
- tnfr/_version.pyi +7 -0
- tnfr/alias.py +723 -0
- tnfr/alias.pyi +108 -0
- tnfr/backends/__init__.py +354 -0
- tnfr/backends/jax_backend.py +173 -0
- tnfr/backends/numpy_backend.py +238 -0
- tnfr/backends/optimized_numpy.py +420 -0
- tnfr/backends/torch_backend.py +408 -0
- tnfr/cache.py +171 -0
- tnfr/cache.pyi +13 -0
- tnfr/cli/__init__.py +110 -0
- tnfr/cli/__init__.pyi +26 -0
- tnfr/cli/arguments.py +489 -0
- tnfr/cli/arguments.pyi +29 -0
- tnfr/cli/execution.py +914 -0
- tnfr/cli/execution.pyi +70 -0
- tnfr/cli/interactive_validator.py +614 -0
- tnfr/cli/utils.py +51 -0
- tnfr/cli/utils.pyi +7 -0
- tnfr/cli/validate.py +236 -0
- tnfr/compat/__init__.py +85 -0
- tnfr/compat/dataclass.py +136 -0
- tnfr/compat/jsonschema_stub.py +61 -0
- tnfr/compat/matplotlib_stub.py +73 -0
- tnfr/compat/numpy_stub.py +155 -0
- tnfr/config/__init__.py +224 -0
- tnfr/config/__init__.pyi +10 -0
- tnfr/config/constants.py +104 -0
- tnfr/config/constants.pyi +12 -0
- tnfr/config/defaults.py +54 -0
- tnfr/config/defaults_core.py +212 -0
- tnfr/config/defaults_init.py +33 -0
- tnfr/config/defaults_metric.py +104 -0
- tnfr/config/feature_flags.py +81 -0
- tnfr/config/feature_flags.pyi +16 -0
- tnfr/config/glyph_constants.py +31 -0
- tnfr/config/init.py +77 -0
- tnfr/config/init.pyi +8 -0
- tnfr/config/operator_names.py +254 -0
- tnfr/config/operator_names.pyi +36 -0
- tnfr/config/physics_derivation.py +354 -0
- tnfr/config/presets.py +83 -0
- tnfr/config/presets.pyi +7 -0
- tnfr/config/security.py +927 -0
- tnfr/config/thresholds.py +114 -0
- tnfr/config/tnfr_config.py +498 -0
- tnfr/constants/__init__.py +92 -0
- tnfr/constants/__init__.pyi +92 -0
- tnfr/constants/aliases.py +33 -0
- tnfr/constants/aliases.pyi +27 -0
- tnfr/constants/init.py +33 -0
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +104 -0
- tnfr/constants/metric.pyi +19 -0
- tnfr/core/__init__.py +33 -0
- tnfr/core/container.py +226 -0
- tnfr/core/default_implementations.py +329 -0
- tnfr/core/interfaces.py +279 -0
- tnfr/dynamics/__init__.py +238 -0
- tnfr/dynamics/__init__.pyi +83 -0
- tnfr/dynamics/adaptation.py +267 -0
- tnfr/dynamics/adaptation.pyi +7 -0
- tnfr/dynamics/adaptive_sequences.py +189 -0
- tnfr/dynamics/adaptive_sequences.pyi +14 -0
- tnfr/dynamics/aliases.py +23 -0
- tnfr/dynamics/aliases.pyi +19 -0
- tnfr/dynamics/bifurcation.py +232 -0
- tnfr/dynamics/canonical.py +229 -0
- tnfr/dynamics/canonical.pyi +48 -0
- tnfr/dynamics/coordination.py +385 -0
- tnfr/dynamics/coordination.pyi +25 -0
- tnfr/dynamics/dnfr.py +3034 -0
- tnfr/dynamics/dnfr.pyi +26 -0
- tnfr/dynamics/dynamic_limits.py +225 -0
- tnfr/dynamics/feedback.py +252 -0
- tnfr/dynamics/feedback.pyi +24 -0
- tnfr/dynamics/fused_dnfr.py +454 -0
- tnfr/dynamics/homeostasis.py +157 -0
- tnfr/dynamics/homeostasis.pyi +14 -0
- tnfr/dynamics/integrators.py +661 -0
- tnfr/dynamics/integrators.pyi +36 -0
- tnfr/dynamics/learning.py +310 -0
- tnfr/dynamics/learning.pyi +33 -0
- tnfr/dynamics/metabolism.py +254 -0
- tnfr/dynamics/nbody.py +796 -0
- tnfr/dynamics/nbody_tnfr.py +783 -0
- tnfr/dynamics/propagation.py +326 -0
- tnfr/dynamics/runtime.py +908 -0
- tnfr/dynamics/runtime.pyi +77 -0
- tnfr/dynamics/sampling.py +36 -0
- tnfr/dynamics/sampling.pyi +7 -0
- tnfr/dynamics/selectors.py +711 -0
- tnfr/dynamics/selectors.pyi +85 -0
- tnfr/dynamics/structural_clip.py +207 -0
- tnfr/errors/__init__.py +37 -0
- tnfr/errors/contextual.py +492 -0
- tnfr/execution.py +223 -0
- tnfr/execution.pyi +45 -0
- tnfr/extensions/__init__.py +205 -0
- tnfr/extensions/__init__.pyi +18 -0
- tnfr/extensions/base.py +173 -0
- tnfr/extensions/base.pyi +35 -0
- tnfr/extensions/business/__init__.py +71 -0
- tnfr/extensions/business/__init__.pyi +11 -0
- tnfr/extensions/business/cookbook.py +88 -0
- tnfr/extensions/business/cookbook.pyi +8 -0
- tnfr/extensions/business/health_analyzers.py +202 -0
- tnfr/extensions/business/health_analyzers.pyi +9 -0
- tnfr/extensions/business/patterns.py +183 -0
- tnfr/extensions/business/patterns.pyi +8 -0
- tnfr/extensions/medical/__init__.py +73 -0
- tnfr/extensions/medical/__init__.pyi +11 -0
- tnfr/extensions/medical/cookbook.py +88 -0
- tnfr/extensions/medical/cookbook.pyi +8 -0
- tnfr/extensions/medical/health_analyzers.py +181 -0
- tnfr/extensions/medical/health_analyzers.pyi +9 -0
- tnfr/extensions/medical/patterns.py +163 -0
- tnfr/extensions/medical/patterns.pyi +8 -0
- tnfr/flatten.py +262 -0
- tnfr/flatten.pyi +21 -0
- tnfr/gamma.py +354 -0
- tnfr/gamma.pyi +36 -0
- tnfr/glyph_history.py +377 -0
- tnfr/glyph_history.pyi +35 -0
- tnfr/glyph_runtime.py +19 -0
- tnfr/glyph_runtime.pyi +8 -0
- tnfr/immutable.py +218 -0
- tnfr/immutable.pyi +36 -0
- tnfr/initialization.py +203 -0
- tnfr/initialization.pyi +65 -0
- tnfr/io.py +10 -0
- tnfr/io.pyi +13 -0
- tnfr/locking.py +37 -0
- tnfr/locking.pyi +7 -0
- tnfr/mathematics/__init__.py +79 -0
- tnfr/mathematics/backend.py +453 -0
- tnfr/mathematics/backend.pyi +99 -0
- tnfr/mathematics/dynamics.py +408 -0
- tnfr/mathematics/dynamics.pyi +90 -0
- tnfr/mathematics/epi.py +391 -0
- tnfr/mathematics/epi.pyi +65 -0
- tnfr/mathematics/generators.py +242 -0
- tnfr/mathematics/generators.pyi +29 -0
- tnfr/mathematics/metrics.py +119 -0
- tnfr/mathematics/metrics.pyi +16 -0
- tnfr/mathematics/operators.py +239 -0
- tnfr/mathematics/operators.pyi +59 -0
- tnfr/mathematics/operators_factory.py +124 -0
- tnfr/mathematics/operators_factory.pyi +11 -0
- tnfr/mathematics/projection.py +87 -0
- tnfr/mathematics/projection.pyi +33 -0
- tnfr/mathematics/runtime.py +182 -0
- tnfr/mathematics/runtime.pyi +64 -0
- tnfr/mathematics/spaces.py +256 -0
- tnfr/mathematics/spaces.pyi +83 -0
- tnfr/mathematics/transforms.py +305 -0
- tnfr/mathematics/transforms.pyi +62 -0
- tnfr/metrics/__init__.py +79 -0
- tnfr/metrics/__init__.pyi +20 -0
- tnfr/metrics/buffer_cache.py +163 -0
- tnfr/metrics/buffer_cache.pyi +24 -0
- tnfr/metrics/cache_utils.py +214 -0
- tnfr/metrics/coherence.py +2009 -0
- tnfr/metrics/coherence.pyi +129 -0
- tnfr/metrics/common.py +158 -0
- tnfr/metrics/common.pyi +35 -0
- tnfr/metrics/core.py +316 -0
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +833 -0
- tnfr/metrics/diagnosis.pyi +86 -0
- tnfr/metrics/emergence.py +245 -0
- tnfr/metrics/export.py +179 -0
- tnfr/metrics/export.pyi +7 -0
- tnfr/metrics/glyph_timing.py +379 -0
- tnfr/metrics/glyph_timing.pyi +81 -0
- tnfr/metrics/learning_metrics.py +280 -0
- tnfr/metrics/learning_metrics.pyi +21 -0
- tnfr/metrics/phase_coherence.py +351 -0
- tnfr/metrics/phase_compatibility.py +349 -0
- tnfr/metrics/reporting.py +183 -0
- tnfr/metrics/reporting.pyi +25 -0
- tnfr/metrics/sense_index.py +1203 -0
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +373 -0
- tnfr/metrics/trig.pyi +13 -0
- tnfr/metrics/trig_cache.py +233 -0
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/multiscale/__init__.py +32 -0
- tnfr/multiscale/hierarchical.py +517 -0
- tnfr/node.py +763 -0
- tnfr/node.pyi +139 -0
- tnfr/observers.py +255 -130
- tnfr/observers.pyi +31 -0
- tnfr/ontosim.py +144 -137
- tnfr/ontosim.pyi +28 -0
- tnfr/operators/__init__.py +1672 -0
- tnfr/operators/__init__.pyi +31 -0
- tnfr/operators/algebra.py +277 -0
- tnfr/operators/canonical_patterns.py +420 -0
- tnfr/operators/cascade.py +267 -0
- tnfr/operators/cycle_detection.py +358 -0
- tnfr/operators/definitions.py +4108 -0
- tnfr/operators/definitions.pyi +78 -0
- tnfr/operators/grammar.py +1164 -0
- tnfr/operators/grammar.pyi +140 -0
- tnfr/operators/hamiltonian.py +710 -0
- tnfr/operators/health_analyzer.py +809 -0
- tnfr/operators/jitter.py +272 -0
- tnfr/operators/jitter.pyi +11 -0
- tnfr/operators/lifecycle.py +314 -0
- tnfr/operators/metabolism.py +618 -0
- tnfr/operators/metrics.py +2138 -0
- tnfr/operators/network_analysis/__init__.py +27 -0
- tnfr/operators/network_analysis/source_detection.py +186 -0
- tnfr/operators/nodal_equation.py +395 -0
- tnfr/operators/pattern_detection.py +660 -0
- tnfr/operators/patterns.py +669 -0
- tnfr/operators/postconditions/__init__.py +38 -0
- tnfr/operators/postconditions/mutation.py +236 -0
- tnfr/operators/preconditions/__init__.py +1226 -0
- tnfr/operators/preconditions/coherence.py +305 -0
- tnfr/operators/preconditions/dissonance.py +236 -0
- tnfr/operators/preconditions/emission.py +128 -0
- tnfr/operators/preconditions/mutation.py +580 -0
- tnfr/operators/preconditions/reception.py +125 -0
- tnfr/operators/preconditions/resonance.py +364 -0
- tnfr/operators/registry.py +74 -0
- tnfr/operators/registry.pyi +9 -0
- tnfr/operators/remesh.py +1809 -0
- tnfr/operators/remesh.pyi +26 -0
- tnfr/operators/structural_units.py +268 -0
- tnfr/operators/unified_grammar.py +105 -0
- tnfr/parallel/__init__.py +54 -0
- tnfr/parallel/auto_scaler.py +234 -0
- tnfr/parallel/distributed.py +384 -0
- tnfr/parallel/engine.py +238 -0
- tnfr/parallel/gpu_engine.py +420 -0
- tnfr/parallel/monitoring.py +248 -0
- tnfr/parallel/partitioner.py +459 -0
- tnfr/py.typed +0 -0
- tnfr/recipes/__init__.py +22 -0
- tnfr/recipes/cookbook.py +743 -0
- tnfr/rng.py +178 -0
- tnfr/rng.pyi +26 -0
- tnfr/schemas/__init__.py +8 -0
- tnfr/schemas/grammar.json +94 -0
- tnfr/sdk/__init__.py +107 -0
- tnfr/sdk/__init__.pyi +19 -0
- tnfr/sdk/adaptive_system.py +173 -0
- tnfr/sdk/adaptive_system.pyi +21 -0
- tnfr/sdk/builders.py +370 -0
- tnfr/sdk/builders.pyi +51 -0
- tnfr/sdk/fluent.py +1121 -0
- tnfr/sdk/fluent.pyi +74 -0
- tnfr/sdk/templates.py +342 -0
- tnfr/sdk/templates.pyi +41 -0
- tnfr/sdk/utils.py +341 -0
- tnfr/secure_config.py +46 -0
- tnfr/security/__init__.py +70 -0
- tnfr/security/database.py +514 -0
- tnfr/security/subprocess.py +503 -0
- tnfr/security/validation.py +290 -0
- tnfr/selector.py +247 -0
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +378 -0
- tnfr/sense.pyi +23 -0
- tnfr/services/__init__.py +17 -0
- tnfr/services/orchestrator.py +325 -0
- tnfr/sparse/__init__.py +39 -0
- tnfr/sparse/representations.py +492 -0
- tnfr/structural.py +705 -0
- tnfr/structural.pyi +83 -0
- tnfr/telemetry/__init__.py +35 -0
- tnfr/telemetry/cache_metrics.py +226 -0
- tnfr/telemetry/cache_metrics.pyi +64 -0
- tnfr/telemetry/nu_f.py +422 -0
- tnfr/telemetry/nu_f.pyi +108 -0
- tnfr/telemetry/verbosity.py +36 -0
- tnfr/telemetry/verbosity.pyi +15 -0
- tnfr/tokens.py +58 -0
- tnfr/tokens.pyi +36 -0
- tnfr/tools/__init__.py +20 -0
- tnfr/tools/domain_templates.py +478 -0
- tnfr/tools/sequence_generator.py +846 -0
- tnfr/topology/__init__.py +13 -0
- tnfr/topology/asymmetry.py +151 -0
- tnfr/trace.py +543 -0
- tnfr/trace.pyi +42 -0
- tnfr/tutorials/__init__.py +38 -0
- tnfr/tutorials/autonomous_evolution.py +285 -0
- tnfr/tutorials/interactive.py +1576 -0
- tnfr/tutorials/structural_metabolism.py +238 -0
- tnfr/types.py +775 -0
- tnfr/types.pyi +357 -0
- tnfr/units.py +68 -0
- tnfr/units.pyi +13 -0
- tnfr/utils/__init__.py +282 -0
- tnfr/utils/__init__.pyi +215 -0
- tnfr/utils/cache.py +4223 -0
- tnfr/utils/cache.pyi +470 -0
- tnfr/utils/callbacks.py +375 -0
- tnfr/utils/callbacks.pyi +49 -0
- tnfr/utils/chunks.py +108 -0
- tnfr/utils/chunks.pyi +22 -0
- tnfr/utils/data.py +428 -0
- tnfr/utils/data.pyi +74 -0
- tnfr/utils/graph.py +85 -0
- tnfr/utils/graph.pyi +10 -0
- tnfr/utils/init.py +821 -0
- tnfr/utils/init.pyi +80 -0
- tnfr/utils/io.py +559 -0
- tnfr/utils/io.pyi +66 -0
- tnfr/utils/numeric.py +114 -0
- tnfr/utils/numeric.pyi +21 -0
- tnfr/validation/__init__.py +257 -0
- tnfr/validation/__init__.pyi +85 -0
- tnfr/validation/compatibility.py +460 -0
- tnfr/validation/compatibility.pyi +6 -0
- tnfr/validation/config.py +73 -0
- tnfr/validation/graph.py +139 -0
- tnfr/validation/graph.pyi +18 -0
- tnfr/validation/input_validation.py +755 -0
- tnfr/validation/invariants.py +712 -0
- tnfr/validation/rules.py +253 -0
- tnfr/validation/rules.pyi +44 -0
- tnfr/validation/runtime.py +279 -0
- tnfr/validation/runtime.pyi +28 -0
- tnfr/validation/sequence_validator.py +162 -0
- tnfr/validation/soft_filters.py +170 -0
- tnfr/validation/soft_filters.pyi +32 -0
- tnfr/validation/spectral.py +164 -0
- tnfr/validation/spectral.pyi +42 -0
- tnfr/validation/validator.py +1266 -0
- tnfr/validation/window.py +39 -0
- tnfr/validation/window.pyi +1 -0
- tnfr/visualization/__init__.py +98 -0
- tnfr/visualization/cascade_viz.py +256 -0
- tnfr/visualization/hierarchy.py +284 -0
- tnfr/visualization/sequence_plotter.py +784 -0
- tnfr/viz/__init__.py +60 -0
- tnfr/viz/matplotlib.py +278 -0
- tnfr/viz/matplotlib.pyi +35 -0
- tnfr-8.5.0.dist-info/METADATA +573 -0
- tnfr-8.5.0.dist-info/RECORD +353 -0
- tnfr-8.5.0.dist-info/entry_points.txt +3 -0
- tnfr-3.0.3.dist-info/licenses/LICENSE.txt → tnfr-8.5.0.dist-info/licenses/LICENSE.md +1 -1
- tnfr/constants.py +0 -183
- tnfr/dynamics.py +0 -543
- tnfr/helpers.py +0 -198
- tnfr/main.py +0 -37
- tnfr/operators.py +0 -296
- tnfr-3.0.3.dist-info/METADATA +0 -35
- tnfr-3.0.3.dist-info/RECORD +0 -13
- {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
- {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"""PyTorch-based GPU-accelerated backend for TNFR computations (Experimental).
|
|
2
|
+
|
|
3
|
+
This module provides a PyTorch implementation of TNFR computational kernels
|
|
4
|
+
with support for:
|
|
5
|
+
|
|
6
|
+
- GPU acceleration via CUDA/ROCm
|
|
7
|
+
- Automatic differentiation with autograd
|
|
8
|
+
- Optimized tensor operations
|
|
9
|
+
- Mixed precision training support
|
|
10
|
+
|
|
11
|
+
**Status**: Experimental - API may change in future releases.
|
|
12
|
+
|
|
13
|
+
The Torch backend currently delegates to the NumPy implementation but provides
|
|
14
|
+
infrastructure for future GPU-optimized kernels.
|
|
15
|
+
|
|
16
|
+
Examples
|
|
17
|
+
--------
|
|
18
|
+
>>> from tnfr.backends import get_backend
|
|
19
|
+
>>> backend = get_backend("torch") # doctest: +SKIP
|
|
20
|
+
>>> backend.supports_gpu # doctest: +SKIP
|
|
21
|
+
True
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
from typing import Any, MutableMapping
|
|
27
|
+
|
|
28
|
+
from . import TNFRBackend
|
|
29
|
+
from ..types import TNFRGraph
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TorchBackend(TNFRBackend):
|
|
33
|
+
"""PyTorch GPU-accelerated implementation of TNFR kernels (Experimental).
|
|
34
|
+
|
|
35
|
+
This backend provides a foundation for GPU-accelerated TNFR computations
|
|
36
|
+
using PyTorch. Current implementation delegates to NumPy backend while
|
|
37
|
+
maintaining interface compatibility for future GPU implementations.
|
|
38
|
+
|
|
39
|
+
Future optimizations planned:
|
|
40
|
+
- GPU-accelerated ΔNFR computation using torch tensors
|
|
41
|
+
- Sparse tensor operations for large-scale graphs
|
|
42
|
+
- Mixed precision support (FP16/BF16) for memory efficiency
|
|
43
|
+
- Automatic device placement (CPU/CUDA/ROCm)
|
|
44
|
+
- Integration with PyTorch Geometric for graph operations
|
|
45
|
+
|
|
46
|
+
Attributes
|
|
47
|
+
----------
|
|
48
|
+
name : str
|
|
49
|
+
Returns "torch"
|
|
50
|
+
supports_gpu : bool
|
|
51
|
+
True (PyTorch supports GPU acceleration)
|
|
52
|
+
supports_jit : bool
|
|
53
|
+
False (TorchScript not yet integrated)
|
|
54
|
+
|
|
55
|
+
Notes
|
|
56
|
+
-----
|
|
57
|
+
Requires PyTorch to be installed: `pip install torch`
|
|
58
|
+
|
|
59
|
+
For GPU support, install PyTorch with CUDA:
|
|
60
|
+
`pip install torch --index-url https://download.pytorch.org/whl/cu118`
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def __init__(self) -> None:
|
|
64
|
+
"""Initialize PyTorch backend."""
|
|
65
|
+
try:
|
|
66
|
+
import torch
|
|
67
|
+
|
|
68
|
+
self._torch = torch
|
|
69
|
+
self._device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
70
|
+
except ImportError as exc:
|
|
71
|
+
raise RuntimeError(
|
|
72
|
+
"PyTorch backend requires torch to be installed. "
|
|
73
|
+
"Install with: pip install torch"
|
|
74
|
+
) from exc
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def name(self) -> str:
|
|
78
|
+
"""Return the backend identifier."""
|
|
79
|
+
return "torch"
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def supports_gpu(self) -> bool:
|
|
83
|
+
"""PyTorch supports GPU acceleration."""
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def supports_jit(self) -> bool:
|
|
88
|
+
"""TorchScript not yet integrated."""
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def device(self) -> Any:
|
|
93
|
+
"""Return the current PyTorch device (CPU or CUDA)."""
|
|
94
|
+
return self._device
|
|
95
|
+
|
|
96
|
+
def compute_delta_nfr(
|
|
97
|
+
self,
|
|
98
|
+
graph: TNFRGraph,
|
|
99
|
+
*,
|
|
100
|
+
cache_size: int | None = 1,
|
|
101
|
+
n_jobs: int | None = None,
|
|
102
|
+
profile: MutableMapping[str, float] | None = None,
|
|
103
|
+
) -> None:
|
|
104
|
+
"""Compute ΔNFR using PyTorch backend with GPU acceleration.
|
|
105
|
+
|
|
106
|
+
Implements vectorized ΔNFR computation using PyTorch tensors with
|
|
107
|
+
automatic device placement (CPU/CUDA). For large graphs (>1000 nodes),
|
|
108
|
+
uses GPU if available for significant speedup.
|
|
109
|
+
|
|
110
|
+
Parameters
|
|
111
|
+
----------
|
|
112
|
+
graph : TNFRGraph
|
|
113
|
+
NetworkX graph with TNFR node attributes
|
|
114
|
+
cache_size : int or None, optional
|
|
115
|
+
Cache size hint (ignored, PyTorch manages memory)
|
|
116
|
+
n_jobs : int or None, optional
|
|
117
|
+
Ignored (PyTorch uses GPU parallelism)
|
|
118
|
+
profile : MutableMapping[str, float] or None, optional
|
|
119
|
+
Dict to collect timing metrics
|
|
120
|
+
|
|
121
|
+
Notes
|
|
122
|
+
-----
|
|
123
|
+
Automatically moves tensors to GPU if available (backend.device).
|
|
124
|
+
For small graphs (<1000 nodes), may use NumPy backend to avoid
|
|
125
|
+
overhead of tensor conversion and device transfer.
|
|
126
|
+
"""
|
|
127
|
+
import time
|
|
128
|
+
import numpy as np
|
|
129
|
+
|
|
130
|
+
if profile is not None:
|
|
131
|
+
profile["dnfr_backend"] = "torch"
|
|
132
|
+
profile["dnfr_device"] = str(self._device)
|
|
133
|
+
|
|
134
|
+
n_nodes = graph.number_of_nodes()
|
|
135
|
+
n_edges = graph.number_of_edges()
|
|
136
|
+
|
|
137
|
+
# For very small graphs, delegate to NumPy (tensor overhead not worth it)
|
|
138
|
+
if n_nodes < 1000:
|
|
139
|
+
if profile is not None:
|
|
140
|
+
profile["dnfr_path"] = "numpy_fallback"
|
|
141
|
+
from ..dynamics.dnfr import default_compute_delta_nfr
|
|
142
|
+
|
|
143
|
+
default_compute_delta_nfr(
|
|
144
|
+
graph, cache_size=cache_size, n_jobs=n_jobs, profile=profile
|
|
145
|
+
)
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
if profile is not None:
|
|
149
|
+
profile["dnfr_path"] = "torch_gpu"
|
|
150
|
+
t0 = time.perf_counter()
|
|
151
|
+
|
|
152
|
+
# Extract graph data
|
|
153
|
+
node_list = list(graph.nodes())
|
|
154
|
+
node_to_idx = {node: idx for idx, node in enumerate(node_list)}
|
|
155
|
+
|
|
156
|
+
# Get node attributes as numpy arrays first
|
|
157
|
+
phase = np.array(
|
|
158
|
+
[graph.nodes[node].get("phase", 0.0) for node in node_list],
|
|
159
|
+
dtype=np.float32,
|
|
160
|
+
)
|
|
161
|
+
epi = np.array(
|
|
162
|
+
[graph.nodes[node].get("EPI", 0.5) for node in node_list], dtype=np.float32
|
|
163
|
+
)
|
|
164
|
+
vf = np.array(
|
|
165
|
+
[graph.nodes[node].get("nu_f", 1.0) for node in node_list], dtype=np.float32
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# Get edge list
|
|
169
|
+
edges = list(graph.edges())
|
|
170
|
+
if not edges:
|
|
171
|
+
# No edges - all nodes get zero ΔNFR
|
|
172
|
+
for node in node_list:
|
|
173
|
+
graph.nodes[node]["ΔNFR"] = 0.0
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
edge_src = np.array([node_to_idx[src] for src, _ in edges], dtype=np.int64)
|
|
177
|
+
edge_dst = np.array([node_to_idx[dst] for _, dst in edges], dtype=np.int64)
|
|
178
|
+
|
|
179
|
+
# Get weights
|
|
180
|
+
weights = graph.graph.get("DNFR_WEIGHTS", {})
|
|
181
|
+
w_phase = float(weights.get("phase", 0.0))
|
|
182
|
+
w_epi = float(weights.get("epi", 0.0))
|
|
183
|
+
w_vf = float(weights.get("vf", 0.0))
|
|
184
|
+
w_topo = float(weights.get("topo", 0.0))
|
|
185
|
+
|
|
186
|
+
if profile is not None:
|
|
187
|
+
profile["dnfr_data_prep"] = time.perf_counter() - t0
|
|
188
|
+
t0 = time.perf_counter()
|
|
189
|
+
|
|
190
|
+
# Convert to PyTorch tensors and move to device
|
|
191
|
+
phase_t = self._torch.tensor(
|
|
192
|
+
phase, device=self._device, dtype=self._torch.float32
|
|
193
|
+
)
|
|
194
|
+
epi_t = self._torch.tensor(epi, device=self._device, dtype=self._torch.float32)
|
|
195
|
+
vf_t = self._torch.tensor(vf, device=self._device, dtype=self._torch.float32)
|
|
196
|
+
edge_src_t = self._torch.tensor(
|
|
197
|
+
edge_src, device=self._device, dtype=self._torch.int64
|
|
198
|
+
)
|
|
199
|
+
edge_dst_t = self._torch.tensor(
|
|
200
|
+
edge_dst, device=self._device, dtype=self._torch.int64
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
if profile is not None:
|
|
204
|
+
profile["dnfr_to_device"] = time.perf_counter() - t0
|
|
205
|
+
t0 = time.perf_counter()
|
|
206
|
+
|
|
207
|
+
# Compute ΔNFR using PyTorch operations
|
|
208
|
+
delta_nfr_t = self._compute_delta_nfr_torch(
|
|
209
|
+
phase_t,
|
|
210
|
+
epi_t,
|
|
211
|
+
vf_t,
|
|
212
|
+
edge_src_t,
|
|
213
|
+
edge_dst_t,
|
|
214
|
+
w_phase,
|
|
215
|
+
w_epi,
|
|
216
|
+
w_vf,
|
|
217
|
+
w_topo,
|
|
218
|
+
graph.is_directed(),
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
if profile is not None:
|
|
222
|
+
profile["dnfr_compute"] = time.perf_counter() - t0
|
|
223
|
+
t0 = time.perf_counter()
|
|
224
|
+
|
|
225
|
+
# Convert back to numpy and write to graph
|
|
226
|
+
delta_nfr = delta_nfr_t.cpu().numpy()
|
|
227
|
+
|
|
228
|
+
if profile is not None:
|
|
229
|
+
profile["dnfr_from_device"] = time.perf_counter() - t0
|
|
230
|
+
t0 = time.perf_counter()
|
|
231
|
+
|
|
232
|
+
for idx, node in enumerate(node_list):
|
|
233
|
+
graph.nodes[node]["ΔNFR"] = float(delta_nfr[idx])
|
|
234
|
+
|
|
235
|
+
if profile is not None:
|
|
236
|
+
profile["dnfr_write_back"] = time.perf_counter() - t0
|
|
237
|
+
|
|
238
|
+
def _compute_delta_nfr_torch(
|
|
239
|
+
self,
|
|
240
|
+
phase: Any,
|
|
241
|
+
epi: Any,
|
|
242
|
+
vf: Any,
|
|
243
|
+
edge_src: Any,
|
|
244
|
+
edge_dst: Any,
|
|
245
|
+
w_phase: float,
|
|
246
|
+
w_epi: float,
|
|
247
|
+
w_vf: float,
|
|
248
|
+
w_topo: float,
|
|
249
|
+
is_directed: bool,
|
|
250
|
+
) -> Any:
|
|
251
|
+
"""Compute ΔNFR using PyTorch tensor operations.
|
|
252
|
+
|
|
253
|
+
Implements the TNFR canonical formula:
|
|
254
|
+
ΔNFR = νf · (w_phase·g_phase + w_epi·g_epi + w_vf·g_vf + w_topo·g_topo)
|
|
255
|
+
|
|
256
|
+
Where:
|
|
257
|
+
- g_phase = angle_diff(phase_mean, phase) / π (circular mean)
|
|
258
|
+
- g_epi = epi_mean - epi
|
|
259
|
+
- g_vf = vf_mean - vf
|
|
260
|
+
- g_topo = neighbor_count · w_topo
|
|
261
|
+
|
|
262
|
+
Parameters
|
|
263
|
+
----------
|
|
264
|
+
phase, epi, vf : torch.Tensor
|
|
265
|
+
Node attribute tensors on device
|
|
266
|
+
edge_src, edge_dst : torch.Tensor
|
|
267
|
+
Edge index tensors
|
|
268
|
+
w_phase, w_epi, w_vf, w_topo : float
|
|
269
|
+
Component weights
|
|
270
|
+
is_directed : bool
|
|
271
|
+
Whether graph is directed
|
|
272
|
+
|
|
273
|
+
Returns
|
|
274
|
+
-------
|
|
275
|
+
torch.Tensor
|
|
276
|
+
ΔNFR values for all nodes
|
|
277
|
+
"""
|
|
278
|
+
n_nodes = phase.shape[0]
|
|
279
|
+
torch = self._torch
|
|
280
|
+
|
|
281
|
+
# Initialize accumulators
|
|
282
|
+
neighbor_cos_sum = torch.zeros(
|
|
283
|
+
n_nodes, device=self._device, dtype=torch.float32
|
|
284
|
+
)
|
|
285
|
+
neighbor_sin_sum = torch.zeros(
|
|
286
|
+
n_nodes, device=self._device, dtype=torch.float32
|
|
287
|
+
)
|
|
288
|
+
neighbor_epi_sum = torch.zeros(
|
|
289
|
+
n_nodes, device=self._device, dtype=torch.float32
|
|
290
|
+
)
|
|
291
|
+
neighbor_vf_sum = torch.zeros(n_nodes, device=self._device, dtype=torch.float32)
|
|
292
|
+
neighbor_count = torch.zeros(n_nodes, device=self._device, dtype=torch.float32)
|
|
293
|
+
|
|
294
|
+
# Accumulate neighbor statistics
|
|
295
|
+
# For each edge, dst receives contributions from src
|
|
296
|
+
neighbor_cos_sum.scatter_add_(0, edge_dst, torch.cos(phase[edge_src]))
|
|
297
|
+
neighbor_sin_sum.scatter_add_(0, edge_dst, torch.sin(phase[edge_src]))
|
|
298
|
+
neighbor_epi_sum.scatter_add_(0, edge_dst, epi[edge_src])
|
|
299
|
+
neighbor_vf_sum.scatter_add_(0, edge_dst, vf[edge_src])
|
|
300
|
+
neighbor_count.scatter_add_(
|
|
301
|
+
0, edge_dst, torch.ones_like(edge_dst, dtype=torch.float32)
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# For undirected graphs, also accumulate in reverse
|
|
305
|
+
if not is_directed:
|
|
306
|
+
neighbor_cos_sum.scatter_add_(0, edge_src, torch.cos(phase[edge_dst]))
|
|
307
|
+
neighbor_sin_sum.scatter_add_(0, edge_src, torch.sin(phase[edge_dst]))
|
|
308
|
+
neighbor_epi_sum.scatter_add_(0, edge_src, epi[edge_dst])
|
|
309
|
+
neighbor_vf_sum.scatter_add_(0, edge_src, vf[edge_dst])
|
|
310
|
+
neighbor_count.scatter_add_(
|
|
311
|
+
0, edge_src, torch.ones_like(edge_src, dtype=torch.float32)
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# Compute means
|
|
315
|
+
has_neighbors = neighbor_count > 0
|
|
316
|
+
|
|
317
|
+
# Circular mean for phase (using atan2)
|
|
318
|
+
phase_mean = torch.zeros(n_nodes, device=self._device, dtype=torch.float32)
|
|
319
|
+
phase_mean[has_neighbors] = torch.atan2(
|
|
320
|
+
neighbor_sin_sum[has_neighbors], neighbor_cos_sum[has_neighbors]
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
# Arithmetic means for EPI and vf
|
|
324
|
+
epi_mean = torch.zeros(n_nodes, device=self._device, dtype=torch.float32)
|
|
325
|
+
vf_mean = torch.zeros(n_nodes, device=self._device, dtype=torch.float32)
|
|
326
|
+
epi_mean[has_neighbors] = (
|
|
327
|
+
neighbor_epi_sum[has_neighbors] / neighbor_count[has_neighbors]
|
|
328
|
+
)
|
|
329
|
+
vf_mean[has_neighbors] = (
|
|
330
|
+
neighbor_vf_sum[has_neighbors] / neighbor_count[has_neighbors]
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
# Compute gradients using TNFR canonical formula
|
|
334
|
+
# Phase: angle_diff with wrapping to [-π, π]
|
|
335
|
+
phase_diff = (phase_mean - phase + torch.pi) % (2 * torch.pi) - torch.pi
|
|
336
|
+
g_phase = phase_diff / torch.pi
|
|
337
|
+
g_phase[~has_neighbors] = 0.0
|
|
338
|
+
|
|
339
|
+
# EPI and vf gradients
|
|
340
|
+
g_epi = epi_mean - epi
|
|
341
|
+
g_epi[~has_neighbors] = 0.0
|
|
342
|
+
|
|
343
|
+
g_vf = vf_mean - vf
|
|
344
|
+
g_vf[~has_neighbors] = 0.0
|
|
345
|
+
|
|
346
|
+
# Topology gradient
|
|
347
|
+
g_topo = neighbor_count * w_topo
|
|
348
|
+
|
|
349
|
+
# Combine gradients
|
|
350
|
+
delta_nfr = w_phase * g_phase + w_epi * g_epi + w_vf * g_vf + g_topo
|
|
351
|
+
|
|
352
|
+
# Apply structural frequency scaling (canonical TNFR)
|
|
353
|
+
delta_nfr = vf * delta_nfr
|
|
354
|
+
|
|
355
|
+
return delta_nfr
|
|
356
|
+
|
|
357
|
+
def compute_si(
|
|
358
|
+
self,
|
|
359
|
+
graph: TNFRGraph,
|
|
360
|
+
*,
|
|
361
|
+
inplace: bool = True,
|
|
362
|
+
n_jobs: int | None = None,
|
|
363
|
+
chunk_size: int | None = None,
|
|
364
|
+
profile: MutableMapping[str, Any] | None = None,
|
|
365
|
+
) -> dict[Any, float] | Any:
|
|
366
|
+
"""Compute sense index using PyTorch backend.
|
|
367
|
+
|
|
368
|
+
**Current implementation**: Delegates to NumPy backend while maintaining
|
|
369
|
+
interface compatibility.
|
|
370
|
+
|
|
371
|
+
**Planned**: GPU-accelerated vectorized Si computation using torch tensors
|
|
372
|
+
with optimized phase dispersion kernels and mixed precision support.
|
|
373
|
+
|
|
374
|
+
Parameters
|
|
375
|
+
----------
|
|
376
|
+
graph : TNFRGraph
|
|
377
|
+
NetworkX graph with TNFR node attributes
|
|
378
|
+
inplace : bool, default=True
|
|
379
|
+
Whether to write Si values back to graph
|
|
380
|
+
n_jobs : int or None, optional
|
|
381
|
+
Ignored (PyTorch uses GPU parallelism)
|
|
382
|
+
chunk_size : int or None, optional
|
|
383
|
+
Chunk size hint (currently passed to NumPy backend)
|
|
384
|
+
profile : MutableMapping[str, Any] or None, optional
|
|
385
|
+
Dict to collect timing metrics
|
|
386
|
+
|
|
387
|
+
Returns
|
|
388
|
+
-------
|
|
389
|
+
dict[Any, float] or numpy.ndarray
|
|
390
|
+
Node-to-Si mapping or array of Si values
|
|
391
|
+
|
|
392
|
+
Notes
|
|
393
|
+
-----
|
|
394
|
+
When implemented, will support mixed precision (FP16/BF16) for
|
|
395
|
+
memory-efficient computation on large graphs, selectable via
|
|
396
|
+
graph.graph["TORCH_DTYPE"] = torch.float16
|
|
397
|
+
"""
|
|
398
|
+
# TODO: Implement GPU-accelerated PyTorch version
|
|
399
|
+
# For now, delegate to NumPy backend
|
|
400
|
+
from ..metrics.sense_index import compute_Si
|
|
401
|
+
|
|
402
|
+
return compute_Si(
|
|
403
|
+
graph,
|
|
404
|
+
inplace=inplace,
|
|
405
|
+
n_jobs=n_jobs,
|
|
406
|
+
chunk_size=chunk_size,
|
|
407
|
+
profile=profile,
|
|
408
|
+
)
|
tnfr/cache.py
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Unified cache interface for TNFR.
|
|
2
|
+
|
|
3
|
+
This module provides a consolidated entry point for all TNFR caching needs,
|
|
4
|
+
integrating both the core CacheManager infrastructure and the advanced
|
|
5
|
+
hierarchical cache with dependency tracking.
|
|
6
|
+
|
|
7
|
+
Quick Start
|
|
8
|
+
-----------
|
|
9
|
+
For basic caching with metrics and persistence layers::
|
|
10
|
+
|
|
11
|
+
from tnfr.cache import CacheManager, build_cache_manager
|
|
12
|
+
|
|
13
|
+
# Create a cache manager with default settings
|
|
14
|
+
manager = build_cache_manager()
|
|
15
|
+
|
|
16
|
+
# Register a named cache
|
|
17
|
+
manager.register("my_cache", lambda: {})
|
|
18
|
+
|
|
19
|
+
# Get and use the cache
|
|
20
|
+
cache = manager.get("my_cache")
|
|
21
|
+
|
|
22
|
+
For advanced hierarchical caching with dependency tracking::
|
|
23
|
+
|
|
24
|
+
from tnfr.cache import TNFRHierarchicalCache, CacheLevel
|
|
25
|
+
|
|
26
|
+
# Create hierarchical cache
|
|
27
|
+
cache = TNFRHierarchicalCache(max_memory_mb=256)
|
|
28
|
+
|
|
29
|
+
# Store with dependencies
|
|
30
|
+
cache.set(
|
|
31
|
+
"metric_key",
|
|
32
|
+
value=0.95,
|
|
33
|
+
level=CacheLevel.DERIVED_METRICS,
|
|
34
|
+
dependencies={'graph_topology', 'node_properties'}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Selective invalidation
|
|
38
|
+
cache.invalidate_by_dependency('graph_topology')
|
|
39
|
+
|
|
40
|
+
For graph-specific caching::
|
|
41
|
+
|
|
42
|
+
from tnfr.cache import configure_graph_cache_limits
|
|
43
|
+
import networkx as nx
|
|
44
|
+
|
|
45
|
+
G = nx.Graph()
|
|
46
|
+
configure_graph_cache_limits(
|
|
47
|
+
G,
|
|
48
|
+
default_capacity=256,
|
|
49
|
+
overrides={"dnfr_prep": 512}
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
See Also
|
|
53
|
+
--------
|
|
54
|
+
tnfr.utils.cache : Core cache infrastructure and CacheManager
|
|
55
|
+
tnfr.caching : Advanced hierarchical cache with dependency tracking
|
|
56
|
+
tnfr.metrics.cache_utils : Hot-path cache configuration helpers
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
from __future__ import annotations
|
|
60
|
+
|
|
61
|
+
# Core cache infrastructure from tnfr.utils.cache
|
|
62
|
+
from .utils.cache import (
|
|
63
|
+
# Main classes
|
|
64
|
+
CacheManager,
|
|
65
|
+
CacheLayer,
|
|
66
|
+
MappingCacheLayer,
|
|
67
|
+
ShelveCacheLayer,
|
|
68
|
+
RedisCacheLayer,
|
|
69
|
+
InstrumentedLRUCache,
|
|
70
|
+
ManagedLRUCache,
|
|
71
|
+
EdgeCacheManager,
|
|
72
|
+
# Configuration and stats
|
|
73
|
+
CacheCapacityConfig,
|
|
74
|
+
CacheStatistics,
|
|
75
|
+
# Factory functions
|
|
76
|
+
build_cache_manager,
|
|
77
|
+
create_hmac_signer,
|
|
78
|
+
create_hmac_validator,
|
|
79
|
+
create_secure_shelve_layer,
|
|
80
|
+
create_secure_redis_layer,
|
|
81
|
+
# Graph-specific helpers
|
|
82
|
+
configure_graph_cache_limits,
|
|
83
|
+
configure_global_cache_layers,
|
|
84
|
+
reset_global_cache_manager,
|
|
85
|
+
edge_version_cache,
|
|
86
|
+
cached_node_list,
|
|
87
|
+
cached_nodes_and_A,
|
|
88
|
+
increment_edge_version,
|
|
89
|
+
edge_version_update,
|
|
90
|
+
# ΔNFR caching
|
|
91
|
+
DnfrCache,
|
|
92
|
+
DnfrPrepState,
|
|
93
|
+
new_dnfr_cache,
|
|
94
|
+
# Security
|
|
95
|
+
SecurityError,
|
|
96
|
+
SecurityWarning,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Hierarchical cache with dependency tracking (now all in utils.cache)
|
|
100
|
+
from .utils.cache import (
|
|
101
|
+
TNFRHierarchicalCache,
|
|
102
|
+
CacheLevel,
|
|
103
|
+
CacheEntry,
|
|
104
|
+
cache_tnfr_computation,
|
|
105
|
+
invalidate_function_cache,
|
|
106
|
+
get_global_cache,
|
|
107
|
+
set_global_cache,
|
|
108
|
+
reset_global_cache,
|
|
109
|
+
GraphChangeTracker,
|
|
110
|
+
track_node_property_update,
|
|
111
|
+
PersistentTNFRCache,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Hot-path cache configuration helpers
|
|
115
|
+
from .metrics.cache_utils import (
|
|
116
|
+
get_cache_config,
|
|
117
|
+
configure_hot_path_caches,
|
|
118
|
+
log_cache_metrics,
|
|
119
|
+
CacheStats,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
__all__ = [
|
|
123
|
+
# Core cache classes
|
|
124
|
+
"CacheManager",
|
|
125
|
+
"CacheLayer",
|
|
126
|
+
"MappingCacheLayer",
|
|
127
|
+
"ShelveCacheLayer",
|
|
128
|
+
"RedisCacheLayer",
|
|
129
|
+
"InstrumentedLRUCache",
|
|
130
|
+
"ManagedLRUCache",
|
|
131
|
+
"EdgeCacheManager",
|
|
132
|
+
# Configuration and stats
|
|
133
|
+
"CacheCapacityConfig",
|
|
134
|
+
"CacheStatistics",
|
|
135
|
+
"CacheStats",
|
|
136
|
+
# Factory functions
|
|
137
|
+
"build_cache_manager",
|
|
138
|
+
"create_hmac_signer",
|
|
139
|
+
"create_hmac_validator",
|
|
140
|
+
"create_secure_shelve_layer",
|
|
141
|
+
"create_secure_redis_layer",
|
|
142
|
+
# Graph-specific helpers
|
|
143
|
+
"configure_graph_cache_limits",
|
|
144
|
+
"configure_global_cache_layers",
|
|
145
|
+
"reset_global_cache_manager",
|
|
146
|
+
"edge_version_cache",
|
|
147
|
+
"cached_node_list",
|
|
148
|
+
"cached_nodes_and_A",
|
|
149
|
+
"increment_edge_version",
|
|
150
|
+
"edge_version_update",
|
|
151
|
+
"get_cache_config",
|
|
152
|
+
"configure_hot_path_caches",
|
|
153
|
+
"log_cache_metrics",
|
|
154
|
+
# ΔNFR caching
|
|
155
|
+
"DnfrCache",
|
|
156
|
+
"DnfrPrepState",
|
|
157
|
+
"new_dnfr_cache",
|
|
158
|
+
# Hierarchical cache
|
|
159
|
+
"TNFRHierarchicalCache",
|
|
160
|
+
"CacheLevel",
|
|
161
|
+
"CacheEntry",
|
|
162
|
+
"cache_tnfr_computation",
|
|
163
|
+
"invalidate_function_cache",
|
|
164
|
+
# Change tracking
|
|
165
|
+
"GraphChangeTracker",
|
|
166
|
+
"track_node_property_update",
|
|
167
|
+
"PersistentTNFRCache",
|
|
168
|
+
# Security
|
|
169
|
+
"SecurityError",
|
|
170
|
+
"SecurityWarning",
|
|
171
|
+
]
|
tnfr/cache.pyi
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Compatibility stub removed; import from :mod:`tnfr.utils.cache` instead."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import NoReturn
|
|
6
|
+
|
|
7
|
+
__all__ = ()
|
|
8
|
+
|
|
9
|
+
def __getattr__(name: str) -> NoReturn:
|
|
10
|
+
"""Indicate that :mod:`tnfr.cache` no longer exports cache helpers."""
|
|
11
|
+
|
|
12
|
+
def __dir__() -> tuple[str, ...]:
|
|
13
|
+
"""Return an empty set of exports to mirror the removed shim."""
|
tnfr/cli/__init__.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Command-line interface entry points for TNFR."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import logging
|
|
7
|
+
import sys
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from .. import __version__
|
|
11
|
+
from ..utils import _configure_root, get_logger
|
|
12
|
+
from .arguments import (
|
|
13
|
+
_add_epi_validate_parser,
|
|
14
|
+
_add_math_run_parser,
|
|
15
|
+
_add_metrics_parser,
|
|
16
|
+
_add_profile_parser,
|
|
17
|
+
_add_profile_pipeline_parser,
|
|
18
|
+
_add_run_parser,
|
|
19
|
+
_add_sequence_parser,
|
|
20
|
+
add_canon_toggle,
|
|
21
|
+
add_common_args,
|
|
22
|
+
add_grammar_args,
|
|
23
|
+
add_grammar_selector_args,
|
|
24
|
+
add_history_export_args,
|
|
25
|
+
)
|
|
26
|
+
from .execution import (
|
|
27
|
+
apply_cli_config,
|
|
28
|
+
build_basic_graph,
|
|
29
|
+
register_callbacks_and_observer,
|
|
30
|
+
resolve_program,
|
|
31
|
+
run_program,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
logger = get_logger(__name__)
|
|
35
|
+
|
|
36
|
+
__all__ = (
|
|
37
|
+
"main",
|
|
38
|
+
"add_common_args",
|
|
39
|
+
"add_grammar_args",
|
|
40
|
+
"add_grammar_selector_args",
|
|
41
|
+
"add_history_export_args",
|
|
42
|
+
"add_canon_toggle",
|
|
43
|
+
"build_basic_graph",
|
|
44
|
+
"apply_cli_config",
|
|
45
|
+
"register_callbacks_and_observer",
|
|
46
|
+
"run_program",
|
|
47
|
+
"resolve_program",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main(argv: Optional[list[str]] = None) -> int:
|
|
52
|
+
"""Entry point for the ``tnfr`` CLI returning the exit status."""
|
|
53
|
+
|
|
54
|
+
_configure_root()
|
|
55
|
+
|
|
56
|
+
root = logging.getLogger()
|
|
57
|
+
root.setLevel(logging.INFO)
|
|
58
|
+
|
|
59
|
+
formatter = logging.Formatter("%(message)s")
|
|
60
|
+
for handler in list(root.handlers):
|
|
61
|
+
root.removeHandler(handler)
|
|
62
|
+
|
|
63
|
+
handler = logging.StreamHandler(stream=sys.stdout)
|
|
64
|
+
handler.setLevel(logging.INFO)
|
|
65
|
+
handler.setFormatter(formatter)
|
|
66
|
+
root.addHandler(handler)
|
|
67
|
+
|
|
68
|
+
p = argparse.ArgumentParser(
|
|
69
|
+
prog="tnfr",
|
|
70
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
71
|
+
description="TNFR - Resonant Fractal Nature Theory computational engine",
|
|
72
|
+
epilog=(
|
|
73
|
+
"Common examples:\n"
|
|
74
|
+
" # Run a preset scenario\n"
|
|
75
|
+
" tnfr run --preset resonant_bootstrap --steps 100\n\n"
|
|
76
|
+
" # Run with math engine validation\n"
|
|
77
|
+
" tnfr math.run --nodes 24 --steps 50\n\n"
|
|
78
|
+
" # Validate EPI integrity\n"
|
|
79
|
+
" tnfr epi.validate --preset coupling_exploration\n\n"
|
|
80
|
+
" # Execute custom sequence from YAML\n"
|
|
81
|
+
" tnfr sequence --sequence-file presets/resonant_bootstrap.yaml\n\n"
|
|
82
|
+
" # Export metrics to JSON\n"
|
|
83
|
+
" tnfr metrics --save metrics.json --steps 200\n\n"
|
|
84
|
+
"For detailed help on any subcommand:\n"
|
|
85
|
+
" tnfr <subcommand> --help"
|
|
86
|
+
),
|
|
87
|
+
)
|
|
88
|
+
p.add_argument(
|
|
89
|
+
"--version",
|
|
90
|
+
action="store_true",
|
|
91
|
+
help=("show the actual version and exit (reads pyproject.toml in development)"),
|
|
92
|
+
)
|
|
93
|
+
sub = p.add_subparsers(dest="cmd", help="Available subcommands")
|
|
94
|
+
|
|
95
|
+
_add_run_parser(sub)
|
|
96
|
+
_add_math_run_parser(sub)
|
|
97
|
+
_add_epi_validate_parser(sub)
|
|
98
|
+
_add_sequence_parser(sub)
|
|
99
|
+
_add_metrics_parser(sub)
|
|
100
|
+
_add_profile_parser(sub)
|
|
101
|
+
_add_profile_pipeline_parser(sub)
|
|
102
|
+
|
|
103
|
+
args = p.parse_args(argv)
|
|
104
|
+
if args.version:
|
|
105
|
+
logger.info("%s", __version__)
|
|
106
|
+
return 0
|
|
107
|
+
if not hasattr(args, "func"):
|
|
108
|
+
p.print_help()
|
|
109
|
+
return 1
|
|
110
|
+
return int(args.func(args))
|