Coverage for mlos_bench/mlos_bench/optimizers/manual_optimizer.py: 96%

23 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 00:44 +0000

1# 

2# Copyright (c) Microsoft Corporation. 

3# Licensed under the MIT License. 

4# 

5""" 

6Manual config suggestor (Optimizer) for mlos_bench that proposes an explicit sequence of 

7configurations. 

8 

9This is useful for testing and validation, as it allows you to run a sequence of 

10configurations in a cyclic fashion. 

11 

12TODO: Add an example configuration. 

13""" 

14 

15import logging 

16from typing import Dict, List, Optional 

17 

18from mlos_bench.optimizers.mock_optimizer import MockOptimizer 

19from mlos_bench.services.base_service import Service 

20from mlos_bench.tunables.tunable import TunableValue 

21from mlos_bench.tunables.tunable_groups import TunableGroups 

22 

23_LOG = logging.getLogger(__name__) 

24 

25 

26class ManualOptimizer(MockOptimizer): 

27 """Optimizer that proposes an explicit sequence of tunable values.""" 

28 

29 def __init__( 

30 self, 

31 tunables: TunableGroups, 

32 config: dict, 

33 global_config: Optional[dict] = None, 

34 service: Optional[Service] = None, 

35 ): 

36 super().__init__(tunables, config, global_config, service) 

37 self._tunable_values_cycle: List[Dict[str, TunableValue]] = config.get( 

38 "tunable_values_cycle", [] 

39 ) 

40 assert len(self._tunable_values_cycle) > 0, "No tunable values provided." 

41 max_cycles = int(config.get("max_cycles", 1)) 

42 self._max_suggestions = min( 

43 self._max_suggestions, 

44 max_cycles * len(self._tunable_values_cycle), 

45 ) 

46 

47 def suggest(self) -> TunableGroups: 

48 """Always produce the same sequence of explicit suggestions, in a cycle.""" 

49 tunables = super().suggest() 

50 cycle_index = (self._iter - 1) % len(self._tunable_values_cycle) 

51 tunables.assign(self._tunable_values_cycle[cycle_index]) 

52 _LOG.info("Iteration %d :: Suggest: %s", self._iter, tunables) 

53 return tunables 

54 

55 @property 

56 def supports_preload(self) -> bool: 

57 return False