PSyclone
PSyclone copied to clipboard
Dependency Analysis bug: _partition method raises IndexError
The dependency analysis raises a IndexError exception while analysing the following loop:
do widx3 = 1, loop_stop_120, 1
loop_stop_121 = SIZE(tmask, 2)
do widx2 = 1, loop_stop_121, 1
loop_stop_122 = SIZE(tmask, 1)
do widx1 = 1, loop_stop_122, 1
if (tmask(widx1,widx2,widx3) == 1._wp .AND. tsn(widx1,widx2,widx3,2) == 0._wp) then
tsn(widx1,widx2,widx3,2) = -99._wp
tmask(widx1,widx2,widx3) = 0._wp
umask(widx1,widx2,widx3) = 0._wp
vmask(widx1,widx2,widx3) = 0._wp
end if
enddo
enddo
enddo
the backtrace is:
self.validate(node, options=options)
File "/home/ssiso/workspace/stfc/PSyclone/src/psyclone/psyir/transformations/parallel_loop_trans.py", line 146, in validate
only_nested_loops=False):
File "/home/ssiso/workspace/stfc/PSyclone/src/psyclone/psyir/tools/dependency_tools.py", line 793, in can_loop_be_parallelised
var_info)
File "/home/ssiso/workspace/stfc/PSyclone/src/psyclone/psyir/tools/dependency_tools.py", line 628, in _array_access_parallelisable
other_access):
File "/home/ssiso/workspace/stfc/PSyclone/src/psyclone/psyir/tools/dependency_tools.py", line 521, in _is_loop_carried_dependency
loop_variables)
File "/home/ssiso/workspace/stfc/PSyclone/src/psyclone/psyir/tools/dependency_tools.py", line 283, in _partition
partition_infos.append((indices_1[i].union(indices_2[i]), [indx]))
IndexError: list index out of range
This is caused by the SIZE(tmask,...)
function registering a read access to tmask
(with no indices). Fixing #1750 will fix this issue properly
The following patch fixes the problem if you need an urgent fix:
diff --git a/src/psyclone/psyir/tools/dependency_tools.py b/src/psyclone/psyir/tools/dependency_tools.py
index 31ece4a74..39de6feb2 100644
--- a/src/psyclone/psyir/tools/dependency_tools.py
+++ b/src/psyclone/psyir/tools/dependency_tools.py
@@ -280,7 +280,8 @@ class DependencyTools():
# [ ({"i"}, [(0,0)]), ({"j","k"}, [(0,1)])]
partition_infos = []
for i, indx in enumerate(comp_ind1.iterate()):
- partition_infos.append((indices_1[i].union(indices_2[i]), [indx]))
+ if i < len(indices_2):
+ partition_infos.append((indices_1[i].union(indices_2[i]), [indx]))
# Check each loop variable to find subscripts in which they are used:
for loop_var in loop_variables:
@@ -519,6 +520,9 @@ class DependencyTools():
partitions = self._partition(write_access.component_indices,
other_access.component_indices,
loop_variables)
+ if not partitions:
+ return True
+
# Get the name of the loop variable that is to be parallelised:
loop_var = loop_variables[0]
Basically if the partition cannot be created (i.e. one access has no indices, like in the zize(tmask,2)
example), it will return no partition information, and this then triggers to allow parallelisation. Note that this is of course in general incorrect (array access without indices would typically indicate that all of the array is read, since the array is also written, the loop cannot be parallelised). I would prefer to properly fix #1750 (but leave the first change in, which would prevent the crash, but do not use the second test ... in this case a mixture of whole array access would be prevented). I'll discuss in the telco tonight.
PR #1852 fixes the problem in this case, additionally #1855 also fixes the root cause of this crash if an array is used with and without indices.