• ffpe-trap=precision and I/O of real numbers

    From Daniel Feenberg@21:1/5 to All on Sun Oct 24 14:13:03 2021
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end

    and run it under gdb with a breakpoint at the first executable statement::

    Breakpoint 1, test () at test.for:2
    2 write(*,*) 'a'
    (gdb) n
    a
    3 write(*,*) 50.
    ( gdb) n

    Program received signal SIGFPE, Arithmetic exception.
    0x00007ffff7ba5a21 in ?? () from /lib64/libgfortran.so.3

    It appears that the attempt to write a small integer triggers an arithmetic exception. Which seems very unlikely.
    .Wouldn't that be worthy of mention in the docs.?

    Daniel Feenberg

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Neil@21:1/5 to baf on Sun Oct 24 22:00:42 2021
    baf <baf@nowhere.com> wrote:
    On 10/24/2021 2:13 PM, Daniel Feenberg wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end

    and run it under gdb with a breakpoint at the first executable statement:: >>
    Breakpoint 1, test () at test.for:2
    2 write(*,*) 'a'
    (gdb) n
    a
    3 write(*,*) 50.
    ( gdb) n

    Program received signal SIGFPE, Arithmetic exception.
    0x00007ffff7ba5a21 in ?? () from /lib64/libgfortran.so.3

    It appears that the attempt to write a small integer triggers an arithmetic exception. Which seems very unlikely.
    .Wouldn't that be worthy of mention in the docs.?

    Daniel Feenberg



    Something is broken in your installation/version of gfortran. Compiling
    your program with version 11.2 I get the following output:

    a
    50.0000000



    The issue seems to occur with gfortran 9.3.0:

    laptop3:~> cat temp.f90
    program test
    write(*,*)'a'
    write(*,*)50.
    end

    laptop3:~> gfortran --version
    GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
    Copyright (C) 2019 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    laptop3:~> gfortran -ffpe-trap=precision temp.f90

    laptop3:~> ./a.out
    a

    Program received signal SIGFPE: Floating-point exception - erroneous
    arithmetic operation.

    Backtrace for this error:
    #0 0x7f6ada3dcd5a
    #1 0x7f6ada3dbef5
    #2 0x7f6ada21020f
    #3 0x7f6ada62d385
    #4 0x7f6ada62eb98
    #5 0x7f6ada62ef35
    #6 0x7f6ada62ff76
    #7 0x5638fc62b25e
    #8 0x5638fc62b2b0
    #9 0x7f6ada1f10b2
    #10 0x5638fc62b0dd
    #11 0xffffffffffffffff
    Floating point exception (core dumped)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From baf@21:1/5 to Daniel Feenberg on Sun Oct 24 14:33:47 2021
    On 10/24/2021 2:13 PM, Daniel Feenberg wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end

    and run it under gdb with a breakpoint at the first executable statement::

    Breakpoint 1, test () at test.for:2
    2 write(*,*) 'a'
    (gdb) n
    a
    3 write(*,*) 50.
    ( gdb) n

    Program received signal SIGFPE, Arithmetic exception.
    0x00007ffff7ba5a21 in ?? () from /lib64/libgfortran.so.3

    It appears that the attempt to write a small integer triggers an arithmetic exception. Which seems very unlikely.
    .Wouldn't that be worthy of mention in the docs.?

    Daniel Feenberg



    Something is broken in your installation/version of gfortran. Compiling
    your program with version 11.2 I get the following output:

    a
    50.0000000

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cyrmag@21:1/5 to Daniel Feenberg on Sun Oct 24 18:04:33 2021
    On 10/24/2021 4:13 PM, Daniel Feenberg wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end

    <--- CUT --->

    Daniel Feenberg


    I see the bug with gcc version 10.2.0 (GCC) under Cygwin-64 bit on
    Windows 10-64 bit.

    -- CyrMag

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jfh@21:1/5 to CyrMag on Sun Oct 24 19:39:29 2021
    On Monday, October 25, 2021 at 12:04:36 PM UTC+13, CyrMag wrote:
    On 10/24/2021 4:13 PM, Daniel Feenberg wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end

    <--- CUT --->

    Daniel Feenberg


    I see the bug with gcc version 10.2.0 (GCC) under Cygwin-64 bit on
    Windows 10-64 bit.

    -- CyrMag
    Hmmm. My system is ubuntu with gfortran 9.3 and it shows the bug. But man gfortran does not include precision in the list of possible ffpe-trap=list options. Is that option legal? If so, what is it supposed to do? If not, should it give a compile-time
    error?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JRR@21:1/5 to Daniel Feenberg on Mon Oct 25 14:36:29 2021
    On 10/24/21 11:13 PM, Daniel Feenberg wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end


    It appears that the attempt to write a small integer triggers an arithmetic exception. Which seems very unlikely.
    .Wouldn't that be worthy of mention in the docs.?

    Daniel Feenberg




    I checked this for both gfortran 7.5 on Ubuntu 18 and 9.3 on Ubuntu 20,
    which shows this feature. As was pointed out, -ffpe-trap=precision
    doesn't exist (in the documentation).
    gfortran
    -ffpe-summary=invalid,zero,overflow,underflow,denormal,inexact prog.f90
    shows
    a
    50.0000000
    Note: The following floating-point exceptions are signalling:
    IEEE_INEXACT_FLAG
    So, correctly it seems to state that 50.000 cannot be represented
    exactly. For some reason, the argument -ffpe-trap=precision
    seems to switch on the option inexact. That to me seems to be indeed
    some sort of bug for parsing the options of the ffpe-trap flag.
    gfortran -ffpe-trap=invalid,zero,overflow,underflow,denormal prec.f90
    works without any problems (leaving out the inexact setting)
    Cheers,
    JRR
    --
    Juergen Reuter
    Theoretical Particle Physics
    Deutsches Elektronen-Synchrotron
    Hamburg, Germany
    ---------------------------------
    invalid is desy .and. com is de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cyrmag@21:1/5 to JRR on Mon Oct 25 07:59:12 2021
    On 10/25/2021 7:36 AM, JRR wrote:
    So, correctly it seems to state that 50.000 cannot be represented
    exactly.

    That is not true; the exact representation of 50.0 as a 32-bit real is Z'42480000'. Note that there are 19 zero bits at the least significant
    end, so there is plenty of leeway for representing more complicated
    numbers than 50.0 using a 23 bit significand.

    There is something going wrong, causing a trap to be signaled.

    -- CyrMag

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JRR@21:1/5 to Cyrmag on Tue Oct 26 14:55:42 2021
    On 10/25/21 2:59 PM, Cyrmag wrote:
    On 10/25/2021 7:36 AM, JRR wrote:
    So, correctly it seems to state that 50.000 cannot be represented
    exactly.

    That is not true; the exact representation of 50.0 as a 32-bit real is Z'42480000'. Note that there are 19 zero bits at the least significant
    end, so there is plenty of leeway for representing more complicated
    numbers than 50.0 using a 23 bit significand.

    There is something going wrong, causing a trap to be signaled.


    Sorry, you are right, I misread the docu of gfortran. 'inexact' does not
    mean that 50. cannot be represented exactly by e.g. 32bit-real, but that
    there is a loss of precision during the performed operation. In that
    case the real 50. loses precision when used within the write (*,*)
    procedure. If you use write (*, "(ES10,3)") no trap is signaled.



    --
    Juergen Reuter
    Theoretical Particle Physics
    Deutsches Elektronen-Synchrotron
    Hamburg, Germany
    ---------------------------------
    invalid is desy .and. com is de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From steve kargl@21:1/5 to Cyrmag on Tue Oct 26 17:10:23 2021
    Cyrmag wrote:

    On 10/25/2021 7:36 AM, JRR wrote:
    So, correctly it seems to state that 50.000 cannot be represented
    exactly.

    That is not true; the exact representation of 50.0 as a 32-bit real is Z'42480000'. Note that there are 19 zero bits at the least significant
    end, so there is plenty of leeway for representing more complicated
    numbers than 50.0 using a 23 bit significand.

    There is something going wrong, causing a trap to be signaled.

    -- CyrMag

    If you compile your code, including the one in this thread, with -ffpe-trap=inexact, it will likely die. For any (non-trivial) code,
    which is doing floating point arithmetic, the code will raise FE_INEXACT.

    For the particular problem with "write(*,*) 50.", the runtime library is
    doing floating arithmetic to determine if it should write "50.00000" or "0.5E+02" or a few other checks.

    If you (generic you here) want to find the location, then compile your
    code with "-g" and use gdb.

    % cat > a.f90
    write(*,*) 50.
    end
    % gfcx -o z -g a.f90
    % ./z
    50.0000000
    % gfcx -o z -g -ffpe-trap=inexact a.f90
    % ./z
    Floating exception (core dumped)
    % gdb ./z z.core

    #0 0x0000000200a73dd9 in get_float_string (dtp=0x7fffffffe4b0,
    f=<optimized out>, source=<optimized out>, kind=4, comp_d=1,
    buffer=0x7fffffffde20 "", precision=<optimized out>, size=<optimized out>,
    result=<optimized out>, res_len=<optimized out>)
    at ../../../gccx/libgfortran/io/write_float.def:1110
    1110 FORMAT_FLOAT(4,)
    (gdb) list
    1105 }
    1106
    1107 switch (kind)
    1108 {
    1109 case 4:
    1110 FORMAT_FLOAT(4,)
    1111 break;
    1112
    1113 case 8:
    1114 FORMAT_FLOAT(8,)

    So, you need to go read FORMAT_FLOAT in write_float.def.

    --
    steve

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jfh@21:1/5 to steve kargl on Thu Oct 28 20:33:26 2021
    On Wednesday, October 27, 2021 at 6:10:26 AM UTC+13, steve kargl wrote:
    Cyrmag wrote:

    On 10/25/2021 7:36 AM, JRR wrote:
    So, correctly it seems to state that 50.000 cannot be represented
    exactly.

    That is not true; the exact representation of 50.0 as a 32-bit real is Z'42480000'. Note that there are 19 zero bits at the least significant
    end, so there is plenty of leeway for representing more complicated
    numbers than 50.0 using a 23 bit significand.

    There is something going wrong, causing a trap to be signaled.

    -- CyrMag
    If you compile your code, including the one in this thread, with -ffpe-trap=inexact, it will likely die. For any (non-trivial) code,
    which is doing floating point arithmetic, the code will raise FE_INEXACT.

    For the particular problem with "write(*,*) 50.", the runtime library is doing floating arithmetic to determine if it should write "50.00000" or "0.5E+02" or a few other checks.

    If you (generic you here) want to find the location, then compile your
    code with "-g" and use gdb.

    % cat > a.f90
    write(*,*) 50.
    end
    % gfcx -o z -g a.f90
    % ./z
    50.0000000
    % gfcx -o z -g -ffpe-trap=inexact a.f90
    % ./z
    Floating exception (core dumped)
    % gdb ./z z.core

    #0 0x0000000200a73dd9 in get_float_string (dtp=0x7fffffffe4b0,
    f=<optimized out>, source=<optimized out>, kind=4, comp_d=1, buffer=0x7fffffffde20 "", precision=<optimized out>, size=<optimized out>, result=<optimized out>, res_len=<optimized out>)
    at ../../../gccx/libgfortran/io/write_float.def:1110
    1110 FORMAT_FLOAT(4,)
    (gdb) list
    1105 }
    1106
    1107 switch (kind)
    1108 {
    1109 case 4:
    1110 FORMAT_FLOAT(4,)
    1111 break;
    1112
    1113 case 8:
    1114 FORMAT_FLOAT(8,)

    So, you need to go read FORMAT_FLOAT in write_float.def.

    --
    steve

    Thank you Steve. As you said elsewhere, -ffpe-trap=inexact is the modern equivalent of -ffpe_trap=precision and they are not often worth using. Gfortran does not have a bug here.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to feen...@gmail.com on Fri Oct 29 17:48:22 2021
    On Monday, October 25, 2021 at 8:13:05 AM UTC+11, feen...@gmail.com wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end

    and run it under gdb with a breakpoint at the first executable statement::

    Breakpoint 1, test () at test.for:2
    2 write(*,*) 'a'
    (gdb) n
    a
    3 write(*,*) 50.
    ( gdb) n

    Program received signal SIGFPE, Arithmetic exception.
    0x00007ffff7ba5a21 in ?? () from /lib64/libgfortran.so.3

    It appears that the attempt to write a small integer triggers an arithmetic exception.
    .
    There are no small integers in this program.
    .
    Which seems very unlikely.
    .Wouldn't that be worthy of mention in the docs.?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to feen...@gmail.com on Sat Oct 30 12:05:44 2021
    On Sunday, October 24, 2021 at 2:13:05 PM UTC-7, feen...@gmail.com wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end

    Some (many!) years ago, I was at a Kahan seminar on floating point
    arithmetic, where he mentioned that no processors have an exception
    for precision loss. After, I asked about IBM S/360 and successors,
    which do have one. But only for all precision loss. If even one bit
    is left, no interrupt.

    Even more, the usual way to zero a register is to subtract it from
    itself, so would cause the interrupt.

    But otherwise, I/O library routines should save the flag state,
    and set appropriate flags for their use. Then restore before
    returning.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jfh@21:1/5 to All on Sat Oct 30 18:32:33 2021
    On Sunday, October 31, 2021 at 8:05:45 AM UTC+13, gah4 wrote:
    On Sunday, October 24, 2021 at 2:13:05 PM UTC-7, feen...@gmail.com wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end
    Some (many!) years ago, I was at a Kahan seminar on floating point arithmetic, where he mentioned that no processors have an exception
    for precision loss. After, I asked about IBM S/360 and successors,
    which do have one. But only for all precision loss. If even one bit
    is left, no interrupt.

    Even more, the usual way to zero a register is to subtract it from
    itself, so would cause the interrupt.

    But otherwise, I/O library routines should save the flag state,
    and set appropriate flags for their use. Then restore before
    returning.
    But there may be situations where the user wants to know precision has been lost even in I/O library routines. (I don't know of any but that may just be my ignorance.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to All on Sat Oct 30 22:23:04 2021
    On Saturday, October 30, 2021 at 6:32:35 PM UTC-7, jfh wrote:

    (snip, I wrote)
    But otherwise, I/O library routines should save the flag state,
    and set appropriate flags for their use. Then restore before
    returning.

    But there may be situations where the user wants to know
    precision has been lost even in I/O library routines.
    (I don't know of any but that may just be my ignorance.)

    In general, one knows what their own code does, but not what
    library routines do. I suspect that is especially true in this case.

    There isn't actually a "precision" exception, but "inexact", which
    is raised by most floating point operations. But consider, more
    likely, that you have underflow exception enabled. And it might
    be that the I/O routines, in normal operation, generate underflow
    exceptions. In most cases, you wouldn't want to know that.

    If the I/O routines did something that you would want to know
    about, you should be able to ask specifically for them, and the
    routines should specifically test for them.

    I almost wrote "library routines" without the I/O in front, and
    probably also mean that. In many cases, library routines
    should specifically test for things, and give the appropriate
    exception, instead of just letting them happen.

    For example, CABS should not generate an overflow when
    the result doesn't overflow, (and is correct), even if
    intermediate values overflow.

    But as well as I know it, you likely never want inexact enabled.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to All on Sun Oct 31 16:10:19 2021
    On Sunday, October 31, 2021 at 6:05:45 AM UTC+11, gah4 wrote:
    On Sunday, October 24, 2021 at 2:13:05 PM UTC-7, feen...@gmail.com wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end
    Some (many!) years ago, I was at a Kahan seminar on floating point arithmetic, where he mentioned that no processors have an exception
    for precision loss. After, I asked about IBM S/360 and successors,
    which do have one. But only for all precision loss. If even one bit
    is left, no interrupt.

    Even more, the usual way to zero a register is to subtract it from
    itself, so would cause the interrupt.
    .
    A FP register can be cleared by either loading zero into it,
    or by loading zero from another register that has zero in it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to All on Sun Oct 31 16:25:15 2021
    On Sunday, October 31, 2021 at 6:05:45 AM UTC+11, gah4 wrote:
    On Sunday, October 24, 2021 at 2:13:05 PM UTC-7, feen...@gmail.com wrote:
    Is there somewhere a discussion of gfortran option "ffpe-trap=precision"? I tried recompiling my code with all the debugging traps enabled, but I couldn't make "Arithmetic Exception" go away. Eventually I made this test program:

    program test
    write(*,*) 'a'
    write(*,*) 50.
    stop
    end
    Some (many!) years ago, I was at a Kahan seminar on floating point arithmetic, where he mentioned that no processors have an exception
    for precision loss. After, I asked about IBM S/360 and successors,
    which do have one.
    .
    They have three.
    1. Loss of significance, when the result of a float operation yields a zero
    mantissa.
    2. Exponent underflow.
    3. Exponent overflow.
    .
    But only for all precision loss. If even one bit
    is left, no interrupt.

    Even more, the usual way to zero a register is to subtract it from
    itself, so would cause the interrupt.
    .
    There are several ways that zero can be placed in a FPR.
    1. Load zero from storage;
    2. Load from another register that has zero in it;
    3. Subtract the register from itself, but first setting the
    significance mask bit to zero with SPM and restoring it
    after the operation.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)