1

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.

hakimo2
  • 143
  • 12
  • Your code is difficult to follow - but are you expecting an implicit barrier on exit of the master construct? If so you will de disappointed. Master is *not* a worksharing construct, so there is *no* implicit barrier on exit. Single has a barrier on exit, but I don't understand your code well enough to recommend it. https://stackoverflow.com/questions/18820471/what-is-the-benefit-of-pragma-omp-master-as-opposed-to-pragma-omp-single might be of interest. – Ian Bush May 25 '21 at 12:18
  • @IanBush I edited my post in order to show you that even without the master construct, I still have a segmentation fault. I replaced the omp master by an "if" condition on the thread number to check if it's equal to 0 or not (master). Still the same problem .. – hakimo2 May 25 '21 at 12:40
  • That's not the point at all. You have to make the other threads wait until threads_list_part3 is initialised. Currently and in the previous version there was no such synchronisation - there was nothing stopping non-master threads accessing threads_list_part3 before it is initialised. The little I understand of what you are saying suggests you need a barrier just before the do ff=5,20 loop. – Ian Bush May 25 '21 at 12:43
  • @IanBush Ah okay !! I added "!$OMP BARRIER" before the do ff=5,20 loop and now it is working. Thank you very much for your help ! – hakimo2 May 25 '21 at 12:49
  • @IanBush sorry for disturbing but now while I have the answer, what should I do ? should I leave the question or delete it ? it's my first time on stackoverflow. And what does mean the "-1" next to my question, please ? does it mean that my question is not useful ? thanks. – hakimo2 May 25 '21 at 12:57
  • @hakimo2 "_now while I have the answer, what should I do ? should I leave the question or delete it ?_" Just leave it open. Someone might write up an answer later on. "_And what does mean the "-1" next to my question_" Someone downvoted your question. Could be because you did not supply a full working minimal example which we can run ourselfs. This always helps alot! – jack May 25 '21 at 13:19
  • @jack Thanks for the explanation. So, I'll edit my post in order to give more information. – hakimo2 May 25 '21 at 13:30

1 Answers1

2

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.

Ian Bush
  • 6,996
  • 1
  • 21
  • 27