Mixed CPU and GPU computations
If GPU memory is a limiting factor for your computation, it may be preferable to carry out particle operations on the CPU rather than on the GPU. This involves basically four steps:
- At the top of the script. The JustPIC backend must be set to CPU, while other packages may still run their own GPU work:
const backend = JustPIC.CPU - At memory allocation stage. A copy of relevant CPU arrays must be allocated on the GPU memory. For example, phase ratios on mesh vertices:
using JustPIC
using CUDA
phv_GPU = cell_array(CUDA.CUDABackend, 0.0, (N_phases,), (nx + 1, ny + 1, nz + 1))where N_phases is the number of different material phases and cell_array(CUDA.CUDABackend, ...) allocates a GPU-backed CellArray.
Similarly, GPU arrays must be copied to CPU memory:
V_CPU = (
x = zeros(nx+1, ny+2, nz+2),
y = zeros(nx+2, ny+1, nz+2),
z = zeros(nx+2, ny+2, nz+1),
)where zeros() allocates on the CPU memory.
- At each time step. The particles are stored in CPU memory. It is hence necessary to transfer some information from the CPU to the GPU memory. For example, here's a transfer of phase proportions:
phv_GPU.data .= CuArray(phase_ratios.vertex).data- At each time step. Once velocity computations are finalized on the GPU, they need to be transferred to the CPU:
V_CPU.x .= TA(backend)(V.x)
V_CPU.y .= TA(backend)(V.y)
V_CPU.z .= TA(backend)(V.z)Advection can then be applied by calling the advection() function:
advection!(particles, RungeKutta2(), values(V), Δt)