Detect NaN in OpenACC parallel loop

Hi,

Is there a way to detect a NaN occurring in a parallel loop?

I have tried the isnanf function as described on the Programming and Compiling forum http://www.pgroup.com/userforum/viewtopic.php?t=614&postdays=0&postorder=asc&start=5

I receive a compiler message ‘Procedures called in a compute region must have acc routine information’ when I use this approach.


The ieee_is_nan approach described here https://forums.developer.nvidia.com/t/undefined-reference-to-isnan/131626/1 gives the same message.


I vaguely recall that in some compilers, a NaN is not equal to any other value so a(i).eq.a(i) returns a false if a(i) is a NaN. This does not seem to be the case for the PGI compiler though…

Can you suggest a way forward?

Tim.

Just a quick update on this,

I realised that NaN variables seem to return .false. for A(i).lt.1.0 and for A(i).gt.1.0 and for A(i).eq.1.0

I have written a quick function that appears to work. Not sure how solid this is though…

Tim

OK, my NaN detection function picks up some NaNs but not all NaNs.

Can you let me know if there is a PGI NaN detection function that I can use in a parallel region please?

Thanks in advance

Tim.

Hi Tim,

The definition of a NaN is a number that’s not equal to itself so the following should work if compiled with “-Kieee” which strictly adheres to IEEE 754.

% cat test_nan.f90
PROGRAM test_check_nan

   IMPLICIT none
   INTEGER, PARAMETER :: n=16
   INTEGER, PARAMETER :: sp = selected_real_kind(6)
   INTEGER, PARAMETER       ::  iintegers = KIND  (1)
   INTEGER :: i
   REAL(KIND=sp) :: x(n)
   LOGICAL :: lfound

   x(:) = 2.0
   x(3) = -1.0
   x = SQRT(x)
   lfound=.FALSE.

   !$acc data copyin(x) copy(lfound)
   !$acc parallel loop
   DO i=1,n
     IF (x(i).ne.x(i)) THEN
       !$acc atomic write
       lfound=.TRUE.  !there is a NAN
       !$acc end atomic
     END IF
   END DO
   !$acc end data
   IF (lfound) THEN
     print*, "TEST check_NaN : OK"
   ELSE
     print*, "TEST check_NaN : FAIL"
   END IF


END PROGRAM test_check_nan

% pgf90 test_nan.f90 -V16.3 -acc -Minfo=accel
test_check_nan:
     16, Generating copyin(x(:))
         Generating copy(lfound)
     17, Accelerator kernel generated
         Generating Tesla code
         18, !$acc loop gang, vector(16) ! blockidx%x threadidx%x
% a.out
 TEST check_NaN : FAIL
% pgf90 test_nan.f90 -V16.3 -Kieee -acc -Minfo=accel
test_check_nan:
     16, Generating copyin(x(:))
         Generating copy(lfound)
     17, Accelerator kernel generated
         Generating Tesla code
         18, !$acc loop gang, vector(16) ! blockidx%x threadidx%x
% a.out
 TEST check_NaN : OK

Note that we are planning on porting the Fortran 2003 ieee_arithmetic module over the GPU at some point, but I’m not sure exactly when that will happen.

Hope this helps,
Mat