Skip to content

Commit 19247c3

Browse files
committed
test with offloading()
1 parent e22158b commit 19247c3

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

tests/test_offloading.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import pytest
2+
from firedrake import (set_offloading_backend,
3+
offloading, solve, FunctionSpace, TestFunction,
4+
TrialFunction, Function, UnitSquareMesh,
5+
SpatialCoordinate, inner, grad, dx, norm, pi, cos,
6+
assemble)
7+
import firedrake_configuration
8+
from pyop2.backends.cpu import cpu_backend
9+
10+
11+
AVAILABLE_BACKENDS = [cpu_backend]
12+
13+
if firedrake_configuration.get_config()["options"].get("cuda"):
14+
from pyop2.backends.cuda import cuda_backend
15+
AVAILABLE_BACKENDS.append(cuda_backend)
16+
17+
18+
def allclose(a, b, rtol=1e-05, atol=1e-08):
19+
"""
20+
Prefer this routine over np.allclose(...) to allow pycuda/pyopencl arrays
21+
"""
22+
return bool(abs(a - b) < (atol + rtol * abs(b)))
23+
24+
25+
@pytest.mark.parametrize("offloading_backend", AVAILABLE_BACKENDS)
26+
def test_nonlinear_variational_solver(offloading_backend):
27+
set_offloading_backend(offloading_backend)
28+
mesh = UnitSquareMesh(32, 32)
29+
V = FunctionSpace(mesh, "CG", 1)
30+
u = TrialFunction(V)
31+
v = TestFunction(V)
32+
x, y = SpatialCoordinate(mesh)
33+
34+
a = (inner(grad(u), grad(v)) + inner(u, v)) * dx
35+
f = Function(V)
36+
f.interpolate((1+8*pi*pi)*cos(x*pi*2)*cos(y*pi*2))
37+
L = inner(f, v) * dx
38+
fem_soln = Function(V)
39+
sp = {"mat_type": "matfree",
40+
"ksp_monitor_true_residual": None,
41+
"ksp_converged_reason": None}
42+
with offloading():
43+
solve(a == L, fem_soln, solver_parameters=sp)
44+
45+
f.interpolate(cos(x*pi*2)*cos(y*pi*2))
46+
47+
assert norm(fem_soln-f) < 1e-2
48+
49+
with offloading():
50+
assert norm(fem_soln-f) < 1e-2
51+
52+
53+
@pytest.mark.parametrize("offloading_backend", AVAILABLE_BACKENDS)
54+
def test_linear_variational_solver(offloading_backend):
55+
set_offloading_backend(offloading_backend)
56+
mesh = UnitSquareMesh(32, 32)
57+
V = FunctionSpace(mesh, "CG", 1)
58+
u = TrialFunction(V)
59+
v = TestFunction(V)
60+
f = Function(V)
61+
x, y = SpatialCoordinate(mesh)
62+
f.interpolate((1+8*pi*pi)*cos(x*pi*2)*cos(y*pi*2))
63+
64+
L = assemble(inner(f, v) * dx)
65+
fem_soln = Function(V)
66+
67+
with offloading():
68+
69+
a = assemble((inner(grad(u), grad(v)) + inner(u, v)) * dx,
70+
mat_type="matfree")
71+
solve(a, fem_soln, L,
72+
solver_parameters={"pc_type": "none",
73+
"ksp_type": "cg",
74+
"ksp_monitor": None})
75+
76+
f.interpolate(cos(x*pi*2)*cos(y*pi*2))
77+
78+
assert norm(fem_soln-f) < 1e-2
79+
80+
with offloading():
81+
assert norm(fem_soln-f) < 1e-2
82+
83+
84+
@pytest.mark.parametrize("offloading_backend", AVAILABLE_BACKENDS)
85+
def test_data_manipulation_on_host(offloading_backend):
86+
set_offloading_backend(offloading_backend)
87+
88+
mesh = UnitSquareMesh(32, 32)
89+
V = FunctionSpace(mesh, "CG", 1)
90+
u = TrialFunction(V)
91+
v = TestFunction(V)
92+
f = Function(V)
93+
x, y = SpatialCoordinate(mesh)
94+
f.interpolate((1+8*pi*pi)*cos(x*pi*2)*cos(y*pi*2))
95+
96+
L = assemble(inner(f, v) * dx)
97+
fem_soln = Function(V)
98+
99+
with offloading():
100+
101+
a = assemble((inner(grad(u), grad(v)) + inner(u, v)) * dx,
102+
mat_type="matfree")
103+
solve(a, fem_soln, L,
104+
solver_parameters={"pc_type": "none",
105+
"ksp_type": "cg",
106+
"ksp_monitor": None})
107+
108+
old_norm = norm(fem_soln)
109+
kappa = 2.0
110+
fem_soln.dat.data[:] *= kappa # update data on host
111+
112+
with offloading():
113+
new_norm = norm(fem_soln)
114+
115+
allclose(kappa*old_norm, new_norm)

0 commit comments

Comments
 (0)