Should this OpenMP code halt due to a FPE?

    use ieee_exceptions 
    
    implicit none
    
    integer, parameter :: n = 100
    real :: nom(n)
    integer :: denom(n)
    
    logical :: saved_fpe_mode(size(ieee_all))
    integer :: i
    
    nom = 1
    denom = 0
    
    !$omp parallel
    print *,"hello from a thread"
    !$omp end parallel
    
    call ieee_get_halting_mode(ieee_all, saved_fpe_mode)
    call ieee_set_halting_mode(ieee_all, .false.)

    !$omp parallel do
    do i = 1, n
      nom(i) = nom(i) / denom(n)
    end do
    !$omp end parallel do

    nom = max(0., nom)
    call ieee_set_halting_mode(ieee_all, saved_fpe_mode)
end

When compiled as gfortran-13 -ffpe-trap=zero,invalid,overflow -fopenmp fpe.f90 and run with multiple threads, the code halts with SIGFPE. When the first parallel region is commented out, it does not halt and the result is Infinity. It also does not halt when the !$omp end parallel is moved after the ieee_ calls. Is there any intended standardized behaviour?

1 Like

Doing the ieee_ calls in parallel does not suffice when using ifx -fpe0.

I understand that these compile-time options are not standardized and I am actually more interested in the case when the halting mode is set in a standard way somewhere higher up and the code shown is in a subroutine, not a program.

Lets consider this one, without any special flags except for enabling OpenMP:

    use ieee_exceptions 
    
    implicit none
    
    integer, parameter :: n = 100
    real :: nom(n)
    integer :: denom(n)
    
    logical :: saved_fpe_mode(size(ieee_all))
    integer :: i
    
    nom = 1
    denom = 0
    
    call ieee_set_halting_mode(ieee_overflow, .true.)
    call ieee_set_halting_mode(ieee_invalid, .true.)
    call ieee_set_halting_mode(ieee_divide_by_zero, .true.)
    
    !$omp parallel
    print *,"hello from a thread"
    !$omp end parallel
    
    call ieee_get_halting_mode(ieee_all, saved_fpe_mode)
    call ieee_set_halting_mode(ieee_all, .false.)

    !$omp parallel do
    do i = 1, n
      nom(i) = nom(i) / denom(i)
    end do
    !$omp end parallel do

    
    nom = max(0., nom)
    
    !$omp parallel
    call ieee_set_halting_mode(ieee_all, saved_fpe_mode)
    !$omp end parallel
    
    print *, nom
end