派生类型和OpenMP中的数组导致分段错误

时间:2016-07-25 16:52:41

标签: fortran openmp

我有一个非常简单的代码。

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

我使用

编译它
gfortran -g temp.F90 -o main.exe -fopenmp

它给了我分段错误。如果不使用派生类型我只使用数组,相同的代码运行正常。

这是一个错误还是我做错了什么。

1 个答案:

答案 0 :(得分:1)

我在笔记本电脑上遇到了你的段错误,但你的代码在我强大的台式机上顺利运行。您的nelems = 500000需要堆访问权限。根据@Vladimir F的建议,我获得了以下内容:

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

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