From f7fa3a035a55f51ce0ff748d83271be6b5133486 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl <alexfikl@gmail.com> Date: Sat, 20 Aug 2022 20:01:42 +0300 Subject: [PATCH] port test_fmm to arraycontext --- test/test_fmm.py | 369 ++++++++++++++++++++++++----------------------- 1 file changed, 185 insertions(+), 184 deletions(-) diff --git a/test/test_fmm.py b/test/test_fmm.py index 58ec8b3a..f447999c 100644 --- a/test/test_fmm.py +++ b/test/test_fmm.py @@ -20,42 +20,47 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ - +import pytest import sys import os -from unittest.mock import patch +from functools import partial + import numpy as np import numpy.linalg as la -import pyopencl as cl -from pyopencl.tools import ( # noqa - pytest_generate_tests_for_pyopencl as pytest_generate_tests) -from sumpy.kernel import (LaplaceKernel, HelmholtzKernel, YukawaKernel, + +from arraycontext import pytest_generate_tests_for_array_contexts +from sumpy.array_context import ( # noqa: F401 + PytestPyOpenCLArrayContextFactory, _acf) + +from sumpy.kernel import ( + LaplaceKernel, + HelmholtzKernel, + YukawaKernel, BiharmonicKernel) from sumpy.expansion.multipole import ( VolumeTaylorMultipoleExpansion, - H2DMultipoleExpansion, Y2DMultipoleExpansion, + H2DMultipoleExpansion, + Y2DMultipoleExpansion, LinearPDEConformingVolumeTaylorMultipoleExpansion) from sumpy.expansion.local import ( VolumeTaylorLocalExpansion, - H2DLocalExpansion, Y2DLocalExpansion, + H2DLocalExpansion, + Y2DLocalExpansion, LinearPDEConformingVolumeTaylorLocalExpansion) from sumpy.fmm import ( - SumpyTreeIndependentDataForWrangler, - SumpyExpansionWrangler) + SumpyTreeIndependentDataForWrangler, + SumpyExpansionWrangler) -import pytest import logging logger = logging.getLogger(__name__) +pytest_generate_tests = pytest_generate_tests_for_array_contexts([ + PytestPyOpenCLArrayContextFactory, + ]) -try: - import faulthandler -except ImportError: - pass -else: - faulthandler.enable() +# {{{ test_sumpy_fmm @pytest.mark.parametrize("use_translation_classes, use_fft, fft_backend", [(False, False, None), (True, False, None), (True, True, "loopy"), @@ -84,10 +89,11 @@ else: (YukawaKernel(2), Y2DLocalExpansion, Y2DMultipoleExpansion, False), ]) -def test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, +def test_sumpy_fmm(actx_factory, knl, local_expn_class, mpole_expn_class, order_varies_with_level, use_translation_classes, use_fft, - fft_backend): - logging.basicConfig(level=logging.INFO) + fft_backend, visualize=False): + if visualize: + logging.basicConfig(level=logging.INFO) if local_expn_class == VolumeTaylorLocalExpansion and use_fft: pytest.skip("VolumeTaylorExpansion with FFT takes a lot of resources.") @@ -96,68 +102,66 @@ def test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, pytest.skip("Fourier/Bessel based expansions with FFT is not supported yet.") if use_fft: + from unittest.mock import patch + with patch.dict(os.environ, {"SUMPY_FFT_BACKEND": fft_backend}): - _test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, + _test_sumpy_fmm(actx_factory, knl, local_expn_class, mpole_expn_class, order_varies_with_level, use_translation_classes, use_fft, fft_backend) else: - _test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, + _test_sumpy_fmm(actx_factory, knl, local_expn_class, mpole_expn_class, order_varies_with_level, use_translation_classes, use_fft, fft_backend) -def _test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, +def _test_sumpy_fmm(actx_factory, knl, local_expn_class, mpole_expn_class, order_varies_with_level, use_translation_classes, use_fft, fft_backend): - ctx = ctx_factory() - queue = cl.CommandQueue(ctx) + actx = actx_factory() nsources = 1000 ntargets = 300 dtype = np.float64 - from boxtree.tools import ( - make_normal_particle_array as p_normal) + from boxtree.tools import make_normal_particle_array as p_normal + sources = p_normal(actx.queue, nsources, knl.dim, dtype, seed=15) - sources = p_normal(queue, nsources, knl.dim, dtype, seed=15) if 1: offset = np.zeros(knl.dim) offset[0] = 0.1 - - targets = ( - p_normal(queue, ntargets, knl.dim, dtype, seed=18) - + offset) + targets = offset + p_normal(actx.queue, ntargets, knl.dim, dtype, seed=18) del offset else: from sumpy.visualization import FieldPlotter fp = FieldPlotter(np.array([0.5, 0]), extent=3, npoints=200) + from pytools.obj_array import make_obj_array - targets = make_obj_array( - [fp.points[i] for i in range(knl.dim)]) + targets = make_obj_array([fp.points[i] for i in range(knl.dim)]) from boxtree import TreeBuilder - tb = TreeBuilder(ctx) + tb = TreeBuilder(actx.context) - tree, _ = tb(queue, sources, targets=targets, + tree, _ = tb(actx.queue, sources, targets=targets, max_particles_in_box=30, debug=True) from boxtree.traversal import FMMTraversalBuilder - tbuild = FMMTraversalBuilder(ctx) - trav, _ = tbuild(queue, tree, debug=True) + tbuild = FMMTraversalBuilder(actx.context) + trav, _ = tbuild(actx.queue, tree, debug=True) # {{{ plot tree if 0: - host_tree = tree.get(queue) - host_trav = trav.get(queue) + host_tree = tree.get(actx.queue) + host_trav = trav.get(actx.queue) if 0: - print("src_box", host_tree.find_box_nr_for_source(403)) - print("tgt_box", host_tree.find_box_nr_for_target(28)) - print(list(host_trav.target_or_target_parent_boxes).index(37)) - print(host_trav.get_box_list("sep_bigger", 22)) + logger.info("src_box: %s", host_tree.find_box_nr_for_source(403)) + logger.info("tgt_box: %s", host_tree.find_box_nr_for_target(28)) + logger.info("%s", + list(host_trav.target_or_target_parent_boxes).index(37)) + logger.info("%s", host_trav.get_box_list("sep_bigger", 22)) from boxtree.visualization import TreePlotter plotter = TreePlotter(host_tree) @@ -170,14 +174,11 @@ def _test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, # }}} - from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(ctx, seed=44) - weights = rng.uniform(queue, nsources, dtype=np.float64) - + rng = np.random.default_rng(44) + weights = actx.from_numpy(rng.random(nsources, dtype=np.float64)) logger.info("computing direct (reference) result") from pytools.convergence import PConvergenceVerifier - pconv_verifier = PConvergenceVerifier() extra_kwargs = {} @@ -201,7 +202,6 @@ def _test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, elif knl.dim == 2 and issubclass(local_expn_class, Y2DLocalExpansion): order_values = [10, 12] - from functools import partial for order in order_values: target_kernels = [knl] @@ -216,7 +216,7 @@ def _test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, knl, local_expn_class)() tree_indep = SumpyTreeIndependentDataForWrangler( - ctx, + actx.context, partial(mpole_expn_class, knl), partial(local_expn_class, knl, m2l_translation=m2l_translation), target_kernels) @@ -238,60 +238,60 @@ def _test_sumpy_fmm(ctx_factory, knl, local_expn_class, mpole_expn_class, pot, = drive_fmm(wrangler, (weights,)) from sumpy import P2P - p2p = P2P(ctx, target_kernels, exclude_self=False) - evt, (ref_pot,) = p2p(queue, targets, sources, (weights,), + p2p = P2P(actx.context, target_kernels, exclude_self=False) + evt, (ref_pot,) = p2p(actx.queue, targets, sources, (weights,), **extra_kwargs) - pot = pot.get() - ref_pot = ref_pot.get() + pot = actx.to_numpy(pot) + ref_pot = actx.to_numpy(ref_pot) rel_err = la.norm(pot - ref_pot, np.inf) / la.norm(ref_pot, np.inf) logger.info("order %d -> relative l2 error: %g", order, rel_err) pconv_verifier.add_data_point(order, rel_err) - print(pconv_verifier) + logger.info("\n%s", pconv_verifier) pconv_verifier() +# }}} + + +# {{{ test_coeff_magnitude_rscale @pytest.mark.parametrize("knl", [LaplaceKernel(2), BiharmonicKernel(2)]) -def test_coeff_magnitude_rscale(ctx_factory, knl): +def test_coeff_magnitude_rscale(actx_factory, knl): """Checks that the rscale used keeps the coefficient magnitude difference small """ local_expn_class = LinearPDEConformingVolumeTaylorLocalExpansion mpole_expn_class = LinearPDEConformingVolumeTaylorMultipoleExpansion - ctx = ctx_factory() - queue = cl.CommandQueue(ctx) + actx = actx_factory() nsources = 1000 ntargets = 300 dtype = np.float64 - from boxtree.tools import ( - make_normal_particle_array as p_normal) + from boxtree.tools import make_normal_particle_array as p_normal - sources = p_normal(queue, nsources, knl.dim, dtype, seed=15) + sources = p_normal(actx.queue, nsources, knl.dim, dtype, seed=15) offset = np.zeros(knl.dim) offset[0] = 0.1 - targets = ( - p_normal(queue, ntargets, knl.dim, dtype, seed=18) + offset) + targets = offset + p_normal(actx.queue, ntargets, knl.dim, dtype, seed=18) from boxtree import TreeBuilder - tb = TreeBuilder(ctx) + tb = TreeBuilder(actx.context) - tree, _ = tb(queue, sources, targets=targets, + tree, _ = tb(actx.queue, sources, targets=targets, max_particles_in_box=30, debug=True) from boxtree.traversal import FMMTraversalBuilder - tbuild = FMMTraversalBuilder(ctx) - trav, _ = tbuild(queue, tree, debug=True) + tbuild = FMMTraversalBuilder(actx.context) + trav, _ = tbuild(actx.queue, tree, debug=True) - from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(ctx, seed=44) - weights = rng.uniform(queue, nsources, dtype=np.float64) + rng = np.random.default_rng(31) + weights = actx.from_numpy(rng.random(nsources, dtype=np.float64)) extra_kwargs = {} dtype = np.float64 @@ -304,11 +304,10 @@ def test_coeff_magnitude_rscale(ctx_factory, knl): extra_kwargs["lam"] = 2 dtype = np.complex128 - from functools import partial target_kernels = [knl] tree_indep = SumpyTreeIndependentDataForWrangler( - ctx, + actx.context, partial(mpole_expn_class, knl), partial(local_expn_class, knl), target_kernels) @@ -330,21 +329,28 @@ def test_coeff_magnitude_rscale(ctx_factory, knl): trav.from_sep_bigger_lists, (weights,)) - result = np.abs(wrangler.local_expansions_view(local_result, 5)[1][0]) + result = actx.to_numpy( + actx.np.abs(wrangler.local_expansions_view(local_result, 5)[1][0]) + ) + + result_ratio = np.max(result) / np.min(result) + assert result_ratio < 10**6, result_ratio + +# }}} - assert np.max(result) / np.min(result) < 10**6 +# {{{ test_unified_single_and_double -def test_unified_single_and_double(ctx_factory): +def test_unified_single_and_double(actx_factory, visualize=False): """ Test that running one FMM for single layer + double layer gives the same result as running one FMM for each and adding the results together at the end """ - logging.basicConfig(level=logging.INFO) + if visualize: + logging.basicConfig(level=logging.INFO) - ctx = ctx_factory() - queue = cl.CommandQueue(ctx) + actx = actx_factory() knl = LaplaceKernel(2) local_expn_class = LinearPDEConformingVolumeTaylorLocalExpansion @@ -354,42 +360,36 @@ def test_unified_single_and_double(ctx_factory): ntargets = 300 dtype = np.float64 - from boxtree.tools import ( - make_normal_particle_array as p_normal) + from boxtree.tools import make_normal_particle_array as p_normal - sources = p_normal(queue, nsources, knl.dim, dtype, seed=15) + sources = p_normal(actx.queue, nsources, knl.dim, dtype, seed=15) offset = np.zeros(knl.dim) offset[0] = 0.1 - targets = ( - p_normal(queue, ntargets, knl.dim, dtype, seed=18) - + offset) - + targets = offset + p_normal(actx.queue, ntargets, knl.dim, dtype, seed=18) del offset from boxtree import TreeBuilder - tb = TreeBuilder(ctx) + tb = TreeBuilder(actx.context) - tree, _ = tb(queue, sources, targets=targets, + tree, _ = tb(actx.queue, sources, targets=targets, max_particles_in_box=30, debug=True) from boxtree.traversal import FMMTraversalBuilder - tbuild = FMMTraversalBuilder(ctx) - trav, _ = tbuild(queue, tree, debug=True) + tbuild = FMMTraversalBuilder(actx.context) + trav, _ = tbuild(actx.queue, tree, debug=True) - from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(ctx, seed=44) + rng = np.random.default_rng(44) weights = ( - rng.uniform(queue, nsources, dtype=np.float64), - rng.uniform(queue, nsources, dtype=np.float64), - ) + actx.from_numpy(rng.random(nsources, dtype=np.float64)), + actx.from_numpy(rng.random(nsources, dtype=np.float64)) + ) logger.info("computing direct (reference) result") dtype = np.float64 order = 3 - from functools import partial from sumpy.kernel import DirectionalSourceDerivative, AxisTargetDerivative deriv_knl = DirectionalSourceDerivative(knl, "dir_vec") @@ -407,7 +407,7 @@ def test_unified_single_and_double(ctx_factory): if deriv_knl in source_kernels: source_extra_kwargs["dir_vec"] = dir_vec tree_indep = SumpyTreeIndependentDataForWrangler( - ctx, + actx.context, partial(mpole_expn_class, knl), partial(local_expn_class, knl), target_kernels=target_kernels, source_kernels=source_kernels, @@ -419,7 +419,7 @@ def test_unified_single_and_double(ctx_factory): from boxtree.fmm import drive_fmm pot = drive_fmm(wrangler, weights) - results.append(np.array([pot[0].get(), pot[1].get()])) + results.append(np.array([actx.to_numpy(pot[0]), actx.to_numpy(pot[1])])) ref_pot = results[0] + results[1] pot = results[2] @@ -427,47 +427,50 @@ def test_unified_single_and_double(ctx_factory): assert rel_err < 1e-12 +# }}} + + +# {{{ test_sumpy_fmm_timing_data_collection @pytest.mark.parametrize("use_fft", [True, False]) -def test_sumpy_fmm_timing_data_collection(ctx_factory, use_fft): - logging.basicConfig(level=logging.INFO) +def test_sumpy_fmm_timing_data_collection(ctx_factory, use_fft, visualize=False): + if visualize: + logging.basicConfig(level=logging.INFO) + + import pyopencl as cl + from sumpy.array_context import PyOpenCLArrayContext ctx = ctx_factory() - queue = cl.CommandQueue( - ctx, - properties=cl.command_queue_properties.PROFILING_ENABLE) + queue = cl.CommandQueue(ctx, + properties=cl.command_queue_properties.PROFILING_ENABLE) + actx = PyOpenCLArrayContext(queue, force_device_scalars=True) nsources = 500 dtype = np.float64 - from boxtree.tools import ( - make_normal_particle_array as p_normal) + from boxtree.tools import make_normal_particle_array as p_normal knl = LaplaceKernel(2) local_expn_class = VolumeTaylorLocalExpansion mpole_expn_class = VolumeTaylorMultipoleExpansion order = 1 - sources = p_normal(queue, nsources, knl.dim, dtype, seed=15) + sources = p_normal(actx.queue, nsources, knl.dim, dtype, seed=15) from boxtree import TreeBuilder - tb = TreeBuilder(ctx) + tb = TreeBuilder(actx.context) - tree, _ = tb(queue, sources, - max_particles_in_box=30, debug=True) + tree, _ = tb(actx.queue, sources, max_particles_in_box=30, debug=True) from boxtree.traversal import FMMTraversalBuilder - tbuild = FMMTraversalBuilder(ctx) - trav, _ = tbuild(queue, tree, debug=True) + tbuild = FMMTraversalBuilder(actx.context) + trav, _ = tbuild(actx.queue, tree, debug=True) - from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(ctx) - weights = rng.uniform(queue, nsources, dtype=np.float64) + rng = np.random.default_rng(44) + weights = actx.from_numpy(rng.random(nsources, dtype=np.float64)) target_kernels = [knl] - from functools import partial - if use_fft: from sumpy.expansion.m2l import FFTM2LTranslationClassFactory m2l_translation_factory = FFTM2LTranslationClassFactory() @@ -479,7 +482,7 @@ def test_sumpy_fmm_timing_data_collection(ctx_factory, use_fft): knl, local_expn_class)() tree_indep = SumpyTreeIndependentDataForWrangler( - ctx, + actx.context, partial(mpole_expn_class, knl), partial(local_expn_class, knl, m2l_translation=m2l_translation), target_kernels) @@ -490,52 +493,48 @@ def test_sumpy_fmm_timing_data_collection(ctx_factory, use_fft): timing_data = {} pot, = drive_fmm(wrangler, (weights,), timing_data=timing_data) - print(timing_data) + logger.info("timing_data:\n%s", timing_data) + assert timing_data -def test_sumpy_fmm_exclude_self(ctx_factory): - logging.basicConfig(level=logging.INFO) +def test_sumpy_fmm_exclude_self(actx_factory, visualize=False): + if visualize: + logging.basicConfig(level=logging.INFO) - ctx = ctx_factory() - queue = cl.CommandQueue(ctx) + actx = actx_factory() nsources = 500 dtype = np.float64 - from boxtree.tools import ( - make_normal_particle_array as p_normal) + from boxtree.tools import make_normal_particle_array as p_normal knl = LaplaceKernel(2) local_expn_class = VolumeTaylorLocalExpansion mpole_expn_class = VolumeTaylorMultipoleExpansion order = 10 - sources = p_normal(queue, nsources, knl.dim, dtype, seed=15) + sources = p_normal(actx.queue, nsources, knl.dim, dtype, seed=15) from boxtree import TreeBuilder - tb = TreeBuilder(ctx) + tb = TreeBuilder(actx.context) - tree, _ = tb(queue, sources, - max_particles_in_box=30, debug=True) + tree, _ = tb(actx.queue, sources, max_particles_in_box=30, debug=True) from boxtree.traversal import FMMTraversalBuilder - tbuild = FMMTraversalBuilder(ctx) - trav, _ = tbuild(queue, tree, debug=True) + tbuild = FMMTraversalBuilder(actx.context) + trav, _ = tbuild(actx.queue, tree, debug=True) - from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(ctx) - weights = rng.uniform(queue, nsources, dtype=np.float64) + rng = np.random.default_rng(44) + weights = actx.from_numpy(rng.random(nsources, dtype=np.float64)) target_to_source = np.arange(tree.ntargets, dtype=np.int32) self_extra_kwargs = {"target_to_source": target_to_source} target_kernels = [knl] - from functools import partial - tree_indep = SumpyTreeIndependentDataForWrangler( - ctx, + actx.context, partial(mpole_expn_class, knl), partial(local_expn_class, knl), target_kernels, @@ -550,65 +549,65 @@ def test_sumpy_fmm_exclude_self(ctx_factory): pot, = drive_fmm(wrangler, (weights,)) from sumpy import P2P - p2p = P2P(ctx, target_kernels, exclude_self=True) - evt, (ref_pot,) = p2p(queue, sources, sources, (weights,), + p2p = P2P(actx.context, target_kernels, exclude_self=True) + evt, (ref_pot,) = p2p(actx.queue, sources, sources, (weights,), **self_extra_kwargs) - pot = pot.get() - ref_pot = ref_pot.get() + pot = actx.to_numpy(pot) + ref_pot = actx.to_numpy(ref_pot) rel_err = la.norm(pot - ref_pot) / la.norm(ref_pot) logger.info("order %d -> relative l2 error: %g", order, rel_err) assert np.isclose(rel_err, 0, atol=1e-7) +# }}} -def test_sumpy_axis_source_derivative(ctx_factory): - logging.basicConfig(level=logging.INFO) - ctx = ctx_factory() - queue = cl.CommandQueue(ctx) +# {{{ test_sumpy_axis_source_derivative + +def test_sumpy_axis_source_derivative(actx_factory, visualize=False): + if visualize: + logging.basicConfig(level=logging.INFO) + + actx = actx_factory() nsources = 500 dtype = np.float64 - from boxtree.tools import ( - make_normal_particle_array as p_normal) + from boxtree.tools import make_normal_particle_array as p_normal knl = LaplaceKernel(2) local_expn_class = VolumeTaylorLocalExpansion mpole_expn_class = VolumeTaylorMultipoleExpansion order = 10 - sources = p_normal(queue, nsources, knl.dim, dtype, seed=15) + sources = p_normal(actx.queue, nsources, knl.dim, dtype, seed=15) from boxtree import TreeBuilder - tb = TreeBuilder(ctx) + tb = TreeBuilder(actx.context) - tree, _ = tb(queue, sources, + tree, _ = tb(actx.queue, sources, max_particles_in_box=30, debug=True) from boxtree.traversal import FMMTraversalBuilder - tbuild = FMMTraversalBuilder(ctx) - trav, _ = tbuild(queue, tree, debug=True) + tbuild = FMMTraversalBuilder(actx.context) + trav, _ = tbuild(actx.queue, tree, debug=True) - from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(ctx, seed=12) - weights = rng.uniform(queue, nsources, dtype=np.float64) + rng = np.random.default_rng(12) + weights = actx.from_numpy(rng.random(nsources, dtype=np.float64)) target_to_source = np.arange(tree.ntargets, dtype=np.int32) self_extra_kwargs = {"target_to_source": target_to_source} - from functools import partial - from sumpy.kernel import AxisTargetDerivative, AxisSourceDerivative pots = [] - for tgt_knl, src_knl in [(AxisTargetDerivative(0, knl), knl), + for tgt_knl, src_knl in [ + (AxisTargetDerivative(0, knl), knl), (knl, AxisSourceDerivative(0, knl))]: - tree_indep = SumpyTreeIndependentDataForWrangler( - ctx, + actx.context, partial(mpole_expn_class, knl), partial(local_expn_class, knl), target_kernels=[tgt_knl], @@ -622,53 +621,53 @@ def test_sumpy_axis_source_derivative(ctx_factory): from boxtree.fmm import drive_fmm pot, = drive_fmm(wrangler, (weights,)) - pots.append(pot.get()) + pots.append(actx.to_numpy(pot)) rel_err = la.norm(pots[0] + pots[1]) / la.norm(pots[0]) logger.info("order %d -> relative l2 error: %g", order, rel_err) assert np.isclose(rel_err, 0, atol=1e-5) +# }}} + + +# {{{ test_sumpy_target_point_multiplier @pytest.mark.parametrize("deriv_axes", [(), (0,), (1,)]) -def test_sumpy_target_point_multiplier(ctx_factory, deriv_axes): - logging.basicConfig(level=logging.INFO) +def test_sumpy_target_point_multiplier(actx_factory, deriv_axes, visualize=False): + if visualize: + logging.basicConfig(level=logging.INFO) - ctx = ctx_factory() - queue = cl.CommandQueue(ctx) + actx = actx_factory() nsources = 500 dtype = np.float64 - from boxtree.tools import ( - make_normal_particle_array as p_normal) + from boxtree.tools import make_normal_particle_array as p_normal knl = LaplaceKernel(2) local_expn_class = VolumeTaylorLocalExpansion mpole_expn_class = VolumeTaylorMultipoleExpansion order = 5 - sources = p_normal(queue, nsources, knl.dim, dtype, seed=15) + sources = p_normal(actx.queue, nsources, knl.dim, dtype, seed=15) from boxtree import TreeBuilder - tb = TreeBuilder(ctx) + tb = TreeBuilder(actx.context) - tree, _ = tb(queue, sources, + tree, _ = tb(actx.queue, sources, max_particles_in_box=30, debug=True) from boxtree.traversal import FMMTraversalBuilder - tbuild = FMMTraversalBuilder(ctx) - trav, _ = tbuild(queue, tree, debug=True) + tbuild = FMMTraversalBuilder(actx.context) + trav, _ = tbuild(actx.queue, tree, debug=True) - from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(ctx, seed=12) - weights = rng.uniform(queue, nsources, dtype=np.float64) + rng = np.random.default_rng(12) + weights = actx.from_numpy(rng.random(nsources, dtype=np.float64)) target_to_source = np.arange(tree.ntargets, dtype=np.int32) self_extra_kwargs = {"target_to_source": target_to_source} - from functools import partial - from sumpy.kernel import TargetPointMultiplier, AxisTargetDerivative tgt_knls = [TargetPointMultiplier(0, knl), knl, knl] @@ -677,7 +676,7 @@ def test_sumpy_target_point_multiplier(ctx_factory, deriv_axes): tgt_knls[1] = AxisTargetDerivative(axis, tgt_knls[1]) tree_indep = SumpyTreeIndependentDataForWrangler( - ctx, + actx.context, partial(mpole_expn_class, knl), partial(local_expn_class, knl), target_kernels=tgt_knls, @@ -691,27 +690,29 @@ def test_sumpy_target_point_multiplier(ctx_factory, deriv_axes): from boxtree.fmm import drive_fmm pot0, pot1, pot2 = drive_fmm(wrangler, (weights,)) - pot0, pot1, pot2 = pot0.get(), pot1.get(), pot2.get() + pot0, pot1, pot2 = actx.to_numpy(pot0), actx.to_numpy(pot1), actx.to_numpy(pot2) if deriv_axes == (0,): - ref_pot = pot1 * sources[0].get() + pot2 + ref_pot = pot1 * actx.to_numpy(sources[0]) + pot2 else: - ref_pot = pot1 * sources[0].get() + ref_pot = pot1 * actx.to_numpy(sources[0]) rel_err = la.norm(pot0 - ref_pot) / la.norm(ref_pot) logger.info("order %d -> relative l2 error: %g", order, rel_err) assert np.isclose(rel_err, 0, atol=1e-5) +# }}} + # You can test individual routines by typing -# $ python test_fmm.py 'test_sumpy_fmm(cl.create_some_context, LaplaceKernel(2), -# VolumeTaylorLocalExpansion, VolumeTaylorMultipoleExpansion, False, False)' +# $ python test_fmm.py 'test_sumpy_fmm(_acf, LaplaceKernel(2), +# VolumeTaylorLocalExpansion, VolumeTaylorMultipoleExpansion, False, False, +# visualize=True)' if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1]) else: - from pytest import main - main([__file__]) + pytest.main([__file__]) # vim: fdm=marker -- GitLab