【发布时间】:2014-10-21 15:07:42
【问题描述】:
我一直在调试模式下使用 Intel 编译器版本 13.1.3.192 运行一个巨大的 Fortran 代码(-O0 -g -traceback -fpe3 标志被打开)。它给了我以下输出消息:
... ...
forrtl: warning (402): fort: (1): In call to MPI_ALLGATHER, an array temporary was created for argument #1
forrtl: error (65): floating invalid
Image PC Routine Line Source
arts 00000000016521D9 pentadiagonal_ser 385 pentadiagonal.f90
arts 0000000001644862 pentadiagonal_ 62 pentadiagonal.f90
arts 00000000004DF167 implicit_solve_x_ 1201 implicit.f90
arts 0000000000538079 scalar_bquick_inv 383 scalar_bquick.f90
arts 00000000004EFEAC scalar_step_ 190 scalar.f90
arts 0000000000401744 simulation_run_ 182 simulation.f90
arts 0000000000401271 MAIN__ 10 main.f90
arts 0000000000400FAC Unknown Unknown Unknown
arts 000000000420E444 Unknown Unknown Unknown
arts 0000000000400E81 Unknown Unknown Unknown
而错误的来源来自子程序pentadiagonal_serial,它是求解一个五对角矩阵:
subroutine pentadiagonal_serial(A,B,C,D,E,R,n,lot)
use precision
implicit none
integer, intent(in) :: n,lot
real(WP), dimension(lot,n) :: A ! LOWER-2
real(WP), dimension(lot,n) :: B ! LOWER-1
real(WP), dimension(lot,n) :: C ! DIAGONAL
real(WP), dimension(lot,n) :: D ! UPPER+1
real(WP), dimension(lot,n) :: E ! UPPER+2
real(WP), dimension(lot,n) :: R ! RHS - RESULT
real(WP), dimension(lot) :: const
integer :: i
if (n .eq. 1) then
! Solve 1x1 system
R(:,1) = R(:,1)/C(:,1)
return
else if (n .eq. 2) then
! Solve 2x2 system
const(:) = B(:,2)/C(:,1)
C(:,2) = C(:,2) - D(:,1)*const(:)
R(:,2) = R(:,2) - R(:,1)*const(:)
R(:,2) = R(:,2)/C(:,2)
R(:,1) = (R(:,1) - D(:,1)*R(:,2))/C(:,1)
return
end if
! Forward elimination
do i=1,n-2
! Eliminate A(2,i+1)
const(:) = B(:,i+1)/(C(:,i)+tiny(1.0_WP))
C(:,i+1) = C(:,i+1) - D(:,i)*const(:)
D(:,i+1) = D(:,i+1) - E(:,i)*const(:)
R(:,i+1) = R(:,i+1) - R(:,i)*const(:)
在哪一行
const(:) = B(:,i+1)/(C(:,i)+tiny(1.0_WP))
导致错误。我试图打印出const(:) 的值,发现确实存在Infinity 值。但是,我不明白为什么它会产生无穷大。据我所知,为了避免分母为零,tiny(1.0_WP) 被添加到C(:,i),现在分母几乎不可能为零......我还检查了这个子程序何时被调用,一切都被初始化或声明后给定一个值。所以我不知道哪里出了问题。
【问题讨论】:
-
如果
C的任何值都在-tiny附近,那么您仍然可以在分母中得到零。 -
是的,没错。但我猜这种情况的概率很小。或者,您有避免这种情况的想法吗?
-
你打印出
C的值了吗?小值是否与const中的无穷大相关? -
嗯,C(:,i)中有“-Infinity”值,但分母中是C(:,i),这让我很困惑……
-
C的最小值大于0.1
标签: fortran intel-fortran infinity floating-point-exceptions