Coverage for mlos_core/mlos_core/tests/spaces/adapters/llamatune_test.py: 99%

171 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"""Tests for LlamaTune space adapter.""" 

6 

7# pylint: disable=missing-function-docstring 

8 

9from typing import Any, Dict, Iterator, List, Set 

10 

11import ConfigSpace as CS 

12import pandas as pd 

13import pytest 

14 

15from mlos_core.spaces.adapters import LlamaTuneAdapter 

16from mlos_core.spaces.converters.util import ( 

17 QUANTIZATION_BINS_META_KEY, 

18 monkey_patch_cs_quantization, 

19) 

20 

21# Explicitly test quantized values with llamatune space adapter. 

22# TODO: Add log scale sampling tests as well. 

23 

24 

25def construct_parameter_space( # pylint: disable=too-many-arguments 

26 *, 

27 n_continuous_params: int = 0, 

28 n_quantized_continuous_params: int = 0, 

29 n_integer_params: int = 0, 

30 n_quantized_integer_params: int = 0, 

31 n_categorical_params: int = 0, 

32 seed: int = 1234, 

33) -> CS.ConfigurationSpace: 

34 """Helper function for construct an instance of `ConfigSpace.ConfigurationSpace`.""" 

35 input_space = CS.ConfigurationSpace( 

36 seed=seed, 

37 space=[ 

38 *( 

39 CS.UniformFloatHyperparameter(name=f"cont_{idx}", lower=0, upper=64) 

40 for idx in range(n_continuous_params) 

41 ), 

42 *( 

43 CS.UniformFloatHyperparameter( 

44 name=f"cont_{idx}", lower=0, upper=64, meta={QUANTIZATION_BINS_META_KEY: 6} 

45 ) 

46 for idx in range(n_quantized_continuous_params) 

47 ), 

48 *( 

49 CS.UniformIntegerHyperparameter(name=f"int_{idx}", lower=-1, upper=256) 

50 for idx in range(n_integer_params) 

51 ), 

52 *( 

53 CS.UniformIntegerHyperparameter( 

54 name=f"int_{idx}", lower=0, upper=256, meta={QUANTIZATION_BINS_META_KEY: 17} 

55 ) 

56 for idx in range(n_quantized_integer_params) 

57 ), 

58 *( 

59 CS.CategoricalHyperparameter( 

60 name=f"str_{idx}", choices=[f"option_{idx}" for idx in range(5)] 

61 ) 

62 for idx in range(n_categorical_params) 

63 ), 

64 ], 

65 ) 

66 return monkey_patch_cs_quantization(input_space) 

67 

68 

69@pytest.mark.parametrize( 

70 ("num_target_space_dims", "param_space_kwargs"), 

71 ( 

72 [ 

73 (num_target_space_dims, param_space_kwargs) 

74 for num_target_space_dims in (2, 4) 

75 for num_orig_space_factor in (1.5, 4) 

76 for param_space_kwargs in ( 

77 {"n_continuous_params": int(num_target_space_dims * num_orig_space_factor)}, 

78 {"n_integer_params": int(num_target_space_dims * num_orig_space_factor)}, 

79 {"n_categorical_params": int(num_target_space_dims * num_orig_space_factor)}, 

80 {"n_categorical_params": int(num_target_space_dims * num_orig_space_factor)}, 

81 {"n_quantized_integer_params": int(num_target_space_dims * num_orig_space_factor)}, 

82 { 

83 "n_quantized_continuous_params": int( 

84 num_target_space_dims * num_orig_space_factor 

85 ) 

86 }, 

87 # Mix of all three types 

88 { 

89 "n_continuous_params": int(num_target_space_dims * num_orig_space_factor / 3), 

90 "n_integer_params": int(num_target_space_dims * num_orig_space_factor / 3), 

91 "n_categorical_params": int(num_target_space_dims * num_orig_space_factor / 3), 

92 }, 

93 ) 

94 ] 

95 ), 

96) 

97def test_num_low_dims( 

98 num_target_space_dims: int, 

99 param_space_kwargs: dict, 

100) -> None: # pylint: disable=too-many-locals 

101 """Tests LlamaTune's low-to-high space projection method.""" 

102 input_space = construct_parameter_space(**param_space_kwargs) 

103 

104 # Number of target parameter space dimensions should be fewer than those of the original space 

105 with pytest.raises(ValueError): 

106 LlamaTuneAdapter( 

107 orig_parameter_space=input_space, num_low_dims=len(list(input_space.keys())) 

108 ) 

