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

30 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-01 00:52 +0000

1# 

2# Copyright (c) Microsoft Corporation. 

3# Licensed under the MIT License. 

4# 

5"""Unit tests for checking tunable parameters' distributions.""" 

6 

7import json5 as json 

8import pytest 

9 

10from mlos_bench.tunables.tunable import Tunable 

11from mlos_bench.tunables.tunable_types import TunableValueTypeName 

12 

13 

14def test_categorical_distribution() -> None: 

15 """Try to instantiate a categorical tunable with distribution specified.""" 

16 with pytest.raises(ValueError): 

17 Tunable( 

18 name="test", 

19 config={ 

20 "type": "categorical", 

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

22 "distribution": {"type": "uniform"}, 

23 "default": "foo", 

24 }, 

25 ) 

26 

27 

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

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

30 """Create a numeric Tunable with explicit uniform distribution.""" 

31 tunable = Tunable( 

32 name="test", 

33 config={ 

34 "type": tunable_type, 

35 "range": [0, 10], 

36 "distribution": {"type": "uniform"}, 

37 "default": 0, 

38 }, 

39 ) 

40 assert tunable.is_numerical 

41 assert tunable.distribution == "uniform" 

42 assert not tunable.distribution_params 

43 

44 

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

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

47 """Create a numeric Tunable with explicit Gaussian distribution specified.""" 

48 tunable = Tunable( 

49 name="test", 

50 config={ 

51 "type": tunable_type, 

52 "range": [0, 10], 

53 "distribution": {"type": "normal", "params": {"mu": 0, "sigma": 1.0}}, 

54 "default": 0, 

55 }, 

56 ) 

57 assert tunable.distribution == "normal" 

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

59 

60 

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

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

63 """Create a numeric Tunable with explicit Beta distribution specified.""" 

64 tunable = Tunable( 

65 name="test", 

66 config={ 

67 "type": tunable_type, 

68 "range": [0, 10], 

69 "distribution": {"type": "beta", "params": {"alpha": 2, "beta": 5}}, 

70 "default": 0, 

71 }, 

72 ) 

73 assert tunable.distribution == "beta" 

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

75 

76 

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

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

79 """Create a numeric Tunable with unsupported distribution.""" 

80 json_config = f""" 

81 { 

82 "type": "{tunable_type}", 

83 "range": [0, 10], 

84 "distribution": { 

85 "type": "poisson", 

86 "params": { 

87 "lambda": 1.0 

88 } 

89 } , 

90 "default": 0 

91 } 

92 """ 

93 config = json.loads(json_config) 

94 assert isinstance(config, dict) 

95 with pytest.raises(ValueError): 

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