2016-07-25 63 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