Вопросы на тему "forrtl: ошибка (65): плавающий недействительный"

Я запустил огромный код Fortran с версией компилятора Intel 13.1.3.192 в режиме отладки (с -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) и теперь почти невозможно, чтобы знаменатель был равен нулю... Я также проверил, когда вызывается эта подпрограмма, все инициализируется или получает значение после объявления. Поэтому я не мог понять, где может пойти не так.

1 ответ

(Ответы в комментариях. См. Вопрос без ответов, но проблема решена в комментариях (или расширена в чате). В комментариях много разговоров, и трудно получить фактический ответ, но ОП указывает, что он решен..)

@SethMMorton написал:

Если любое из значений C вокруг -tiny тогда вы все равно можете получить ноль в знаменателе.

Вы распечатали значения C? Соответствуют ли небольшие значения бесконечности в const?

@ Александр Фогт написал:

Что ж, добавление чего-либо к бесконечности приводит к исключению с плавающей запятой... И я не уверен, что ifort может обнаружить, что деление на бесконечность равно нулю, я думаю, это еще одно исключение с плавающей запятой! Вам лучше убедиться, что внутри C. нет бесконечных значений

@Stefan написал:

Обходной путь: как насчет рутины ?gbsv из МКЛ / Лапак? Затем последний совет: попробуйте скомпилировать с gfortran, Разные компиляторы создают разные предупреждения и / или ошибки времени компиляции / времени выполнения и, возможно, gfortran обнаружит вашу проблему ранее.

Другие вопросы по тегам