1
votes

I'm modifying an existing Fortran code which uses the openmp library. The original version of this code works perfectly in parallel.

I obtain a segmentation fault when a certain variable is accessed during the multi-thread run (I verified by setting flags all over the code). This array is defined allocatable, then as threadprivate and then allocated, while in the original version it's not an allocatable and its size is set immediately. I modified this part due to the workplan I was given.

Here is a basic piece of code which reproduces the error. The guilty variable is an array here named "var".

program testparallel
  use omp_lib
  implicit none
  integer :: thread_id, thread_num
  integer :: i,N
  integer,dimension(:),allocatable,save :: var

  !$omp threadprivate(var)

  N = 20
  allocate(var(5))

  !$omp parallel default(shared) private(thread_id)

  thread_id  = omp_get_thread_num()
  thread_num = omp_get_num_threads()
  write(*,*)'Parallel execution on ',thread_num, ' Threads'

  !$omp do

  do i=1,N
    var = 0
    write(*,*) thread_id,i
  end do

  !$omp end do
  !$omp end parallel

end program testparallel

This is how more or less the original code is structured, I didn't modify this part directly. var is initialised within the loop and, according to the inputs, its values are used later by other routines.

This is the error traceback I obtained:

 Parallel execution on            2  Threads
           0           1
           0           2
 Parallel execution on            2  Threads
           0           3
           0           4
           0           5

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
           0           6

Backtrace for this error:
           0           7
           0           8
           0           9
           0          10
#0  0x7F0149194697
#1  0x7F0149194CDE
#2  0x7F014824E33F
#3  0x400FB2 in MAIN__._omp_fn.0 at testparallel.F90:?
#4  0x7F0148C693C4
#5  0x7F01485ECDD4
#6  0x7F0148315F6C
#7  0xFFFFFFFFFFFFFFFF

The segfault doesn't occur if I don't define var as allocatable but define its size straighaway (as in the original code). If I allocate it before setting it as threadprivate I get a compilation error.

How can I avoid this error but keep var as allocatable (which is necessary)?

EDIT: I corrected the description of the original code.

1
I assume you have 8 threads in your computer. Can you increase the allocated from 5 to >8? - cho_uc
The same thing still happens with 10 threads. - matteeeo
No, what I mean is, if you change allocate(var(5)) to allocate(var(20)), will you get the same error? - cho_uc
Yes, still the same - matteeeo

1 Answers

3
votes

Your issue comes from the fact that, although your allocatable array var is declared threadprivate, it is only allocated in the non-parallel part of the code. Therefore, once on a parallel section, only the master thread can safely access to the array.

A very simple fix is to enclose your array allocation (and subsequent de-allocation) within a parallel section like this:

!$omp parallel
allocate(var(5))
!$omp end parallel