Building on Week 5’s work with the TASK
construct and fixes for shared
/private
variables, Week 6 focused on making shared
variables work reliably in the TASK
construct and adding the TASKWAIT
construct. Last week, I planned to enhance TASK
support and implement teams
, but debugging TASK
issues took priority. This week, I made PR #7905, and spent about 25 hours tackling these challenges through careful debugging and implementation.
Debugging and Fixing TASK Construct Issues
This week, I worked on ensuring shared
variables function correctly in the TASK
construct, a task that proved more complex than expected. I faced multiple segfaults and struggled to pinpoint the cause, eventually realizing it was a mix of two or three bugs. To tackle this, I took a step-by-step approach, starting from scratch by writing lowered Fortran code with GOMP calls for TASK
. This revealed the first issue: the task data struct size sent to GOMP_TASK
was incorrect, causing segfaults. The second problem was that shared
variables in OMPRegion
had garbage initial values. Debugging the LLVM IR showed that c_f_pointer
was using the address of the struct member instead of its value for non-array shared
variables, leading to junk data.
Implementation Details and Fixes in PR #7905
In PR #7905, I addressed these issues to support shared
variables in the TASK
construct and implemented the TASKWAIT
construct, contributing to Issue #7332 and Issue #7365 while fixing Issue #7904. I corrected the task data struct size calculation for GOMP_TASK
calls and fixed the c_f_pointer
issue in asr_to_llvm.cpp
by ensuring it references the correct memory address for non-array shared
variables. This required debugging of the LLVM IR to identify all failure scenarios. Additionally, I added TASKWAIT
to synchronize tasks, ensuring proper execution flow.
Examples: TASK and TASKWAIT Constructs
Below are the MREs from PR #7905 that demonstrate the improved TASK
construct with shared
variables and the new TASKWAIT
construct.
View MRE for TASK
with Pointers (bindc5.f90)
1module thread_data_module_tasks
2 use, intrinsic :: iso_c_binding
3 implicit none
4 type :: thread_data
5 type(c_ptr) :: i_ptr
6 end type thread_data
7end module thread_data_module_tasks
8
9program bindc5
10 use thread_data_module_tasks
11 use, intrinsic :: iso_c_binding
12 implicit none
13 integer, target :: i
14 integer, pointer :: ptr_i, ptr_i2
15 type(thread_data), pointer :: d,d1
16 type(thread_data), target :: threadData, taskData
17 type(c_ptr) :: threadPtr, taskPtr
18
19 i=0
20
21 threadData%i_ptr = c_loc(i)
22 threadPtr = c_loc(threadData)
23 call c_f_pointer(threadPtr, d)
24 call c_f_pointer(d%i_ptr, ptr_i)
25
26 ptr_i=2
27
28 taskData%i_ptr = d%i_ptr
29 taskPtr = c_loc(taskData)
30 call c_f_pointer(taskPtr, d1)
31 call c_f_pointer(d1%i_ptr, ptr_i2)
32
33 ptr_i2=3
34
35 print*, i,ptr_i2,ptr_i
36 if(i/=ptr_i2 .and. i/=ptr_i) error stop
37end program bindc5
View MRE for TASK
with Shared Counter (openmp_55.f90)
1program openmp_55
2 use omp_lib
3 implicit none
4 integer :: i,n=10,counter
5 call omp_set_num_threads(8)
6counter=0
7 !$OMP PARALLEL
8 !$OMP MASTER
9 do i = 1, n
10 !$OMP TASK shared(counter)
11 counter=counter+1
12 print *, "Task Done by TID:-",omp_get_thread_num()
13 !$OMP END TASK
14 end do
15 !$OMP END MASTER
16 !$OMP END PARALLEL
17 if(counter/=10) error stop
18end program openmp_55
View MRE for TASK
with Shared Counter (openmp_56.f90)
1program openmp_56
2 use omp_lib
3 implicit none
4 integer :: counter
5 counter=0
6 call omp_set_num_threads(10)
7
8 !$omp parallel
9 !$omp task shared(counter)
10 counter=counter+1
11 print *, "Task done by TID:-",omp_get_thread_num()
12 !$omp end task
13 !$omp end parallel
14 if(counter/=10) error stop
15end program openmp_56
View MRE for TASK
with TASKWAIT
(openmp_57.f90)
1program openmp_57
2 use omp_lib
3 implicit none
4 integer, parameter :: N = 5
5 integer :: A(N)
6 integer :: i, index,total
7
8 A = 1
9 total=0
10 index=1
11
12 !$omp parallel
13 !$omp single
14 do i = 1, N
15 !$omp task shared(A)
16 total = total + A(index) * 2
17 index=index+1
18 !$omp end task
19 end do
20 !$omp end single
21 !$omp taskwait
22 !$omp end parallel
23
24 print *, "Total = ", total, index
25 if(total/=10) error stop
26end program openmp_57
Next Steps
For Week 7, I plan to:
- Implement the
teams
construct using theOMPRegion
node (Issue #7363). - Fix more bugs and implement other clauses if possible for
TASKS
I am grateful to my mentors, Ondrej Certik, Pranav Goswami, and Gaurav Dhingra, for their expert guidance during this debugging process. I also thank the LFortran community for their support and encouragement.