tnfr 4.5.2__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 +334 -50
- 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 +214 -37
- 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 +149 -556
- tnfr/cache.pyi +13 -0
- tnfr/cli/__init__.py +51 -16
- tnfr/cli/__init__.pyi +26 -0
- tnfr/cli/arguments.py +344 -32
- tnfr/cli/arguments.pyi +29 -0
- tnfr/cli/execution.py +676 -50
- tnfr/cli/execution.pyi +70 -0
- tnfr/cli/interactive_validator.py +614 -0
- tnfr/cli/utils.py +18 -3
- 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/{constants_glyphs.py → config/constants.py} +26 -20
- tnfr/config/constants.pyi +12 -0
- tnfr/config/defaults.py +54 -0
- tnfr/{constants/core.py → config/defaults_core.py} +59 -6
- 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 +51 -133
- tnfr/constants/__init__.pyi +92 -0
- tnfr/constants/aliases.py +33 -0
- tnfr/constants/aliases.pyi +27 -0
- tnfr/constants/init.py +3 -1
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +9 -15
- 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 +213 -633
- 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 +2699 -398
- 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 +496 -102
- 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 +10 -5
- 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 +77 -55
- 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 +29 -50
- tnfr/flatten.pyi +21 -0
- tnfr/gamma.py +66 -53
- tnfr/gamma.pyi +36 -0
- tnfr/glyph_history.py +144 -57
- tnfr/glyph_history.pyi +35 -0
- tnfr/glyph_runtime.py +19 -0
- tnfr/glyph_runtime.pyi +8 -0
- tnfr/immutable.py +70 -30
- tnfr/immutable.pyi +36 -0
- tnfr/initialization.py +22 -16
- tnfr/initialization.pyi +65 -0
- tnfr/io.py +5 -241
- tnfr/io.pyi +13 -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 +47 -9
- 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 +1510 -330
- tnfr/metrics/coherence.pyi +129 -0
- tnfr/metrics/common.py +23 -16
- tnfr/metrics/common.pyi +35 -0
- tnfr/metrics/core.py +251 -36
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +709 -110
- tnfr/metrics/diagnosis.pyi +86 -0
- tnfr/metrics/emergence.py +245 -0
- tnfr/metrics/export.py +60 -18
- tnfr/metrics/export.pyi +7 -0
- tnfr/metrics/glyph_timing.py +233 -43
- 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 +63 -28
- tnfr/metrics/reporting.pyi +25 -0
- tnfr/metrics/sense_index.py +1126 -43
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +215 -23
- tnfr/metrics/trig.pyi +13 -0
- tnfr/metrics/trig_cache.py +148 -24
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/multiscale/__init__.py +32 -0
- tnfr/multiscale/hierarchical.py +517 -0
- tnfr/node.py +646 -140
- tnfr/node.pyi +139 -0
- tnfr/observers.py +160 -45
- tnfr/observers.pyi +31 -0
- tnfr/ontosim.py +23 -19
- tnfr/ontosim.pyi +28 -0
- tnfr/operators/__init__.py +1358 -106
- 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 +107 -38
- 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 +1415 -91
- 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 +75 -151
- 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 +59 -22
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +92 -67
- 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 +639 -263
- 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 +2 -4
- 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 +300 -126
- 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 +743 -12
- 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/{callback_utils.py → utils/callbacks.py} +26 -39
- 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/{helpers → utils}/numeric.py +51 -24
- 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-4.5.2.dist-info → tnfr-8.5.0.dist-info}/entry_points.txt +1 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/licenses/LICENSE.md +1 -1
- tnfr/collections_utils.py +0 -300
- tnfr/config.py +0 -32
- tnfr/grammar.py +0 -344
- tnfr/graph_utils.py +0 -84
- tnfr/helpers/__init__.py +0 -71
- tnfr/import_utils.py +0 -228
- tnfr/json_utils.py +0 -162
- tnfr/logging_utils.py +0 -116
- tnfr/presets.py +0 -60
- tnfr/validators.py +0 -84
- tnfr/value_utils.py +0 -59
- tnfr-4.5.2.dist-info/METADATA +0 -379
- tnfr-4.5.2.dist-info/RECORD +0 -67
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from .._compat import TypeAlias
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"apply_network_remesh",
|
|
9
|
+
"apply_topological_remesh",
|
|
10
|
+
"apply_remesh_if_globally_stable",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
CommunityGraph: TypeAlias = Any
|
|
14
|
+
|
|
15
|
+
def apply_network_remesh(G: CommunityGraph) -> None: ...
|
|
16
|
+
def apply_topological_remesh(
|
|
17
|
+
G: CommunityGraph,
|
|
18
|
+
mode: str | None = None,
|
|
19
|
+
*,
|
|
20
|
+
k: int | None = None,
|
|
21
|
+
p_rewire: float = 0.2,
|
|
22
|
+
seed: int | None = None,
|
|
23
|
+
) -> None: ...
|
|
24
|
+
def apply_remesh_if_globally_stable(
|
|
25
|
+
G: CommunityGraph, stable_step_window: int | None = None, **kwargs: Any
|
|
26
|
+
) -> None: ...
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"""Structural units and types for TNFR canonical measurements.
|
|
2
|
+
|
|
3
|
+
This module provides type-safe wrappers for TNFR structural units,
|
|
4
|
+
ensuring canonical unit enforcement throughout the engine.
|
|
5
|
+
|
|
6
|
+
Key structural units:
|
|
7
|
+
- Hz_str: Structural hertz (reorganization rate, νf)
|
|
8
|
+
- rad_str: Structural radians (phase, θ)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from typing import Any, Union
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"HzStr",
|
|
17
|
+
"StructuralFrequency",
|
|
18
|
+
"ensure_hz_str",
|
|
19
|
+
"hz_to_hz_str",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
# Default tolerance for structural frequency validation
|
|
23
|
+
MIN_STRUCTURAL_FREQUENCY = 0.0
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HzStr:
|
|
27
|
+
"""Structural frequency in Hz_str (structural hertz) units.
|
|
28
|
+
|
|
29
|
+
Hz_str represents the rate of structural reorganization, not physical
|
|
30
|
+
frequency. It measures how rapidly a node's Primary Information Structure
|
|
31
|
+
(EPI) evolves according to the nodal equation:
|
|
32
|
+
|
|
33
|
+
∂EPI/∂t = νf · ΔNFR(t)
|
|
34
|
+
|
|
35
|
+
Where νf is the structural frequency in Hz_str units.
|
|
36
|
+
|
|
37
|
+
Attributes
|
|
38
|
+
----------
|
|
39
|
+
value : float
|
|
40
|
+
Magnitude of the structural frequency
|
|
41
|
+
unit : str
|
|
42
|
+
Always "Hz_str" to maintain unit clarity
|
|
43
|
+
|
|
44
|
+
Notes
|
|
45
|
+
-----
|
|
46
|
+
Hz_str is distinct from physical Hz (cycles per second). It represents
|
|
47
|
+
the rate of structural change in TNFR's reorganization phase space.
|
|
48
|
+
Conversion from physical Hz depends on the domain context (biological,
|
|
49
|
+
quantum, social, etc.).
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
__slots__ = ("value", "unit")
|
|
53
|
+
|
|
54
|
+
def __init__(self, value: float) -> None:
|
|
55
|
+
"""Initialize structural frequency.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
value : float
|
|
60
|
+
Structural frequency magnitude (must be non-negative)
|
|
61
|
+
|
|
62
|
+
Raises
|
|
63
|
+
------
|
|
64
|
+
ValueError
|
|
65
|
+
If value is negative (structural frequencies are non-negative)
|
|
66
|
+
"""
|
|
67
|
+
if value < MIN_STRUCTURAL_FREQUENCY:
|
|
68
|
+
raise ValueError(
|
|
69
|
+
f"Structural frequency must be >= {MIN_STRUCTURAL_FREQUENCY} Hz_str, got {value}"
|
|
70
|
+
)
|
|
71
|
+
self.value = float(value)
|
|
72
|
+
self.unit = "Hz_str"
|
|
73
|
+
|
|
74
|
+
def __float__(self) -> float:
|
|
75
|
+
"""Convert to float for numerical operations."""
|
|
76
|
+
return self.value
|
|
77
|
+
|
|
78
|
+
def __repr__(self) -> str:
|
|
79
|
+
"""String representation."""
|
|
80
|
+
return f"HzStr({self.value})"
|
|
81
|
+
|
|
82
|
+
def __str__(self) -> str:
|
|
83
|
+
"""Human-readable string."""
|
|
84
|
+
return f"{self.value} Hz_str"
|
|
85
|
+
|
|
86
|
+
def __eq__(self, other: Any) -> bool:
|
|
87
|
+
"""Equality comparison."""
|
|
88
|
+
if isinstance(other, HzStr):
|
|
89
|
+
return abs(self.value - other.value) < 1e-10
|
|
90
|
+
if isinstance(other, (int, float)):
|
|
91
|
+
return abs(self.value - float(other)) < 1e-10
|
|
92
|
+
return NotImplemented
|
|
93
|
+
|
|
94
|
+
def __lt__(self, other: Any) -> bool:
|
|
95
|
+
"""Less than comparison."""
|
|
96
|
+
if isinstance(other, HzStr):
|
|
97
|
+
return self.value < other.value
|
|
98
|
+
if isinstance(other, (int, float)):
|
|
99
|
+
return self.value < float(other)
|
|
100
|
+
return NotImplemented
|
|
101
|
+
|
|
102
|
+
def __le__(self, other: Any) -> bool:
|
|
103
|
+
"""Less than or equal comparison."""
|
|
104
|
+
if isinstance(other, HzStr):
|
|
105
|
+
return self.value <= other.value
|
|
106
|
+
if isinstance(other, (int, float)):
|
|
107
|
+
return self.value <= float(other)
|
|
108
|
+
return NotImplemented
|
|
109
|
+
|
|
110
|
+
def __gt__(self, other: Any) -> bool:
|
|
111
|
+
"""Greater than comparison."""
|
|
112
|
+
if isinstance(other, HzStr):
|
|
113
|
+
return self.value > other.value
|
|
114
|
+
if isinstance(other, (int, float)):
|
|
115
|
+
return self.value > float(other)
|
|
116
|
+
return NotImplemented
|
|
117
|
+
|
|
118
|
+
def __ge__(self, other: Any) -> bool:
|
|
119
|
+
"""Greater than or equal comparison."""
|
|
120
|
+
if isinstance(other, HzStr):
|
|
121
|
+
return self.value >= other.value
|
|
122
|
+
if isinstance(other, (int, float)):
|
|
123
|
+
return self.value >= float(other)
|
|
124
|
+
return NotImplemented
|
|
125
|
+
|
|
126
|
+
def __add__(self, other: Any) -> HzStr:
|
|
127
|
+
"""Addition."""
|
|
128
|
+
if isinstance(other, HzStr):
|
|
129
|
+
return HzStr(self.value + other.value)
|
|
130
|
+
if isinstance(other, (int, float)):
|
|
131
|
+
return HzStr(self.value + float(other))
|
|
132
|
+
return NotImplemented
|
|
133
|
+
|
|
134
|
+
def __radd__(self, other: Any) -> HzStr:
|
|
135
|
+
"""Right addition."""
|
|
136
|
+
return self.__add__(other)
|
|
137
|
+
|
|
138
|
+
def __sub__(self, other: Any) -> HzStr:
|
|
139
|
+
"""Subtraction."""
|
|
140
|
+
if isinstance(other, HzStr):
|
|
141
|
+
return HzStr(self.value - other.value)
|
|
142
|
+
if isinstance(other, (int, float)):
|
|
143
|
+
return HzStr(self.value - float(other))
|
|
144
|
+
return NotImplemented
|
|
145
|
+
|
|
146
|
+
def __rsub__(self, other: Any) -> HzStr:
|
|
147
|
+
"""Right subtraction."""
|
|
148
|
+
if isinstance(other, (int, float)):
|
|
149
|
+
return HzStr(float(other) - self.value)
|
|
150
|
+
return NotImplemented
|
|
151
|
+
|
|
152
|
+
def __mul__(self, other: Any) -> Union[HzStr, float]:
|
|
153
|
+
"""Multiplication.
|
|
154
|
+
|
|
155
|
+
When multiplied by another HzStr or dimensionless number, returns HzStr.
|
|
156
|
+
When multiplied by ΔNFR (dimensionless), returns float (∂EPI/∂t rate).
|
|
157
|
+
"""
|
|
158
|
+
if isinstance(other, HzStr):
|
|
159
|
+
return HzStr(self.value * other.value)
|
|
160
|
+
if isinstance(other, (int, float)):
|
|
161
|
+
# This is typically νf · ΔNFR in nodal equation
|
|
162
|
+
return self.value * float(other)
|
|
163
|
+
return NotImplemented
|
|
164
|
+
|
|
165
|
+
def __rmul__(self, other: Any) -> Union[HzStr, float]:
|
|
166
|
+
"""Right multiplication."""
|
|
167
|
+
return self.__mul__(other)
|
|
168
|
+
|
|
169
|
+
def __truediv__(self, other: Any) -> HzStr:
|
|
170
|
+
"""Division."""
|
|
171
|
+
if isinstance(other, HzStr):
|
|
172
|
+
return HzStr(self.value / other.value)
|
|
173
|
+
if isinstance(other, (int, float)):
|
|
174
|
+
if other == 0:
|
|
175
|
+
raise ZeroDivisionError(
|
|
176
|
+
f"Cannot divide structural frequency {self.value} Hz_str by zero"
|
|
177
|
+
)
|
|
178
|
+
return HzStr(self.value / float(other))
|
|
179
|
+
return NotImplemented
|
|
180
|
+
|
|
181
|
+
def __hash__(self) -> int:
|
|
182
|
+
"""Hash for use in sets/dicts."""
|
|
183
|
+
return hash((self.value, self.unit))
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# Alias for clarity in type hints
|
|
187
|
+
StructuralFrequency = HzStr
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def ensure_hz_str(value: Union[float, HzStr]) -> HzStr:
|
|
191
|
+
"""Ensure value is in Hz_str units.
|
|
192
|
+
|
|
193
|
+
Parameters
|
|
194
|
+
----------
|
|
195
|
+
value : float or HzStr
|
|
196
|
+
Value to convert to Hz_str
|
|
197
|
+
|
|
198
|
+
Returns
|
|
199
|
+
-------
|
|
200
|
+
HzStr
|
|
201
|
+
Value as structural frequency
|
|
202
|
+
|
|
203
|
+
Examples
|
|
204
|
+
--------
|
|
205
|
+
>>> ensure_hz_str(1.5)
|
|
206
|
+
HzStr(1.5)
|
|
207
|
+
>>> ensure_hz_str(HzStr(2.0))
|
|
208
|
+
HzStr(2.0)
|
|
209
|
+
"""
|
|
210
|
+
if isinstance(value, HzStr):
|
|
211
|
+
return value
|
|
212
|
+
return HzStr(float(value))
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def hz_to_hz_str(
|
|
216
|
+
hz_value: float,
|
|
217
|
+
context: str = "default",
|
|
218
|
+
) -> HzStr:
|
|
219
|
+
"""Convert physical Hz to structural Hz_str with domain-specific scaling.
|
|
220
|
+
|
|
221
|
+
Different physical domains have different relationships between physical
|
|
222
|
+
frequency and structural reorganization rate. This function provides
|
|
223
|
+
context-aware conversion factors.
|
|
224
|
+
|
|
225
|
+
Parameters
|
|
226
|
+
----------
|
|
227
|
+
hz_value : float
|
|
228
|
+
Physical frequency in Hz (cycles per second)
|
|
229
|
+
context : str, default "default"
|
|
230
|
+
Domain context for conversion:
|
|
231
|
+
- "default": Direct 1:1 mapping
|
|
232
|
+
- "biological": Biological systems (slower structural reorganization)
|
|
233
|
+
- "quantum": Quantum systems (faster structural reorganization)
|
|
234
|
+
- "social": Social systems (much slower structural reorganization)
|
|
235
|
+
- "neural": Neural systems (moderate structural reorganization)
|
|
236
|
+
|
|
237
|
+
Returns
|
|
238
|
+
-------
|
|
239
|
+
HzStr
|
|
240
|
+
Structural frequency in Hz_str units
|
|
241
|
+
|
|
242
|
+
Notes
|
|
243
|
+
-----
|
|
244
|
+
Conversion factors are based on typical timescales in each domain:
|
|
245
|
+
- Biological: 0.1 (10 Hz physical → 1 Hz_str)
|
|
246
|
+
- Quantum: 1e12 (1 Hz physical → 1 THz_str)
|
|
247
|
+
- Social: 1e-6 (1 MHz physical → 1 Hz_str)
|
|
248
|
+
- Neural: 1.0 (1 Hz physical → 1 Hz_str, matched to firing rates)
|
|
249
|
+
|
|
250
|
+
Examples
|
|
251
|
+
--------
|
|
252
|
+
>>> hz_to_hz_str(10.0, "biological")
|
|
253
|
+
HzStr(1.0)
|
|
254
|
+
>>> hz_to_hz_str(1.0, "quantum")
|
|
255
|
+
HzStr(1000000000000.0)
|
|
256
|
+
"""
|
|
257
|
+
CONVERSION_FACTORS = {
|
|
258
|
+
"default": 1.0,
|
|
259
|
+
"biological": 0.1,
|
|
260
|
+
"quantum": 1e12,
|
|
261
|
+
"social": 1e-6,
|
|
262
|
+
"neural": 1.0,
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
factor = CONVERSION_FACTORS.get(context, 1.0)
|
|
266
|
+
hz_str_value = hz_value * factor
|
|
267
|
+
|
|
268
|
+
return HzStr(hz_str_value)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Unified TNFR Grammar - Facade to GrammarValidator.
|
|
2
|
+
|
|
3
|
+
This module provides a clean facade to the canonical grammar validation
|
|
4
|
+
implemented in grammar.py. It exports the unified grammar constraints (U1-U4)
|
|
5
|
+
and the validator for use in tests and applications.
|
|
6
|
+
|
|
7
|
+
All grammar rules derive inevitably from TNFR physics:
|
|
8
|
+
- U1: STRUCTURAL INITIATION & CLOSURE
|
|
9
|
+
- U2: CONVERGENCE & BOUNDEDNESS
|
|
10
|
+
- U3: RESONANT COUPLING
|
|
11
|
+
- U4: BIFURCATION DYNAMICS (U4a: triggers, U4b: transformers)
|
|
12
|
+
|
|
13
|
+
References
|
|
14
|
+
----------
|
|
15
|
+
- UNIFIED_GRAMMAR_RULES.md: Complete physics derivations
|
|
16
|
+
- AGENTS.md: Canonical invariants and formal contracts
|
|
17
|
+
- TNFR.pdf: Nodal equation and bifurcation theory
|
|
18
|
+
|
|
19
|
+
Notes
|
|
20
|
+
-----
|
|
21
|
+
This is a facade module that re-exports from grammar.py for clean imports.
|
|
22
|
+
The actual implementation is in grammar.py::GrammarValidator.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from typing import TYPE_CHECKING, List
|
|
28
|
+
|
|
29
|
+
if TYPE_CHECKING:
|
|
30
|
+
from .definitions import Operator
|
|
31
|
+
|
|
32
|
+
# Import validator class and rename for clarity
|
|
33
|
+
from .grammar import GrammarValidator as UnifiedGrammarValidator
|
|
34
|
+
|
|
35
|
+
# Import operator sets (canonical definitions from grammar.py)
|
|
36
|
+
from .grammar import (
|
|
37
|
+
BIFURCATION_HANDLERS,
|
|
38
|
+
BIFURCATION_TRIGGERS,
|
|
39
|
+
CLOSURES,
|
|
40
|
+
COUPLING_RESONANCE,
|
|
41
|
+
DESTABILIZERS,
|
|
42
|
+
GENERATORS,
|
|
43
|
+
STABILIZERS,
|
|
44
|
+
TRANSFORMERS,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Import validation functions
|
|
48
|
+
from .grammar import validate_grammar
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
# Validator class
|
|
52
|
+
"UnifiedGrammarValidator",
|
|
53
|
+
# Convenience function
|
|
54
|
+
"validate_unified",
|
|
55
|
+
# Operator sets (U1-U4 categories)
|
|
56
|
+
"GENERATORS",
|
|
57
|
+
"CLOSURES",
|
|
58
|
+
"STABILIZERS",
|
|
59
|
+
"DESTABILIZERS",
|
|
60
|
+
"COUPLING_RESONANCE",
|
|
61
|
+
"BIFURCATION_TRIGGERS",
|
|
62
|
+
"BIFURCATION_HANDLERS",
|
|
63
|
+
"TRANSFORMERS",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def validate_unified(
|
|
68
|
+
sequence: List["Operator"],
|
|
69
|
+
epi_initial: float = 0.0,
|
|
70
|
+
) -> bool:
|
|
71
|
+
"""Validate sequence using unified TNFR grammar (U1-U4).
|
|
72
|
+
|
|
73
|
+
Convenience function that returns only boolean result.
|
|
74
|
+
For detailed messages, use UnifiedGrammarValidator.validate().
|
|
75
|
+
|
|
76
|
+
Parameters
|
|
77
|
+
----------
|
|
78
|
+
sequence : List[Operator]
|
|
79
|
+
Sequence of operators to validate
|
|
80
|
+
epi_initial : float, optional
|
|
81
|
+
Initial EPI value (default: 0.0)
|
|
82
|
+
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
bool
|
|
86
|
+
True if sequence satisfies all U1-U4 constraints
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
>>> from tnfr.operators.definitions import Emission, Coherence, Silence
|
|
91
|
+
>>> from tnfr.operators.unified_grammar import validate_unified
|
|
92
|
+
>>> ops = [Emission(), Coherence(), Silence()]
|
|
93
|
+
>>> validate_unified(ops, epi_initial=0.0) # doctest: +SKIP
|
|
94
|
+
True
|
|
95
|
+
|
|
96
|
+
Notes
|
|
97
|
+
-----
|
|
98
|
+
This validator is 100% physics-based. All constraints emerge from:
|
|
99
|
+
- Nodal equation: ∂EPI/∂t = νf · ΔNFR(t)
|
|
100
|
+
- TNFR invariants (AGENTS.md)
|
|
101
|
+
- Formal operator contracts
|
|
102
|
+
|
|
103
|
+
See UNIFIED_GRAMMAR_RULES.md for complete derivations.
|
|
104
|
+
"""
|
|
105
|
+
return validate_grammar(sequence, epi_initial)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Parallel and distributed computation engines for TNFR networks.
|
|
2
|
+
|
|
3
|
+
This module provides parallelization strategies that respect TNFR's structural
|
|
4
|
+
coherence while enabling efficient computation on large networks. All parallel
|
|
5
|
+
implementations preserve the canonical nodal equation and operator closure.
|
|
6
|
+
|
|
7
|
+
Key components:
|
|
8
|
+
- FractalPartitioner: Partitions networks using coherence-based communities
|
|
9
|
+
- TNFRParallelEngine: Multiprocessing/threading engine for medium networks
|
|
10
|
+
- TNFRDistributedEngine: Optional Ray/Dask backend for massive networks
|
|
11
|
+
- TNFRGPUEngine: Optional GPU acceleration via JAX/CuPy
|
|
12
|
+
- TNFRAutoScaler: Recommends optimal execution strategy
|
|
13
|
+
- ParallelExecutionMonitor: Real-time performance tracking
|
|
14
|
+
|
|
15
|
+
All engines maintain TNFR invariants:
|
|
16
|
+
- EPI changes only via structural operators
|
|
17
|
+
- νf expressed in Hz_str (structural hertz)
|
|
18
|
+
- ΔNFR semantics preserved (not reinterpreted as ML gradient)
|
|
19
|
+
- Operator closure maintained
|
|
20
|
+
- Phase synchrony verification
|
|
21
|
+
- Operational fractality preserved
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
# Import all core components
|
|
27
|
+
from .partitioner import FractalPartitioner
|
|
28
|
+
from .engine import TNFRParallelEngine
|
|
29
|
+
from .auto_scaler import TNFRAutoScaler
|
|
30
|
+
from .monitoring import ParallelExecutionMonitor, PerformanceMetrics
|
|
31
|
+
|
|
32
|
+
__all__ = (
|
|
33
|
+
"FractalPartitioner",
|
|
34
|
+
"TNFRParallelEngine",
|
|
35
|
+
"TNFRAutoScaler",
|
|
36
|
+
"ParallelExecutionMonitor",
|
|
37
|
+
"PerformanceMetrics",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Optional distributed backends
|
|
41
|
+
try:
|
|
42
|
+
from .distributed import TNFRDistributedEngine
|
|
43
|
+
|
|
44
|
+
__all__ = __all__ + ("TNFRDistributedEngine",)
|
|
45
|
+
except ImportError:
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
# Optional GPU backend
|
|
49
|
+
try:
|
|
50
|
+
from .gpu_engine import TNFRGPUEngine
|
|
51
|
+
|
|
52
|
+
__all__ = __all__ + ("TNFRGPUEngine",)
|
|
53
|
+
except ImportError:
|
|
54
|
+
pass
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"""Auto-scaling and execution strategy recommendation for TNFR computations.
|
|
2
|
+
|
|
3
|
+
Recommends optimal execution strategies based on network size, available
|
|
4
|
+
resources, and hardware capabilities.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from multiprocessing import cpu_count
|
|
10
|
+
from typing import Any, Dict
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TNFRAutoScaler:
|
|
14
|
+
"""Auto-scaler for TNFR parallel execution strategies.
|
|
15
|
+
|
|
16
|
+
Analyzes network characteristics and system resources to recommend optimal
|
|
17
|
+
execution strategies (sequential, multiprocessing, GPU, or distributed).
|
|
18
|
+
|
|
19
|
+
Examples
|
|
20
|
+
--------
|
|
21
|
+
>>> from tnfr.parallel import TNFRAutoScaler
|
|
22
|
+
>>> scaler = TNFRAutoScaler()
|
|
23
|
+
>>> strategy = scaler.recommend_execution_strategy(
|
|
24
|
+
... graph_size=500,
|
|
25
|
+
... available_memory_gb=8.0,
|
|
26
|
+
... has_gpu=False
|
|
27
|
+
... )
|
|
28
|
+
>>> strategy['backend'] in ['sequential', 'multiprocessing']
|
|
29
|
+
True
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self):
|
|
33
|
+
self.performance_history: Dict[str, Any] = {}
|
|
34
|
+
self.optimal_configs: Dict[str, Any] = {}
|
|
35
|
+
|
|
36
|
+
def recommend_execution_strategy(
|
|
37
|
+
self,
|
|
38
|
+
graph_size: int,
|
|
39
|
+
available_memory_gb: float = 8.0,
|
|
40
|
+
has_gpu: bool = False,
|
|
41
|
+
) -> Dict[str, Any]:
|
|
42
|
+
"""Recommend optimal execution strategy for given configuration.
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
graph_size : int
|
|
47
|
+
Number of nodes in the network
|
|
48
|
+
available_memory_gb : float, default=8.0
|
|
49
|
+
Available system memory in gigabytes
|
|
50
|
+
has_gpu : bool, default=False
|
|
51
|
+
Whether GPU acceleration is available
|
|
52
|
+
|
|
53
|
+
Returns
|
|
54
|
+
-------
|
|
55
|
+
Dict[str, Any]
|
|
56
|
+
Strategy recommendation with keys:
|
|
57
|
+
- backend: str (sequential/multiprocessing/gpu/distributed)
|
|
58
|
+
- workers: int (recommended worker count)
|
|
59
|
+
- explanation: str (reasoning)
|
|
60
|
+
- estimated_time_minutes: float (expected duration)
|
|
61
|
+
- estimated_memory_gb: float (expected memory usage)
|
|
62
|
+
|
|
63
|
+
Notes
|
|
64
|
+
-----
|
|
65
|
+
Strategy selection follows TNFR-aware heuristics:
|
|
66
|
+
- Small networks (<100): Sequential is fastest (overhead dominates)
|
|
67
|
+
- Medium networks (100-1000): Multiprocessing optimal
|
|
68
|
+
- Large networks (1000-10000) with GPU: Vectorized GPU
|
|
69
|
+
- Massive networks (>10000): Distributed computation required
|
|
70
|
+
"""
|
|
71
|
+
strategy: Dict[str, Any] = {}
|
|
72
|
+
|
|
73
|
+
# Select backend based on size
|
|
74
|
+
if graph_size < 100:
|
|
75
|
+
strategy["backend"] = "sequential"
|
|
76
|
+
strategy["workers"] = 1
|
|
77
|
+
strategy["explanation"] = (
|
|
78
|
+
"Small network - sequential processing fastest due to overhead"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
elif graph_size < 1000:
|
|
82
|
+
strategy["backend"] = "multiprocessing"
|
|
83
|
+
strategy["workers"] = min(cpu_count(), graph_size // 50)
|
|
84
|
+
strategy["explanation"] = (
|
|
85
|
+
"Medium network - multiprocessing provides optimal speedup"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
elif graph_size < 10000 and has_gpu:
|
|
89
|
+
strategy["backend"] = "gpu"
|
|
90
|
+
strategy["workers"] = 1
|
|
91
|
+
strategy["gpu_engine"] = "jax"
|
|
92
|
+
strategy["explanation"] = (
|
|
93
|
+
"Large network with GPU - vectorized acceleration available"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
else:
|
|
97
|
+
strategy["backend"] = "distributed"
|
|
98
|
+
strategy["workers"] = cpu_count() * 2
|
|
99
|
+
strategy["chunk_size"] = min(500, graph_size // 20)
|
|
100
|
+
strategy["explanation"] = (
|
|
101
|
+
"Massive network - distributed computation recommended"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Estimate memory requirements
|
|
105
|
+
estimated_memory = self._estimate_memory_usage(graph_size, strategy["backend"])
|
|
106
|
+
strategy["estimated_memory_gb"] = estimated_memory
|
|
107
|
+
|
|
108
|
+
# Check memory constraints
|
|
109
|
+
if estimated_memory > available_memory_gb * 0.8:
|
|
110
|
+
strategy["warning"] = (
|
|
111
|
+
f"Estimated memory ({estimated_memory:.1f}GB) may exceed "
|
|
112
|
+
f"available memory ({available_memory_gb:.1f}GB)"
|
|
113
|
+
)
|
|
114
|
+
strategy["recommendation"] = (
|
|
115
|
+
"Consider distributed backend or smaller partition sizes"
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Estimate execution time
|
|
119
|
+
estimated_time = self._estimate_execution_time(graph_size, strategy["backend"])
|
|
120
|
+
strategy["estimated_time_minutes"] = estimated_time
|
|
121
|
+
|
|
122
|
+
return strategy
|
|
123
|
+
|
|
124
|
+
def _estimate_memory_usage(self, graph_size: int, backend: str) -> float:
|
|
125
|
+
"""Estimate memory usage in gigabytes.
|
|
126
|
+
|
|
127
|
+
Parameters
|
|
128
|
+
----------
|
|
129
|
+
graph_size : int
|
|
130
|
+
Number of nodes
|
|
131
|
+
backend : str
|
|
132
|
+
Execution backend
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
float
|
|
137
|
+
Estimated memory in GB
|
|
138
|
+
"""
|
|
139
|
+
# Base memory: ~1KB per node for attributes
|
|
140
|
+
base_memory_gb = graph_size * 0.001 / 1024
|
|
141
|
+
|
|
142
|
+
# Backend multipliers account for overhead
|
|
143
|
+
backend_multipliers = {
|
|
144
|
+
"sequential": 1.0,
|
|
145
|
+
"multiprocessing": 1.5, # Serialization overhead
|
|
146
|
+
"gpu": 2.0, # GPU + CPU copies
|
|
147
|
+
"distributed": 1.2, # Network overhead minimal
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
multiplier = backend_multipliers.get(backend, 1.0)
|
|
151
|
+
return base_memory_gb * multiplier
|
|
152
|
+
|
|
153
|
+
def _estimate_execution_time(self, graph_size: int, backend: str) -> float:
|
|
154
|
+
"""Estimate execution time in minutes.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
graph_size : int
|
|
159
|
+
Number of nodes
|
|
160
|
+
backend : str
|
|
161
|
+
Execution backend
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
float
|
|
166
|
+
Estimated time in minutes
|
|
167
|
+
|
|
168
|
+
Notes
|
|
169
|
+
-----
|
|
170
|
+
Based on empirical observations. Actual times depend on:
|
|
171
|
+
- Network density (edges per node)
|
|
172
|
+
- Operator complexity
|
|
173
|
+
- Hardware specifications
|
|
174
|
+
- Cache efficiency
|
|
175
|
+
"""
|
|
176
|
+
# Base time per 1000 nodes (calibrated with benchmarks)
|
|
177
|
+
base_time_per_1k = {
|
|
178
|
+
"sequential": 2.0, # 2 min per 1000 nodes
|
|
179
|
+
"multiprocessing": 0.5, # 4x speedup typical
|
|
180
|
+
"gpu": 0.1, # 20x speedup on modern GPUs
|
|
181
|
+
"distributed": 0.2, # 10x speedup with cluster
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
time_factor = base_time_per_1k.get(backend, 2.0)
|
|
185
|
+
return (graph_size / 1000.0) * time_factor
|
|
186
|
+
|
|
187
|
+
def get_optimization_suggestions(
|
|
188
|
+
self, performance_metrics: Dict[str, Any]
|
|
189
|
+
) -> List[str]:
|
|
190
|
+
"""Generate optimization suggestions based on observed performance.
|
|
191
|
+
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
performance_metrics : Dict[str, Any]
|
|
195
|
+
Performance data from execution monitoring
|
|
196
|
+
|
|
197
|
+
Returns
|
|
198
|
+
-------
|
|
199
|
+
list[str]
|
|
200
|
+
List of actionable optimization suggestions
|
|
201
|
+
"""
|
|
202
|
+
suggestions = []
|
|
203
|
+
|
|
204
|
+
# Check parallelization efficiency
|
|
205
|
+
if "parallelization_efficiency" in performance_metrics:
|
|
206
|
+
eff = performance_metrics["parallelization_efficiency"]
|
|
207
|
+
if eff < 0.5:
|
|
208
|
+
suggestions.append(
|
|
209
|
+
"⚡ Low parallelization efficiency - consider reducing "
|
|
210
|
+
"worker count or increasing partition size"
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# Check memory usage
|
|
214
|
+
if "memory_efficiency" in performance_metrics:
|
|
215
|
+
mem_eff = performance_metrics["memory_efficiency"]
|
|
216
|
+
if mem_eff < 0.1:
|
|
217
|
+
suggestions.append(
|
|
218
|
+
"💾 High memory usage - consider distributed execution "
|
|
219
|
+
"or memory optimization"
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Check throughput
|
|
223
|
+
if "operations_per_second" in performance_metrics:
|
|
224
|
+
ops = performance_metrics["operations_per_second"]
|
|
225
|
+
if ops < 100:
|
|
226
|
+
suggestions.append(
|
|
227
|
+
"📈 Low throughput - consider GPU backend or algorithm "
|
|
228
|
+
"optimization"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
if not suggestions:
|
|
232
|
+
suggestions.append("✨ Performance looks optimal!")
|
|
233
|
+
|
|
234
|
+
return suggestions
|