Fortran 派生类型的数组和OpenMP导致分段错误
我有一个非常简单的代码Fortran 派生类型的数组和OpenMP导致分段错误,fortran,openmp,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) :
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
这给了我一个错误。如果我不使用派生类型而只是使用数组,那么同样的代码运行良好
这是一个错误还是我做错了什么 我在笔记本电脑上遇到了你的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
从
有关可能/可能的原因,请参阅。如果我按原样运行您的代码,则会出现seg错误,但如果我先执行
ulimit-s unlimited
,则运行良好。我什么都没有得到,但我的堆栈可能更大。我认为d_1999是对的。一个简单的补救方法:使用可分配数组。或者,在所有用户的计算机上,挖掘改变堆栈大小的混乱。我的选择是明确的,可分配的。如果链接不能解决您的问题,请报告。如果有必要,我们可以很容易地重新讨论这个问题。谢谢。ulimit-s unlimited解决了这个问题。但我不知道为什么在派生类型的情况下会发生这种情况,但如果它是数组,就不会发生这种情况。
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