This page was generated from unit-5.5-cuda/poisson_cuda.ipynb.

5.5 Solving the Poisson Equation using CUDAΒΆ

We use the ngscuda library to move compute intense linear algebra operations onto a GPU. The library is now included in NGSolve Linux - distributions, and can be used whenever an accelerator card by NVIDIA is available, and the cuda-runtime is installed.

from ngsolve import *
mesh = Mesh(unit_square.GenerateMesh(maxh=0.1))
for l in range(4):
fes = H1(mesh, order=2, dirichlet=".*")
print ("ndof =", fes.ndof)

u, v = fes.TnT()
with TaskManager():
    a = BilinearForm(grad(u)*grad(v)*dx+u*v*dx).Assemble()
    f = LinearForm(x*v*dx).Assemble()

gfu = GridFunction(fes)

jac = a.mat.CreateSmoother(fes.FreeDofs())

with TaskManager():
    inv_host = CGSolver(a.mat, jac, maxsteps=2000) = inv_host * f.vec
ndof = 119425

Now we import the NGSolve - cuda library.

It provides

  • an UnifiedVector, which allocates memory on both, host and device. The data is updated on demand either on host, or on device.

  • NGSolve - matrices can create their counterparts on the device. In the following, the conjugate gradients iteration runs on the host, but all operations involving big data are performed on the accelerator.

    from ngsolve.ngscuda import *

    fdev = UnifiedVector(f.vec)
    adev = a.mat.CreateDeviceMatrix()
    jacdev = jac.CreateDeviceMatrix()

    inv = CGSolver(adev, jacdev, maxsteps=2000)
    res = (inv * fdev).Evaluate()

    diff = Norm(gfu.vec - res)
    print ("diff = ", diff)
    print ("no CUDA library or device available")
no CUDA library or device available