Coverage for sparkle/configurator/configurator.py: 80%
51 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 09:10 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 09:10 +0000
1#!/usr/bin/env python3
2# -*- coding: UTF-8 -*-
3"""Configurator class to use different algorithm configurators like SMAC."""
5from __future__ import annotations
6from abc import abstractmethod
7from pathlib import Path
9from runrunner import Runner, Run
10from sparkle.solver import Solver
11from sparkle.solver.validator import Validator
12from sparkle.instance import InstanceSet
13from sparkle.types import SparkleObjective
16class Configurator:
17 """Abstact class to use different configurators like SMAC."""
18 configurator_cli_path = Path(__file__).parent.resolve() / "configurator_cli.py"
20 def __init__(self: Configurator, validator: Validator, output_path: Path,
21 executable_path: Path, configurator_target: Path,
22 objectives: list[SparkleObjective], base_dir: Path, tmp_path: Path,
23 multi_objective_support: bool = False) -> None:
24 """Initialize Configurator.
26 Args:
27 validator: Validator object to validate configurations runs
28 output_path: Output directory of the Configurator.
29 executable_path: Executable of the configurator for Sparkle to call
30 configurator_target: The wrapper algorithm to standardize configurator
31 input/output towards solver wrappers.
32 objectives: The list of Sparkle Objectives the configurator has to
33 optimize.
34 base_dir: Where to execute the configuration
35 tmp_path: Path for the temporary files of the configurator, optional
36 multi_objective_support: Whether the configurator supports
37 multi objective optimization for solvers.
38 """
39 self.validator = validator
40 self.output_path = output_path
41 self.executable_path = executable_path
42 self.configurator_target = configurator_target
43 self.objectives = objectives
44 self.base_dir = base_dir
45 self.tmp_path = tmp_path
46 self.multiobjective = multi_objective_support
47 self.scenario = None
48 if len(self.objectives) > 1 and not self.multiobjective:
49 print("Warning: Multiple objectives specified but current configurator "
50 f"{self.configurator_path.name} only supports single objective. "
51 f"Defaulted to first specified objective: {self.objectives[0].name}")
53 @property
54 def scenario_class(self: Configurator) -> ConfigurationScenario:
55 """Return the scenario class of the configurator."""
56 return ConfigurationScenario
58 @abstractmethod
59 def configure(self: Configurator,
60 scenario: ConfigurationScenario,
61 validate_after: bool = True,
62 sbatch_options: list[str] = [],
63 num_parallel_jobs: int = None,
64 base_dir: Path = None,
65 run_on: Runner = Runner.SLURM) -> Run:
66 """Start configuration job.
68 Args:
69 scenario: ConfigurationScenario to execute.
70 validate_after: Whether to validate the configuration on the training set
71 afterwards or not.
72 sbatch_options: List of slurm batch options to use
73 num_parallel_jobs: The maximum number of jobs to run in parallel
74 base_dir: The base_dir of RunRunner where the sbatch scripts will be placed
75 run_on: On which platform to run the jobs. Default: Slurm.
77 Returns:
78 A RunRunner Run object.
79 """
80 raise NotImplementedError
82 @abstractmethod
83 def get_optimal_configuration(self: Configurator,
84 solver: Solver,
85 instance_set: InstanceSet,
86 objective: SparkleObjective) -> tuple[float, str]:
87 """Returns the optimal configuration string for a solver of an instance set."""
88 raise NotImplementedError
90 @staticmethod
91 def organise_output(output_source: Path, output_target: Path) -> None | str:
92 """Method to restructure and clean up after a single configurator call."""
93 raise NotImplementedError
95 def set_scenario_dirs(self: Configurator,
96 solver: Solver, instance_set: InstanceSet) -> None:
97 """Patching method to allow the rebuilding of configuration scenario."""
98 raise NotImplementedError
100 def get_status_from_logs(self: Configurator) -> None:
101 """Method to scan the log files of the configurator for warnings."""
102 raise NotImplementedError
105class ConfigurationScenario:
106 """Template class to handle a configuration scenarios."""
107 def __init__(self: ConfigurationScenario, solver: Solver,
108 instance_set: InstanceSet,
109 sparkle_objectives: list[SparkleObjective] = None)\
110 -> None:
111 """Initialize scenario paths and names.
113 Args:
114 solver: Solver that should be configured.
115 instance_set: Instances object for the scenario.
116 sparkle_objectives: SparkleObjectives used for each run of the configuration.
117 """
118 self.solver = solver
119 self.instance_set = instance_set
120 self.sparkle_objectives = sparkle_objectives
121 self.name = f"{self.solver.name}_{self.instance_set.name}"
123 def create_scenario(self: ConfigurationScenario, parent_directory: Path) -> None:
124 """Create scenario with solver and instances in the parent directory.
126 This prepares all the necessary subdirectories related to configuration.
128 Args:
129 parent_directory: Directory in which the scenario should be created.
130 """
131 raise NotImplementedError
133 def create_scenario_file(self: ConfigurationScenario) -> None:
134 """Create a file with the configuration scenario.
136 Writes supplementary information to the target algorithm (algo =) as:
137 algo = {configurator_target} {solver_directory} {sparkle_objective}
138 """
139 raise NotImplementedError
141 @staticmethod
142 def from_file(scenario_file: Path, solver: Solver, instance_set: InstanceSet,
143 ) -> ConfigurationScenario:
144 """Reads scenario file and initalises ConfigurationScenario."""
145 raise NotImplementedError