Вопросы на тему "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
обнаружит вашу проблему ранее.