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

Floating point exception handling

netphilou31
New Contributor III
2,738 Views

Hi,

I am trying to implement a floating point exception handling routine for a fortran DLL compiled with version 11.1.051 (under Windows 7 and Microsoft VisualStudio 2005 IDE).

I was using the MATHERRQQ function with CVF and I know that this feature is no longer available with Intel Fortran so I have tried several things but unsuccessfuly !

- Using the (set/get)controlfpqq routines to modify the FPE environment
- Using the -fp:strict compiler directive
- Using the FOR_SET_FPE routine

None of the above attempts worked correctly, Furthermore, I was never able to set a breakpoint in the FPE exception handling routine. In some cases the FPE exception handling seems to work but the program never stops in the routine!

Here is my routine:
[fortran]!
!  FPE_HANDLER.F90 - Handling runtime math exceptions
!
integer(4) function FPE_HANDLER(sigid, except)
!DEC$ ATTRIBUTES C :: FPE_HANDLER
    use IFPORT
    use ReacTypes

    implicit none

    integer(2) sigid, except

    sigid = sigid
    except = except
    FPE_HANDLER = 1

    ! Retour
    call LONGJMP(JMP_BUF, -1)

end function FPE_HANDLER
[/fortran]
Note that the ReacTypes module contains interface definition for the setjmp/longjmp routines as well as the JMP_BUF buffer.
[bash]    .../...

    integer(4) JMP_BUF(16)

    interface
        integer(4) function SETJMP(JMP_BUF)
        !dec$ attributes C, Alias:'__setjmp' :: SETJMP
            integer(4) JMP_BUF(16)
        end function
    end interface

    interface
        subroutine LONGJMP(JMP_BUF, RET_VALUE)
        !dec$ attributes C :: LONGJMP
            integer(4) JMP_BUF(16), RET_VALUE
        end subroutine
    end interface

    .../...

[/bash]
I have placed the declaration of the signal handling routine in the DLLMain routine hereafter:
[fortran]    .../...

    interface
        integer(4) function FPE_HANDLER(sigid, except)
        !DEC$ ATTRIBUTES C :: FPE_HANDLER
            integer(2) sigid, except
        end function
    end interface

    .../...

    if (ul_reason_being_called == DLL_PROCESS_ATTACH) then

!        rc = SIGNALQQ(SIG$FPE, FPE_HANDLER)

    end if
[/fortran]
I have tried to take some code from the examples shown in the documentation (particularly for the FOR_SET_FPE, SETCONTROLFPQQ routines just before calling the SIGNALQQ routine) but with no success at all!

Did I miss something ? I have tried this with a previous version of the Intel Fortan compiler (version 9.x or 10.x I do not remember exactly) and as far as I can remember it was working pretty well. What about the 11.1.051 version of the compiler ?

Do I need to try with the IEEE_FLAGS / IEEE_HANDLER routines ?

I recognize that I have no more ideas on how to solve this annoying problem !

0 Kudos
12 Replies
Steven_L_Intel1
Employee
2,738 Views
Does it work better with /arch:ia32? We've identified and fixed a bug in the run-time library exception handling that may be what's wrong here. I think it is fixed in the next major release, due out soon.
0 Kudos
netphilou31
New Contributor III
2,738 Views
Hi Steve,

Unfortunately not.

Something happen (but the same behavior as previously) when the exception is triggered: It seems that the routine exits but do not reenters where the call to the setjmp function was made (that seems logical because I cannot define breakpoints in my FPE_HANDLER routine that,asit seems, is never called so the call longjmp() function is never performed). In y case I get some additional problems because the routine tries then to allocate arrays that have not been deallocated previously because of the exception.

Additionally the behavior is different with and without the fpe-all:0 compiler directive (if set I do not have to change the floating-point control word in order to get the exception, if not set nothing happens and the calculation involving the exception returns +Infinity).

What is the exact difference between the (get/set)controlfpqq and for_(set/get)_fpe routines ?
same question withthe routines signalqq and signal ?

Best regards,
0 Kudos
netphilou31
New Contributor III
2,738 Views
Steve,

Just an additional couple of information. The behavior is the same if Ido register my FPE handling function by using the SIGNALQQ routine or not! The exception seems to handledby anotherroutine (in the runtime library I assume). Furthermore if I don't use the fpe-all:0 compiler directive nothing happens; the exception is not triggerred in the IVF dllbut it seems that it iscatched by another Fortran DLL (compiled with CVF 6.6C) that usesa special matherrqq handling routine (and uses the same setjmp/longjmp procedure). I don't know if this first dll is catching the signal or if another FPE exception is triggered in this dll because of the first one.
0 Kudos
Steven_L_Intel1
Employee
2,738 Views
I don't know what happens if you mix CVF code with IVF code, especially for exception handling. Probably nothing good. Cab you rebuild the DLL with Intel Fortran?
0 Kudos
netphilou31
New Contributor III
2,738 Views

