power operator compatibility


I’m working with a code of a scientific model using the ifort compiler. I switched to pgf90 for other purposes, but I found differences in the computations with the power operator that affects the final results of the model (ifort results are considered as reference). The example code below illustrates the differences in result for a particular value (val2) used with the power operator.

System: Intel Core i7 7820x, Linux CentOS 7.5.1804
Compilers: Intel Fortran (ifort), PGI Fortran 19.10-0 (pgf90)
Compilation: Intel -> ifort -o pow.ifort pow.f90; PGI -> pgf90 -o pow.pgf90 pow.f90 -tp=px

val1: 313.43318861381879969485
val2: 303.02806408588475051147
val1: 313.43318861381879969485
val2: 303.02806408588469366805

program calcpow

    real*8 :: val1, val2

    val1 = 5.608458518981933593750
    val2 = 5.551941394805908203125

    write(*,'(A,F30.20)') 'val1: ', val1**(10.0/3.0)
    write(*,'(A,F30.20)') 'val2: ', val2**(10.0/3.0)

end program calcpow

Is there a flag of pgf90 that can be used to match the results?


The results are already matched. You show many digits in the two real constants that you use to set values for val1 and val2, but the expression is of type single-precision real, which implies that the precision is no more than seven digits. The results match as far as the first seven significant digits are concerned.

If you want better agreement, add “D0” to the two constants. In general, these considerations apply to mixed-precision expressions. See the Fortran documentation regarding how such expressions are evaluated, and consider the expression “10.0/3.0” similarly.

Thanks for your reply.

Results match at many digits but are not the same, and this difference makes the model I’m working with produce final results that are too different. In a previous message I reported the differences returned by the log function (that I found out after debugging), and it seemed that the flag “-tp=px” pointed out by another forum user solved the problem in that case (https://forums.developer.nvidia.com/t/log-function-compatibility/136338/1), producing the same results for log.

Using D0 did not work, even in this test example I posted. This code illustrates how the original code of the model works: a real*8 (double precision) variable powered to 10.0/3.0 (single precision). If I change these values to 10.0_8/3.0_8 or 10.d0/3.d0, results do not match. I want the pgf90 program to behave similar to the ifort program, and to produce the final results as close as to the final results I get with ifort (reference).

That’s why I wrote the example with the same values I get in one iteration of the numerical method. val1 and val2 are values computed during simulation that must be powered. The results of ifort and pgf90 power operator match for val1, but not for val2, so at a particular time step of the simulation the results start to diverge, and at the end the final results are too different. My doubt is why both compilers return the same power result for val1, but not for val2? Why just changing the power base between compilers change its result?

About the final results, for example, at the end of the original model run, one time series variable has value 206.x with ifort, but with pgf90 the value is 221.y, i.e., an error of about 15 units, and this is large for my problem.

I want to use the CUDA Fortran capabilities of pgf90, but first I need to solve this issue in order to get similar final results. Please, let me know if there is a way to make the power computations behave equally.

Hi Henrique Rennó,

Try adding the flag “-Kieee” for strict IEEE 754 compliance.

% pgfortran test.f90 -Kieee; a.out
val1:       313.43318861381879969485
val2:       303.02806408588475051147
% ifort test.f90; a.out
val1:       313.43318861381879969485
val2:       303.02806408588475051147

Hope this helps,

Thanks for your reply. Now these results are matching.