def test_vortex_init(ctx_factory): """ Simple test to check that Vortex2D initializer creates the expected solution field. """ cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) dim = 2 nel_1d = 4 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=[(0.0, ), (-5.0, )], b=[(10.0, ), (5.0, )], nelements_per_axis=(nel_1d, ) * dim) order = 3 logger.info(f"Number of elements: {mesh.nelements}") discr = EagerDGDiscretization(actx, mesh, order=order) nodes = thaw(actx, discr.nodes()) # Init soln with Vortex vortex = Vortex2D() cv = vortex(nodes) gamma = 1.4 p = 0.4 * (cv.energy - 0.5 * np.dot(cv.momentum, cv.momentum) / cv.mass) exp_p = cv.mass**gamma errmax = actx.to_numpy(discr.norm(p - exp_p, np.inf)) logger.info(f"vortex_soln = {cv}") logger.info(f"pressure = {p}") assert errmax < 1e-15
def test_external_call(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) def double(queue, x): return 2 * x from meshmode.mesh.generation import generate_regular_rect_mesh dims = 2 mesh = generate_regular_rect_mesh(a=(0, ) * dims, b=(1, ) * dims, n=(4, ) * dims) discr = DGDiscretizationWithBoundaries(actx, mesh, order=1) ones = sym.Ones(sym.DD_VOLUME) op = (ones * 3 + sym.FunctionSymbol("double")(ones)) from grudge.function_registry import (base_function_registry, register_external_function) freg = register_external_function(base_function_registry, "double", implementation=double, dd=sym.DD_VOLUME) bound_op = bind(discr, op, function_registry=freg) result = bound_op(actx, double=double) assert actx.to_numpy(flatten(result) == 5).all()
def test_unregularized_off_surface_fmm_vs_direct(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) nelements = 300 target_order = 8 fmm_order = 4 # {{{ geometry mesh = make_curve_mesh(WobblyCircle.random(8, seed=30), np.linspace(0, 1, nelements+1), target_order) from pytential.unregularized import UnregularizedLayerPotentialSource from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory density_discr = Discretization( actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order)) direct = UnregularizedLayerPotentialSource( density_discr, fmm_order=False, ) fmm = direct.copy( fmm_level_to_order=lambda kernel, kernel_args, tree, level: fmm_order) sigma = density_discr.zeros(actx) + 1 fplot = FieldPlotter(np.zeros(2), extent=5, npoints=100) from pytential.target import PointsTarget ptarget = PointsTarget(fplot.points) from pytential import GeometryCollection places = GeometryCollection({ "unregularized_direct": direct, "unregularized_fmm": fmm, "targets": ptarget}) # }}} # {{{ check from sumpy.kernel import LaplaceKernel op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=None) direct_fld_in_vol = bind(places, op, auto_where=("unregularized_direct", "targets"))( actx, sigma=sigma) fmm_fld_in_vol = bind(places, op, auto_where=("unregularized_fmm", "targets"))(actx, sigma=sigma) err = actx.np.fabs(fmm_fld_in_vol - direct_fld_in_vol) linf_err = actx.to_numpy(err).max() print("l_inf error:", linf_err) assert linf_err < 5e-3
def test_target_association_failure(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) # {{{ generate circle order = 5 nelements = 40 # Make the curve mesh. curve_f = partial(ellipse, 1) mesh = make_curve_mesh(curve_f, np.linspace(0, 1, nelements + 1), order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory factory = InterpolatoryQuadratureSimplexGroupFactory(order) discr = Discretization(actx, mesh, factory) lpot_source = QBXLayerPotentialSource( discr, qbx_order=order, # not used in target association fine_order=order) places = GeometryCollection(lpot_source) # }}} # {{{ generate targets and check close_circle = 0.999 * np.exp( 2j * np.pi * np.linspace(0, 1, 500, endpoint=False)) from pytential.target import PointsTarget close_circle_target = (PointsTarget( actx.from_numpy(np.array([close_circle.real, close_circle.imag])))) targets = ((close_circle_target, 0), ) from pytential.qbx.target_assoc import (TargetAssociationCodeContainer, associate_targets_to_qbx_centers, QBXTargetAssociationFailedException ) from pytential.qbx.utils import TreeCodeContainer code_container = TargetAssociationCodeContainer(actx, TreeCodeContainer(actx)) with pytest.raises(QBXTargetAssociationFailedException): associate_targets_to_qbx_centers(places, places.auto_source, code_container.get_wrangler(actx), targets, target_association_tolerance=1e-10)
def main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) nel_1d = 16 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), n=(nel_1d, nel_1d)) order = 3 # no deep meaning here, just a fudge factor dt = 0.75 / (nel_1d * order**2) print("%d elements" % mesh.nelements) discr = DGDiscretization(actx, mesh, order=order) fields = flat_obj_array(bump(actx, discr), [discr.zeros(actx) for i in range(discr.dim)]) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr.volume_discr, discr.order + 3) def rhs(t, w): return wave_operator(actx, discr, c=1, w=w) t = 0 t_final = 3 istep = 0 while t < t_final: fields = rk4_step(fields, t, dt, rhs) if istep % 10 == 0: # FIXME: Maybe an integral function to go with the # DOFArray would be nice? assert len(fields[0]) == 1 print(istep, t, la.norm(actx.to_numpy(fields[0][0]))) vis.write_vtk_file("fld-wave-min-%04d.vtu" % istep, [ ("u", fields[0]), ("v", fields[1:]), ]) t += dt istep += 1
def test_block_builder(ctx_factory, ambient_dim, block_builder_type, index_sparsity_factor, op_type, visualize=False): """Test that block builders and full matrix builders actually match.""" ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) # prevent cache explosion from sympy.core.cache import clear_cache clear_cache() if ambient_dim == 2: case = extra.CurveTestCase( name="ellipse", target_order=7, index_sparsity_factor=index_sparsity_factor, op_type=op_type, resolutions=[32], curve_fn=partial(ellipse, 3.0), )
def test_tangential_onb(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import generate_torus mesh = generate_torus(5, 2, order=3) discr = Discretization( actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(3)) tob = sym.tangential_onb(mesh.ambient_dim) nvecs = tob.shape[1] # make sure tangential_onb is mutually orthogonal and normalized orth_check = bind(discr, sym.make_obj_array([ np.dot(tob[:, i], tob[:, j]) - (1 if i == j else 0) for i in range(nvecs) for j in range(nvecs)]) )(actx) from meshmode.dof_array import flatten orth_check = flatten(orth_check) for i, orth_i in enumerate(orth_check): assert (cl.clmath.fabs(orth_i) < 1e-13).get().all() # make sure tangential_onb is orthogonal to normal orth_check = bind(discr, sym.make_obj_array([ np.dot(tob[:, i], sym.normal(mesh.ambient_dim).as_vector()) for i in range(nvecs)]) )(actx) orth_check = flatten(orth_check) for i, orth_i in enumerate(orth_check): assert (cl.clmath.fabs(orth_i) < 1e-13).get().all()
def scalar_assignment_percent_of_total_mem_ops_table(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) result2d = mem_ops_results(actx, 2) result3d = mem_ops_results(actx, 3) with open_output_file("scalar-assignments-mem-op-percentage.tex") as outf: if not PAPER_OUTPUT: print("==== Scalar Assigment % of Total Mem Ops ====", file=outf) print(table( "lr", ("Operator", r"\parbox{1in}{\centering \% Memory Ops. " r"Due to Scalar Assignments}"), ( ("2D: Baseline", "%.1f" % (100 * result2d["nonfused_bytes_total_by_scalar_assignments"] / result2d["nonfused_bytes_total"])), ("2D: Inlined", "%.1f" % (100 * result2d["fused_bytes_total_by_scalar_assignments"] / result2d["fused_bytes_total"])), ("3D: Baseline", "%.1f" % (100 * result3d["nonfused_bytes_total_by_scalar_assignments"] / result3d["nonfused_bytes_total"])), ("3D: Inlined", "%.1f" % (100 * result3d["fused_bytes_total_by_scalar_assignments"] / result3d["fused_bytes_total"])), )), file=outf) logger.info("Wrote '%s'", outf.name)
def problem_stats(order=3): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) with open_output_file("grudge-problem-stats.txt") as outf: _, dg_discr_2d = get_strong_wave_op_with_discr_direct(actx, dims=2, order=order) print("Number of 2D elements:", dg_discr_2d.mesh.nelements, file=outf) vol_discr_2d = dg_discr_2d.discr_from_dd("vol") dofs_2d = {group.nunit_dofs for group in vol_discr_2d.groups} from pytools import one print("Number of DOFs per 2D element:", one(dofs_2d), file=outf) _, dg_discr_3d = get_strong_wave_op_with_discr_direct(actx, dims=3, order=order) print("Number of 3D elements:", dg_discr_3d.mesh.nelements, file=outf) vol_discr_3d = dg_discr_3d.discr_from_dd("vol") dofs_3d = {group.nunit_dofs for group in vol_discr_3d.groups} from pytools import one print("Number of DOFs per 3D element:", one(dofs_3d), file=outf) logger.info("Wrote '%s'", outf.name)
def test_cost_model(ctx_factory, dim, use_target_specific_qbx): """Test that cost model gathering can execute successfully.""" cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) lpot_source = get_lpot_source(actx, dim).copy( _use_target_specific_qbx=use_target_specific_qbx, cost_model=CostModel()) places = GeometryCollection(lpot_source) density_discr = places.get_discretization(places.auto_source.geometry) sigma = get_density(actx, density_discr) sigma_sym = sym.var("sigma") k_sym = LaplaceKernel(lpot_source.ambient_dim) sym_op_S = sym.S(k_sym, sigma_sym, qbx_forced_limit=+1) op_S = bind(places, sym_op_S) cost_S = op_S.get_modeled_cost(actx, sigma=sigma) assert len(cost_S) == 1 sym_op_S_plus_D = ( sym.S(k_sym, sigma_sym, qbx_forced_limit=+1) + sym.D(k_sym, sigma_sym, qbx_forced_limit="avg")) op_S_plus_D = bind(places, sym_op_S_plus_D) cost_S_plus_D = op_S_plus_D.get_modeled_cost(actx, sigma=sigma) assert len(cost_S_plus_D) == 2
def test_reversed_chained_connection(ctx_factory, ndim, mesh_name): ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) def run(nelements, order): discr = create_discretization(actx, ndim, nelements=nelements, order=order, mesh_name=mesh_name) threshold = 1.0 connections = [] conn = create_refined_connection(actx, discr, threshold=threshold) connections.append(conn) if ndim == 2: # NOTE: additional refinement makes the 3D meshes explode in size conn = create_refined_connection(actx, conn.to_discr, threshold=threshold) connections.append(conn) conn = create_refined_connection(actx, conn.to_discr, threshold=threshold) connections.append(conn) from meshmode.discretization.connection import \ ChainedDiscretizationConnection chained = ChainedDiscretizationConnection(connections) from meshmode.discretization.connection import \ L2ProjectionInverseDiscretizationConnection reverse = L2ProjectionInverseDiscretizationConnection(chained) # create test vector from_nodes = thaw(actx, chained.from_discr.nodes()) to_nodes = thaw(actx, chained.to_discr.nodes()) from_x = 0 to_x = 0 for d in range(ndim): from_x += actx.np.cos(from_nodes[d]) ** (d + 1) to_x += actx.np.cos(to_nodes[d]) ** (d + 1) from_interp = reverse(to_x) return (1.0 / nelements, flat_norm(from_interp - from_x, np.inf) / flat_norm(from_x, np.inf)) from pytools.convergence import EOCRecorder eoc = EOCRecorder() order = 4 mesh_sizes = [16, 32, 48, 64, 96, 128] for n in mesh_sizes: h, error = run(n, order) eoc.add_data_point(h, error) print(eoc) assert eoc.order_estimate() > (order + 1 - 0.5)
def test_chained_connection(ctx_factory, ndim, visualize=False): ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) discr = create_discretization(actx, ndim, nelements=10) connections = [] conn = create_refined_connection(actx, discr, threshold=np.inf) connections.append(conn) conn = create_refined_connection(actx, conn.to_discr, threshold=np.inf) connections.append(conn) from meshmode.discretization.connection import \ ChainedDiscretizationConnection chained = ChainedDiscretizationConnection(connections) def f(x): from functools import reduce return 0.1 * reduce(lambda x, y: x * actx.np.sin(5 * y), x) x = thaw(actx, connections[0].from_discr.nodes()) fx = f(x) f1 = chained(fx) f2 = connections[1](connections[0](fx)) assert flat_norm(f1-f2, np.inf) / flat_norm(f2) < 1e-11
def main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import ( # noqa generate_icosphere, generate_icosahedron, generate_torus) #mesh = generate_icosphere(1, order=order) mesh = generate_icosahedron(1, order=order) #mesh = generate_torus(3, 1, order=order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory discr = Discretization(actx, mesh, PolynomialWarpAndBlendGroupFactory(order)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, order) vis.write_vtk_file("geometry.vtu", [ ("f", thaw(actx, discr.nodes()[0])), ]) from meshmode.discretization.visualization import \ write_nodal_adjacency_vtk_file write_nodal_adjacency_vtk_file("adjacency.vtu", mesh)
def test_mean_curvature(ctx_factory, discr_name, resolutions, discr_and_ref_mean_curvature_getter, visualize=False): ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) from pytools.convergence import EOCRecorder eoc = EOCRecorder() for r in resolutions: discr, ref_mean_curvature = \ discr_and_ref_mean_curvature_getter(actx, r) mean_curvature = bind(discr, sym.mean_curvature(discr.ambient_dim))(actx) h = 1.0 / r from meshmode.dof_array import flat_norm h_error = flat_norm(mean_curvature - ref_mean_curvature, np.inf) eoc.add_data_point(h, h_error) print(eoc) order = min([g.order for g in discr.groups]) assert eoc.order_estimate() > order - 1.1
def test_geometry(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) nelements = 30 order = 5 mesh = make_curve_mesh(partial(ellipse, 1), np.linspace(0, 1, nelements+1), order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory discr = Discretization(actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(order)) import pytential.symbolic.primitives as prim area_sym = prim.integral(2, 1, 1) area = bind(discr, area_sym)(actx) err = abs(area-2*np.pi) print(err) assert err < 1e-3
def test_function_symbol_array(ctx_factory, array_type): ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import generate_regular_rect_mesh dim = 2 mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, n=(8, ) * dim, order=4) discr = DGDiscretizationWithBoundaries(actx, mesh, order=4) volume_discr = discr.discr_from_dd(sym.DD_VOLUME) ndofs = sum(grp.ndofs for grp in volume_discr.groups) import pyopencl.clrandom # noqa: F401 if array_type == "scalar": sym_x = sym.var("x") x = unflatten(actx, volume_discr, cl.clrandom.rand(queue, ndofs, dtype=np.float)) elif array_type == "vector": sym_x = sym.make_sym_array("x", dim) x = make_obj_array([ unflatten(actx, volume_discr, cl.clrandom.rand(queue, ndofs, dtype=np.float)) for _ in range(dim) ]) else: raise ValueError("unknown array type") norm = bind(discr, sym.norm(2, sym_x))(x=x) assert isinstance(norm, float)
def test_bessel(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) dims = 2 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(0.1, ) * dims, b=(1.0, ) * dims, n=(8, ) * dims) discr = DGDiscretizationWithBoundaries(actx, mesh, order=3) nodes = sym.nodes(dims) r = sym.cse(sym.sqrt(nodes[0]**2 + nodes[1]**2)) # https://dlmf.nist.gov/10.6.1 n = 3 bessel_zero = (sym.bessel_j(n + 1, r) + sym.bessel_j(n - 1, r) - 2 * n / r * sym.bessel_j(n, r)) z = bind(discr, sym.norm(2, bessel_zero))(actx) assert z < 1e-15
def test_timing_data_gathering(ctx_factory): """Test that timing data gathering can execute succesfully.""" pytest.importorskip("pyfmmlib") cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx, properties=cl.command_queue_properties.PROFILING_ENABLE) actx = PyOpenCLArrayContext(queue) lpot_source = get_lpot_source(actx, 2) places = GeometryCollection(lpot_source) dofdesc = places.auto_source.to_stage1() density_discr = places.get_discretization(dofdesc.geometry) sigma = get_density(actx, density_discr) sigma_sym = sym.var("sigma") k_sym = LaplaceKernel(lpot_source.ambient_dim) sym_op_S = sym.S(k_sym, sigma_sym, qbx_forced_limit=+1) op_S = bind(places, sym_op_S) timing_data = {} op_S.eval(dict(sigma=sigma), timing_data=timing_data, array_context=actx) assert timing_data print(timing_data)
def simple_mpi_communication_entrypoint(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis from meshmode.mesh import BTAG_ALL from mpi4py import MPI comm = MPI.COMM_WORLD num_parts = comm.Get_size() mesh_dist = MPIMeshDistributor(comm) if mesh_dist.is_mananger_rank(): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-1, ) * 2, b=(1, ) * 2, nelements_per_axis=(2, ) * 2) part_per_element = get_partition_by_pymetis(mesh, num_parts) local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element, num_parts) else: local_mesh = mesh_dist.receive_mesh_part() vol_discr = DiscretizationCollection(actx, local_mesh, order=5, mpi_communicator=comm) sym_x = sym.nodes(local_mesh.dim) myfunc_symb = sym.sin(np.dot(sym_x, [2, 3])) myfunc = bind(vol_discr, myfunc_symb)(actx) sym_all_faces_func = sym.cse( sym.project("vol", "all_faces")(sym.var("myfunc"))) sym_int_faces_func = sym.cse( sym.project("vol", "int_faces")(sym.var("myfunc"))) sym_bdry_faces_func = sym.cse( sym.project(BTAG_ALL, "all_faces")(sym.project("vol", BTAG_ALL)(sym.var("myfunc")))) bound_face_swap = bind( vol_discr, sym.project("int_faces", "all_faces")( sym.OppositeInteriorFaceSwap("int_faces")(sym_int_faces_func)) - (sym_all_faces_func - sym_bdry_faces_func)) hopefully_zero = bound_face_swap(myfunc=myfunc) error = actx.np.linalg.norm(hopefully_zero, ord=np.inf) print(__file__) with np.printoptions(threshold=100000000, suppress=True): logger.debug(hopefully_zero) logger.info("error: %.5e", error) assert error < 1e-14
def op_test_data(ctx_factory): """Test fixtures for lazy tests.""" cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) eager_actx = PyOpenCLArrayContext( queue, allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue))) lazy_actx = PytatoPyOpenCLArrayContext( queue, allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue))) def get_discr(order): from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh( a=(-0.5,)*2, b=(0.5,)*2, nelements_per_axis=(4,)*2, boundary_tag_to_face={ "x": ["-x", "+x"], "y": ["-y", "+y"] }) from grudge.eager import EagerDGDiscretization return EagerDGDiscretization(eager_actx, mesh, order=order) return eager_actx, lazy_actx, get_discr
def main(write_output=True): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.mesh import BTAG_ALL from meshmode.mesh.generation import generate_warped_rect_mesh mesh = generate_warped_rect_mesh(dim=2, order=4, nelements_side=6) discr = DiscretizationCollection(actx, mesh, order=4) sym_op = sym.normal(BTAG_ALL, mesh.dim) # sym_op = sym.nodes(mesh.dim, dd=BTAG_ALL) print(sym.pretty(sym_op)) op = bind(discr, sym_op) print() print(op.eval_code) vec = op(actx) vis = shortcuts.make_visualizer(discr) vis.write_vtk_file("geo.vtu", []) bvis = shortcuts.make_boundary_visualizer(discr) bvis.write_vtk_file("bgeo.vtu", [("normals", vec)])
def test_chained_batch_table(ctx_factory, ndim, visualize=False): from meshmode.discretization.connection.chained import \ _build_element_lookup_table ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) discr = create_discretization(actx, ndim) connections = [] conn = create_refined_connection(actx, discr) connections.append(conn) conn = create_refined_connection(actx, conn.to_discr) connections.append(conn) from meshmode.discretization.connection import ChainedDiscretizationConnection chained = ChainedDiscretizationConnection(connections) conn = chained.connections[0] el_table = _build_element_lookup_table(actx, conn) for igrp, grp in enumerate(conn.groups): for ibatch, batch in enumerate(grp.batches): ifrom = batch.from_element_indices.get(queue) jfrom = el_table[igrp][batch.to_element_indices.get(queue)] assert np.all(ifrom == jfrom) assert np.min(el_table[igrp]) >= 0
def test_stepper_timing(ctx_factory, use_fusion): cl_ctx = ctx_factory() queue = cl.CommandQueue( cl_ctx, properties=cl.command_queue_properties.PROFILING_ENABLE) actx = PyOpenCLArrayContext(queue) dims = 3 sym_operator, discr = get_strong_wave_op_with_discr_direct(actx, dims=dims, order=3) t_start = 0 dt = 0.04 t_end = 0.1 ic = flat_obj_array(discr.zeros(actx), [discr.zeros(actx) for i in range(discr.dim)]) if not use_fusion: bound_op = bind(discr, sym_operator, exec_mapper_factory=ExecutionMapperWithTiming) stepper = RK4TimeStepper(discr, "w", bound_op, 1 + discr.dim, get_strong_wave_component, exec_mapper_factory=ExecutionMapperWithTiming) else: stepper = FusedRK4TimeStepper( discr, "w", sym_operator, 1 + discr.dim, get_strong_wave_component, exec_mapper_factory=ExecutionMapperWithTiming) step = 0 import time t = time.time() nsteps = int(np.ceil((t_end + 1e-9) / dt)) for (_, _, profile_data) in stepper.run(ic, t_start, dt, t_end, return_profile_data=True): step += 1 tn = time.time() logger.info("step %d/%d: %f", step, nsteps, tn - t) t = tn logger.info("fusion? %s", use_fusion) for key, value in profile_data.items(): if isinstance(value, TimingFutureList): print(key, value.elapsed())
def test_pulse(ctx_factory, dim): """ Test of Gaussian pulse generator. If it looks, walks, and quacks like a Gaussian, then ... """ cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) nel_1d = 10 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, nelements_per_axis=(nel_1d, ) * dim) order = 1 print(f"Number of elements: {mesh.nelements}") discr = EagerDGDiscretization(actx, mesh, order=order) nodes = thaw(actx, discr.nodes()) print(f"DIM = {dim}, {len(nodes)}") print(f"Nodes={nodes}") tol = 1e-15 from mirgecom.initializers import make_pulse amp = 1.0 w = .1 rms2 = w * w r0 = np.zeros(dim) r2 = np.dot(nodes, nodes) / rms2 pulse = make_pulse(amp=amp, r0=r0, w=w, r=nodes) print(f"Pulse = {pulse}") # does it return the expected exponential? pulse_check = actx.np.exp(-.5 * r2) print(f"exact: {pulse_check}") pulse_resid = pulse - pulse_check print(f"pulse residual: {pulse_resid}") assert (discr.norm(pulse_resid, np.inf) < tol) # proper scaling with amplitude? amp = 2.0 pulse = 0 pulse = make_pulse(amp=amp, r0=r0, w=w, r=nodes) pulse_resid = pulse - (pulse_check + pulse_check) assert (discr.norm(pulse_resid, np.inf) < tol) # proper scaling with r? amp = 1.0 rcheck = np.sqrt(2.0) * nodes pulse = make_pulse(amp=amp, r0=r0, w=w, r=rcheck) assert (discr.norm(pulse - (pulse_check * pulse_check), np.inf) < tol) # proper scaling with w? w = w / np.sqrt(2.0) pulse = make_pulse(amp=amp, r0=r0, w=w, r=nodes) assert (discr.norm(pulse - (pulse_check * pulse_check), np.inf) < tol)
def test_unregularized_with_ones_kernel(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) nelements = 10 order = 8 mesh = make_curve_mesh(partial(ellipse, 1), np.linspace(0, 1, nelements+1), order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory discr = Discretization(actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(order)) from pytential.unregularized import UnregularizedLayerPotentialSource lpot_source = UnregularizedLayerPotentialSource(discr) from pytential.target import PointsTarget targets = PointsTarget(np.zeros((2, 1), dtype=float)) places = GeometryCollection({ sym.DEFAULT_SOURCE: lpot_source, sym.DEFAULT_TARGET: lpot_source, "target_non_self": targets}) from sumpy.kernel import one_kernel_2d sigma_sym = sym.var("sigma") op = sym.IntG(one_kernel_2d, sigma_sym, qbx_forced_limit=None) sigma = discr.zeros(actx) + 1 result_self = bind(places, op, auto_where=places.auto_where)( actx, sigma=sigma) result_nonself = bind(places, op, auto_where=(places.auto_source, "target_non_self"))( actx, sigma=sigma) from meshmode.dof_array import flatten assert np.allclose(actx.to_numpy(flatten(result_self)), 2 * np.pi) assert np.allclose(actx.to_numpy(result_nonself), 2 * np.pi)
def _visualize_refinement(actx: PyOpenCLArrayContext, discr, niter, stage_nr, stage_name, flags, visualize=False): if not visualize: return if stage_nr not in (1, 2): raise ValueError("unexpected stage number") flags = flags.get() logger.info("for stage %s: splitting %d/%d stage-%d elements", stage_name, np.sum(flags), discr.mesh.nelements, stage_nr) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, 3) assert len(flags) == discr.mesh.nelements flags = flags.astype(bool) nodes_flags_template = discr.zeros(actx) nodes_flags = [] for grp in discr.groups: meg = grp.mesh_el_group nodes_flags_grp = actx.to_numpy(nodes_flags_template[grp.index]) nodes_flags_grp[flags[meg.element_nr_base:meg.nelements + meg.element_nr_base]] = 1 nodes_flags.append(actx.from_numpy(nodes_flags_grp)) nodes_flags = DOFArray(actx, tuple(nodes_flags)) vis_data = [ ("refine_flags", nodes_flags), ] if 0: from pytential import sym, bind bdry_normals = bind(discr, sym.normal( discr.ambient_dim))(actx).as_vector(dtype=object) vis_data.append(("bdry_normals", bdry_normals), ) vis.write_vtk_file(f"refinement-{stage_name}-{niter:03d}.vtu", vis_data)
def test_cost_model_order_varying_by_level(ctx_factory): """For FMM order varying by level, this checks to ensure that the costs are different. The varying-level case should have larger cost. """ cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) # {{{ constant level to order def level_to_order_constant(kernel, kernel_args, tree, level): return 1 lpot_source = get_lpot_source(actx, 2).copy( cost_model=QBXCostModel(), fmm_level_to_order=level_to_order_constant) places = GeometryCollection(lpot_source) density_discr = places.get_discretization(places.auto_source.geometry) sigma_sym = sym.var("sigma") k_sym = LaplaceKernel(2) sym_op = sym.S(k_sym, sigma_sym, qbx_forced_limit=+1) sigma = get_density(actx, density_discr) cost_constant, metadata = bind(places, sym_op).cost_per_stage( "constant_one", sigma=sigma) cost_constant = one(cost_constant.values()) metadata = one(metadata.values()) # }}} # {{{ varying level to order def level_to_order_varying(kernel, kernel_args, tree, level): return metadata["nlevels"] - level lpot_source = get_lpot_source(actx, 2).copy( cost_model=QBXCostModel(), fmm_level_to_order=level_to_order_varying) places = GeometryCollection(lpot_source) density_discr = places.get_discretization(places.auto_source.geometry) sigma = get_density(actx, density_discr) cost_varying, _ = bind(lpot_source, sym_op).cost_per_stage( "constant_one", sigma=sigma) cost_varying = one(cost_varying.values()) # }}} assert sum(cost_varying.values()) > sum(cost_constant.values())
def test_stepper_mem_ops(ctx_factory, use_fusion): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) dims = 2 sym_operator, discr = get_strong_wave_op_with_discr_direct(actx, dims=dims, order=3) t_start = 0 dt = 0.04 t_end = 0.2 ic = flat_obj_array(discr.zeros(actx), [discr.zeros(actx) for i in range(discr.dim)]) if not use_fusion: bound_op = bind(discr, sym_operator, exec_mapper_factory=ExecutionMapperWithMemOpCounting) stepper = RK4TimeStepper( discr, "w", bound_op, 1 + discr.dim, get_strong_wave_component, exec_mapper_factory=ExecutionMapperWithMemOpCounting) else: stepper = FusedRK4TimeStepper( discr, "w", sym_operator, 1 + discr.dim, get_strong_wave_component, exec_mapper_factory=ExecutionMapperWithMemOpCounting) step = 0 nsteps = int(np.ceil((t_end + 1e-9) / dt)) for (_, _, profile_data) in stepper.run(ic, t_start, dt, t_end, return_profile_data=True): step += 1 logger.info("step %d/%d", step, nsteps) logger.info("using fusion? %s", use_fusion) logger.info("bytes read: %d", profile_data["bytes_read"]) logger.info("bytes written: %d", profile_data["bytes_written"]) logger.info("bytes total: %d", profile_data["bytes_read"] + profile_data["bytes_written"])
def _acf(): """A tiny undocumented function to pass to tests that take an ``actx_factory`` argument when running them from the command line. """ import pyopencl as cl from meshmode.array_context import PyOpenCLArrayContext context = cl._csc() queue = cl.CommandQueue(context) return PyOpenCLArrayContext(queue)
def main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) dim = 2 nel_1d = 16 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh( a=(-0.5,)*dim, b=(0.5,)*dim, n=(nel_1d,)*dim) order = 3 if dim == 2: # no deep meaning here, just a fudge factor dt = 0.75/(nel_1d*order**2) elif dim == 3: # no deep meaning here, just a fudge factor dt = 0.45/(nel_1d*order**2) else: raise ValueError("don't have a stable time step guesstimate") print("%d elements" % mesh.nelements) discr = EagerDGDiscretization(actx, mesh, order=order) fields = flat_obj_array( bump(discr, actx), [discr.zeros(actx) for i in range(discr.dim)] ) vis = make_visualizer(discr, order+3 if dim == 2 else order) def rhs(t, w): return wave_operator(discr, c=1, w=w) t = 0 t_final = 3 istep = 0 while t < t_final: fields = rk4_step(fields, t, dt, rhs) if istep % 10 == 0: print(f"step: {istep} t: {t} L2: {discr.norm(fields[0])} " f"sol max: {discr.nodal_max('vol', fields[0])}") vis.write_vtk_file("fld-wave-eager-%04d.vtu" % istep, [ ("u", fields[0]), ("v", fields[1:]), ]) t += dt istep += 1