This could be a good idea but this other dll uses a lot of source files plus a library also compiled using CVF and it would require some time to migrate/recompile all of them with IVF (this is what I intend to do but later). Futhermore, the two dlls are not linked in a statically (there is another intermediate dll between the two, which is written in delphi).

What about the fpe-all:0 and fpe:0 compiler options?
The documentation mentions that the fpe:0 option works only for main programs but not with dlls and that in such case fpe-all:0 must be used instead.
Did I understand correctly?

What about the other questions regarding the differences between the signal and signalqq routines and (set/get)fpcontrolqq and for_set_fpe ?

Thanks.

0 Kudos
Steven_L_Intel1
Employee
2,738 Views
Yes, /fpe-all:0 is used for DLLs and library routines.

I'll have to research your other questions and get back to you.
0 Kudos
netphilou31
New Contributor III
2,738 Views
Ok Steve, Thanks for your help.

I have tried the same things with another dll (still compiled with the 11.1.051 version) which is directly called from Excel through an ActiveX component written in Delphi and again I was unable to catch the exceptions.

I was using theGETCONTROLFPQQ and SETCONTROLFPQQ routines to change the floating-point exception mask and the SIGNALQQ routine to register my handling routine ; all of this being done in theDllMain entry point when the dll is attached to the calling process).
0 Kudos
netphilou31
New Contributor III
2,738 Views
Steve,

I have made some progress in the test of FPE handling and you can find attached a ZIP file containing some sources code (a copy of the sample code taken from the compiler's documentation).

I have built four test cases:

  1. Console program that trap FPE exceptions using the IEEE_HANDLER function to register the handler
  2. Same as 1. but the exception occurs in an external dll (the FPE handler is defined in the main programwhich is a console application)
  3. Same as 1. but with the SIGNALQQ routine
  4. Same as 2. with the SIGNALQQ routine
I experienced the same behavior with 1 and 3 and 2 and 4 respectively:

  • 1. and 3. : The exception (a zero divide) is trapped (but not as a zero divide, it is detected as an invalidoperation). I have used the setjmp/longjmp procedure du resume the calculation. However the second is not detected (exponential overflow) as it is when it is the first one.
  • 2. and 4. : Nothing happens the calculations results are 'Infinity' and no exception is trapped !
The ZIP file attached contains the corresponding source files along with their bluid files. I hope this will help you to improve the handling of this problem as it is the last one that prevent us to switch to Intel compiler (we are still using the COMPAQ visual fortran for this reason).

Note that I did not test all the compilation directives combinations nor the other possibilibities with the FOR_SET_FPE or SET/GETCONTROLFPQQ routines.

I have read in the documentation(please correct me if I am wrong) that the Structured Exception Handling (SEH) is not implemented in the compiler. Do you know if a try/except/finally mechanism is forecasted in the future (it will be a tremendous improvement) ?
0 Kudos
Steven_L_Intel1
Employee
2,738 Views
No sort of exception handling has been formally proposed for Fortran, and we're not going to add it on our own. I recommend trying the F2003 IEEE FP modules to see if they work better for you. I won't be able to look at your test case for a while.
0 Kudos
netphilou31
New Contributor III
2,738 Views
You are right,

I was just expecting that I could (in my point of view it should) be part of a future evolution of the Fortran language. We are developping Fortran dlls that perform a lot of calculations and we cannot check every results without increasing the calculation time in an unacceptable way !

Where can I find the F2003 IEEE FP modules ? Are they part of a recent release of the Intel Fortran or can I find them with just a google request ?

Best regards.
0 Kudos
Steven_L_Intel1
Employee
2,738 Views
The modules are part of Intel Fortran: IEEE_ARITHMETIC, IEEE_EXCEPTIONS and IEEE_FEATURES. At this point you'll have to read the standard (link is on this forum's home page) for details on using them.

Basically the way they work is that you disable "trapping" of exceptions, do the operations you think might fail, and then check to see if an exception occurred.
0 Kudos
netphilou31
New Contributor III
2,738 Views
Thanks Steve for the information,

I will have a look at these features, but I am afraid that some problems arise because I have already tried to use the IEEE_HANDLER function to try to catch IEEE exceptions and it does not work with a dll. Moreover asmentionned in my previous reply, it seems not very easy to understand why two successive FPE exceptions arenot trapped (only the first one is).

Anyway I will try to have a look on this dark side....

Best regards,
0 Kudos
Reply