Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
91 Views

Crash with allocatable structures in OpenMP loop

Hi,

running the attached OpenMP code with ifort 18.0.3 results in a segmentation fault:

$ ifort -fopenmp gtemplate.f90 -o gtemplate && ./gtemplate
forrtl: severe (174): SIGSEGV, segmentation fault occurred
forrtl: severe (174): SIGSEGV, segmentation fault occurred

Does anyone confirm the crash? And what could be the issue? Something illegal with the private-per-thread structure? Thanks,

Sebastien

 

0 Kudos
9 Replies
Highlighted
Valued Contributor I
91 Views

Salut Sebastien, I am not an expert on OMP. But this looks not very good. I can confirm the issue with both ifort and NAG. I assume that the problem is that you have an OMP-parallel loop accessing the global object hbeam and its component. This generates a race condition, most likely if more than one thread tests positively for hbeam%teles being allocated and trying to deallocate it in parallel. 

0 Kudos
Highlighted
91 Views

The structure "hbeam" is declared FIRSTPRIVATE, which means that 1) each thread should have its own copy and 2) each copy should be identical (i.e. values initialized) to the original structure. From this point I believe I should be able to deallocate each copy. As I do not reproduce the crash with gfortran, I thought it was an ifort issue. But if you believe that's an OpenMP problem, I can ask for help on comp.lang.fortran.

0 Kudos
Highlighted
91 Views

Hi, I am facing again a crash when using allocatable arrays in structures, when the structures are set as PRIVATE in a parallel OpenMP region. I could not test the latest ifort release. Can anyone check if the example I attached in my first post still crashes? Thanks.

0 Kudos
Highlighted
91 Views

I seem to recall an issue with earlier versions of IVF with use of private and firstprivate of user defined types containing allocatables (as well as the private entity being allocatable as well). Do you need a work around?

Jim Dempsey

0 Kudos
Highlighted
91 Views

Untested code that ought to work.

module myclean_arrays
  !
  type :: telesco
    character(len=12) :: ctele
  end type telesco
  !
  type :: gildas
    type(telesco), allocatable :: teles(:)
  end type gildas
  !
  type (gildas) :: hbeam
  !
end module myclean_arrays
!
program gtemplate
  use myclean_arrays
  ! Local
  integer(kind=4) :: jfield
  !
  ! At this point hbeam%teles is not allocated
  !$OMP PARALLEL DEFAULT(none) &
  !$OMP   & FIRSTPRIVATE(hbeam) &
  !$OMP   & PRIVATE(jfield)
  ! at this point the teles of the private copy of hbeam is not allocated
  ! allocate it
  allocate(hbeam%teles(1))
  ! initialize it
  hbeam%teles(1)%ctele = 'NOEMA'
  ! do some meaningless valid code that exhibits the issue
  !$OMP DO
  !
  do jfield=1,1000
    if (allocated(hbeam%teles)) deallocate(hbeam%teles)
  enddo
  !
  !$OMP END DO
  ! in event that you have more threads than 1000
  if (allocated(hbeam%teles)) deallocate(hbeam%teles)
  !$OMP END PARALLEL
  !
end program gtemplate

The prior bug had issues with the (first)private having allocatables. The old work around was to enter the parallel region with the unallocated components (thus firstprivating an unallocated array descriptor) then perform the allocations within the parallel region.

Jim Dempsey

0 Kudos
Highlighted
Moderator
91 Views

This is a problem with the compiler.  I filed a bug report with the developers on your behalf.

Jim's idea is a good workaround.

 

0 Kudos
Highlighted
91 Views

Dear Barbara and Jim,

as far as I understand, the crash is about implicit allocation of the allocatable component when the structure is to be duplicated (FIRSTPRIVATE) to all threads. Knowing this, yes, Jim's workaround is a solution. I can imagine others, as my real use case is more complicated than my example. I need to review my code.

Barbara, it would nice to know when (which revision) the fix for this issue is released.

Thank you for your support.

0 Kudos
Highlighted
Moderator
91 Views

I have a note to watch for the fix and let you know.

 

0 Kudos
Highlighted
Moderator
91 Views

I have an update on this issue with allocating outside a parallel region and deallocating what was allocated outside the parallel region inside a parallel region. 

The developer has several workarounds:

(1)  both allocate and deallocate outside the parallel region

(2)  allocate and deallocate inside the parallel region

(3)  Use SHARED clause

       program test
          integer, allocatable :: AAA(:)
          allocate(AAA(100))

          !$OMP PARALLEL SHARED(AAA)
          ...
          !$OMP MASTER
          if (allocated(AAA)) deallocate(AAA)
          !$OMP END MASTER
          !$OMP END PARALLEL
        end program test

The plan is to fix this issue in a future release of the compiler.  No promises, though, when that will be.

0 Kudos