|
41 | 41 | from psyclone.configuration import Config
|
42 | 42 | from psyclone.core import AccessType, Signature, VariablesAccessInfo
|
43 | 43 | from psyclone.errors import InternalError
|
44 |
| -from psyclone.psyir.nodes import Loop |
| 44 | +from psyclone.psyir.nodes import Assignment, Loop |
45 | 45 | from psyclone.psyir.tools import DependencyTools, DTCode
|
46 | 46 | from psyclone.tests.utilities import get_invoke
|
47 | 47 |
|
@@ -1107,3 +1107,67 @@ def test_fuse_dimension_change(fortran_reader):
|
1107 | 1107 | "in different index locations: s%comp1(jj)%comp2(ji) and "
|
1108 | 1108 | "s%comp1(ji)%comp2(jj)."
|
1109 | 1109 | in str(msg))
|
| 1110 | + |
| 1111 | + |
| 1112 | +# ---------------------------------------------------------------------------- |
| 1113 | +@pytest.mark.parametrize("range1, range2, overlap", |
| 1114 | + [("1:3", "4:6", False), |
| 1115 | + ("3:9", "-1:-3", False), |
| 1116 | + ("1:3", "4", False), |
| 1117 | + ("5", "-1:-3", False), |
| 1118 | + ("i:i+3", "i+5:i+7", False), |
| 1119 | + ("i:i+3", "i+2", True), |
| 1120 | + ("i:i+3", "i+5", False), |
| 1121 | + ("i:i+3", "i-1", False), |
| 1122 | + (":", "1", True), |
| 1123 | + (":", "i", True), |
| 1124 | + ("::", "1", True), |
| 1125 | + ("::", "i", True), |
| 1126 | + ("1", ":", True), |
| 1127 | + ("i", ":", True), |
| 1128 | + ]) |
| 1129 | +def test_ranges_overlap(range1, range2, overlap, fortran_reader): |
| 1130 | + '''Test the detection of overlapping ranges. |
| 1131 | + ''' |
| 1132 | + source = f'''program test |
| 1133 | + integer i, ji, inbj |
| 1134 | + integer, parameter :: jpi=5, jpj=10 |
| 1135 | + real, dimension(jpi,jpi) :: ldisoce |
| 1136 | +
|
| 1137 | + ldisoce({range1},{range2}) = 1.0 |
| 1138 | + end program test''' |
| 1139 | + |
| 1140 | + psyir = fortran_reader.psyir_from_source(source) |
| 1141 | + dep_tools = DependencyTools() |
| 1142 | + assign = psyir.walk(Assignment)[0] |
| 1143 | + r1 = assign.lhs.children[0] |
| 1144 | + r2 = assign.lhs.children[1] |
| 1145 | + assert dep_tools._ranges_overlap(r1, r2) == overlap |
| 1146 | + # Also make sure that _independent_0_var handles this correctly: |
| 1147 | + assert dep_tools._independent_0_var(r1, r2) is not overlap |
| 1148 | + |
| 1149 | + |
| 1150 | +# ---------------------------------------------------------------------------- |
| 1151 | +def test_nemo_example_ranges(fortran_reader): |
| 1152 | + '''Tests an actual NEMO example |
| 1153 | + ''' |
| 1154 | + source = '''program test |
| 1155 | + integer ji, inbj |
| 1156 | + integer, parameter :: jpi=5, jpj=10 |
| 1157 | + real, dimension(jpi,jpi) :: ldisoce |
| 1158 | + do jj = 1, inbj, 1 |
| 1159 | + if (COUNT(ldisoce(:,jj)) == 0) then |
| 1160 | + ldisoce(1,jj) = .true. |
| 1161 | + end if |
| 1162 | + enddo |
| 1163 | + end program test''' |
| 1164 | + |
| 1165 | + psyir = fortran_reader.psyir_from_source(source) |
| 1166 | + loops = psyir.children[0].children[0] |
| 1167 | + dep_tools = DependencyTools() |
| 1168 | + |
| 1169 | + # This loop can be parallelised because all instances of ldisoce use |
| 1170 | + # the index jj in position 2 (the overlap between ":" and "1" |
| 1171 | + # is tested in test_ranges_overlap above, here we check that this |
| 1172 | + # overlap is indeed ignored because of the jj index). |
| 1173 | + assert dep_tools.can_loop_be_parallelised(loops) |
0 commit comments