I encountered an issue with nested task constructs (page 137) while testing MagIC. The application built with Intel, GNU and Arm compilers, shows inconsistent behaviours. While Intel and GNU compilers performs well, Arm compiler triggers a segmentation fault at execution time.
Here is a reduced pseudo-code that triggers the problem (see full example for more details lines 199-308):
!$omp parallel default(shared)
[...]
!$omp single
!$omp task default(shared) &
!$omp private(l1) &
!$omp private(n,i)
[...]
l1=l1_value
n=5
do i=1,n
!$omp task default(shared) &
!$omp firstprivate(i)
[...]
[Accessing an array with l1 as index]
!$omp end task
end do
!$omp taskwait
!$omp end task
!$omp end single
!$omp end parallel
Here the value of l1 becomes undefined in the task construct line 14 and that causes a segmentation fault when trying to access the array at execution time.
I have tested various declarations for l1 and declaring it as first private, at line 15 of the example, seems to be a good fix (to get the last value of l1 inside the innermost construct).
However I still would like to understand since the documentation is unclear to me.
It says
If a task construct is encountered during execution of an outer task, the generated task region that corresponds to this construct is not a part of the outer task region unless the generated task is an included task.
My questions are
l1 be propagated into the task construct line 14 or should it be undefined in the original code?Thank you for your help.
I don't have the answer about the inner tasks being "included tasks" or not. The specification on this topic is really unclear to me.
However, you have specified the default(shared) clause for the inner tasks, meaning that l1 is supposed to be (obviously) shared... The question is "shared with what?"... With the l1 that is private to the outer task, or with the global l1 that has not been initialized?
l1 of the outer task: this l1 is initialized, so the shared l1 within the inner tasks should not be undefined... Unless the outer task terminates before the inner tasks are fully executed (in which case the private l1 would go out of scope): but this should NOT happen, thanks to the taskwait directive that you have inserted.l1: it is unitialized, thus undefined. But declaring the inner task l1 as firstprivate would have then no reason to fix the issue: you would have private l1 in the inner tasks, which would be initialized to undefined values.Conclusion: I bet on a compiler bug for the ARM version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With