Skip to content

5. The unstructured model ​

So far the temperature lived only on the device. When the host also works on an array (input, output, a part of the code not yet ported), the unstructured model gives an existing host array a copy on the device:

fortran
allocate(t(0:n+1), tn(0:n+1))
t = [(sin(pi*i*dx), i=0, n+1)]
t(0) = 0._R8P ; t(n+1) = 0._R8P
call dev_alloc_unstr(fptr_dev=t)                      ! a device copy of t, uninitialised
call dev_memcpy_to_device_unstr(dst=t)                ! host t -> device t
call dev_alloc_unstr(fptr_dev=tn, init_value=0._R8P)  ! a device copy of tn, set on the device

dev_alloc_unstr creates the device copy without setting it, unless init_value is passed (the value is then set on the device, not on the host); dev_memcpy_to_device_unstr copies the host values into it. The kernels name the host arrays themselves: OpenACC finds their device copies with present, OpenMP needs no clause because they are already mapped. With allocatables there is no pointer to swap, so each iteration makes two steps:

fortran
do s=1, steps, 2 ! two steps per iteration: t -> tn, then tn -> t
   !$acc parallel loop present(t, tn)
   !$omp OMPLOOP
   do i=1, n
      tn(i) = t(i) + r * (t(i-1) - 2._R8P * t(i) + t(i+1))
   enddo
   !$acc parallel loop present(t, tn)
   !$omp OMPLOOP
   do i=1, n
      t(i) = tn(i) + r * (tn(i-1) - 2._R8P * tn(i) + tn(i+1))
   enddo
enddo

At the end the device copy goes back to the host, and the mapping is released (the host arrays stay allocated):

fortran
call dev_memcpy_from_device_unstr(dst=t) ! device t -> host t
call dev_free_unstr(fptr=t)
call dev_free_unstr(fptr=tn)
text
$ heat_5
temperature at the centre after 50 steps: 0.61712
equal to the exact discrete solution: T

Two copies of the same array

After dev_alloc_unstr the host and the device copies are independent: a kernel changes only the device copy, a host assignment only the host copy, until dev_memcpy_to_device_unstr or dev_memcpy_from_device_unstr copies one onto the other. In a host run the two copies are the same memory, so a missing copy goes unnoticed: test on a device. Do not deallocate the host array before dev_free_unstr.

What you learned

dev_alloc_unstr, dev_memcpy_to_device_unstr, dev_memcpy_from_device_unstr, dev_free_unstr; present for mapped arrays; when to prefer each model (Concepts). Reference: Unstructured memory.

Next: 6. Several devices with MPI.