Coverage for sparkle/CLI/run_configured_solver.py: 89%
63 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-05 14:48 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-05 14:48 +0000
1#!/usr/bin/env python3
2"""Sparkle command to execute a configured solver."""
4import sys
5import argparse
6from pathlib import PurePath
8from runrunner.base import Runner
10from sparkle.CLI.help import global_variables as gv
11from sparkle.CLI.help import logging as sl
12from sparkle.platform.settings_objects import Settings, SettingState
13from sparkle.instance import Instance_Set
14from sparkle.platform import CommandName, COMMAND_DEPENDENCIES
15from sparkle.CLI.initialise import check_for_initialise
16from sparkle.CLI.help import argparse_custom as ac
17from sparkle.CLI.help.nicknames import resolve_object_name
20def parser_function() -> argparse.ArgumentParser:
21 """Define the command line arguments."""
22 parser = argparse.ArgumentParser(
23 description="Command to run a configured solver on an instance (set).")
24 parser.add_argument(*ac.InstancePathPositional.names,
25 **ac.InstancePathPositional.kwargs)
26 parser.add_argument(*ac.SettingsFileArgument.names,
27 **ac.SettingsFileArgument.kwargs)
28 parser.add_argument(*ac.SparkleObjectiveArgument.names,
29 **ac.SparkleObjectiveArgument.kwargs)
30 parser.add_argument(*ac.RunOnArgument.names,
31 **ac.RunOnArgument.kwargs)
32 return parser
35def main(argv: list[str]) -> None:
36 """Main function of the run configured solver command."""
37 # Log command call
38 sl.log_command(sys.argv)
40 # Define command line arguments
41 parser = parser_function()
43 # Process command line arguments
44 args = parser.parse_args(argv)
46 check_for_initialise(COMMAND_DEPENDENCIES[CommandName.RUN_CONFIGURED_SOLVER])
48 if args.settings_file is not None:
49 # Do first, so other command line options can override settings from the file
50 gv.settings().read_settings_ini(args.settings_file, SettingState.CMD_LINE)
51 if args.objectives is not None:
52 gv.settings().set_general_sparkle_objectives(
53 args.objectives, SettingState.CMD_LINE
54 )
55 if args.run_on is not None:
56 gv.settings().set_run_on(
57 args.run_on.value, SettingState.CMD_LINE)
59 # Compare current settings to latest.ini
60 prev_settings = Settings(PurePath("Settings/latest.ini"))
61 Settings.check_settings_changes(gv.settings(), prev_settings)
63 # Try to resolve the instance path (Dir or list instance paths)
64 data_set = resolve_object_name(
65 args.instance_path,
66 gv.file_storage_data_mapping[gv.instances_nickname_path],
67 gv.settings().DEFAULT_instance_dir, Instance_Set)
68 if data_set is None:
69 print(f"Could not resolve instance (set): {args.instance_path}! Exiting...")
70 sys.exit(-1)
72 run_on = gv.settings().get_run_on()
73 # Get the name of the configured solver and the training set
74 solver = gv.latest_scenario().get_config_solver()
75 train_set = gv.latest_scenario().get_config_instance_set_train()
76 custom_cutoff = gv.settings().get_general_target_cutoff_time()
77 if solver is None or train_set is None:
78 # Print error and stop execution
79 print("ERROR: No configured solver found! Stopping execution.")
80 sys.exit(-1)
81 # Get optimised configuration
82 configurator = gv.settings().get_general_sparkle_configurator()
83 objectives = gv.settings().get_general_sparkle_objectives()
84 configuration_scenario = gv.latest_scenario().get_configuration_scenario(
85 configurator.scenario_class)
86 _, config_str = configurator.get_optimal_configuration(configuration_scenario)
87 config = solver.config_str_to_dict(config_str)
88 # Call the configured solver
89 sbatch_options = gv.settings().get_slurm_extra_options(as_args=True)
90 if run_on == Runner.LOCAL:
91 print(f"Start running solver on {data_set.size} instances...")
92 run = solver.run(instance=data_set,
93 objectives=objectives,
94 seed=gv.get_seed(),
95 cutoff_time=custom_cutoff,
96 configuration=config,
97 run_on=run_on,
98 commandname=CommandName.RUN_CONFIGURED_SOLVER,
99 sbatch_options=sbatch_options,
100 log_dir=sl.caller_log_dir)
102 # Print result
103 if run_on == Runner.SLURM:
104 print(f"Running configured solver. Waiting for Slurm "
105 f"job(s) with id(s): {run.run_id}")
106 else:
107 if isinstance(run, dict):
108 run = [run]
109 for i, solver_output in enumerate(run):
110 print(f"Execution of {solver.name} on instance "
111 f"{data_set.instance_names[i]} completed with status "
112 f"{solver_output['status']} in {solver_output['cpu_time']} seconds.")
113 print("Running configured solver done!")
115 # Write used settings to file
116 gv.settings().write_used_settings()
117 sys.exit(0)
120if __name__ == "__main__":
121 main(sys.argv[1:])