109 

110 # Enable only low-dimensional space projections 

111 adapter = LlamaTuneAdapter( 

112 orig_parameter_space=input_space, 

113 num_low_dims=num_target_space_dims, 

114 special_param_values=None, 

115 max_unique_values_per_param=None, 

116 ) 

117 

118 sampled_configs = adapter.target_parameter_space.sample_configuration(size=100) 

119 for sampled_config in sampled_configs: # pylint: disable=not-an-iterable # (false positive) 

120 # Transform low-dim config to high-dim point/config 

121 sampled_config_sr = pd.Series(dict(sampled_config)) 

122 orig_config_sr = adapter.transform(sampled_config_sr) 

123 

124 # High-dim (i.e., original) config should be valid 

125 orig_config = CS.Configuration(input_space, values=orig_config_sr.to_dict()) 

126 orig_config.check_valid_configuration() 

127 

128 # Transform high-dim config back to low-dim 

129 target_config_sr = adapter.inverse_transform(orig_config_sr) 

130 

131 # Sampled config and this should be the same 

132 target_config = CS.Configuration( 

133 adapter.target_parameter_space, 

134 values=target_config_sr.to_dict(), 

135 ) 

136 assert target_config == sampled_config 

137 

138 # Try inverse projection (i.e., high-to-low) for previously unseen configs 

139 unseen_sampled_configs = adapter.target_parameter_space.sample_configuration(size=25) 

140 for ( 

141 unseen_sampled_config 

142 ) in unseen_sampled_configs: # pylint: disable=not-an-iterable # (false positive) 

143 if ( 

144 unseen_sampled_config 

145 in sampled_configs # pylint: disable=unsupported-membership-test # (false positive) 

146 ): 

147 continue 

148 

149 unseen_sampled_config_sr = pd.Series(dict(unseen_sampled_config)) 

150 with pytest.raises(ValueError): 

151 _ = adapter.inverse_transform( 

152 unseen_sampled_config_sr 

153 ) # pylint: disable=redefined-variable-type 

154 

155 

156def test_special_parameter_values_validation() -> None: 

157 """Tests LlamaTune's validation process of user-provided special parameter values 

158 dictionary. 

159 """ 

160 input_space = CS.ConfigurationSpace(seed=1234) 

161 input_space.add( 

162 CS.CategoricalHyperparameter(name="str", choices=[f"choice_{idx}" for idx in range(5)]) 

163 ) 

164 input_space.add(CS.UniformFloatHyperparameter(name="cont", lower=-1, upper=100)) 

165 input_space.add(CS.UniformIntegerHyperparameter(name="int", lower=0, upper=100)) 

166 

167 # Only UniformIntegerHyperparameters are currently supported 

168 with pytest.raises(NotImplementedError): 

169 special_param_values_dict_1 = {"str": "choice_1"} 

170 LlamaTuneAdapter( 

171 orig_parameter_space=input_space, 

172 num_low_dims=2, 

173 special_param_values=special_param_values_dict_1, 

174 max_unique_values_per_param=None, 

175 ) 

176 

177 with pytest.raises(NotImplementedError): 

178 special_param_values_dict_2 = {"cont": -1} 

179 LlamaTuneAdapter( 

180 orig_parameter_space=input_space, 

181 num_low_dims=2, 

182 special_param_values=special_param_values_dict_2, 

183 max_unique_values_per_param=None, 

184 ) 

185 

186 # Special value should belong to parameter value domain 

187 with pytest.raises(ValueError, match="value domain"): 

188 special_param_values_dict = {"int": -1} 

189 LlamaTuneAdapter( 

190 orig_parameter_space=input_space, 

191 num_low_dims=2, 

192 special_param_values=special_param_values_dict, 

193 max_unique_values_per_param=None, 

194 ) 

195 

196 # Invalid dicts; ValueError should be thrown 

197 invalid_special_param_values_dicts: List[Dict[str, Any]] = [ 

198 {"int-Q": 0}, # parameter does not exist 

199 {"int": {0: 0.2}}, # invalid definition 

200 {"int": 0.2}, # invalid parameter value 

201 {"int": (0.4, 0)}, # (biasing %, special value) instead of (special value, biasing %) 

202 {"int": [0, 0]}, # duplicate special values 

203 {"int": []}, # empty list 

204 {"int": [{0: 0.2}]}, 

205 {"int": [(0.4, 0), (1, 0.7)]}, # first tuple is inverted; second is correct 

206 {"int": [(0, 0.1), (0, 0.2)]}, # duplicate special values 

207 ] 

