我遇到了一些问题,这些问题似乎是由于代码中的内存处理引起的。在下面的示例中,我设法隔离了该问题。使用intel而不使用gfortran进行编译时,它将在迭代1024处返回segmentation fault (core dumped)
(这就是为什么我从1000开始循环)。如果对该函数的调用已被注释掉,则对该子例程的调用将至少在循环结束之前一直有效。从理论上讲,当调用函数时,gfortran从堆中获取Dmat的内存,而intel从堆栈中获取内存。
是这种情况吗?还有其他事情吗?这意味着为了使我的代码能够充分扩展并支持intel编译,我必须将我的所有过程都定义为子例程,而只是放弃函数?
module auxmod
implicit none
contains
function matmul3_fun( Amat, Bmat, Cmat ) result( Dmat )
implicit none
real*8, intent(in) :: Amat(:,:)
real*8, intent(in) :: Bmat(:,:)
real*8, intent(in) :: Cmat(:,:)
real*8 :: Dmat( size(Bmat,1), size(Bmat,2) )
real*8, allocatable :: Emat(:,:)
allocate( Emat( size(Bmat,1), size(Bmat,2) ) )
Emat = matmul( Amat, Bmat )
Dmat = matmul( Emat, Cmat )
end function matmul3_fun
subroutine matmul3_sub( Amat, Bmat, Cmat, Dmat)
implicit none
real*8, intent(in) :: Amat(:,:)
real*8, intent(in) :: Bmat(:,:)
real*8, intent(in) :: Cmat(:,:)
real*8, intent(out) :: Dmat( size(Bmat,1), size(Bmat,2) )
real*8, allocatable :: Emat(:,:)
allocate( Emat( size(Bmat,1), size(Bmat,2) ) )
Emat = matmul( Amat, Bmat )
Dmat = matmul( Emat, Cmat )
end subroutine matmul3_sub
end module auxmod
program size_overflow
use auxmod
implicit none
real*8, allocatable :: Amat(:,:)
real*8, allocatable :: Bmat(:,:)
real*8, allocatable :: Cmat(:,:)
real*8, allocatable :: Dmat(:,:)
integer :: kk
do kk=1000, 2000
allocate ( Amat(kk,kk), Bmat(kk,kk), Cmat(kk,kk), Dmat(kk,kk) )
Amat(:,:) = 1.d0
Bmat(:,:) = 2.d0
Cmat(:,:) = 3.d0
call matmul3_sub( Amat, Bmat, Cmat, Dmat )
write(*,*) "SUB works for size = ", kk
Dmat = matmul3_fun( Amat, Bmat, Cmat )
write(*,*) "FUN works for size = ", kk
deallocate( Amat, Bmat, Cmat, Dmat )
end do
end program size_overflow