Skip to content

Commit 66faf5e

Browse files
refactor(config): implement hybrid nested/flat configuration architecture
Resolve configuration duplication issues by implementing a hybrid system that supports both nested sections and flat backward-compatible access patterns. Changes: - Update config loader to preserve non-general sections as nested dicts - Add mirroring function to copy nested values to root for backward compat - Move route_method and allocation_method from required to optional settings - Reorganize routing and spectrum parameters into dedicated sections - Add missing ml_settings parameters across all config files - Add missing failure_settings parameters to survivability examples This allows new code to access engine_props["routing_settings"]["k_paths"] while legacy code continues to work with engine_props["k_paths"]. All configuration files now have clean separation between general_settings and specialized sections (routing_settings, spectrum_settings, ml_settings). Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c9259bf commit 66faf5e

9 files changed

Lines changed: 129 additions & 48 deletions

File tree

fusion/cli/config_setup.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ def _process_optional_options(
140140
# This allows .get() calls with defaults to work correctly
141141
continue
142142

143+
# Determine if this section should be nested or flattened
144+
# general_settings gets flattened (backward compatibility)
145+
# Other sections get nested (new architecture)
146+
flatten_section = category == "general_settings"
147+
148+
if not flatten_section:
149+
# Initialize nested dict for this section if needed
150+
if category not in config_dict[DEFAULT_THREAD_NAME]:
151+
config_dict[DEFAULT_THREAD_NAME][category] = {}
152+
143153
for option, type_obj in options_dict.items():
144154
# Only process options that are present in the config
145155
if option in config[category]:
@@ -153,9 +163,16 @@ def _process_optional_options(
153163

154164
# Apply CLI override
155165
cli_value = args_dict.get(option)
156-
config_dict[DEFAULT_THREAD_NAME][option] = apply_cli_override(
166+
final_value = apply_cli_override(
157167
converted_value, cli_value, type_obj
158168
)
169+
170+
# Store in appropriate location (flat or nested)
171+
if flatten_section:
172+
config_dict[DEFAULT_THREAD_NAME][option] = final_value
173+
else:
174+
config_dict[DEFAULT_THREAD_NAME][category][option] = final_value
175+
159176
except ConfigTypeConversionError:
160177
# Skip options that can't be converted - they're optional
161178
continue
@@ -233,6 +250,9 @@ def load_config(
233250
)
234251
_process_optional_options(config, config_dict, OPTIONAL_OPTIONS_DICT, args_dict)
235252

253+
# Mirror routing_settings and spectrum_settings to root for backward compatibility
254+
_mirror_nested_to_flat(config_dict[DEFAULT_THREAD_NAME])
255+
236256
thread_sections = [s for s in config.sections() if s != REQUIRED_SECTION]
237257
if thread_sections:
238258
config_dict = _setup_threads(
@@ -315,6 +335,41 @@ def _find_category(
315335
return None
316336

317337

338+
def _mirror_nested_to_flat(config: dict[str, Any]) -> None:
339+
"""
340+
Mirror values from nested sections to root level for backward compatibility.
341+
342+
This allows newer code to use nested structure (engine_props["routing_settings"]["k_paths"])
343+
while older code can still use flat structure (engine_props["k_paths"]).
344+
345+
:param config: Configuration dictionary to update in-place
346+
:type config: dict[str, Any]
347+
"""
348+
# Define which nested sections should be mirrored to root
349+
# All optional sections that aren't general_settings should be mirrored
350+
mirror_sections = [
351+
"routing_settings",
352+
"spectrum_settings",
353+
"ml_settings",
354+
"rl_settings",
355+
"failure_settings",
356+
"protection_settings",
357+
"offline_rl_settings",
358+
"dataset_logging_settings",
359+
"recovery_timing_settings",
360+
"reporting_settings",
361+
]
362+
363+
for section in mirror_sections:
364+
if section in config and isinstance(config[section], dict):
365+
# Copy all values from nested section to root level
366+
for key, value in config[section].items():
367+
# Only mirror if not already present at root level
368+
# (root level takes precedence for backward compat)
369+
if key not in config:
370+
config[key] = value
371+
372+
318373
def load_and_validate_config(args: Any) -> dict[str, Any]:
319374
"""
320375
Load and validate configuration from CLI arguments.

fusion/configs/examples/dataset_generation.ini

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
erlang_start = 100
99
erlang_stop = 150
1010
erlang_step = 100
11-
max_iters = 2
11+
max_iters = 3
1212
# More requests for larger dataset
13-
num_requests = 10
13+
num_requests = 8
1414
holding_time = 0.2
1515
thread_num = s1
1616
seed = 42
@@ -26,11 +26,6 @@ dynamic_lps = False
2626
fixed_grid = False
2727
pre_calc_mod_selection = False
2828
max_segments = 4
29-
30-
# Routing/spectrum (also in sections below)
31-
route_method = k_shortest_path
32-
allocation_method = first_fit
33-
k_paths = 4
3429
guard_slots = 1
3530

3631
# Monitoring
@@ -47,14 +42,14 @@ log_level = WARNING
4742

4843
[topology_settings]
4944
network = NSFNet
50-
cores_per_link = 7
45+
cores_per_link = 3
5146
bw_per_slot = 12.5
5247
const_link_weight = False
5348
is_only_core_node = True
5449
multi_fiber = False
5550

5651
[spectrum_settings]
57-
c_band = 320
52+
c_band = 10
5853
guard_slots = 1
5954
allocation_method = first_fit
6055

@@ -63,6 +58,11 @@ file_type = json
6358

6459
[ml_settings]
6560
deploy_model = False
61+
output_train_data = False
62+
ml_training = False
63+
ml_model = None
64+
train_file_path = None
65+
test_size = 0.3
6666

6767
[rl_settings]
6868
obs_space = obs_3
@@ -71,12 +71,16 @@ device = cpu
7171
optimize_hyperparameters = False
7272
optuna_trials = 1
7373
is_training = False
74+
7475
path_algorithm = dqn
7576
path_model = None
77+
7678
core_algorithm = first_fit
7779
core_model = None
80+
7881
spectrum_algorithm = first_fit
7982
spectrum_model = None
83+
8084
render_mode = None
8185
super_channel_space = 3
8286
alpha_start = 0.000215
@@ -88,13 +92,16 @@ epsilon_end = 0.01
8892
epsilon_update = exp_decay
8993
path_levels = 2
9094
decay_rate = 0.4
95+
9196
feature_extractor = path_gnn
9297
gnn_type = graph_conv
9398
layers = 2
9499
emb_dim = 64
95100
heads = 4
101+
96102
conf_param = 2
97103
cong_cutoff = 0.9
104+
98105
reward = 1
99106
penalty = -10
100107
dynamic_reward = False
@@ -108,15 +115,17 @@ precompute_paths = true
108115

109116
[failure_settings]
110117
# Vary failure types across runs for diverse data
111-
failure_type = geo
118+
failure_type = link
119+
failed_link_src = 0
120+
failed_link_dst = 1
112121
geo_center_node = 5
113122
geo_hop_radius = 2
114123

115124
t_fail_arrival_index = -1
116-
t_repair_after_arrivals = 1000
125+
t_repair_after_arrivals = 2
117126

118127
[protection_settings]
119-
protection_mode = none
128+
protection_mode = one_plus_one
120129

121130
[offline_rl_settings]
122131
# Use KSP-FF for data collection
@@ -130,15 +139,15 @@ log_offline_dataset = true
130139
dataset_output_path = datasets/training_dataset.jsonl
131140

132141
# Higher epsilon for more exploration during data collection
133-
epsilon_mix = 0.2
142+
epsilon_mix = 0.05
134143

135144
[recovery_timing_settings]
136145
protection_switchover_ms = 50.0
137146
restoration_latency_ms = 100.0
138147
failure_window_size = 1000
139148

140149
[reporting_settings]
141-
export_csv = true
150+
export_csv = false
142151
csv_output_path = results/dataset_generation.csv
143152

144153
[snr_settings]

fusion/configs/examples/geo_failure_protection.ini

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ dynamic_lps = False
2626
fixed_grid = False
2727
pre_calc_mod_selection = False
2828
max_segments = 4
29-
30-
# Routing/spectrum (also in sections below)
31-
route_method = k_shortest_path
32-
allocation_method = first_fit
33-
k_paths = 4
3429
guard_slots = 1
3530

3631
# Monitoring
@@ -63,6 +58,11 @@ file_type = json
6358

6459
[ml_settings]
6560
deploy_model = False
61+
output_train_data = False
62+
ml_training = False
63+
ml_model = None
64+
train_file_path = None
65+
test_size = 0.3
6666

6767
[rl_settings]
6868
obs_space = obs_3
@@ -109,6 +109,8 @@ precompute_paths = true
109109
[failure_settings]
110110
# Geographic failure (F4) - simulates disaster scenario
111111
failure_type = geo
112+
failed_link_src = 0
113+
failed_link_dst = 1
112114
geo_center_node = 5
113115
geo_hop_radius = 2
114116

fusion/configs/examples/link_failure_ksp_ff.ini

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ dynamic_lps = False
2525
fixed_grid = False
2626
pre_calc_mod_selection = False
2727
max_segments = 4
28-
29-
# Routing/spectrum (also in sections below)
30-
route_method = k_shortest_path
31-
allocation_method = first_fit
32-
k_paths = 4
3328
guard_slots = 1
3429

3530
# Monitoring
@@ -62,6 +57,11 @@ file_type = json
6257

6358
[ml_settings]
6459
deploy_model = False
60+
output_train_data = False
61+
ml_training = False
62+
ml_model = None
63+
train_file_path = None
64+
test_size = 0.3
6565

6666
[rl_settings]
6767
obs_space = obs_3
@@ -110,6 +110,8 @@ precompute_paths = true
110110
failure_type = link
111111
failed_link_src = 0
112112
failed_link_dst = 1
113+
geo_center_node = 5
114+
geo_hop_radius = 2
113115

114116
# Failure timing
115117
t_fail_arrival_index = -1 # Midpoint

fusion/configs/examples/rl_policy_eval.ini

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ dynamic_lps = False
2525
fixed_grid = False
2626
pre_calc_mod_selection = False
2727
max_segments = 4
28-
29-
# Routing/spectrum (also in sections below)
30-
route_method = k_shortest_path
31-
allocation_method = first_fit
32-
k_paths = 4
3328
guard_slots = 1
3429

3530
# Monitoring
@@ -62,6 +57,11 @@ file_type = json
6257

6358
[ml_settings]
6459
deploy_model = False
60+
output_train_data = False
61+
ml_training = False
62+
ml_model = None
63+
train_file_path = None
64+
test_size = 0.3
6565

6666
[rl_settings]
6767
obs_space = obs_3
@@ -108,6 +108,10 @@ precompute_paths = true
108108
[failure_settings]
109109
# SRLG failure (F3) - multiple links sharing common risk
110110
failure_type = srlg
111+
failed_link_src = 0
112+
failed_link_dst = 1
113+
geo_center_node = 5
114+
geo_hop_radius = 2
111115

112116
# Define SRLG: links that share a conduit
113117
srlg_links = [(0,1), (1,2), (2,3)]

fusion/configs/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
"fixed_grid": str_to_bool,
3434
"pre_calc_mod_selection": str_to_bool,
3535
"max_segments": int,
36-
"route_method": str,
37-
"allocation_method": str,
3836
"save_snapshots": str_to_bool,
3937
"snapshot_step": int,
4038
"print_step": int,
@@ -88,6 +86,8 @@
8886
"e_band": int,
8987
"s_band": int,
9088
"l_band": int,
89+
"guard_slots": int,
90+
"allocation_method": str,
9191
},
9292
"file_settings": {
9393
"run_id": str,

fusion/configs/templates/default.ini

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ spectrum_priority = None
2323
num_requests = 500
2424
request_distribution = {"25": 0.10, "50": 0.10, "100": 0.50, "200": 0.20, "400": 0.10}
2525

26-
# Routing and spectrum assignment
27-
allocation_method = first_fit
28-
k_paths = 4
29-
route_method = k_shortest_path
30-
3126
# Output and monitoring
3227
save_snapshots = False
3328
snapshot_step = 10
@@ -48,9 +43,16 @@ const_link_weight = False
4843
is_only_core_node = True
4944
multi_fiber = False
5045

46+
[routing_settings]
47+
# Routing configuration
48+
route_method = k_shortest_path
49+
k_paths = 4
50+
5151
[spectrum_settings]
5252
# Spectrum management
5353
c_band = 320
54+
guard_slots = 1
55+
allocation_method = first_fit
5456

5557
[snr_settings]
5658
# Signal-to-noise ratio configuration

0 commit comments

Comments
 (0)