Coverage for mlos_core/mlos_core/tests/spaces/adapters/space_adapter_factory_test.py: 97%

34 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-10-07 01:52 +0000

1# 

2# Copyright (c) Microsoft Corporation. 

3# Licensed under the MIT License. 

4# 

5"""Tests for space adapter factory.""" 

6 

7# pylint: disable=missing-function-docstring 

8 

9from typing import List, Optional, Type 

10 

11import ConfigSpace as CS 

12import pytest 

13 

14from mlos_core.spaces.adapters import ( 

15 ConcreteSpaceAdapter, 

16 SpaceAdapterFactory, 

17 SpaceAdapterType, 

18) 

19from mlos_core.spaces.adapters.adapter import BaseSpaceAdapter 

20from mlos_core.spaces.adapters.identity_adapter import IdentityAdapter 

21from mlos_core.tests import get_all_concrete_subclasses 

22 

23 

24@pytest.mark.parametrize( 

25 ("space_adapter_type"), 

26 [ 

27 # Enumerate all supported SpaceAdapters 

28 # *[member for member in SpaceAdapterType], 

29 *list(SpaceAdapterType), 

30 ], 

31) 

32def test_concrete_optimizer_type(space_adapter_type: SpaceAdapterType) -> None: 

33 """Test that all optimizer types are listed in the ConcreteOptimizer constraints.""" 

34 # pylint: disable=no-member 

35 assert space_adapter_type.value in ConcreteSpaceAdapter.__constraints__ 

36 

37 

38@pytest.mark.parametrize( 

39 ("space_adapter_type", "kwargs"), 

40 [ 

41 # Default space adapter 

42 (None, {}), 

43 # Enumerate all supported Optimizers 

44 *[(member, {}) for member in SpaceAdapterType], 

45 ], 

46) 

47def test_create_space_adapter_with_factory_method( 

48 space_adapter_type: Optional[SpaceAdapterType], 

49 kwargs: Optional[dict], 

50) -> None: 

51 # Start defining a ConfigurationSpace for the Optimizer to search. 

52 input_space = CS.ConfigurationSpace(seed=1234) 

53 

54 # Add a single continuous input dimension between 0 and 1. 

55 input_space.add(CS.UniformFloatHyperparameter(name="x", lower=0, upper=1)) 

56 # Add a single continuous input dimension between 0 and 1. 

57 input_space.add(CS.UniformFloatHyperparameter(name="y", lower=0, upper=1)) 

58 

59 # Adjust some kwargs for specific space adapters 

60 if space_adapter_type is SpaceAdapterType.LLAMATUNE: 

61 if kwargs is None: 

62 kwargs = {} 

63 kwargs.setdefault("num_low_dims", 1) 

64 

65 space_adapter: BaseSpaceAdapter 

66 if space_adapter_type is None: 

67 space_adapter = SpaceAdapterFactory.create(parameter_space=input_space) 

68 else: 

69 space_adapter = SpaceAdapterFactory.create( 

70 parameter_space=input_space, 

71 space_adapter_type=space_adapter_type, 

72 space_adapter_kwargs=kwargs, 

73 ) 

74 

75 if space_adapter_type is None or space_adapter_type is SpaceAdapterType.IDENTITY: 

76 assert isinstance(space_adapter, IdentityAdapter) 

77 else: 

78 assert space_adapter is not None 

79 assert space_adapter.orig_parameter_space is not None 

80 myrepr = repr(space_adapter) 

81 assert myrepr.startswith( 

82 space_adapter_type.value.__name__ 

83 ), f"Expected {space_adapter_type.value.__name__} but got {myrepr}" 

84 

85 

86# Dynamically determine all of the optimizers we have implemented. 

87# Note: these must be sorted. 

88space_adapter_subclasses: List[Type[BaseSpaceAdapter]] = get_all_concrete_subclasses( 

89 BaseSpaceAdapter, # type: ignore[type-abstract] 

90 pkg_name="mlos_core", 

91) 

92assert space_adapter_subclasses 

93 

94 

95@pytest.mark.parametrize(("space_adapter_class"), space_adapter_subclasses) 

96def test_space_adapter_type_defs(space_adapter_class: Type[BaseSpaceAdapter]) -> None: 

97 """Test that all space adapter classes are listed in the SpaceAdapterType enum.""" 

98 space_adapter_type_classes = { 

99 space_adapter_type.value for space_adapter_type in SpaceAdapterType 

100 } 

101 assert space_adapter_class in space_adapter_type_classes