массив fortran = 0 не заданы значения при оптимизации - PullRequest
0 голосов
/ 01 мая 2019

У меня довольно большой код (> 6000 строк), с проблемой, которую я пытаюсь проиллюстрировать следующим очень упрощенным фрагментом:

program TestFortran
implicit none
real, parameter                  ::  eps = 1d-30
real              ::  res
real              ::  tmp

call TestInitialisation(res,tmp)
if (res>0 .and. res <eps) then
  write(*,*) "res is small but not zero and tmp = ", tmp
  res = 0d0
else
  write(*,*) "res is zero and tmp = ", tmp
end if

contains

subroutine TestInitialization(output,out2)
real,intent(out)  ::  output
real,intent(out)  ::  out2
real              ::  origa(10,10)
real              ::  copya(10,10)
origa = 0d0
copya = origa
call TIS1(copya,output,out2)
end subroutine TestInitialization


subroutine TIS1(arr2d,ret,out2)
real,intent(in)   ::  arr2d(:,:)
real,intent(out)  ::  ret
real,intent(out)  ::  out2
integer           ::  ii

do ii = 1,size(arr2d,2)
  call TIS2(arr2d(:,ii),ii,ret,out2)
  if (ret > 0) then
    exit
  end if
end do

end subroutine TIS1

subroutine TIS2(arr1d,jj,ret,out2)
real,intent(in)   ::  arr1d(:)
real,intent(out)  ::  ret
real,intent(out)  ::  out2
integer           ::  ii
integer,intent(in)::  jj

do ii = 1,size(arr1d)
  ret = arr1d(ii)
  out2 = real(jj)
  if (ret > 0) then
    out2 = -1d0
    exit
  end if
end do
end subroutine TIS2
end program TestFortran

Реальная программа работает должным образом в режиме отладки. Однако, когда в режиме выпуска (Visual Studio 2017 с Intel Compiler 2017), переключите / O3, значение res - просто мусор (как 1.0831d-273, однако я не уверен, стоит ли доверять проводнику переменных при отладке оптимизированного кода) , Я не мог воссоздать ситуацию с приведенным выше примером, он просто служит иллюстрацией (переменная tmp предназначена для того, чтобы не просто оптимизировать все это). Если я добавлю write(*,*) "res in TIS2 =",res в подпрограмму TIS2 в коде реальной программы , результат будет правильным, но этого не требуется (особенно из-за снижения скорости).

Я проверил различные комбинации флагов компилятора; то есть следующее:

/ debug: full / O2 / Qinit: snan / Qinit: arrays / fpe: 0 / Qipo / traceback / check: uninit / arch: SSE3 / real_size: 64 / fp: fast = 2 / Qvec-порог: 60 / рекурсивный

У кого-нибудь есть подсказки или комментарии по этому поводу?

1 Ответ

0 голосов
/ 03 мая 2019

Я допустил ошибку (ошибку), когда массив не был заполнен правильно.Я нашел это, используя флаги компилятора: /Qinit:snan вместе с /Qinit:arrays в режиме отладки.Это не показывалось в режиме выпуска.Так что в целом это была просто довольно простая ошибка в моем коде, которая осталась незамеченной, в основном (в 99% случаев) все прошло хорошо, но не всегда.Странно было то, что он не был пойман в режиме релиза.

...