【问题标题】:Questions on "forrtl: error (65): floating invalid"关于“forrtl:错误(65):浮动无效”的问题
【发布时间】: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


【解决方案1】:

(cmets中的答案。见Question with no answers, but issue solved in the comments (or extended in chat)。cmets中有很多聊天,很难提取实际答案,但OP表示已解决。)

@SethMMorton 写道:

如果C 的任何值都在-tiny 附近,那么您仍然可以在分母中得到零。

你打印出C 的值了吗?小值是否与const 中的无穷大相关?

@Alexander Vogt 写道:

好吧,向无穷大添加一些东西会导致浮点异常......而且我不确定 ifort 是否可以检测到除以无穷大为零,我想这是另一个浮点异常!你最好确保 C 内部没有无限值。

@Stefan 写道:

解决方法:MKL/Lapack 的例程 ?gbsv 怎么样? 然后,最后一个提示:尝试使用gfortran 进行编译。不同的编译器会产生不同的编译时/运行时警告和/或错误,gfortran 可能会更早地检测到您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多