208 for spv_dict in invalid_special_param_values_dicts: 

209 with pytest.raises(ValueError): 

210 LlamaTuneAdapter( 

211 orig_parameter_space=input_space, 

212 num_low_dims=2, 

213 special_param_values=spv_dict, 

214 max_unique_values_per_param=None, 

215 ) 

216 

217 # Biasing percentage of special value(s) are invalid 

218 invalid_special_param_values_dicts = [ 

219 {"int": (0, 1.1)}, # >1 probability 

220 {"int": (0, 0)}, # Zero probability 

221 {"int": (0, -0.1)}, # Negative probability 

222 {"int": (0, 20)}, # 2,000% instead of 20% 

223 {"int": [0, 1, 2, 3, 4, 5]}, # default biasing is 20%; 6 values * 20% > 100% 

224 {"int": [(0, 0.4), (1, 0.7)]}, # combined probability >100% 

225 {"int": [(0, -0.4), (1, 0.7)]}, # probability for value 0 is invalid. 

226 ] 

227 

228 for spv_dict in invalid_special_param_values_dicts: 

229 with pytest.raises(ValueError): 

230 LlamaTuneAdapter( 

231 orig_parameter_space=input_space, 

232 num_low_dims=2, 

233 special_param_values=spv_dict, 

234 max_unique_values_per_param=None, 

235 ) 

236 

237 

238def gen_random_configs(adapter: LlamaTuneAdapter, num_configs: int) -> Iterator[CS.Configuration]: 

239 for sampled_config in adapter.target_parameter_space.sample_configuration(size=num_configs): 

240 # Transform low-dim config to high-dim config 

241 sampled_config_sr = pd.Series(dict(sampled_config)) 

242 orig_config_sr = adapter.transform(sampled_config_sr) 

243 orig_config = CS.Configuration( 

244 adapter.orig_parameter_space, 

245 values=orig_config_sr.to_dict(), 

246 ) 

247 yield orig_config 

248 

249 

250def test_special_parameter_values_biasing() -> None: # pylint: disable=too-complex 

251 """Tests LlamaTune's special parameter values biasing methodology.""" 

252 input_space = CS.ConfigurationSpace(seed=1234) 

253 input_space.add(CS.UniformIntegerHyperparameter(name="int_1", lower=0, upper=100)) 

254 input_space.add(CS.UniformIntegerHyperparameter(name="int_2", lower=0, upper=100)) 

255 

256 num_configs = 400 

257 bias_percentage = LlamaTuneAdapter.DEFAULT_SPECIAL_PARAM_VALUE_BIASING_PERCENTAGE 

258 eps = 0.2 

259 

260 # Single parameter; single special value 

261 special_param_value_dicts: List[Dict[str, Any]] = [ 

262 {"int_1": 0}, 

263 {"int_1": (0, bias_percentage)}, 

264 {"int_1": [0]}, 

265 {"int_1": [(0, bias_percentage)]}, 

266 ] 

267 

268 for spv_dict in special_param_value_dicts: 

269 adapter = LlamaTuneAdapter( 

270 orig_parameter_space=input_space, 

271 num_low_dims=1, 

272 special_param_values=spv_dict, 

273 max_unique_values_per_param=None, 

274 ) 

275 

276 special_value_occurrences = sum( 

277 1 for config in gen_random_configs(adapter, num_configs) if config["int_1"] == 0 

278 ) 

279 assert (1 - eps) * int(num_configs * bias_percentage) <= special_value_occurrences 

280 

281 # Single parameter; multiple special values 

282 special_param_value_dicts = [ 

283 {"int_1": [0, 1]}, 

284 {"int_1": [(0, bias_percentage), (1, bias_percentage)]}, 

285 ] 

286 

287 for spv_dict in special_param_value_dicts: 

288 adapter = LlamaTuneAdapter( 

289 orig_parameter_space=input_space, 

290 num_low_dims=1, 

291 special_param_values=spv_dict, 

292 max_unique_values_per_param=None, 

293 ) 

294 

295 special_values_occurrences = {0: 0, 1: 0} 

296 for config in gen_random_configs(adapter, num_configs): 

297 if config["int_1"] == 0: 

298 special_values_occurrences[0] += 1 

299 elif config["int_1"] == 1: 

300 special_values_occurrences[1] += 1 

301 

