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

Different behaviour due to -xHost, zeroing of array elements.

Haakon
Beginner
553 Views

Hi,

I am seeing some behavior that I would like to understand better. In some sense it seems somewhat reasonable that this issue occurs, at least it would be unreasonable to expect that there would be no issues.

First, let me give you my machine and compiler details (I have tested other compiler versions by the way).
Compiler:

 

/> ifort --version
ifort (IFORT) 2021.3.0 20210609

 

 

CPU: Intel Xeon Gold 6130

I am running and developing a fairly large and complex code, which I only develop a small part of. During tests I found random instances of some matrix elements being set to zero, identically = zero. I traced the issue down to a part of the code where I think the issue is caused by small numbers being added together and subtracted, basically a float issue. So far so good.

The strange part is that the error only occurred when i used vectorization for the calculations. Putting the calculation into a loop resolved the issue.  In order to make sure I understood this rather strange problem I wrote the following code that reproduces the error.

The following code illustrates the issue.

 

 

program main
  integer :: nvec, i
  real(kind=8),dimension(:),allocatable :: alpha,A,B,C,tau
  integer, allocatable :: seed(:)
  integer :: n

  call random_seed(size = n)
  allocate(seed(n))
  call random_seed(get=seed)
  write (*, *) seed

  nvec = 50
  allocate(alpha(nvec),tau(nvec),A(nvec),B(nvec),C(nvec))

  call random_number(tau)
  tau = tau*1.0d-40

  alpha = tanh(1.0/tau)
  call random_number(C)
  call random_number(B)
 
  C = (C-1.0d0)*1.0d-23
  B = (B-1.0d0)*1.3423d15
  A = alpha*C + (1.0-alpha)*B

  do i = 1,nvec
     if(A(i) .eq. 0.0d0) then
        write(*,"(e20.10,e20.10,e20.10,e20.10,e20.10)") A(i),B(i),C(i),tau(i),alpha(i)
     end if
  end do     
end program main

 

 

The issue is connected to the calculations taking place when alpha is set to 1 and A should be equal to C. Compiling the code with compile this with ifort -O2 -xHost produces a few places in the array where A = 0.0. Removing xHost solves this issue, meaning that it has to do with the instruction set that xHost enforces.

I am aware that checking strict equality with floats is somewhat problematic, but you can modify the code and remove the IF, just print the whole array, and you should see the same behavior.

I would like to understand this a bit better so that I can adjust my code to account for issues like this in the future. Is it simply because the behavior for tiny-tiny+tiny is not well defined? Is there some decision made in one instruction set that was different in the other? Am I right in my explanation as of why this happens? Any advice or information would be appreciated. I have fixed the issue in my code, by rewriting how some calculations are done to avoid this scenario, but coding advice is of course also welcome, although I am more interested in learning about this type of behavior from a compiler/code execution perspective.

The output when I run the code with -Xhost.

 

2147483562  2147483398
0.0000000000E+00   -0.1134597913E+16   -0.6302833313E-23    0.4387013564E-40    0.1000000000E+01
0.0000000000E+00   -0.5383806066E+15   -0.5119086162E-23    0.2087532956E-40    0.1000000000E+01

 

 

 



0 Kudos
3 Replies
Haakon
Beginner
481 Views

bump

0 Kudos
andrew_4619
Honored Contributor III
478 Views

Strange thing can happen with optimisation read https://community.intel.com/t5/Intel-Fortran-Compiler/Ifort-IFORT-2021-8-evaluates-1-0E-37-1-0E-38-to-0/m-p/1442372#M164219

 

Here if i recall correctly the vectorisation takes a say 4 values at a time and does an operation but if say the array was 5 long the last value goes on a different code path and uses different instructions.  Try fp-strict option.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
461 Views

Two suggestions:

1)

Change:  alpha = tanh(1.0/tau) 

To:  alpha = tanh(1.0d0/tau) 

2)

Use: /Qfast-transcendentals- for Windows, or -no-fast-transcendentals for Linux

 

Jim Dempsey

0 Kudos
Reply