Coverage for src/sparkle/CLI/run_portfolio_selector.py: 30%
57 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-08 12:00 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-08 12:00 +0000
1#!/usr/bin/env python3
2"""Sparkle command to execute a portfolio selector."""
4import sys
5import argparse
7from runrunner import Runner
9from sparkle.CLI.help import global_variables as gv
10from sparkle.CLI.help import logging as sl
11from sparkle.platform.settings_objects import Settings
12from sparkle.CLI.help import argparse_custom as ac
13from sparkle.structures import FeatureDataFrame
14from sparkle.CLI.initialise import check_for_initialise
15from sparkle.CLI.help.nicknames import resolve_object_name
16from sparkle.instance import Instance_Set, InstanceSet
17from sparkle.CLI.compute_features import compute_features
18from sparkle.selector import SelectionScenario, Extractor
19from sparkle.CLI.help import jobs as jobs_help
22def parser_function() -> argparse.ArgumentParser:
23 """Define the command line arguments."""
24 parser = argparse.ArgumentParser(
25 description="Run a portfolio selector on instance (set): Determine which solver "
26 "is most likely to perform well and run it on the instance (set)."
27 )
28 parser.add_argument(
29 *ac.SelectionScenarioArgument.names, **ac.SelectionScenarioArgument.kwargs
30 )
31 parser.add_argument(
32 *ac.InstanceSetRequiredArgument.names, **ac.InstanceSetRequiredArgument.kwargs
33 )
34 # Settings arguments
35 parser.add_argument(*ac.SettingsFileArgument.names, **ac.SettingsFileArgument.kwargs)
36 parser.add_argument(*Settings.OPTION_run_on.args, **Settings.OPTION_run_on.kwargs)
37 return parser
40def main(argv: list[str]) -> None:
41 """Main function of the run portfolio selector command."""
42 # Define command line arguments
43 parser = parser_function()
44 # Process command line arguments
45 args = parser.parse_args(argv)
46 settings = gv.settings(args)
48 # Log command call
49 sl.log_command(sys.argv, settings.random_state)
50 check_for_initialise()
52 # Compare current settings to latest.ini
53 prev_settings = Settings(Settings.DEFAULT_previous_settings_path)
54 Settings.check_settings_changes(settings, prev_settings)
56 data_set: InstanceSet = resolve_object_name(
57 args.instance,
58 gv.file_storage_data_mapping[gv.instances_nickname_path],
59 settings.DEFAULT_instance_dir,
60 Instance_Set,
61 )
63 if data_set is None:
64 print(
65 "ERROR: The instance (set) could not be found. Please make sure the "
66 "path is correct."
67 )
68 sys.exit(-1)
70 run_on = settings.run_on
71 selector_scenario = SelectionScenario.from_file(args.selection_scenario)
72 jobs_help.check_running_waiting_jobs(
73 settings.DEFAULT_log_output,
74 )
76 # Create a new feature dataframe for this run, compute the features
77 test_case_path = selector_scenario.directory / data_set.name
78 test_case_path.mkdir(exist_ok=True)
79 feature_dataframe = FeatureDataFrame(test_case_path / "feature_data.csv")
80 feature_dataframe.remove_instance(feature_dataframe.instance_pairs)
82 for extractor_name in selector_scenario.feature_extractors:
83 extractor = resolve_object_name(
84 extractor_name,
85 gv.file_storage_data_mapping[gv.instances_nickname_path],
86 settings.DEFAULT_extractor_dir,
87 Extractor,
88 )
89 feature_dataframe.add_extractor(extractor_name, extractor.features)
91 feature_dataframe.add_instance(data_set.instance_pairs)
92 feature_dataframe.save_csv()
93 feature_runs = compute_features(
94 feature_dataframe,
95 recompute=False,
96 run_on=run_on,
97 instance_sets=[data_set],
98 )
100 # Results need to be stored in the performance data object of the scenario:
101 # Add the instance set to it
102 selector_scenario.selector_performance_data.add_instance(data_set.instance_pairs)
103 selector_scenario.selector_performance_data.save_csv()
105 selector_run = selector_scenario.selector.run_cli(
106 scenario_path=selector_scenario.scenario_file,
107 instance_set=data_set,
108 feature_data=feature_dataframe.csv_filepath,
109 run_on=run_on,
110 slurm_prepend=settings.slurm_job_prepend,
111 sbatch_options=settings.sbatch_settings,
112 dependencies=feature_runs,
113 log_dir=sl.caller_log_dir,
114 )
116 if run_on == Runner.LOCAL:
117 selector_run.wait()
118 print("Running Sparkle portfolio selector done!")
119 else:
120 print("Sparkle portfolio selector is running ...")
122 # Write used settings to file
123 settings.write_used_settings()
124 sys.exit(0)
127if __name__ == "__main__":
128 main(sys.argv[1:])