Coverage for mlos_bench/mlos_bench/tests/tunables/tunable_distributions_test.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-05 00:36 +0000

1# 

2# Copyright (c) Microsoft Corporation. 

3# Licensed under the MIT License. 

4# 

5""" 

6Unit tests for checking tunable parameters' distributions. 

7""" 

8 

9import json5 as json 

10import pytest 

11 

12from mlos_bench.tunables.tunable import Tunable, TunableValueTypeName 

13 

14 

15def test_categorical_distribution() -> None: 

16 """ 

17 Try to instantiate a categorical tunable with distribution specified. 

18 """ 

19 with pytest.raises(ValueError): 

20 Tunable(name='test', config={ 

21 "type": "categorical", 

22 "values": ["foo", "bar", "baz"], 

23 "distribution": { 

24 "type": "uniform" 

25 }, 

26 "default": "foo" 

27 }) 

28 

29 

30@pytest.mark.parametrize("tunable_type", ["int", "float"]) 

31def test_numerical_distribution_uniform(tunable_type: TunableValueTypeName) -> None: 

32 """ 

33 Create a numeric Tunable with explicit uniform distribution. 

34 """ 

35 tunable = Tunable(name="test", config={ 

36 "type": tunable_type, 

37 "range": [0, 10], 

38 "distribution": { 

39 "type": "uniform" 

40 }, 

41 "default": 0 

42 }) 

43 assert tunable.is_numerical 

44 assert tunable.distribution == "uniform" 

45 assert not tunable.distribution_params 

46 

47 

48@pytest.mark.parametrize("tunable_type", ["int", "float"]) 

49def test_numerical_distribution_normal(tunable_type: TunableValueTypeName) -> None: 

50 """ 

51 Create a numeric Tunable with explicit Gaussian distribution specified. 

52 """ 

53 tunable = Tunable(name="test", config={ 

54 "type": tunable_type, 

55 "range": [0, 10], 

56 "distribution": { 

57 "type": "normal", 

58 "params": { 

59 "mu": 0, 

60 "sigma": 1.0 

61 } 

62 }, 

63 "default": 0 

64 }) 

65 assert tunable.distribution == "normal" 

66 assert tunable.distribution_params == {"mu": 0, "sigma": 1.0} 

67 

68 

69@pytest.mark.parametrize("tunable_type", ["int", "float"]) 

70def test_numerical_distribution_beta(tunable_type: TunableValueTypeName) -> None: 

71 """ 

72 Create a numeric Tunable with explicit Beta distribution specified. 

73 """ 

74 tunable = Tunable(name="test", config={ 

75 "type": tunable_type, 

76 "range": [0, 10], 

77 "distribution": { 

78 "type": "beta", 

79 "params": { 

80 "alpha": 2, 

81 "beta": 5 

82 } 

83 }, 

84 "default": 0 

85 }) 

86 assert tunable.distribution == "beta" 

87 assert tunable.distribution_params == {"alpha": 2, "beta": 5} 

88 

89 

90@pytest.mark.parametrize("tunable_type", ["int", "float"]) 

91def test_numerical_distribution_unsupported(tunable_type: str) -> None: 

92 """ 

93 Create a numeric Tunable with unsupported distribution. 

94 """ 

95 json_config = f""" 

96 {{ 

97 "type": "{tunable_type}", 

98 "range": [0, 10], 

99 "distribution": {{ 

100 "type": "poisson", 

101 "params": {{ 

102 "lambda": 1.0 

103 }} 

104 }}, 

105 "default": 0 

106 }} 

107 """ 

108 config = json.loads(json_config) 

109 with pytest.raises(ValueError): 

110 Tunable(name="test", config=config)