Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28767 Discussions

IFX compiler bug during optimization

Jon_D
New Contributor I
557 Views

Hello,

I think I found a bug in IFX. I know this is a question for Intel Support Services but my paid support has lapsed and will take me a couple of months to get it back. I am hoping forum moderators can help me with this.

I am using the latest Fortran compiler under Windows OS with VS2022. Default compiler settings are used.

Attached code, which is heavily dumbed down from a more complex code, prints out different results for array "s" for Debug and Release builds for IFX (IFORT produces same results for both builds).  It seems that Release version gets confused at the inner loop (do=i,k-1....). Modifying that loop slightly, such as adding a WRITE statement, fixes the results from the Release build.

Thanks for your attention.

Jon 

module Givens
    implicit none
    
contains
    
  subroutine generate_givens_rotation(a, b, c, s)
    real(8), intent(in) :: a, b
    real(8), intent(out) :: c, s
    real(8) :: t
    if (b == 0.0) then
      c = 1.0
      s = 0.0
    else if (abs(b) > abs(a)) then
      t = -a / b
      s = 1.0 / sqrt(1.0 + t*t)
      c = s * t
    else
      t = -b / a
      c = 1.0 / sqrt(1.0 + t*t)
      s = c * t
    end if
    
  end subroutine generate_givens_rotation

  
  subroutine apply_givens_rotation(a, b, c, s)
    real(8), intent(in) :: c, s
    real(8), intent(inout) :: a, b
    real(8) :: temp
    temp = c * a - s * b
    b = s * a + c * b
    a = temp
  end subroutine apply_givens_rotation

end module Givens
    
    
program main
    use Givens
    implicit none
    
    integer :: i,k
    real(8) :: H(6,5),cs(5),sn(5),s(6)
    
    H(1,1) = 4394077.91825606d0
    H(2,1) = 4390331.68641289d0
    H(1,2) = 4390331.68648831d0
    H(2,2) = 4744441.61955293d0
    H(3,2) = 780510.389061229d0
    H(1,3) = -1.533207649345059d-003
    H(2,3) = 780510.388841464d0
    H(3,3) = 2158595.01177019d0
    H(4,3) = 91073.4308275071d0
    H(1,4) = 2.947285695881874d-003
    H(2,4) = 2.413949687884331d-003
    H(3,4) = 91073.4289573376d0
    H(4,4) = 4041006.02451326d0
    H(5,4) = 4455961.41073396d0
    H(1,5) = 3.751656505301071d-003
    H(2,5) = 3.166228009130689d-003
    H(3,5) = -1.854696104521314d-003
    H(4,5) = 4455961.41080901d0
    H(5,5) = 5007363.80342342d0
    H(6,5) = 164542.266561260d0
    s      = 0.0
    s(1)   = 9511318.49307146d0
    
    do k=1,5
        do i=1,k-1
            call apply_givens_rotation(H(i,k), H(i+1,k), cs(i), sn(i))
            !write (*,*) 'Uncommenting this fixes RELEASE version'
        end do
        call generate_givens_rotation(H(k,k), H(k+1,k), cs(k), sn(k))
        call apply_givens_rotation(H(k,k), H(k+1,k), cs(k), sn(k))
        call apply_givens_rotation(s(k), s(k+1), cs(k), sn(k))
    end do
    
    do k=1,6
        write (1111,*) k,s(k)
    end do
end program main

 

2 Replies
Mentzer__Stuart
399 Views

That's a good one, Jon. I fiddled around with it and learned a few things.

  • The inner (i) loop (and its use of uninitialized cs and sn) seems to be a red herring. You can remove the i loop (and line 74) and still get different results with IFX /Od vs /O2, but with /O1 the results match those with /Od.
  • /O2 /Qunroll:0 (suppressing loop unrolling) doesn't prevent the buggy behavior.
  • /O2 /fp:strict prevents the buggy behavior.

[Using latest IFX 2024.2.1]

0 Kudos
Jon_D
New Contributor I
312 Views

Thank you for spending time on this.

It turns out, unlike this simplified code, adding a simple WRITE statement within the inner loop doesn't work for my actual, more complicated code. I had to replace

 

call apply_givens_rotation(...)

 

line with the actual body of that subroutine within the inner loop to get it working:

 

 do i=1,k-1
    !call apply_givens_rotation(H(i,k), H(i+1,k), cs(i), sn(i))
    temp     = cs(i) * H(i,k) - sn(i) * H(i+1,k)
    H(i+1,k) = sn(i) * H(i,k) + cs(i) * H(i+1,k)
    H(i,k)   = temp
 end do
0 Kudos
Reply