Hi,
I am having trouble with this bit of code. The idea is to go through a vector and find the min and max values in the vector to determine the bounds of a simulation domain.
It works well on the CPU. When I try to do it with a CUF kernel, I get an incorrect answer. I am looking for an easy way to do this without getting into really complicated CUDA kernels…
I have set up a little test:
Program Bounds
Use cudafor
Implicit None
! Host Variables
Integer:: d, i, im
Integer, Parameter:: nTotal = 20000 ! Total number of nodes in the domain
Integer:: nCell(3) ! Number of cells in the domain
Real:: Bound(3,2) ! Bounds for the domain
Real:: x(nTotal,3) ! Position vector for nodes
! Device Variables
Integer, Device:: nCell_d(3) ! Number of cells in the domain
Real, Device:: Bound_d(3,2) ! Bounds for the domain
Real, Device:: x_d(nTotal,3) ! Position vector for nodes
! Initialize the position vector for zeroes except for some seeded values
x = 0
x(100,1) = 1.2
x(200,2) = 1.6
x(300,3) = 1.4
x(400,1) = -1.2
x(500,2) = -1.6
x(600,3) = -1.4
nCell = 0
! Perform the algorithm on the CPU
Write(*,*) ""
Write(*,*) "CPU Implementation"
Bound(:,1) = -1.0E+10
Bound(:,2) = 1.0E+10
Do d = 1, 3
Bound(d,1) = maxval(x(:,d))
Bound(d,2) = minval(x(:,d))
nCell(d) = ceiling(abs(Bound(d,1) - Bound(d,2))/(0.072))
End Do
Write(*,*) "xBoundMax = ",Bound(1,1)
Write(*,*) "xBoundMin = ",Bound(1,2)
Write(*,*) "yBoundMax = ",Bound(2,1)
Write(*,*) "yBoundMin = ",Bound(2,2)
Write(*,*) "zBoundMax = ",Bound(3,1)
Write(*,*) "zBoundMin = ",Bound(3,2)
Write(*,*) "nCellx = ",nCell(1)
Write(*,*) "nCelly = ",nCell(2)
Write(*,*) "nCellz = ",nCell(3)
! Perform the algorithm on the GPU
Write(*,*) ""
Write(*,*) "GPU Implementation"
Bound(:,1) = -1.0E+10
Bound(:,2) = 1.0E+10
Bound_d = Bound
nCell_d = nCell
x_d = x
!$CUF Kernel Do <<<*,128>>>
Do i = 1, nTotal
Do d = 1, 3
Bound_d(d,1) = max(Bound_d(d,1),x_d(i,d))
Bound_d(d,2) = min(Bound_d(d,2),x_d(i,d))
nCell_d(d) = ceiling(abs(Bound_d(d,1) - Bound_d(d,2))/(0.072))
End Do
End Do
Bound = Bound_d
nCell = nCell_d
Write(*,*) "xBoundMax = ",Bound(1,1)
Write(*,*) "xBoundMin = ",Bound(1,2)
Write(*,*) "yBoundMax = ",Bound(2,1)
Write(*,*) "yBoundMin = ",Bound(2,2)
Write(*,*) "zBoundMax = ",Bound(3,1)
Write(*,*) "zBoundMin = ",Bound(3,2)
Write(*,*) "nCellx = ",nCell(1)
Write(*,*) "nCelly = ",nCell(2)
Write(*,*) "nCellz = ",nCell(3)
End Program Bounds
The above code is of course useless (normally the position vector would not be mainly zero), but the general idea is there.
Thank you,
Kirk