I am trying to use CUDA to run what I thought would be a very simple-minded coding of the diffusion equation. Here’s the code:
module dimensions
integer, parameter :: nx=256, ny=256
end module
program diffuse
use cudafor
use dimensions
real*8 :: v(nx,ny), diffconst
real*8, device :: v_d(nx,ny)
integer :: nloops, outputdl
type(dim3) :: grid, tBlock
integer, device :: n_d, outputdl_d
real*8, device :: diffconst_d
nloops=10000
outputdl=1000
diffconst=.25
outputdl_d=outputdl
diffconst_d=diffconst
tBlock=dim3(64,64,1)
grid=dim3(ceiling(real(nx)/tBlock%x), &
ceiling(real(ny)/tBlock%y), 1)
open(unit=11,file='diff_output.txt')
v=0
n=0
do while (n.le.nloops)
v_d=v
n_d=n
call diff_time_stepper<<<grid>>>(v_d,diffconst_d,n_d,outputdl_d)
v=v_d
n=n_d
write(11,*) v
print *,n
enddo
end program
attributes(global) subroutine diff_time_stepper(v,diffconst,n,nsteps)
real*8 :: v(:,:)
real*8 :: diffconst
integer :: n
integer :: nsteps
real*8 :: vintermed
integer :: i,j,m
integer :: nx, ny
nx=256
ny=256
i=(blockIdx%x-1)*blockDim%x+threadIdx%x
j=(blockIdx%y-1)*blockDim%y+threadIdx%y
do m=1,nsteps
if (i<nx .and. j<ny>1 .and. j>1) then
vintermed=v(i,j)+diffconst*(v(i-1,j)-2.*v(i,j)+v(i+1,j)+v(i,j-1)-2.*v(i,j)+v(i,j+1))
v(i,j)=vintermed
endif
! add a source for the heck of it
if (i==64 .and. j==64) v(i,j)=v(i,j)+1
enddo
n=n+nsteps
end subroutine
The one obvious problem I have is is that the variable “n” (returned to main as “n_d”) is not updating. At all. There are probably numerous other problems i don’t know about too. Trying to run with cuda=emu gives a seg fault. Any ideas? THanks. I’m really new to this.