Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct behaviour for nested task constructs?

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

  • Does OpenMP consider the task construct line 14 as an included task of the one line 4?
  • Should the value of l1 be propagated into the task construct line 14 or should it be undefined in the original code?
  • Which compiler shows the right behaviour so I can report correctly?

Thank you for your help.

like image 939
JulieGaspar Avatar asked Aug 06 '26 15:08

JulieGaspar


1 Answers

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?

  • If shared with the private 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.
  • If shared with the global 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.

like image 153
PierU Avatar answered Aug 09 '26 09:08

PierU



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!