302 assert (1 - eps) * int(num_configs * bias_percentage) <= special_values_occurrences[0] 

303 assert (1 - eps) * int(num_configs * bias_percentage) <= special_values_occurrences[1] 

304 

305 # Multiple parameters; multiple special values; different biasing percentage 

306 spv_dict = { 

307 "int_1": [(0, bias_percentage), (1, bias_percentage / 2)], 

308 "int_2": [(2, bias_percentage / 2), (100, bias_percentage * 1.5)], 

309 } 

310 adapter = LlamaTuneAdapter( 

311 orig_parameter_space=input_space, 

312 num_low_dims=1, 

313 special_param_values=spv_dict, 

314 max_unique_values_per_param=None, 

315 ) 

316 

317 special_values_instances: Dict[str, Dict[int, int]] = { 

318 "int_1": {0: 0, 1: 0}, 

319 "int_2": {2: 0, 100: 0}, 

320 } 

321 for config in gen_random_configs(adapter, num_configs): 

322 if config["int_1"] == 0: 

323 special_values_instances["int_1"][0] += 1 

324 elif config["int_1"] == 1: 

325 special_values_instances["int_1"][1] += 1 

326 

327 if config["int_2"] == 2: 

328 special_values_instances["int_2"][2] += 1 

329 elif config["int_2"] == 100: 

330 special_values_instances["int_2"][100] += 1 

331 

332 assert (1 - eps) * int(num_configs * bias_percentage) <= special_values_instances["int_1"][0] 

333 assert (1 - eps) * int(num_configs * bias_percentage / 2) <= ( 

334 special_values_instances["int_1"][1] 

335 ) 

336 assert (1 - eps) * int(num_configs * bias_percentage / 2) <= ( 

337 special_values_instances["int_2"][2] 

338 ) 

339 assert (1 - eps) * int(num_configs * bias_percentage * 1.5) <= ( 

340 special_values_instances["int_2"][100] 

341 ) 

342 

343 

344def test_max_unique_values_per_param() -> None: 

345 """Tests LlamaTune's parameter values discretization implementation.""" 

346 # Define config space with a mix of different parameter types 

347 input_space = CS.ConfigurationSpace(seed=1234) 

348 input_space.add( 

349 CS.UniformFloatHyperparameter(name="cont_1", lower=0, upper=5), 

350 ) 

351 input_space.add(CS.UniformFloatHyperparameter(name="cont_2", lower=1, upper=100)) 

352 input_space.add(CS.UniformIntegerHyperparameter(name="int_1", lower=1, upper=10)) 

353 input_space.add(CS.UniformIntegerHyperparameter(name="int_2", lower=0, upper=2048)) 

354 input_space.add(CS.CategoricalHyperparameter(name="str_1", choices=["on", "off"])) 

355 input_space.add( 

356 CS.CategoricalHyperparameter(name="str_2", choices=[f"choice_{idx}" for idx in range(10)]) 

357 ) 

358 

359 # Restrict the number of unique parameter values 

360 num_configs = 200 

361 for max_unique_values_per_param in (5, 25, 100): 

362 adapter = LlamaTuneAdapter( 

363 orig_parameter_space=input_space, 

364 num_low_dims=3, 

365 special_param_values=None, 

366 max_unique_values_per_param=max_unique_values_per_param, 

367 ) 

368 

369 # Keep track of unique values generated for each parameter 

370 unique_values_dict: Dict[str, set] = {param: set() for param in list(input_space.keys())} 

371 for config in gen_random_configs(adapter, num_configs): 

372 for param, value in config.items(): 

373 unique_values_dict[param].add(value) 

374 

375 # Ensure that their number is less than the maximum number allowed 

376 for _, unique_values in unique_values_dict.items(): 

377 assert len(unique_values) <= max_unique_values_per_param 

378 

379 

380@pytest.mark.parametrize( 

381 ("num_target_space_dims", "param_space_kwargs"), 

382 ( 

383 [ 

384 (num_target_space_dims, param_space_kwargs) 

385 for num_target_space_dims in (2, 4) 

386 for num_orig_space_factor in (1.5, 4) 

387 for param_space_kwargs in ( 

388 {"n_continuous_params": int(num_target_space_dims * num_orig_space_factor)}, 

389 {"n_integer_params": int(num_target_space_dims * num_orig_space_factor)}, 

390 {"n_categorical_params": int(num_target_space_dims * num_orig_space_factor)}, 

391 {"n_quantized_integer_params": int(num_target_space_dims * num_orig_space_factor)}, 

392 { 

393 "n_quantized_continuous_params": int( 

394 num_target_space_dims * num_orig_space_factor 

395 ) 

396 }, 

397 # Mix of all three types 

398 { 

399 "n_continuous_params": int(num_target_space_dims * num_orig_space_factor / 3), 

400 "n_integer_params": int(num_target_space_dims * num_orig_space_factor / 3), 

401 "n_categorical_params": int(num_target_space_dims * num_orig_space_factor / 3), 

402 }, 

403 ) 

404 ] 

405 ), 

406) 

