|
45 | 45 | Routine, |
46 | 46 | Loop, |
47 | 47 | OMPParallelDirective, |
| 48 | + Node, |
48 | 49 | ) |
49 | 50 | from psyclone.psyir.transformations import ( |
50 | 51 | MaximalRegionTrans, |
@@ -386,3 +387,67 @@ def test_apply_force_private(fortran_reader): |
386 | 387 | assert isinstance(nodes[0], OMPParallelDirective) is True |
387 | 388 | pdir = nodes[0] |
388 | 389 | assert len(pdir.explicitly_private_symbols) == 5 |
| 390 | + |
| 391 | + |
| 392 | +def test_full_region_doesnt_meet_minimum_rules_compute_transformable_section( |
| 393 | + fortran_reader |
| 394 | +): |
| 395 | + '''Test that if the full region validates but doesn't meet the |
| 396 | + requirements for _satisfies_minimum_region_rules then the returned |
| 397 | + list is empty.''' |
| 398 | + code = """subroutine x |
| 399 | + integer :: i, ii, k, l, block |
| 400 | + integer :: array_l(8) |
| 401 | + block = 2 |
| 402 | + do ii = 1, 4 |
| 403 | + do k = 4, 1, -1 |
| 404 | + l = 0 |
| 405 | + do i = ii, min(ii+block -1, 4) |
| 406 | + l = l + 1 |
| 407 | + array_l(l) = 1 + 2 |
| 408 | + end do |
| 409 | + end do |
| 410 | + end do |
| 411 | + end subroutine x |
| 412 | + """ |
| 413 | + psyir = fortran_reader.psyir_from_source(code) |
| 414 | + # Apply loop_trans to all the loops possible. |
| 415 | + ltrans = OMPLoopTrans(omp_schedule="static") |
| 416 | + ltrans.apply( |
| 417 | + psyir.walk(Loop)[0], |
| 418 | + ignore_dependencies_for=["array_l"], |
| 419 | + nowait=True) |
| 420 | + |
| 421 | + # Create a transformation that always validates correctly |
| 422 | + class testTrans(Transformation): |
| 423 | + '''Dummy transformation that never fails validation.''' |
| 424 | + |
| 425 | + def validate(self, nodes, **kwargs): |
| 426 | + pass |
| 427 | + |
| 428 | + def apply(self, nodes, **kwargs): |
| 429 | + pass |
| 430 | + |
| 431 | + # Create a region transformation that has a custom |
| 432 | + # _satisfies_minimum_region_rules function that the |
| 433 | + # input code will fail. |
| 434 | + class TestRegTrans(MaximalRegionTrans): |
| 435 | + ''' Dummy class to test MaxParallelRegionTrans' functionality. ''' |
| 436 | + # The apply function will do OMPParallelTrans around allowed regions. |
| 437 | + _transformation = testTrans |
| 438 | + _SUB_TRANSFORMATIONS = [testTrans] |
| 439 | + # We're allowing any Node. |
| 440 | + _allowed_contiguous_statements = (Node, ) |
| 441 | + # Should parallelise any found region. |
| 442 | + _required_nodes = (Node, ) |
| 443 | + |
| 444 | + def _satisfies_minimum_region_rules(self, node_list): |
| 445 | + ''' Arbitrarily the node list needs to be size 100 for this |
| 446 | + MaximalRegionTrans.''' |
| 447 | + return len(node_list) > 100 |
| 448 | + |
| 449 | + mtrans = TestRegTrans() |
| 450 | + routine = psyir.walk(Routine)[0] |
| 451 | + rval = mtrans._compute_transformable_sections(routine.children[:], |
| 452 | + testTrans(), {}) |
| 453 | + assert len(rval) == 0 |
0 commit comments