 # 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?

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