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

IFX bug taking the sqrt of 0.0?

bwe
Beginner
493 Views

I'm encountering what I think has to be a compiler bug in ifx version 2022.2.0. I don't see any way around it. I don't have a minimum example that demonstrates the issue, but in our main code base, I've added some debug code that looks like this:

 

print*,var1(1),var2(1)
print*,(var1(1)**2 + var2(1)**2)
print*,sqrt(0.0)
print*,sqrt(0.0d0)
print*,0.0 == (var1(1)**2 + var2(1)**2)
print*,sqrt(var1(1)**2 + var2(1)**2)

 

Output:

 

  0.0000000E+00  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.000000000000000E+00
 T
forrtl: error (65): floating invalid

 

It crashes on the line trying to take the square root of zero even though taking the square root of zero should be fine, and I have no problem taking the sqrt of literal zeros. Is/was there a known bug in taking roots of zero variables? (I can't reproduce it in a minimal case, so it must require some complexity) I've requested that IT upgrade our version of IFX but in the meantime I'm wondering if I can stop working on trying to figure out what's going on here.

I was getting a crash elsewhere in our code trying to take sqrt(0.0), but I added some code to bypass it in the zero case. Now that I'm encountering the same problem somewhere else, I'm thinking it must be the compiler--right?

0 Kudos
1 Solution
Ron_Green
Moderator
443 Views

I just notice that you said you used ifx 2022.2.0.  Don't use that IFX.  It was immature until the 2023 versions.  Still, just like @andrew_4619 noticed, we can't reproduce what you are seeing even with that not-so-great ifx version:  Please use ifort OR upgrade to the 2024.0.0 version first if you want to use IFX.

 

ifx -what -V  -O0 -g -traceback sqrt.f90

Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2022.1.0 Build 20220316

Copyright (C) 1985-2022 Intel Corporation. All rights reserved.

 

Intel(R) Fortran 22.0-1296

GNU ld version 2.39-9.fc38

rwgreen@orcsle153:~/quad/friday$ ./a.out

  0.0000000E+00  0.0000000E+00

  0.0000000E+00

  0.0000000E+00

  0.000000000000000E+000

T

  0.0000000E+00

View solution in original post

0 Kudos
6 Replies
andrew_4619
Honored Contributor II
448 Views

 

 

 

program sqrtzero
    implicit none
    real :: var1(3), var2(3)
    var1 = 1.0e-45
    var2 = -1.0e-45
    print*,var1(1),var2(1)
    write(*,'(z8.8,1x,z8.8)') var1(1),var2(1)
    print*,(var1(1)**2 + var2(1)**2)
    print*,sqrt(0.0)
    print*,sqrt(0.0d0)
    print*,0.0 == (var1(1)**2 + var2(1)**2)
    print*,sqrt(var1(1)**2 + var2(1)**2)
end program sqrtzero

 

 

 

Out of interest I tried to reproduce the problem (on Windows) and could not.  How are var1 and var2 declared, what are the values prior to the sqrt?

You need to show hex output with a z format as that gives the raw info the print does interpretation/formatting that obscures the actuals. Either there is a bug or there is some under/overflow condition happening. I would suggest trying the program above and see if it works for you.

For what it is worth I would always use the intrinsic norm2 or hypot it saves typing (and typos), looks cleaner and maybe is  more obvious for optimisation.

EDIT:  I should have added Compiling with Intel® Fortran Compiler 2024.0.0 [Intel(R) 64]...

 

0 Kudos
Ron_Green
Moderator
445 Views

sqrt is a thin wrapper to either the system math library or our Intel optimized version of libm.  

So it's crucial to know if you are on Windows or Linux. 

If Windows, what version.  and your Visual Studio version as well.

Linux just the distro and version

It's quite possible it's not our compiler but underlying math lib on your system. 

I cannot reproduce what you are seeing on my linux system:

$ ifort -what -V  -O0 -g -traceback sqrt.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.6.0 Build 20220226_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.

 Intel(R) Fortran 2021.6.0-1299
GNU ld version 2.39-9.fc38
rwgreen@orcsle153:~/quad/friday$ ./a.out
  0.0000000E+00  0.0000000E+00
  0.0000000E+00
  0.0000000E+00
  0.000000000000000E+000
 T
  0.0000000E+00

$ cat sqrt.f90
program square  
implicit none
real (kind=4 ) :: var1(1) = 0.0
real (kind=4 ) :: var2(1) = 0.0

print*,var1(1),var2(1)
print*,(var1(1)**2 + var2(1)**2)
print*,sqrt(0.0)
print*,sqrt(0.0d0)
print*,0.0 == (var1(1)**2 + var2(1)**2)
print*,sqrt(var1(1)**2 + var2(1)**2)

end program square
0 Kudos
Ron_Green
Moderator
444 Views

I just notice that you said you used ifx 2022.2.0.  Don't use that IFX.  It was immature until the 2023 versions.  Still, just like @andrew_4619 noticed, we can't reproduce what you are seeing even with that not-so-great ifx version:  Please use ifort OR upgrade to the 2024.0.0 version first if you want to use IFX.

 

ifx -what -V  -O0 -g -traceback sqrt.f90

Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2022.1.0 Build 20220316

Copyright (C) 1985-2022 Intel Corporation. All rights reserved.

 

Intel(R) Fortran 22.0-1296

GNU ld version 2.39-9.fc38

rwgreen@orcsle153:~/quad/friday$ ./a.out

  0.0000000E+00  0.0000000E+00

  0.0000000E+00

  0.0000000E+00

  0.000000000000000E+000

T

  0.0000000E+00

0 Kudos
bwe
Beginner
323 Views

Good news: IT updated us to ifx 2024.0 and that bypasses the issue entirely. I'm surprised this wasn't a widely known bug since it manifested twice for us. Wonder what the cause was. Every couple months I'd revisit this and go crazy trying to figure it out, so I'm glad to have this in the past.

 

Bad news: IT tells me that ifx 2024 is not compatible with RHEL 7, so only our RHEL 8 test machines will have the fixed compiler for now.

 

As for one of the previous questions:

 

How are var1 and var2 declared, what are the values prior to the sqrt?

 

The values prior to the square root appear to be identically zero according to the output, which outputs them as exact zero and tests their equality to zero immediately prior to trying to sqrt them. The values were declared in a module that was USE'd in the crashing subroutine.

0 Kudos
andrew_4619
Honored Contributor II
316 Views

" The values prior to the square root appear to be identically zero according to the output, which outputs them as exact zero and tests their equality to zero immediately prior to trying to sqrt them. The values were declared in a module that was USE'd in the crashing subroutine."

 

The reason I asks it that the code does not show that. It shows a formatted print giving zero and and equality being true neither of which definitively say they are zero. The hex representation does.  Anyway no problem this is yesterdays news! 

0 Kudos
bwe
Beginner
312 Views

I actually did manage to come up with a minimum example (with Z-formats--did I use them right?) that shows the issue. It seems to be an issue with uninitialized variables specifically from used modules.

 

! extmod.f90
module extmod
real :: value_mod
end module

! test.f90
program main
use extmod
implicit none

real :: value_local

print*,"Sqrt of local uninit variable:"
print*,value_local
write (*,'(Z10.5)') value_local
print*,value_local == 0.0
print*,sqrt(value_local**2)

print*,"Sqrt of mod uninit variable:"
print*,value_mod
write (*,'(Z10.5)') value_mod
print*,value_mod == 0.0
print*,sqrt(value_mod**2)    ! Crashes here with ifx 2022.2.0

end program

 

The output using ifx 2022.2.0 is:

 

 Sqrt of local uninit variable:
  0.000000E+00
    00000
 T
  0.000000E+00
 Sqrt of mod uninit variable:
  0.000000E+00
    00000
 T
forrtl: error (65): floating invalid

 

Everything works as expected with ifort 2024.0.

0 Kudos
Reply