Coverage for src / sparkle / CLI / run_portfolio_selector.py: 28%

57 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 15:31 +0000

1#!/usr/bin/env python3 

2"""Sparkle command to execute a portfolio selector.""" 

3 

4import sys 

5import argparse 

6 

7from runrunner import Runner 

8 

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 

19 

20 

21def parser_function() -> argparse.ArgumentParser: 

22 """Define the command line arguments.""" 

23 parser = argparse.ArgumentParser( 

24 description="Run a portfolio selector on instance (set): Determine which solver " 

25 "is most likely to perform well and run it on the instance (set)." 

26 ) 

27 parser.add_argument( 

28 *ac.SelectionScenarioArgument.names, **ac.SelectionScenarioArgument.kwargs 

29 ) 

30 parser.add_argument( 

31 *ac.InstanceSetRequiredArgument.names, **ac.InstanceSetRequiredArgument.kwargs 

32 ) 

33 # Settings arguments 

34 parser.add_argument(*ac.SettingsFileArgument.names, **ac.SettingsFileArgument.kwargs) 

35 parser.add_argument(*Settings.OPTION_run_on.args, **Settings.OPTION_run_on.kwargs) 

36 return parser 

37 

38 

39def main(argv: list[str]) -> None: 

40 """Main function of the run portfolio selector command.""" 

41 # Define command line arguments 

42 parser = parser_function() 

43 # Process command line arguments 

44 args = parser.parse_args(argv) 

45 settings = gv.settings(args) 

46 

47 # Log command call 

48 sl.log_command(sys.argv, settings.random_state) 

49 check_for_initialise() 

50 

51 # Compare current settings to latest.ini 

52 prev_settings = Settings(Settings.DEFAULT_previous_settings_path) 

53 Settings.check_settings_changes(settings, prev_settings) 

54 

55 data_set: InstanceSet = resolve_object_name( 

56 args.instance, 

57 gv.file_storage_data_mapping[gv.instances_nickname_path], 

58 settings.DEFAULT_instance_dir, 

59 Instance_Set, 

60 ) 

61 

62 if data_set is None: 

63 print( 

64 "ERROR: The instance (set) could not be found. Please make sure the " 

65 "path is correct." 

66 ) 

67 sys.exit(-1) 

68 

69 run_on = settings.run_on 

70 selector_scenario = SelectionScenario.from_file(args.selection_scenario) 

71 # Create a new feature dataframe for this run, compute the features 

72 test_case_path = selector_scenario.directory / data_set.name 

73 test_case_path.mkdir(exist_ok=True) 

74 feature_dataframe = FeatureDataFrame(test_case_path / "feature_data.csv") 

75 feature_dataframe.remove_instances(feature_dataframe.instances) 

76 print(feature_dataframe.extractors) 

77 for extractor_name in selector_scenario.feature_extractors: 

78 extractor = resolve_object_name( 

79 extractor_name, 

80 gv.file_storage_data_mapping[gv.instances_nickname_path], 

81 settings.DEFAULT_extractor_dir, 

82 Extractor, 

83 ) 

84 feature_dataframe.add_extractor(extractor_name, extractor.features) 

85 

86 feature_dataframe.add_instances(data_set.instances) 

87 feature_dataframe.save_csv() 

88 feature_runs = compute_features(feature_dataframe, recompute=False, run_on=run_on) 

89 

90 # Results need to be stored in the performance data object of the scenario: 

91 # Add the instance set to it 

92 for instance in data_set.instance_names: 

93 selector_scenario.selector_performance_data.add_instance(str(instance)) 

94 selector_scenario.selector_performance_data.save_csv() 

95 

96 selector_run = selector_scenario.selector.run_cli( 

97 scenario_path=selector_scenario.scenario_file, 

98 instance_set=data_set, 

99 feature_data=feature_dataframe.csv_filepath, 

100 run_on=run_on, 

101 slurm_prepend=settings.slurm_job_prepend, 

102 sbatch_options=settings.sbatch_settings, 

103 dependencies=feature_runs, 

104 log_dir=sl.caller_log_dir, 

105 ) 

106 

107 if run_on == Runner.LOCAL: 

108 selector_run.wait() 

109 print("Running Sparkle portfolio selector done!") 

110 else: 

111 print("Sparkle portfolio selector is running ...") 

112 

113 # Write used settings to file 

114 settings.write_used_settings() 

115 sys.exit(0) 

116 

117 

118if __name__ == "__main__": 

119 main(sys.argv[1:])