Ah, I see. Thanks very much Mat. I think I’ve come across that bug on the forum before but for some reason I though it was the other way around (i.e. that the ‘::’ notation works and the bug occurs without it).
Great so I’m able to compile but I’m getting unexpected behaviour from the syncthreads_and call. Here is the subroutine:
! Check the minimum separation between atoms in the cell
attributes( global ) subroutine check_minsep( N, atoms, minsep, valid )
use cudafor
use bcUtils
! Input parameters
integer, value, intent( in ) :: N
real( kind_wp ), dimension( N, 3 ), device, intent( in ) :: atoms
real( kind_wp ), value, intent( in ) :: minsep
integer, device, intent( out ) :: valid
!! Subroutine variables
integer :: i, j, i_max, j_max
real( kind_wp ) :: dx, dy, dz, sep_sq, max_sep_sq
real( kind_wp ) :: a_num
integer :: a_from, a_to
integer my_valid ! Is the bit of the cell of this thread valid?
max_sep_sq = minsep * minsep
! Calculate atom numbers that will be done by this thread
a_num = N / blockdim%x
a_from = a_num * ( threadidx%x - 1 ) + 1
a_to = min( a_num * threadidx%x, N )
! Assume valid unless test has failed
my_valid = 1
valid = 1
outer: do i = a_from, a_to
do j = 1, N
if( i .ne. j ) then
dx = atoms( i, 1 ) - atoms( j, 1 )
dy = atoms( i, 2 ) - atoms( j, 2 )
dz = atoms( i, 3 ) - atoms( j, 3 )
sep_sq = dx * dx + dy * dy + dz * dz
if( sep_sq .le. max_sep_sq ) then
my_valid = 0
exit outer
end if
endif
end do
end do outer
#ifdef SANITY_CHECK
my_valid = 0
#endif
valid = syncthreads_and( my_valid )
#ifdef ONE_THREAD_TEST
valid = my_valid
#endif
end subroutine check_minsep
As you can see I’m checking that no atoms are closer than a given diameter.
Here’s the behaviour that I get with the various flag setting when I check the value of ‘valid’ on the host once check_minsep has returned:
– No flags set –
valid = 1 always
– SANITY_CHECK set –
valid = 1 always
– ONE_THREAD_TEST set (kernel called with <<< 1, 1 >>> –
valid = my_valid (as expected)
Any ideas?
Again, thanks for your help.
-Martin