Newer
Older
import pyopencl as cl
from sympy.core.cache import clear_cache
import numpy as np
from meshmode.discretization import Discretization
from pytential import bind, sym, norm
from sumpy.kernel import LaplaceKernel
from pytential.qbx import QBXLayerPotentialSource
from pytential.qbx.distributed import DistributedQBXLayerPotentialSource
from mpi4py import MPI
import logging
import os
# Configure logging
logging.basicConfig(level=os.environ.get("LOGLEVEL", "WARNING"))
logging.getLogger("pytential.qbx.distributed").setLevel(logging.INFO)
warnings.filterwarnings("ignore", category=UserWarning)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# Disable sympy cache
clear_cache()
# Setup PyOpenCL
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
class GreenExpr(object):
zero_op_name = "green"
def get_zero_op(self, kernel, **knl_kwargs):
u_sym = sym.var("u")
dn_u_sym = sym.var("dn_u")
return (
sym.S(kernel, dn_u_sym, qbx_forced_limit=-1, **knl_kwargs)
- sym.D(kernel, u_sym, qbx_forced_limit="avg", **knl_kwargs)
- 0.5*u_sym)
order_drop = 0
def get_sphere_mesh(refinement_increment, target_order):
from meshmode.mesh.generation import generate_icosphere
mesh = generate_icosphere(1, target_order)
from meshmode.mesh.refinement import Refiner
refiner = Refiner(mesh)
for i in range(refinement_increment):
flags = np.ones(mesh.nelements, dtype=bool)
refiner.refine(flags)
mesh = refiner.get_current_mesh()
return mesh
# Parameters
k = 0
qbx_order = 3
fmm_order = 10
_expansion_stick_out_factor = 0.5
expr = GreenExpr()
def generate_expr(refinement_increment, target_order, lp_source_contructor):
mesh = get_sphere_mesh(refinement_increment, target_order)
d = mesh.ambient_dim
lap_k_sym = LaplaceKernel(d)
k_sym = lap_k_sym
knl_kwargs = {}
from meshmode.discretization import Discretization
from meshmode.discretization.poly_element import \
InterpolatoryQuadratureSimplexGroupFactory
pre_density_discr = Discretization(
ctx, mesh,
InterpolatoryQuadratureSimplexGroupFactory(target_order))
refiner_extra_kwargs = {}
qbx, _ = lp_source_contructor(
pre_density_discr, 4 * target_order,
qbx_order,
fmm_order=fmm_order,
_expansions_in_tree_have_extent=True,
_expansion_stick_out_factor=_expansion_stick_out_factor
).with_refinement(**refiner_extra_kwargs)
density_discr = qbx.density_discr
# {{{ compute values of a solution to the PDE
nodes_host = density_discr.nodes().get(queue)
normal = bind(density_discr, sym.normal(d))(queue).as_vector(np.object)
normal_host = [normal[j].get() for j in range(d)]
center = np.array([3, 1, 2])[:d]
diff = nodes_host - center[:, np.newaxis]
dist_squared = np.sum(diff ** 2, axis=0)
dist = np.sqrt(dist_squared)
if d == 2:
u = np.log(dist)
grad_u = diff / dist_squared
elif d == 3:
u = 1 / dist
grad_u = -diff / dist ** 3
else:
assert False
dn_u = 0
for i in range(d):
dn_u = dn_u + normal_host[i] * grad_u[i]
# }}}
u_dev = cl.array.to_device(queue, u)
dn_u_dev = cl.array.to_device(queue, dn_u)
grad_u_dev = cl.array.to_device(queue, grad_u)
bound_op = bind(qbx, expr.get_zero_op(k_sym, **knl_kwargs))
return bound_op, {'u': u_dev, 'dn_u': dn_u_dev, 'grad_u': grad_u_dev, 'k': k}
def train():
from pytential.qbx.perf_model import QBXPerformanceModel
model = QBXPerformanceModel(ctx, True)
model.loadjson('model.json')
training_cases = [
(0, 8),
lp_source_contructor = functools.partial(QBXLayerPotentialSource, fmm_backend='fmmlib')
for refinement_increment, target_order in training_cases:
expr, context = generate_expr(refinement_increment, target_order, lp_source_contructor)
model.time_qbx_performance(queue, expr, context)
model.savejson('model.json')
def eval():
# MPI information
comm = MPI.COMM_WORLD
current_rank = comm.Get_rank()
if current_rank == 0:
lp_source_contructor = functools.partial(DistributedQBXLayerPotentialSource, comm)
bound_op.eval(queue, context=context)
else:
for _ in range(2):
lp_source = DistributedQBXLayerPotentialSource(comm, None, None)
distribute_geo_data = lp_source.distibuted_geo_data(None, queue, None)
from pytential.qbx.distributed import drive_dfmm
weights = None
drive_dfmm(queue, weights, distribute_geo_data, comm=comm)
if __name__ == '__main__':
import sys
if len(sys.argv) != 2:
raise RuntimeError("Please specify train or eval")
if sys.argv[1] == 'train':
train()
elif sys.argv[1] == 'eval':
eval()
else: