I am facing a segmentation fault. So, I decided to use valgrind. For the compilation, I used :
gfortran -fopenmp -g HECESE_openmp.f90
For the execution, I used:
valgrind --track-origins=yes ./a.out
One of the errors I got is "Conditional jump or move depends on uninitialised value(s)" followed by "Uninitialised value was created by a stack allocation". You can see it below.
==13202== Conditional jump or move depends on uninitialised value(s)
==13202== at 0x1159DC: __procedures_MOD_grad._omp_fn.4 (HECESE_openmp.f90:690)
==13202== by 0x4C78E75: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Uninitialised value was created by a stack allocation
==13202== at 0x10B211: __procedures_MOD_grad (HECESE_openmp.f90:482)
==13202==
==13202== Conditional jump or move depends on uninitialised value(s)
==13202== at 0x1159E2: __procedures_MOD_grad._omp_fn.4 (HECESE_openmp.f90:690)
==13202== by 0x4C78E75: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Uninitialised value was created by a stack allocation
==13202== at 0x10B211: __procedures_MOD_grad (HECESE_openmp.f90:482)
==13202==
==13202== Jump to the invalid address stated on the next line
==13202== at 0x0: ???
==13202== by 0x4C7BD7A: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x4C846A7: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x4C8304C: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==13202== by 0x10BF25: __procedures_MOD_grad (HECESE_openmp.f90:660)
==13202== by 0x1123FF: MAIN__ (HECESE_openmp.f90:1063)
==13202== by 0x113E89: main (HECESE_openmp.f90:721)
==13202== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Here is the code I compiled :
tasklist_GRAD(5)%f_ptr => u_prime_2 !5
tasklist_GRAD(6)%f_ptr => taux_ !6
tasklist_GRAD(7)%f_ptr => u_prime_gauche_2 !7
tasklist_GRAD(8)%f_ptr => u_prime_droite_2 !8
tasklist_GRAD(9)%f_ptr => ax_droite_1 !9
tasklist_GRAD(10)%f_ptr => ax_gauche_1 !10
tasklist_GRAD(11)%f_ptr => ux_droite_1 !11
tasklist_GRAD(12)%f_ptr => ux_gauche_1 !12
tasklist_GRAD(13)%f_ptr => u_grad_x_2 !13
tasklist_GRAD(14)%f_ptr => u_prime_gauche_3 !14
tasklist_GRAD(15)%f_ptr => u_prime_droite_3 !15
tasklist_GRAD(16)%f_ptr => ax_droite_2 !16
tasklist_GRAD(17)%f_ptr => ax_gauche_2 !17
tasklist_GRAD(18)%f_ptr => ux_droite_2 !18
tasklist_GRAD(19)%f_ptr => ux_gauche_2 !19
tasklist_GRAD(20)%f_ptr => u_grad_x_3 !20
!$OMP PARALLEL PRIVATE(num_thread,nthreads) &
!$OMP SHARED(tasklist_GRAD,threads_list,threads_list_all,tasks_ready_master) &
!$OMP SHARED(threads_list_part1,threads_list_part2,threads_list_part3)
num_thread=OMP_GET_THREAD_NUM()
nthreads=OMP_GET_NUM_THREADS()
!Thread Application Master
if (num_thread==1) then
do ff=5,20
if (associated(tasklist_GRAD(ff)%f_ptr) .eqv. .true.) then
tasks_ready_master(ff) = tasklist_GRAD(ff)
end if
end do
do ff=5,20
if (associated(tasks_ready_master(ff)%f_ptr) .eqv. .true.) then
tasks_ready_master(ff)%state=STATE_READY
end if
end do
end if
!Thread Master
if (num_thread==0) then
allocate(threads_list(nthreads-2))
do ff=1,nthreads-2
threads_list(ff)=ff+1
end do
do ff=5,20,nthreads-2
if (tasks_ready_master(ff)%state==STATE_READY) then
threads_list_all(ff:ff+nthreads-3)=threads_list(:)
end if
end do
threads_list_part3=threads_list_all(5:20)
end if
!$OMP BARRIER
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
!$OMP TASK
call tasks_ready_master(ff)%f_ptr(self,ww,pas,cpt ,nb_element,cpt1,dt,dx,p_element,u_prime,u_prime_moins,u_prime_plus,&
&taux,grad_x_u,grad_t_u,grad_x_f,grad_t_f,ax_plus,ax_moins,ux_plus,ux_moins,sm,flux,tab0,tab)
!$OMP END TASK
end if
end do
!$OMP END PARALLEL
The line 690 is : if (tasks_ready_master(ff)%state==STATE_READY)
then
For the used lists :
type(tcb),dimension(20)::tasklist_GRAD,tasks_ready_master
integer,allocatable,dimension(:)::threads_list
integer,dimension(30)::threads_list_all
integer,dimension(3)::threads_list_part1
integer::threads_list_part2
integer,dimension(16)::threads_list_part3
I ignore where the error comes from. Can you help me, please ? It's the first time I use Valgrind and the first time I ask a question on this website.
Unfortunately you have edited the code into the working version which obscures what the problem was. The relevant piece of the earlier code read
!Thread Master
if (num_thread==0) then
...
threads_list_part3=threads_list_all(5:20)
end if
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
You have a race condition. Thread zero executes the block in the brackets, but the other threads are still running and so carry on into the do loop, and therefore threads_list_part3
might be accessed by non-master threads before the master thread has initialised it. The simplest fix is to use a barrier to ensure non-master threads wait for the master to complete its work. You can either do this explicitly
!Thread Master
if (num_thread==0) then
...
threads_list_part3=threads_list_all(5:20)
end if
!$omp barrier
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
Or implicitly via a worksharing construct, such as !$omp single
!$omp single
!Thread Master
...
threads_list_part3=threads_list_all(5:20)
!$omp end single
!Threads workers
do ff=5,20
if (num_thread==threads_list_part3(ff-4)) then
Personally I think I prefer the second form.