Modules Directory Overview
Why This Page Exists
The fusion/modules/ directory contains algorithm implementations that can be
confusing to navigate. This page provides a high-level map to help you understand:
What lives where and why
Legacy code vs. orchestrator-compatible code
How modules connect to the simulation engine
Where to go when you want to modify specific functionality
Overview
At a Glance
- Purpose:
Pluggable algorithm implementations (routing, spectrum, SNR, RL, etc.)
- Location:
fusion/modules/- Contains:
routing/, spectrum/, snr/, rl/, ml/, failures/
- Used By:
fusion.core(via adapters),fusion.pipelines
Detailed Module Documentation
Looking for specific module docs? Jump directly to:
Failures Module - Network failure injection (beta)
Machine Learning Module - Machine learning utilities (beta)
Reinforcement Learning Module - Reinforcement learning (transitioning to UnifiedSimEnv)
Routing Module - Path computation algorithms
SNR Module - Signal quality assessment
Spectrum Module - Spectrum slot assignment algorithms
The modules directory contains algorithm implementations - the actual logic for
routing paths, assigning spectrum, calculating SNR, and making RL decisions. These are
the building blocks that the simulation engine uses.
The key confusion point: There are multiple places where similar-sounding code lives:
fusion/modules/- Algorithm implementations (this directory)fusion/pipelines/- Orchestrator pipeline wrappersfusion/core/adapters/- Legacy-to-orchestrator bridgesfusion/interfaces/- Protocol definitions (no logic)fusion/domain/- Data structures (no logic)
This page explains how they all connect.
Understanding the Architecture
Legacy vs. Orchestrator: The Big Picture
FUSION supports two simulation architectures that coexist:
+------------------------------------------------------------------+
| SIMULATION ENGINE |
| |
| use_orchestrator = False use_orchestrator = True |
| (Legacy Path) (Orchestrator Path) |
+------------------------------------------------------------------+
| |
v v
+------------------+ +------------------+
| SDNController | | SDNOrchestrator |
| (fusion/core/) | | (fusion/core/) |
+--------+---------+ +--------+---------+
| |
| Direct calls | Via Adapters
| |
v v
+------------------+ +------------------+
| fusion/modules/ | | fusion/core/ |
| routing/ |<-----------------| adapters/ |
| spectrum/ | Adapters wrap | |
| snr/ | legacy modules +--------+---------+
+------------------+ |
| Adapters call
|
v
+------------------+
| fusion/modules/ |
| (same code!) |
+------------------+
Key insight: The modules in fusion/modules/ are used by BOTH paths. The adapters
in fusion/core/adapters/ simply wrap them to satisfy the orchestrator’s pipeline
protocols.
Where Algorithm Logic Lives
If You Want To… |
Look In… |
Notes |
|---|---|---|
Modify routing algorithms |
|
K-shortest-path, congestion-aware, etc. |
Modify spectrum assignment |
|
First-fit, best-fit, last-fit |
Modify SNR calculations |
|
Module has helpers; core has main logic |
Add RL policies |
|
BC, IQL, pointer network policies |
Add RL environments |
|
Gym-compatible environments |
Modify failure handling |
|
Link, node, SRLG failures |
Modify ML preprocessing |
|
Feature engineering, evaluation |
What About fusion/pipelines/?
The fusion/pipelines/ directory contains orchestrator-specific implementations
that don’t use the legacy module structure:
fusion/pipelines/
|-- routing_pipeline.py # New routing for orchestrator
|-- routing_strategies.py # Strategy pattern implementations
|-- protection_pipeline.py # 1+1 protection logic
|-- slicing_pipeline.py # Request slicing logic
`-- disjoint_path_finder.py # Path computation utilities
These are not wrappers around fusion/modules/. They are fresh implementations
designed specifically for the orchestrator’s pipeline protocol.
When to use which:
Modifying legacy simulation behavior ->
fusion/modules/Adding new orchestrator features ->
fusion/pipelines/The adapters bridge the gap when orchestrator needs legacy algorithms
See also
For detailed documentation on the pipelines module, see Pipelines Module.
Module Directory Structure
fusion/modules/
|
|-- routing/ # Path computation algorithms
| |-- k_shortest_path.py # Basic K-SP routing
| |-- congestion_aware.py # Load-balanced routing
| |-- least_congested.py # Bottleneck-aware routing
| |-- fragmentation_aware.py
| |-- nli_aware.py # Non-linear impairment aware
| |-- xt_aware.py # Cross-talk aware (multi-core)
| |-- one_plus_one_protection.py # Protection path finding
| |-- registry.py # Algorithm discovery
| `-- utils.py
|
|-- spectrum/ # Spectrum slot assignment
| |-- first_fit.py # First available slots
| |-- best_fit.py # Smallest fitting gap
| |-- last_fit.py # Last available slots
| |-- light_path_slicing.py # Large request segmentation
| |-- registry.py
| `-- utils.py
|
|-- snr/ # Signal quality utilities
| |-- snr.py # SNR helper functions
| |-- registry.py
| `-- utils.py
|
|-- rl/ # Reinforcement learning
| |-- policies/ # Decision-making policies
| | |-- bc_policy.py # Behavioral cloning
| | |-- iql_policy.py # Implicit Q-learning
| | |-- pointer_policy.py # Attention-based
| | |-- ksp_ff_policy.py # K-SP + First-Fit baseline
| | `-- one_plus_one_policy.py
| |-- gymnasium_envs/ # RL environments
| |-- agents/ # Agent implementations
| |-- algorithms/ # RL algorithm configs
| |-- feat_extrs/ # Feature extractors
| |-- sb3/ # Stable-Baselines3 integration
| `-- utils/ # RL utilities
|
|-- ml/ # Machine learning utilities
| |-- preprocessing.py # Data preprocessing
| |-- feature_engineering.py
| |-- evaluation.py
| `-- model_io.py # Model save/load
|
`-- failures/ # Network failure simulation
|-- failure_manager.py # Failure orchestration
|-- failure_types.py # F1/F2/F3/F4 failures
`-- registry.py
How Modules Connect to the Simulator
The Registry Pattern
Each module uses a registry pattern for algorithm discovery:
# In fusion/modules/routing/registry.py
from fusion.modules.routing import RoutingRegistry, create_algorithm
# List available algorithms
algorithms = RoutingRegistry.list_algorithms()
# ['k_shortest_path', 'congestion_aware', 'least_congested', ...]
# Create an algorithm instance
router = create_algorithm("k_shortest_path", engine_props, sdn_props)
# Use it
path = router.route(source="0", destination="5", request=request_obj)
The same pattern applies to:
fusion.modules.spectrum.SpectrumRegistryfusion.modules.snr.SnrRegistry
Legacy Path: Direct Usage
In the legacy path, SDNController creates algorithm instances directly:
# Inside SDNController (simplified)
from fusion.modules.routing import create_algorithm
self.router = create_algorithm(
engine_props["routing_algorithm"],
engine_props,
sdn_props
)
# Later, during request processing:
path = self.router.route(source, destination, request)
Orchestrator Path: Via Adapters
The orchestrator uses adapters that wrap legacy modules:
# Inside fusion/core/adapters/routing_adapter.py (simplified)
from fusion.modules.routing import create_algorithm
class RoutingAdapter:
"""Wraps legacy routing to satisfy RoutingPipeline protocol."""
def __init__(self, engine_props, sdn_props):
# Create the legacy algorithm
self._legacy_router = create_algorithm(
engine_props["routing_algorithm"],
engine_props,
sdn_props
)
def find_routes(self, source, dest, bandwidth, network_state, **kwargs):
# Call legacy router, convert result to RouteResult
paths = self._legacy_router.route(source, dest, ...)
return RouteResult(paths=paths, ...)
The adapter’s job:
Accept orchestrator-style parameters (
NetworkState, etc.)Call the legacy module with its expected parameters
Convert the result to a domain object (
RouteResult, etc.)
Common Confusion Points
“Where is First-Fit implemented?”
There are two first-fit implementations:
Legacy:
fusion/modules/spectrum/first_fit.py- Class:FirstFitSpectrum- Used by:SDNController(legacy path) - Also used by:SpectrumAdapter(orchestrator path, via wrapping)There is no separate orchestrator first-fit - The orchestrator uses the legacy implementation via
SpectrumAdapter
“What’s the difference between policies and modules?”
Concept |
|
|
|---|---|---|
Contains |
Actual policy implementations |
Protocol definition (interface) |
Purpose |
Provides BC, IQL, pointer policies |
Defines what methods a policy must have |
Has Logic? |
Yes - neural networks, decision logic |
No - just method signatures |
Think of it this way:
interfaces/control_policy.pysays “a policy must haveselect_action()”modules/rl/policies/iql_policy.pyprovides an actualselect_action()implementation
“Where do I add a new routing algorithm?”
Create
fusion/modules/routing/my_algorithm.pyInherit from
AbstractRoutingAlgorithm(infusion/interfaces/router.py)Register in
fusion/modules/routing/registry.pyThat’s it - both legacy and orchestrator paths will be able to use it
The adapters automatically pick up registered algorithms.
“Why are there adapters if modules already work?”
The orchestrator uses typed protocols (RoutingPipeline, SpectrumPipeline)
that expect:
Immutable
NetworkStateparameterReturn domain objects (
RouteResult,SpectrumResult)Specific method signatures
Legacy modules expect:
Mutable
engine_propsandsdn_propsdictsReturn plain dictionaries or tuples
Different method names
Adapters bridge this gap so we can reuse existing, tested algorithms without rewriting them.
Development Guide
Adding a New Algorithm
For routing:
# fusion/modules/routing/my_routing.py
from fusion.interfaces.router import AbstractRoutingAlgorithm
class MyRouting(AbstractRoutingAlgorithm):
def __init__(self, engine_props, sdn_props):
super().__init__(engine_props, sdn_props)
def route(self, source, destination, request):
# Your routing logic here
return {"path": [...], "weight": ...}
# Register in registry.py
RoutingRegistry.register("my_routing", MyRouting)
For spectrum:
# fusion/modules/spectrum/my_spectrum.py
from fusion.interfaces.spectrum import AbstractSpectrumAssigner
class MySpectrum(AbstractSpectrumAssigner):
def assign(self, path, request):
# Your spectrum logic here
return {"start_slot": ..., "end_slot": ..., "core": ...}
# Register in registry.py
SpectrumRegistry.register("my_spectrum", MySpectrum)
Adding a New RL Policy
# fusion/modules/rl/policies/my_policy.py
from fusion.modules.rl.policies.base import BasePolicy
class MyPolicy(BasePolicy):
def select_action(self, observation, action_mask=None):
# Your decision logic here
return action_index
def update(self, *args, **kwargs):
# Training update (or pass for heuristics)
pass
Testing
- Test Location:
fusion/modules/tests/(integration) andfusion/modules/*/tests/(unit)- Run Tests:
pytest fusion/modules/ -v
# Run all module tests
pytest fusion/modules/ -v
# Run specific submodule tests
pytest fusion/modules/tests/routing/ -v
pytest fusion/modules/tests/spectrum/ -v
pytest fusion/modules/tests/rl/ -v
Quick Reference: Where To Go
I want to… |
Go to… |
|---|---|
Add a new routing algorithm |
|
Modify first-fit spectrum |
|
Add an RL policy |
|
Create an RL environment |
|
Change how adapters convert data |
|
Add a new pipeline stage |
|
Define a new protocol |
|
Add a domain object |
|
Change failure simulation |