407def test_approx_inverse_mapping( 

408 num_target_space_dims: int, 

409 param_space_kwargs: dict, 

410) -> None: # pylint: disable=too-many-locals 

411 """Tests LlamaTune's approximate high-to-low space projection method, using pseudo- 

412 inverse. 

413 """ 

414 input_space = construct_parameter_space(**param_space_kwargs) 

415 

416 # Enable low-dimensional space projection, but disable reverse mapping 

417 adapter = LlamaTuneAdapter( 

418 orig_parameter_space=input_space, 

419 num_low_dims=num_target_space_dims, 

420 special_param_values=None, 

421 max_unique_values_per_param=None, 

422 use_approximate_reverse_mapping=False, 

423 ) 

424 

425 sampled_config = input_space.sample_configuration() # size=1) 

426 with pytest.raises(ValueError): 

427 sampled_config_sr = pd.Series(dict(sampled_config)) 

428 _ = adapter.inverse_transform(sampled_config_sr) 

429 

430 # Enable low-dimensional space projection *and* reverse mapping 

431 adapter = LlamaTuneAdapter( 

432 orig_parameter_space=input_space, 

433 num_low_dims=num_target_space_dims, 

434 special_param_values=None, 

435 max_unique_values_per_param=None, 

436 use_approximate_reverse_mapping=True, 

437 ) 

438 

439 # Warning should be printed the first time 

440 sampled_config = input_space.sample_configuration() # size=1) 

441 with pytest.warns(UserWarning): 

442 sampled_config_sr = pd.Series(dict(sampled_config)) 

443 target_config_sr = adapter.inverse_transform(sampled_config_sr) 

444 # Low-dim (i.e., target) config should be valid 

445 target_config = CS.Configuration( 

446 adapter.target_parameter_space, 

447 values=target_config_sr.to_dict(), 

448 ) 

449 target_config.check_valid_configuration() 

450 

451 # Test inverse transform with 100 random configs 

452 for _ in range(100): 

453 sampled_config = input_space.sample_configuration() # size=1) 

454 sampled_config_sr = pd.Series(dict(sampled_config)) 

455 target_config_sr = adapter.inverse_transform(sampled_config_sr) 

456 # Low-dim (i.e., target) config should be valid 

457 target_config = CS.Configuration( 

458 adapter.target_parameter_space, 

459 values=target_config_sr.to_dict(), 

460 ) 

461 target_config.check_valid_configuration() 

462 

463 

464@pytest.mark.parametrize( 

465 ("num_low_dims", "special_param_values", "max_unique_values_per_param"), 

466 ( 

467 [ 

468 (num_low_dims, special_param_values, max_unique_values_per_param) 

469 for num_low_dims in (8, 16) 

470 for special_param_values in ( 

471 {"int_1": -1, "int_2": -1, "int_3": -1, "int_4": [-1, 0]}, 

472 { 

473 "int_1": (-1, 0.1), 

474 "int_2": -1, 

475 "int_3": (-1, 0.3), 

476 "int_4": [(-1, 0.1), (0, 0.2)], 

477 }, 

478 ) 

479 for max_unique_values_per_param in (50, 250) 

480 ] 

481 ), 

482) 

483def test_llamatune_pipeline( 

484 num_low_dims: int, 

485 special_param_values: dict, 

486 max_unique_values_per_param: int, 

487) -> None: 

488 """Tests LlamaTune space adapter when all components are active.""" 

489 # pylint: disable=too-many-locals 

490 

491 # Define config space with a mix of different parameter types 

492 input_space = construct_parameter_space( 

493 n_continuous_params=10, 

494 n_integer_params=10, 

495 n_categorical_params=5, 

496 ) 

497 adapter = LlamaTuneAdapter( 

498 orig_parameter_space=input_space, 

499 num_low_dims=num_low_dims, 

500 special_param_values=special_param_values, 

501 max_unique_values_per_param=max_unique_values_per_param, 

502 ) 

