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 test_surface_mass_operator_inverse(actx_factory, name): actx = actx_factory() # {{{ cases if name == "2-1-ellipse": from mesh_data import EllipseMeshBuilder builder = EllipseMeshBuilder(radius=3.1, aspect_ratio=2.0) elif name == "spheroid": from mesh_data import SpheroidMeshBuilder builder = SpheroidMeshBuilder() else: raise ValueError("unknown geometry name: %s" % name) # }}} # {{{ convergence from pytools.convergence import EOCRecorder eoc = EOCRecorder() for resolution in builder.resolutions: mesh = builder.get_mesh(resolution, builder.mesh_order) discr = DiscretizationCollection(actx, mesh, order=builder.order) volume_discr = discr.discr_from_dd(dof_desc.DD_VOLUME) logger.info("ndofs: %d", volume_discr.ndofs) logger.info("nelements: %d", volume_discr.mesh.nelements) # {{{ compute inverse mass dd = dof_desc.DD_VOLUME sym_f = sym.cos(4.0 * sym.nodes(mesh.ambient_dim, dd)[0]) sym_op = sym.InverseMassOperator(dd, dd)(sym.MassOperator(dd, dd)( sym.var("f"))) f = bind(discr, sym_f)(actx) f_inv = bind(discr, sym_op)(actx, f=f) inv_error = bind( discr, sym.norm(2, sym.var("x") - sym.var("y")) / sym.norm(2, sym.var("y")))( actx, x=f_inv, y=f) # }}} h_max = bind( discr, sym.h_max_from_volume(discr.ambient_dim, dim=discr.dim, dd=dd))(actx) eoc.add_data_point(h_max, inv_error) # }}} logger.info("inverse mass error\n%s", str(eoc)) # NOTE: both cases give 1.0e-16-ish at the moment, but just to be on the # safe side, choose a slightly larger tolerance assert eoc.max_error() < 1.0e-14
def test_operator_compiler_overwrite(actx_factory): """Tests that the same expression in ``eval_code`` and ``discr_code`` does not confuse the OperatorCompiler in grudge/symbolic/compiler.py. """ actx = actx_factory() ambient_dim = 2 target_order = 4 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * ambient_dim, b=(0.5, ) * ambient_dim, n=(8, ) * ambient_dim, order=1) discr = DiscretizationCollection(actx, mesh, order=target_order) # {{{ test sym_u = sym.nodes(ambient_dim) sym_div_u = sum(d(u) for d, u in zip(sym.nabla(ambient_dim), sym_u)) div_u = bind(discr, sym_div_u)(actx) error = bind(discr, sym.norm(2, sym.var("x")))(actx, x=div_u - discr.dim) logger.info("error: %.5e", error)
def test_norm_obj_array(actx_factory, p): """Test :func:`grudge.symbolic.operators.norm` for object arrays.""" actx = actx_factory() dim = 2 mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, nelements_per_axis=(8, ) * dim, order=1) discr = DiscretizationCollection(actx, mesh, order=4) w = make_obj_array([1.0, 2.0, 3.0])[:dim] # {{ scalar sym_w = sym.var("w") norm = bind(discr, sym.norm(p, sym_w))(actx, w=w[0]) norm_exact = w[0] logger.info("norm: %.5e %.5e", norm, norm_exact) assert abs(norm - norm_exact) < 1.0e-14 # }}} # {{{ vector sym_w = sym.make_sym_array("w", dim) norm = bind(discr, sym.norm(p, sym_w))(actx, w=w) norm_exact = np.sqrt(np.sum(w**2)) if p == 2 else np.max(w) logger.info("norm: %.5e %.5e", norm, norm_exact) assert abs(norm - norm_exact) < 1.0e-14
def simple_mpi_communication_entrypoint(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis 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, n=(3, ) * 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 = DGDiscretizationWithBoundaries(cl_ctx, 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)(queue) sym_all_faces_func = sym.cse( sym.interp("vol", "all_faces")(sym.var("myfunc"))) sym_int_faces_func = sym.cse( sym.interp("vol", "int_faces")(sym.var("myfunc"))) sym_bdry_faces_func = sym.cse( sym.interp(sym.BTAG_ALL, "all_faces")(sym.interp("vol", sym.BTAG_ALL)(sym.var("myfunc")))) bound_face_swap = bind( vol_discr, sym.interp("int_faces", "all_faces")( sym.OppositeInteriorFaceSwap("int_faces")(sym_int_faces_func)) - (sym_all_faces_func - sym_bdry_faces_func)) # print(bound_face_swap) # 1/0 hopefully_zero = bound_face_swap(queue, myfunc=myfunc) import numpy.linalg as la error = la.norm(hopefully_zero.get()) np.set_printoptions(threshold=100000000, suppress=True) print(hopefully_zero) print(error) assert error < 1e-14
def test_1d_mass_mat_trig(ctx_factory): """Check the integral of some trig functions on an interval using the mass matrix """ cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-4 * np.pi, ), b=(9 * np.pi, ), n=(17, ), order=1) discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=8) x = sym.nodes(1) f = bind(discr, sym.cos(x[0])**2)(queue) ones = bind(discr, sym.Ones(sym.DD_VOLUME))(queue) mass_op = bind(discr, sym.MassOperator()(sym.var("f"))) num_integral_1 = np.dot(ones.get(), mass_op(queue, f=f)) num_integral_2 = np.dot(f.get(), mass_op(queue, f=ones)) num_integral_3 = bind(discr, sym.integral(sym.var("f")))(queue, f=f) true_integral = 13 * np.pi / 2 err_1 = abs(num_integral_1 - true_integral) err_2 = abs(num_integral_2 - true_integral) err_3 = abs(num_integral_3 - true_integral) assert err_1 < 1e-10 assert err_2 < 1e-10 assert err_3 < 1e-10
def test_foreign_points(ctx_factory): pytest.importorskip("sumpy") import sumpy.point_calculus as pc cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) dim = 2 cp = pc.CalculusPatch(np.zeros(dim)) from grudge.discretization import PointsDiscretization pdiscr = PointsDiscretization(cl.array.to_device(queue, cp.points)) bind(pdiscr, sym.nodes(dim)**2)(queue)
def test_stepper_equivalence(ctx_factory, order=4): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext( queue, allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue)) ) dims = 2 sym_operator, discr = get_wave_op_with_discr( actx, dims=dims, order=order) #sym_operator_direct, discr = get_wave_op_with_discr_direct( # actx, dims=dims, order=order) if dims == 2: dt = 0.04 elif dims == 3: dt = 0.02 ic = flat_obj_array(discr.zeros(actx), [discr.zeros(actx) for i in range(discr.dim)]) bound_op = bind(discr, sym_operator) stepper = RK4TimeStepper( discr, "w", bound_op, 1 + discr.dim, get_wave_component) fused_stepper = FusedRK4TimeStepper( discr, "w", sym_operator, 1 + discr.dim, get_wave_component) t_start = 0 t_end = 0.5 nsteps = int(np.ceil((t_end + 1e-9) / dt)) print("dt=%g nsteps=%d" % (dt, nsteps)) step = 0 norm = bind(discr, sym.norm(2, sym.var("u_ref") - sym.var("u"))) fused_steps = fused_stepper.run(ic, t_start, dt, t_end) for t_ref, (u_ref, _v_ref) in stepper.run(ic, t_start, dt, t_end): step += 1 logger.debug("step %d/%d", step, nsteps) t, (u, v) = next(fused_steps) assert t == t_ref, step assert norm(u=u, u_ref=u_ref) <= 1e-13, step
def get_example_stepper(actx, dims=2, order=3, use_fusion=True, exec_mapper_factory=ExecutionMapper, return_ic=False): sym_operator, discr = get_wave_op_with_discr( actx, dims=dims, order=3) if not use_fusion: bound_op = bind( discr, sym_operator, exec_mapper_factory=exec_mapper_factory) stepper = RK4TimeStepper( discr, "w", bound_op, 1 + discr.dim, get_wave_component, exec_mapper_factory=exec_mapper_factory) else: stepper = FusedRK4TimeStepper( discr, "w", sym_operator, 1 + discr.dim, get_wave_component, exec_mapper_factory=exec_mapper_factory) if return_ic: ic = flat_obj_array(discr.zeros(actx), [discr.zeros(actx) for i in range(discr.dim)]) return stepper, ic return stepper
def test_map_if(actx_factory): """Test :meth:`grudge.symbolic.execution.ExecutionMapper.map_if` handling of scalar conditions. """ actx = actx_factory() dim = 2 mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, nelements_per_axis=(8, ) * dim, order=4) discr = DiscretizationCollection(actx, mesh, order=4) sym_if = sym.If(sym.Comparison(2.0, "<", 1.0e-14), 1.0, 2.0) bind(discr, sym_if)(actx)
def test_external_call(actx_factory): actx = actx_factory() def double(queue, x): return 2 * x dims = 2 mesh = mgen.generate_regular_rect_mesh(a=(0, ) * dims, b=(1, ) * dims, nelements_per_axis=(4, ) * dims) discr = DiscretizationCollection(actx, mesh, order=1) ones = sym.Ones(dof_desc.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=dof_desc.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_inverse_metric(actx_factory, dim): actx = actx_factory() mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, nelements_per_axis=(6, ) * dim, order=4) def m(x): result = np.empty_like(x) result[0] = (1.5 * x[0] + np.cos(x[0]) + 0.1 * np.sin(10 * x[1])) result[1] = (0.05 * np.cos(10 * x[0]) + 1.3 * x[1] + np.sin(x[1])) if len(x) == 3: result[2] = x[2] return result from meshmode.mesh.processing import map_mesh mesh = map_mesh(mesh, m) discr = DiscretizationCollection(actx, mesh, order=4) sym_op = (sym.forward_metric_derivative_mat(mesh.dim).dot( sym.inverse_metric_derivative_mat(mesh.dim)).reshape(-1)) op = bind(discr, sym_op) mat = op(actx).reshape(mesh.dim, mesh.dim) for i in range(mesh.dim): for j in range(mesh.dim): tgt = 1 if i == j else 0 err = actx.np.linalg.norm(mat[i, j] - tgt, ord=np.inf) logger.info("error[%d, %d]: %.5e", i, j, err) assert err < 1.0e-12, (i, j, err)
def test_map_if(actx_factory): """Test :meth:`grudge.symbolic.execution.ExecutionMapper.map_if` handling of scalar conditions. """ actx = actx_factory() 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) sym_if = sym.If(sym.Comparison(2.0, "<", 1.0e-14), 1.0, 2.0) bind(discr, sym_if)(actx)
def test_assignment_memory_model(ctx_factory): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext( queue, allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue)) ) _, discr = get_wave_op_with_discr(actx, dims=2, order=3) # Assignment instruction bound_op = bind( discr, sym.Variable("input0", dof_desc.DD_VOLUME) + sym.Variable("input1", dof_desc.DD_VOLUME), exec_mapper_factory=ExecutionMapperWithMemOpCounting) input0 = discr.zeros(actx) input1 = discr.zeros(actx) result, profile_data = bound_op( profile_data={}, input0=input0, input1=input1) assert profile_data["bytes_read"] == \ dof_array_nbytes(input0) + dof_array_nbytes(input1) assert profile_data["bytes_written"] == dof_array_nbytes(result)
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 main(write_output=True): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from meshmode.mesh.generation import generate_warped_rect_mesh mesh = generate_warped_rect_mesh(dim=2, order=4, n=6) discr = DGDiscretizationWithBoundaries(cl_ctx, mesh, order=4) sym_op = sym.normal(sym.BTAG_ALL, mesh.dim) #sym_op = sym.nodes(mesh.dim, where=sym.BTAG_ALL) print(sym.pretty(sym_op)) op = bind(discr, sym_op) print() print(op.eval_code) vec = op(queue) vis = shortcuts.make_visualizer(discr, 4) vis.write_vtk_file("geo.vtu", [ ]) bvis = shortcuts.make_boundary_visualizer(discr, 4) bvis.write_vtk_file("bgeo.vtu", [ ("normals", vec) ])
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_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 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 set_up_stepper(self, discr, field_var_name, sym_rhs, num_fields, function_registry=base_function_registry, exec_mapper_factory=ExecutionMapper): dt_method = LSRK4MethodBuilder(component_id=field_var_name) dt_code = dt_method.generate() self.field_var_name = field_var_name self.state_name = f"input_{field_var_name}" # Transcribe the phase. output_vars, results, yielded_states = transcribe_phase( dt_code, field_var_name, num_fields, "primary", sym_rhs) # Build the bound operator for the time integrator. output_t = results[0] output_dt = results[1] output_states = results[2] output_residuals = results[3] assert len(output_states) == num_fields assert len(output_states) == len(output_residuals) flattened_results = flat_obj_array(output_t, output_dt, *output_states) self.bound_op = bind( discr, flattened_results, function_registry=function_registry, exec_mapper_factory=exec_mapper_factory)
def test_incorrect_assignment_aggregation(actx_factory, ambient_dim): """Tests that the greedy assignemnt aggregation code works on a non-trivial expression (on which it didn't work at the time of writing). """ actx = actx_factory() target_order = 4 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, ) * ambient_dim, b=(0.5, ) * ambient_dim, n=(8, ) * ambient_dim, order=1) discr = DiscretizationCollection(actx, mesh, order=target_order) # {{{ test with a relative norm from grudge.dof_desc import DD_VOLUME dd = DD_VOLUME sym_x = sym.make_sym_array("y", ambient_dim, dd=dd) sym_y = sym.make_sym_array("y", ambient_dim, dd=dd) sym_norm_y = sym.norm(2, sym_y, dd=dd) sym_norm_d = sym.norm(2, sym_x - sym_y, dd=dd) sym_op = sym_norm_d / sym_norm_y logger.info("%s", sym.pretty(sym_op)) # FIXME: this shouldn't raise a RuntimeError with pytest.raises(RuntimeError): bind(discr, sym_op)(actx, x=1.0, y=discr.discr_from_dd(dd).nodes()) # }}} # {{{ test with repeated mass inverses sym_minv_y = sym.cse(sym.InverseMassOperator()(sym_y), "minv_y") sym_u = make_obj_array([0.5 * sym.Ones(dd), 0.0, 0.0])[:ambient_dim] sym_div_u = sum(d(u) for d, u in zip(sym.nabla(ambient_dim), sym_u)) sym_op = sym.MassOperator(dd)(sym_u) \ + sym.MassOperator(dd)(sym_minv_y * sym_div_u) logger.info("%s", sym.pretty(sym_op)) # FIXME: this shouldn't raise a RuntimeError either bind(discr, sym_op)(actx, y=discr.discr_from_dd(dd).nodes())
def test_stepper_equivalence(ctx_factory, order=4): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) dims = 2 sym_operator, _ = get_strong_wave_op_with_discr(cl_ctx, dims=dims, order=order) sym_operator_direct, discr = get_strong_wave_op_with_discr_direct( cl_ctx, dims=dims, order=order) if dims == 2: dt = 0.04 elif dims == 3: dt = 0.02 from pytools.obj_array import join_fields ic = join_fields(discr.zeros(queue), [discr.zeros(queue) for i in range(discr.dim)]) bound_op = bind(discr, sym_operator) stepper = RK4TimeStepper(queue, discr, "w", bound_op, 1 + discr.dim, get_strong_wave_component) fused_stepper = FusedRK4TimeStepper(queue, discr, "w", sym_operator_direct, 1 + discr.dim, get_strong_wave_component) t_start = 0 t_end = 0.5 nsteps = int(np.ceil((t_end + 1e-9) / dt)) print("dt=%g nsteps=%d" % (dt, nsteps)) step = 0 norm = bind(discr, sym.norm(2, sym.var("u_ref") - sym.var("u"))) fused_steps = fused_stepper.run(ic, t_start, dt, t_end) for t_ref, (u_ref, v_ref) in stepper.run(ic, t_start, dt, t_end): step += 1 logger.debug("step %d/%d", step, nsteps) t, (u, v) = next(fused_steps) assert t == t_ref, step assert norm(queue, u=u, u_ref=u_ref) <= 1e-13, step
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 normal(self, dd): surface_discr = self.discr_from_dd(dd) actx = surface_discr._setup_actx return freeze( bind(self, sym.normal(dd, surface_discr.ambient_dim, surface_discr.dim), local_only=True) (array_context=actx))
def test_stepper_mem_ops(ctx_factory, use_fusion): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) dims = 2 sym_operator, discr = get_strong_wave_op_with_discr_direct(cl_ctx, dims=dims, order=3) t_start = 0 dt = 0.04 t_end = 0.2 from pytools.obj_array import join_fields ic = join_fields(discr.zeros(queue), [discr.zeros(queue) for i in range(discr.dim)]) if not use_fusion: bound_op = bind(discr, sym_operator, exec_mapper_factory=ExecutionMapperWithMemOpCounting) stepper = RK4TimeStepper( queue, discr, "w", bound_op, 1 + discr.dim, get_strong_wave_component, exec_mapper_factory=ExecutionMapperWithMemOpCounting) else: stepper = FusedRK4TimeStepper( queue, 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 conv_test(descr, use_quad): logger.info("-" * 75) logger.info(descr) logger.info("-" * 75) eoc_rec = EOCRecorder() ns = [20, 25] for n in ns: mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * dims, b=(0.5, ) * dims, nelements_per_axis=(n, ) * dims, order=order) if use_quad: discr_tag_to_group_factory = { "product": QuadratureSimplexGroupFactory(order=4 * order) } else: discr_tag_to_group_factory = {"product": None} discr = DiscretizationCollection( actx, mesh, order=order, discr_tag_to_group_factory=discr_tag_to_group_factory) bound_op = bind(discr, op.sym_operator()) fields = bind(discr, gaussian_mode())(actx, t=0) norm = bind(discr, sym.norm(2, sym.var("u"))) esc = bound_op(u=fields) total_error = norm(u=esc) eoc_rec.add_data_point(1.0 / n, total_error) logger.info( "\n%s", eoc_rec.pretty_print(abscissa_label="h", error_label="L2 Error")) return eoc_rec.order_estimate(), np.array( [x[1] for x in eoc_rec.history])
def normal(dcoll, dd): """Get unit normal to specified surface discretization, *dd*. :arg dd: a :class:`~grudge.dof_desc.DOFDesc` as the surface discretization. :returns: an object array of :class:`~meshmode.dof_array.DOFArray`. """ surface_discr = dcoll.discr_from_dd(dd) actx = surface_discr._setup_actx return freeze( bind(dcoll, sym.normal(dd, surface_discr.ambient_dim, surface_discr.dim), local_only=True)(array_context=actx))
def test_tri_diff_mat(ctx_factory, dim, order=4): """Check differentiation matrix along the coordinate axes on a disk Uses sines as the function to differentiate. """ cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import generate_regular_rect_mesh from pytools.convergence import EOCRecorder axis_eoc_recs = [EOCRecorder() for axis in range(dim)] for n in [10, 20]: mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim, b=(0.5, ) * dim, n=(n, ) * dim, order=4) discr = DGDiscretizationWithBoundaries(actx, mesh, order=4) nabla = sym.nabla(dim) for axis in range(dim): x = sym.nodes(dim) f = bind(discr, sym.sin(3 * x[axis]))(actx) df = bind(discr, 3 * sym.cos(3 * x[axis]))(actx) sym_op = nabla[axis](sym.var("f")) bound_op = bind(discr, sym_op) df_num = bound_op(f=f) linf_error = flat_norm(df_num - df, np.Inf) axis_eoc_recs[axis].add_data_point(1 / n, linf_error) for axis, eoc_rec in enumerate(axis_eoc_recs): logger.info("axis %d\n%s", axis, eoc_rec) assert eoc_rec.order_estimate() >= order
def conv_test(descr, use_quad): print("-" * 75) print(descr) print("-" * 75) eoc_rec = EOCRecorder() ns = [20, 25] for n in ns: mesh = generate_regular_rect_mesh(a=(-0.5, ) * dims, b=(0.5, ) * dims, n=(n, ) * dims, order=order) if use_quad: quad_tag_to_group_factory = { "product": QuadratureSimplexGroupFactory(order=4 * order) } else: quad_tag_to_group_factory = {"product": None} discr = DGDiscretizationWithBoundaries( cl_ctx, mesh, order=order, quad_tag_to_group_factory=quad_tag_to_group_factory) bound_op = bind(discr, op.sym_operator()) fields = bind(discr, gaussian_mode())(queue, t=0) norm = bind(discr, sym.norm(2, sym.var("u"))) esc = bound_op(queue, u=fields) total_error = norm(queue, u=esc) eoc_rec.add_data_point(1.0 / n, total_error) print( eoc_rec.pretty_print(abscissa_label="h", error_label="LInf Error")) return eoc_rec.order_estimate(), np.array( [x[1] for x in eoc_rec.history])
def test_stepper_mem_ops(ctx_factory, use_fusion): cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext( queue, allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue)) ) dims = 2 sym_operator, discr = get_wave_op_with_discr( 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_wave_component, exec_mapper_factory=ExecutionMapperWithMemOpCounting) else: stepper = FusedRK4TimeStepper( discr, "w", sym_operator, 1 + discr.dim, get_wave_component, exec_mapper_factory=ExecutionMapperWithMemOpCounting) step = 0 nsteps = int(np.ceil((t_end + 1e-9) / dt)) for (_, _, profile_data) in stepper.run( # noqa: B007 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"])