оптимизация ifort O3 приводит к несоответствию

У меня проблема с моим кодом на фортране при использовании оптимизации O3: значения, рассчитанные для нормы массива, меняются с O3 и без него и неверны с O3. Ниже показан минимальный пример моего кода

program main
use wavefunction
implicit none

integer(I4B) :: Na, Nb, Npes
complex(DPC), ALLOCATABLE, DIMENSION(:,:,:) :: phi 
real(DP), ALLOCATABLE, DIMENSION(:) :: normPerPes1
real(DP) :: sigma

integer(I4B) :: i,j
Na=100
Nb=100
Npes=4

ALLOCATE(phi(Na,Nb,Npes), normPerPes1(Npes))

sigma=10
phi=(0.D0,0.D0)
do i=1,Na
   do j=1,Nb
      !gaussian on pes 1
      phi(i,j,1)=1.D0/(sigma**2*2.D0*pi)*exp(-(dble(i-50)**2+dble(j-50)**2/(2.D0*sigma**2))
   end do
end do

!total norm
write(*,*) norm(Na,Nb,Npes,phi)
!norm on each pes
CALL normPerPes(Na,Nb,Npes,phi,NormPerPes1)
write(*,*) NormPerPes1

end program main

который использует следующий модуль

module wavefunction
use nrtype
implicit none

contains
  function norm(Na,Nb,Npes, phi)
  implicit none
  INTEGER(I4B), INTENT(IN) :: Na, Nb, Npes
  COMPLEX(DPC), INTENT(IN) :: phi(Na,Nb,Npes)
  REAL(DP) :: norm

  INTEGER(I4B) :: i,j, pesNr

  norm=0.D0
  do i=1,Na
     do j=1,Nb
        do pesNr=1, Npes
           norm=norm+abs(phi(i,j,pesNr))**2
        end do
     end do
  end do

end function norm
!----------------------------------------------------------
subroutine normPerPes(Na, Nb, Npes, phi, normPerPes1)
  IMPLICIT none

  REAL(DP) :: normPerPes1(Npes)
  INTEGER(I4B), INTENT(IN) :: Na, Nb, Npes
  COMPLEX(DPC), INTENT(IN) :: phi(Na,Nb,Npes)
  INTEGER(I4B):: i,j,pesNr

  normPerPes1=0.0d0
  do i=1,Na
    do j=1,Nb
       do pesNr=1,Npes
          normPerPes1(pesNr)=normPerPes1(pesNr)+abs(phi(i,j,pesNr))**2
       end do
     end do
  end do
  return
end subroutine normPerPes
!-----------------------------------------------------------
end module wavefunction

если я скомпилирую следующий Makefile

# compiler
FC = ifort
# flags
FFLAGS = #  -O3

main: main.o nrtype.o wavefunction.o
main.o: main.f90 nrtype.o wavefunction.o
wavefunction.o: wavefunction.f90 nrtype.o
nrtype.o: nrtype.f90

%: %.o
    $(FC) $(FFLAGS) -o dynamic  $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FFLAGS) -c $<

clean:
rm -f *.o *.mod *_genmod.f90

Я получаю следующий правильный вывод:

7.957747154568253E-004

7.957747154568242E-004 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000

Однако, если я использую O3, я получаю следующий неверный результат

7.957747154568253E-004

1.989436788642788E-004 0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000

Мне кажется, что в моем коде было что-то серьезно подозрительное, но я не могу найти проблему. Спасибо за помощь!


person user1638145    schedule 18.06.2014    source источник


Ответы (1)


Как подтверждено корпорацией Intel (см. https://software.intel.com/en-us/forums/topic/516819), это проблема используемой версии компилятора (начальный выпуск Composer XE 2013 SP1 (pkg. 080)). Утверждают, что обновление до Update 2 или 3 помогает - мне пока не удалось попробовать. В то же время обходной путь — забыть об O3 и использовать оптимизацию O2.

person user1638145    schedule 19.06.2014