- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am trying to understand if my interpretation of nested WHERE blocks is incorrect or if the compiler is producing an incorrect execution.
I encountered numerical floating point exceptions in a large program because of the execution of LOG10(0.D00) inside a nested WHERE block, even though execution of array arguments with values <= 0.0D0 should be prevented by a mask in the outer WHERE block.
The following test code reproduces the problem when the compiler flag /fpe:0 is set for floating point exception handling.
!** A simple program to test issues with nested WHERE constructs ** PROGRAM NestedWHERE IMPLICIT NONE INTEGER(4) :: j INTEGER(4), PARAMETER :: n = 4, k = 100 REAL(8),DIMENSION(n) :: arrayA, arrayB, arrayC, arrayD !------------------------------------------------------- arrayA = [1.0D0, 2.0D0, 0.0D0, 4.0D4] arrayB = [1.0D0, 2.0D-2, 0.0D0, 4.0D-6] !Nested WHERE block WHERE (arrayA(1:n) > 0.0D0) WHERE (ABS(LOG10(arrayA(1:n))) + ABS(LOG10(arrayB(1:n))) < 300.0D0) !issue: LOG10 seems to be executed for all array elements (including elements where arrayA == 0.0D0). Why is the mask (of the outer WHERE) not applied? arrayC(1:n) = arrayB(1:n)/arrayA(1:n) ELSEWHERE arrayC(1:n) = 8.0D-4 ENDWHERE ELSEWHERE arrayC(1:n) = 1.111111111 ENDWHERE !The procedure of the above nested WHERE block expressed by DO-loop and nested IF-END IF blocks (works as expected). DO j = 1,n IF (arrayA(j) > 0.0D0) THEN IF (ABS(LOG10(arrayA(j))) + ABS(LOG10(arrayB(j))) < 300.0D0) THEN arrayD(j) = arrayB(j)/arrayA(j) ELSE arrayD(j) = 8.0D-4 ENDIF ELSE arrayD(j) = 1.111111111 ENDIF ENDDO !J WRITE(*,'(A23)') " arrayC, arrayD " DO j = 1,n WRITE(*,'(2(ES12.4,2x))') arrayC(j), arrayD(j) ENDDO WRITE(*,*) "" WRITE(*,*) "... done." READ(*,*) END PROGRAM
I use the Intel(R) Visual Fortran Compiler 16.0.0.110 [IA-32], in MS Visual Studio 2010 on Windows 7.
The ifort command line used is:
/nologo /debug:full /Od /warn:interfaces /fpe:0 /fp:source /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc100.pdb" /traceback /check:bounds /check:stack /libs:static /threads /dbglibs /c
The following is an excerpt of the call stack at the point of floating point exception:
TestNestedWHERE.exe!___libm_log10_w7() + 0x226 bytes
TestNestedWHERE.exe!NESTEDWHERE() Line 15 + 0x45 bytes Fortran
I am not sure if my use of nested WHERE statements in this case is incorrect (even though both ABS and LOG10 are elemental intrinsic functions) or if it is supposed to work according to the Fortran standard.
Andi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good news - yes, bug is still there in the last release. It's fixed in the upcoming 2023.0 packages. Also fixed in the IFX compiler coming out in the 2023.0 packages, version 2023.0.0 for IFX. These should be coming out very soon. Hopefully before the end of the month.
Before and current 2021.7 compiler
$ ifort -g -traceback -O0 -fpe0 -fp-model source wheredat.f90 -V
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.7.1 Build 20221019_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
Intel(R) Fortran 2021.7.1-1776
GNU ld version 2.37-27.fc36
rwgreen@orcsle153:~/quad/qnew$ ./a.out
forrtl: error (73): floating divide by zero
Image PC Routine Line Source
libc.so.6 00007FCA04537A70 Unknown Unknown Unknown
a.out 000000000045C5A9 Unknown Unknown Unknown
a.out 00000000004042FF MAIN__ 14 wheredat.f90
a.out 000000000040419D Unknown Unknown Unknown
libc.so.6 00007FCA04522590 Unknown Unknown Unknown
libc.so.6 00007FCA04522649 __libc_start_main Unknown Unknown
a.out 00000000004040B5 Unknown Unknown Unknown
Aborted (core dumped)
r
and with an early build of the 2021.8 compiler coming in oneAPI 2023.0 packages very soon. Note that the build date will probably be different in the product compiler. version will be 2021.8.0 like this one.
ifort -g -traceback -O0 -fpe0 -fp-model source wheredat.f90 -V
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.8.0 Build 20221107_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
Intel(R) Fortran 2021.8.0-1196
GNU ld version 2.37-27.fc36
rwgreen@orcsle153:~/quad/qnew$ ./a.out
arrayC, arrayD
1.0000E+00 1.0000E+00
1.0000E-02 1.0000E-02
1.1111E+00 1.1111E+00
1.0000E-10 1.0000E-10
... done.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the very convenient reproducer. In reviewing WHERE in the Fortran 2008 Standard, I believe this is a defect. It seems the compiler is not applying the outer WHERE mask during evaluation/execution of the inner WHERE as it should. I reported this to Development for their analysis and will let you know what I hear back.
(Internal tracking id: DPD200376235)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I've noticed that the above stated issues with nested WHERE blocks still exists in the ifort version 2021.7.0.
Is there an update on a fix in a future edition of the compiler?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good news - yes, bug is still there in the last release. It's fixed in the upcoming 2023.0 packages. Also fixed in the IFX compiler coming out in the 2023.0 packages, version 2023.0.0 for IFX. These should be coming out very soon. Hopefully before the end of the month.
Before and current 2021.7 compiler
$ ifort -g -traceback -O0 -fpe0 -fp-model source wheredat.f90 -V
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.7.1 Build 20221019_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
Intel(R) Fortran 2021.7.1-1776
GNU ld version 2.37-27.fc36
rwgreen@orcsle153:~/quad/qnew$ ./a.out
forrtl: error (73): floating divide by zero
Image PC Routine Line Source
libc.so.6 00007FCA04537A70 Unknown Unknown Unknown
a.out 000000000045C5A9 Unknown Unknown Unknown
a.out 00000000004042FF MAIN__ 14 wheredat.f90
a.out 000000000040419D Unknown Unknown Unknown
libc.so.6 00007FCA04522590 Unknown Unknown Unknown
libc.so.6 00007FCA04522649 __libc_start_main Unknown Unknown
a.out 00000000004040B5 Unknown Unknown Unknown
Aborted (core dumped)
r
and with an early build of the 2021.8 compiler coming in oneAPI 2023.0 packages very soon. Note that the build date will probably be different in the product compiler. version will be 2021.8.0 like this one.
ifort -g -traceback -O0 -fpe0 -fp-model source wheredat.f90 -V
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.8.0 Build 20221107_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
Intel(R) Fortran 2021.8.0-1196
GNU ld version 2.37-27.fc36
rwgreen@orcsle153:~/quad/qnew$ ./a.out
arrayC, arrayD
1.0000E+00 1.0000E+00
1.0000E-02 1.0000E-02
1.1111E+00 1.1111E+00
1.0000E-10 1.0000E-10
... done.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page