From: tkoenig@netcologne.de   
      
   MitchAlsup schrieb:   
   >   
   > Thomas Koenig posted:   
   >   
   >> Fortran has an optional IEEE module. One of its important features   
   >> is that flags (IEEE exceptions) are set to quiet on entry of a procedure   
   >> and restored to signalling if it was signalling on entry, or keep it   
   >> signalling if it was raised on in the procedure. Similarly, rounding   
   >> modes are saved and restored for procedures. This is automatically   
   >> done if the right IEEE modules are used. A user can set rounding   
   >> modes or set and clear exceptions using the right modes.   
   >   
   > How does a user set up his environment such that if TAN()* overflows   
   > to infinity it returns with the OVERFLOW flag set ?!?   
   >   
   > (*) EXP(), POW(,)   
      
   TAN and other numeric intrinsics are defined very loosely in the   
   standard: "The result has a value equal to a processor-dependent   
   approximation to tan(X)". Unfortunately, the language standard does   
   not define this, but allows IEEE_OVERFLOW to signal in that case.   
   In practice, all implementations I have tested do so.   
      
   > Conversely, how does one write a TAN()* subroutine with the above property ?   
      
   IEEE_OVERFLOW on exit is IEEE_OVERFLOW on entry || IEEE_OVERFLOW   
   when it is raised in the procedure.   
      
   >> Conceptually, this is the right thing to do. A library routine should   
   >> not produce different results depending on what a user did for his   
   >> own calculations.   
   >   
   > I would think that a user setting RM=ToZero would WANT a different   
   > result from SIN() than the same call with RM=RNE ?!?   
      
   You have to explicitly use the IEEE modules for this behavior,   
   which the intrinsic procedures do not do.   
      
   An example for dot product:   
      
   module mymod   
    implicit none   
   contains   
    subroutine my_dot(a, b, r_down, r_up, error)   
    use, intrinsic :: iso_fortran_env, only : real64   
    use, intrinsic:: ieee_arithmetic   
    integer :: i   
    real(real64), dimension(:), intent(in) :: a, b   
    real(real64), intent(out) :: r_down,r_up   
    logical, intent(out) :: error   
    if (size(a) /= size(b)) then   
    error = .true.   
    return   
    end if   
    r_down = 0   
    call ieee_set_rounding_mode(IEEE_DOWN)   
    do i=1,size(a,1)   
    r_down = ieee_fma(a(i),b(i),r_down)   
    end do   
    call ieee_set_rounding_mode(IEEE_UP)   
    do i=1,size(a,1)   
    r_up = ieee_fma(a(i),b(i),r_up)   
    end do   
    call ieee_get_flag(IEEE_OVERFLOW, error)   
    call ieee_set_flag(IEEE_OVERFLOW,.false.)   
    end subroutine my_dot   
   end module mymod   
      
   program main   
    use, intrinsic :: iso_fortran_env, only : real64   
    use mymod   
    integer, parameter :: n = 1000   
    real(real64), dimension(n) :: a, b   
    real(real64) :: r_down, r_up, r_mid   
    logical :: error   
    call random_number(a)   
    call random_number(b)   
    a = a - 0.5   
    b = b - 0.5   
    call my_dot (a, b, r_down, r_up, error)   
    if (error) stop "Oh no!"   
    r_mid = dot_product(a,b)   
    print '(1P,E22.15)',r_down,r_mid,r_up   
   end program main   
      
   [...]   
      
   > Oh, and BTW, how does a user CALL a subroutine to set his RM when   
   > the RETURN undoes the very nature of his request ?!?   
      
   That's a no-op :-)   
      
   But the way to do it is just to call the IEEE routines directly.   
      
   >   
   >> An example of the high cost is   
   >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121570 where, depending   
   >> on the library implementation, gfortran may be over-cautious   
   >> for the ieee_next_after function by saving and restoring fp state,   
   >> but I'm not sure that the overhead is actually from the FP state or   
   >> from calling extra functions.   
   >>   
   >> So... What is the best way to do allow this to be more efficient?   
   >   
   > UN DO this change to IEEE 754.   
      
   Does IEEE 754 concern itself with how it is implemented in   
   programming languages? Terje?   
      
   >   
   >> The CPU could speculate on the FP mode (not sure if that is actually   
   >> done). Other suggestions? How do current CPUs do so?   
   >   
   > Multi-threaded cores already have to ship different RMs to FUs on   
   > each FP instruction. The HW is all there--its the ISAs that are screwed   
   > up.   
      
   And that would be an interesting part - how to specify this   
   efficiently, and allow the microarchiteture not to flush when   
   rounding modes are changed.   
   --   
   This USENET posting was made without artificial intelligence,   
   artificial impertinence, artificial arrogance, artificial stupidity,   
   artificial flavorings or artificial colorants.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|