2016-07-25 59 views
2

我有一个非常简单的代码。派生类型和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

见http://stackoverflow.com/a/13266595/6382074为可能/可能的原因。如果我按原样运行代码,则会遇到seg故障,但如果首先执行“ulimit -s unlimited”,则运行良好。 –

+2

我什么也没得到,但是我的堆栈可能更大。我认为d_1999是对的。一个简单的补救措施:使用可分配的数组。或者在所有用户的计算机上挖掘堆栈大小的变化。我的选择很明确,可分配。 –

+0

如果链接不能解决您的问题,请报告。如有必要,我们可以轻松地重新打开这个问题。 –

回答

1

我的笔记本电脑遇到了您的segfault难题,但您的代码在我强大的桌面计算机上顺利运行。您的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