|
18 | 18 | # pylint: disable=R0201 |
19 | 19 | import os |
20 | 20 | import sys |
| 21 | +import re |
21 | 22 | from collections import defaultdict |
22 | 23 | from unittest import TestCase |
23 | 24 |
|
@@ -240,3 +241,268 @@ def test_includes(self): |
240 | 241 | 's1-wk2': {'section': 'one', 'memcpy': True}, |
241 | 242 | 's2-wk2': {'section': 'two', 'included': True, 'memcpy': True}, |
242 | 243 | }) |
| 244 | + |
| 245 | +GLOBAL_WKL_SWEEP_TEST = """ |
| 246 | +workloads: |
| 247 | + - name: dhrystone |
| 248 | + workload_params: |
| 249 | + sweep(range): |
| 250 | + threads: [1,2,3] |
| 251 | +""" |
| 252 | + |
| 253 | +SECTION_SWEEP_TEST = """ |
| 254 | +sections: |
| 255 | + - id: my_section |
| 256 | + workload_params: |
| 257 | + sweep(range): |
| 258 | + threads: [1,2,3] |
| 259 | +
|
| 260 | +workloads: |
| 261 | + - name: dhrystone |
| 262 | +""" |
| 263 | + |
| 264 | +SECTION_GROUP_SWEEP_TEST = """ |
| 265 | +sections: |
| 266 | + - id: my_section1 |
| 267 | + group: mygroup |
| 268 | + workload_params: |
| 269 | + sweep(range): |
| 270 | + threads: [1,2,3] |
| 271 | + - id: my_section2 |
| 272 | + group: mygroup |
| 273 | + workload_params: |
| 274 | + threads: 8 |
| 275 | + - id: my_section3 |
| 276 | + group: othergroup |
| 277 | + runtime_parameters: |
| 278 | + freq: 10 |
| 279 | +workloads: |
| 280 | + - name: dhrystone |
| 281 | +""" |
| 282 | + |
| 283 | +GLOBAL_CFG_SWEEP_TEST = """ |
| 284 | +config: |
| 285 | + workload_parameters: |
| 286 | + sweep(range): |
| 287 | + duration: [1,2,3,4,5] |
| 288 | +
|
| 289 | +workloads: |
| 290 | + - name: idle |
| 291 | +""" |
| 292 | + |
| 293 | +WKL_OVERRIDE_SECTION_SWEEP_TEST = """ |
| 294 | +sections: |
| 295 | + - id: mysection |
| 296 | + workload_parameters: |
| 297 | + sweep(range): |
| 298 | + duration: [1,2,3] |
| 299 | + group: a |
| 300 | +
|
| 301 | +workloads: |
| 302 | + - name: idle |
| 303 | + workload_parameters: |
| 304 | + sweep(range): |
| 305 | + duration: [4,5,6] |
| 306 | + - name: idle |
| 307 | + workload_parameters: |
| 308 | + duration: 7 |
| 309 | + - name: idle |
| 310 | +""" |
| 311 | + |
| 312 | + |
| 313 | +SECTION_SWEEP_OVERRIDE_CFG_SWEEP_TEST = """ |
| 314 | +config: |
| 315 | + workload_parameters: |
| 316 | + sweep(range): |
| 317 | + duration: [1,2,3] |
| 318 | +
|
| 319 | +sections: |
| 320 | + - id: mysection |
| 321 | + workload_parameters: |
| 322 | + sweep(range): |
| 323 | + duration: [4,5,6,7] |
| 324 | +
|
| 325 | +workloads: |
| 326 | + - name: idle |
| 327 | +""" |
| 328 | + |
| 329 | +NESTED_WKL_SWEEP_TEST = """ |
| 330 | +sections: |
| 331 | + - id: mysection |
| 332 | + workloads: |
| 333 | + - name: idle |
| 334 | + params: |
| 335 | + sweep(range): |
| 336 | + duration: [1,2,3] |
| 337 | +workloads: |
| 338 | + - name: idle |
| 339 | + params: |
| 340 | + duration: 4 |
| 341 | +""" |
| 342 | + |
| 343 | +NESTED_WKL_SWEEP_OVERRIDE_TEST = """ |
| 344 | +sections: |
| 345 | + - id: mysection |
| 346 | + workload_parameters: |
| 347 | + duration: 100 |
| 348 | + workloads: |
| 349 | + - name: idle |
| 350 | + params: |
| 351 | + sweep(range): |
| 352 | + duration: [1,2,3] |
| 353 | +
|
| 354 | +workloads: |
| 355 | + - name: idle |
| 356 | + params: |
| 357 | + duration: 20 |
| 358 | +""" |
| 359 | + |
| 360 | +RANGE_SWEEP_TEST = """ |
| 361 | +workloads: |
| 362 | + - name: idle |
| 363 | + params: |
| 364 | + sweep(range): |
| 365 | + duration: 1-10,2 |
| 366 | +""" |
| 367 | + |
| 368 | +SWEEP_METADATA_TEST_1 = """ |
| 369 | +sections: |
| 370 | + - id: mysection |
| 371 | + runtime_params: |
| 372 | + sweep(range): |
| 373 | + threads: 1-4 |
| 374 | +workloads: |
| 375 | + - name: idle |
| 376 | + params: |
| 377 | + sweep(range): |
| 378 | + duration: 1-5 |
| 379 | +""" |
| 380 | + |
| 381 | +SWEEP_METADATA_TEST_2 = """ |
| 382 | +workloads: |
| 383 | + - name: idle |
| 384 | + label: testlabel |
| 385 | + params: |
| 386 | + sweep(range): |
| 387 | + duration: 1-5 |
| 388 | +""" |
| 389 | + |
| 390 | +AUTOPARAM_TEST = """ |
| 391 | +workloads: |
| 392 | + - name: Youtube |
| 393 | + params: |
| 394 | + sweep(autoparam): |
| 395 | + param: video_source |
| 396 | + plugin: Youtube |
| 397 | +""" |
| 398 | + |
| 399 | + |
| 400 | +class SweepsTest(TestCase): |
| 401 | + |
| 402 | + def test_global_workload_sweeps(self): |
| 403 | + # Do sweeps work on global workloads? |
| 404 | + jobspecs = get_job_specs(GLOBAL_WKL_SWEEP_TEST) |
| 405 | + assert_equal(len(jobspecs), 3) |
| 406 | + for jobspec, threads in zip(jobspecs, [1,2,3]): |
| 407 | + assert_equal(jobspec.workload_parameters['threads'], threads) |
| 408 | + |
| 409 | + def test_section_sweeps(self): |
| 410 | + # Do sweeps work within a section? |
| 411 | + jobspecs = get_job_specs(SECTION_SWEEP_TEST) |
| 412 | + assert_equal(len(jobspecs), 3) |
| 413 | + for jobspec, threads in zip(jobspecs, [1,2,3]): |
| 414 | + assert_equal(jobspec.workload_parameters['threads'], threads) |
| 415 | + |
| 416 | + def test_section_group_sweeps(self): |
| 417 | + # Do sweeps work when defined in a group? |
| 418 | + jobspecs = get_job_specs(SECTION_GROUP_SWEEP_TEST) |
| 419 | + assert_equal(len(jobspecs), 4) |
| 420 | + for jobspec, threads in zip(jobspecs, [1,2,3,8]): |
| 421 | + assert_equal(jobspec.workload_parameters['threads'], threads) |
| 422 | + assert_equal(list(jobspec.runtime_parameters.values())[0]['freq'], 10) |
| 423 | + |
| 424 | + def test_global_config_sweeps(self): |
| 425 | + # Do sweeps work when defined in a global config? |
| 426 | + jobspecs = get_job_specs(GLOBAL_CFG_SWEEP_TEST) |
| 427 | + assert_equal(len(jobspecs), 5) |
| 428 | + for jobspec, duration in zip(jobspecs, [1,2,3,4,5]): |
| 429 | + assert_equal(jobspec.workload_parameters['duration'], duration) |
| 430 | + |
| 431 | + def test_wkl_sweep_override_section(self): |
| 432 | + # Do global workload sweeps override section parameters? |
| 433 | + jobspecs = get_job_specs(WKL_OVERRIDE_SECTION_SWEEP_TEST) |
| 434 | + expect = [4,4,4,5,5,5,6,6,6,7,7,7,1,2,3] |
| 435 | + assert_equal(len(jobspecs), len(expect)) |
| 436 | + for jobspec in jobspecs: |
| 437 | + duration = jobspec.workload_parameters['duration'] |
| 438 | + assert duration in expect |
| 439 | + |
| 440 | + def test_section_sweep_override_config(self): |
| 441 | + # Do section sweeps override global config? |
| 442 | + jobspecs = get_job_specs(SECTION_SWEEP_OVERRIDE_CFG_SWEEP_TEST) |
| 443 | + expect = [4,4,4, 5,5,5, 6,6,6, 7,7,7] |
| 444 | + assert_equal(len(jobspecs), len(expect)) |
| 445 | + for jobspec in jobspecs: |
| 446 | + cfg = jobspec.workload_parameters['duration'] |
| 447 | + assert cfg in expect |
| 448 | + |
| 449 | + def test_nested_wkl_sweep_in_section(self): |
| 450 | + # Handle sweeps correctly inside workloads inside sections |
| 451 | + jobspecs = get_job_specs(NESTED_WKL_SWEEP_TEST) |
| 452 | + expect = {1,2,3,4} |
| 453 | + assert_equal(len(jobspecs), len(expect)) |
| 454 | + for jobspec in jobspecs: |
| 455 | + cfg = jobspec.workload_parameters['duration'] |
| 456 | + expect.remove(cfg) |
| 457 | + |
| 458 | + def test_nested_wkl_override(self): |
| 459 | + jobspecs = get_job_specs(NESTED_WKL_SWEEP_OVERRIDE_TEST) |
| 460 | + expect = {1,2,3,20} |
| 461 | + assert_equal(len(jobspecs), len(expect)) |
| 462 | + for jobspec in jobspecs: |
| 463 | + cfg = jobspec.workload_parameters['duration'] |
| 464 | + expect.remove(cfg) |
| 465 | + |
| 466 | + def test_section_wkl_sweep_metadata(self): |
| 467 | + # Do sweeps derived from a labelled entry share the label? |
| 468 | + # Do sweeps derived from the same entry share a commonly prefixed identifier? |
| 469 | + jobspecs = get_job_specs(SWEEP_METADATA_TEST_1) |
| 470 | + ids = [job.id for job in jobspecs] |
| 471 | + initial = r'(?P<section>\w*)_\d*-(?P<workload>\w*)_\d*' |
| 472 | + result = re.match(initial, ids[0]) |
| 473 | + assert result |
| 474 | + section = result.group('section') |
| 475 | + workload = result.group('workload') |
| 476 | + confirm = section + r'_\d*-' + workload + r'_\d*' |
| 477 | + |
| 478 | + assert all(re.fullmatch(confirm, other) for other in ids[1:]) |
| 479 | + assert_equal([job.label for job in jobspecs], [jobspecs[0].label]*len(jobspecs)) |
| 480 | + |
| 481 | + def test_wkl_sweep_metadata(self): |
| 482 | + jobspecs = get_job_specs(SWEEP_METADATA_TEST_2) |
| 483 | + ids = [job.id for job in jobspecs] |
| 484 | + initial = r'(?P<workload>\w*)_\d*' |
| 485 | + result = re.match(initial, ids[0]) |
| 486 | + assert result |
| 487 | + workload = result.group('workload') |
| 488 | + confirm = workload + r'_\d*' |
| 489 | + assert all(re.fullmatch(confirm, other) for other in ids[1:]) |
| 490 | + assert_equal([job.label for job in jobspecs], [jobspecs[0].label]*len(jobspecs)) |
| 491 | + |
| 492 | + def test_autoparam_sweep(self): |
| 493 | + jobspecs = get_job_specs(AUTOPARAM_TEST) |
| 494 | + from wa.workloads.youtube import Youtube |
| 495 | + expect = set(Youtube.parameters['video_source'].allowed_values) |
| 496 | + assert_equal(len(expect), len(jobspecs)) |
| 497 | + for jobspec in jobspecs: |
| 498 | + expect.remove(jobspec.workload_parameters['video_source']) |
| 499 | + |
| 500 | +def get_job_specs(text): |
| 501 | + ap = AgendaParser() |
| 502 | + cm = ConfigManager() |
| 503 | + tm = FakeTargetManager() |
| 504 | + |
| 505 | + raw = yaml.load(text) |
| 506 | + ap.load(cm, raw, None) |
| 507 | + cm.jobs_config.expand_sweeps(tm) |
| 508 | + return cm.jobs_config.generate_job_specs(tm) |
0 commit comments