2

I have a very simple code.

program test_example

use iso_c_binding, only: c_double, c_int

implicit none

integer, parameter :: nelems = 500000
integer, parameter :: Np = 16, Nvar = 4, Nflux = 16

type mesh2d
    real(c_double) :: u(Np, nelems)
    real(c_double) :: uflux(Nflux, nelems)
    real(c_double) :: ucommon(Nflux, nelems)
end type mesh2d

type(mesh2d)     :: mesh

integer(c_int)   :: i, j, k


!$OMP PARALLEL DO 
     do j = 1, nelems
        do k = 1, Np
            mesh%u(k, j) = j+k
        end do
    end do
!$END PARALLEL DO 

end program test_example

I compile it using

gfortran -g temp.F90 -o main.exe -fopenmp

And it gives me segmentation fault. The same code runs fine if instead of using a derived type I simply used an array.

Is this a bug or am I doing something wrong.

Vikram
  • 308
  • 1
  • 5
  • 1
    See http://stackoverflow.com/a/13266595/6382074 for a possible/likely cause. I get a seg fault if I run your code as is, but it runs fine if I do `ulimit -s unlimited` first. – d_1999 Jul 25 '16 at 17:00
  • 2
    I don't get anything, but my stack is likely larger. I think d_1999 is right. A simple remedy: use allocatable arrays. Or dig into the mess of changing stack size at all your users' computers. My choice is clear, allocatables. – Vladimir F Героям слава Jul 25 '16 at 17:01
  • Please report if the link doesn't solve your issue. We could reopen the question easily if necessary. – Vladimir F Героям слава Jul 26 '16 at 09:45
  • Thanks. ulimit -s unlimited solved the issue. But don't know why it happens in case of derived type but not if its an array. – Vikram Jul 26 '16 at 15:40

1 Answers1

1

I ran into your segfault conundrum on my laptop, but your code ran without a hitch on my powerful desktop machine. Your nelems = 500000 requires heap access. Following @Vladimir F suggestion I obtained the following:

This file was compiled by GCC version 5.4.0 20160609 using the options -cpp -imultiarch x86_64-linux-gnu -D_REENTRANT -mtune=generic -march=x86-64 -g -fopenmp

from

module type_Mesh2D

  use iso_c_binding, only: &
       wp => c_double, &
       ip => c_int

  ! Explicit typing only
  implicit none

  ! Everything is private unless stated otherwise
  private
  public :: wp, ip
  public :: nelems, Np, Nvar, Nflux
  public :: Mesh2D

  integer (ip), parameter :: nelems = 500000
  integer (ip), parameter :: Np = 16, Nvar = 4, Nflux = 16

  type, public ::  Mesh2D
    real (wp), dimension (:,:), allocatable :: u, uflux, ucommon
  end type Mesh2D

  interface Mesh2D
    module procedure allocate_arrays
    module procedure default_allocate_arrays
  end interface Mesh2D

contains

  pure function allocate_arrays(n, m, k) result (return_value)
    ! Dummy arguments
    integer (ip), intent (in) :: n, m, k
    type (Mesh2D) :: return_value

    allocate( return_value%u(n, m) )
    allocate( return_value%uflux(k, m) )
    allocate( return_value%ucommon(k, m) )

  end function allocate_arrays


  pure function default_allocate_arrays() result (return_value)
    ! Dummy arguments
    type (Mesh2D) :: return_value

    return_value = allocate_arrays(Np, nelems, Nflux)

  end function default_allocate_arrays

end module type_Mesh2D


program test_example

  use iso_fortran_env, only: &
       compiler_version, compiler_options

  use type_Mesh2D

  ! Explicit typing only
  implicit none

  type (Mesh2D)  :: mesh
  integer (ip)   :: i, j, k

  ! Allocate memory
  mesh = Mesh2D()

  !$OMP PARALLEL DO 
  do j = 1, nelems
     do k = 1, Np
    mesh%u(k, j) = j + k
     end do
  end do
  !$END PARALLEL DO

  print '(4A)', &
       'This file was compiled by ', compiler_version(), &
       ' using the options ', compiler_options()

end program test_example
jlokimlin
  • 593
  • 4
  • 9