503 

504 special_value_occurrences = { 

505 # pylint: disable=protected-access 

506 param: {special_value: 0 for special_value, _ in tuples_list} 

507 for param, tuples_list in adapter._special_param_values_dict.items() 

508 } 

509 unique_values_dict: Dict[str, Set] = {param: set() for param in input_space.keys()} 

510 

511 num_configs = 1000 

512 for ( 

513 config 

514 ) in adapter.target_parameter_space.sample_configuration( # pylint: disable=not-an-iterable 

515 size=num_configs 

516 ): 

517 # Transform low-dim config to high-dim point/config 

518 sampled_config_sr = pd.Series(dict(config)) 

519 orig_config_sr = adapter.transform(sampled_config_sr) 

520 # High-dim (i.e., original) config should be valid 

521 orig_config = CS.Configuration(input_space, values=orig_config_sr.to_dict()) 

522 orig_config.check_valid_configuration() 

523 

524 # Transform high-dim config back to low-dim 

525 target_config_sr = adapter.inverse_transform(orig_config_sr) 

526 # Sampled config and this should be the same 

527 target_config = CS.Configuration( 

528 adapter.target_parameter_space, 

529 values=target_config_sr.to_dict(), 

530 ) 

531 assert target_config == config 

532 

533 for param, value in orig_config.items(): 

534 # Keep track of special value occurrences 

535 if param in special_value_occurrences: 

536 if value in special_value_occurrences[param]: 

537 special_value_occurrences[param][value] += 1 

538 

539 # Keep track of unique values generated for each parameter 

540 unique_values_dict[param].add(value) 

541 

542 # Ensure that occurrences of special values do not significantly deviate from expected 

543 eps = 0.2 

544 for ( 

545 param, 

546 tuples_list, 

547 ) in adapter._special_param_values_dict.items(): # pylint: disable=protected-access 

548 for value, bias_percentage in tuples_list: 

549 assert (1 - eps) * int(num_configs * bias_percentage) <= special_value_occurrences[ 

550 param 

551 ][value] 

552 

553 # Ensure that number of unique values is less than the maximum number allowed 

554 for _, unique_values in unique_values_dict.items(): 

555 assert len(unique_values) <= max_unique_values_per_param 

556 

557 

558@pytest.mark.parametrize( 

559 ("num_target_space_dims", "param_space_kwargs"), 

560 ( 

561 [ 

562 (num_target_space_dims, param_space_kwargs) 

563 for num_target_space_dims in (2, 4) 

564 for num_orig_space_factor in (1.5, 4) 

565 for param_space_kwargs in ( 

566 {"n_continuous_params": int(num_target_space_dims * num_orig_space_factor)}, 

567 {"n_integer_params": int(num_target_space_dims * num_orig_space_factor)}, 

568 {"n_categorical_params": int(num_target_space_dims * num_orig_space_factor)}, 

569 # Mix of all three types 

570 { 

571 "n_continuous_params": int(num_target_space_dims * num_orig_space_factor / 3), 

572 "n_integer_params": int(num_target_space_dims * num_orig_space_factor / 3), 

573 "n_categorical_params": int(num_target_space_dims * num_orig_space_factor / 3), 

574 }, 

575 ) 

576 ] 

577 ), 

578) 

579def test_deterministic_behavior_for_same_seed( 

580 num_target_space_dims: int, 

581 param_space_kwargs: dict, 

582) -> None: 

583 """Tests LlamaTune's space adapter deterministic behavior when given same seed in 

584 the input parameter space. 

585 """ 

586 

587 def generate_target_param_space_configs(seed: int) -> List[CS.Configuration]: 

588 input_space = construct_parameter_space(**param_space_kwargs, seed=seed) 

589 

590 # Init adapter and sample points in the low-dim space 

591 adapter = LlamaTuneAdapter( 

592 orig_parameter_space=input_space, 

593 num_low_dims=num_target_space_dims, 

594 special_param_values=None, 

595 max_unique_values_per_param=None, 

596 use_approximate_reverse_mapping=False, 

597 ) 

598 

599 sample_configs: List[CS.Configuration] = ( 

600 adapter.target_parameter_space.sample_configuration(size=100) 

601 ) 

602 return sample_configs 

603 

604 assert generate_target_param_space_configs(42) == generate_target_param_space_configs(42) 

605 assert generate_target_param_space_configs(1234) != generate_target_param_space_configs(42)