From d1b10c7fc2041b60e8ddb6c19a854cf65e0747e4 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl <alexfikl@gmail.com> Date: Fri, 4 Aug 2023 14:58:53 +0300 Subject: [PATCH] tests: only send cl arrays to kernels --- test/test_fmm.py | 21 +++++--- test/test_kernels.py | 117 +++++++++++++++++++++++++------------------ test/test_qbx.py | 33 ++++++------ 3 files changed, 100 insertions(+), 71 deletions(-) diff --git a/test/test_fmm.py b/test/test_fmm.py index d00b5b45..cf0c6a23 100644 --- a/test/test_fmm.py +++ b/test/test_fmm.py @@ -62,9 +62,13 @@ pytest_generate_tests = pytest_generate_tests_for_array_contexts([ # {{{ test_sumpy_fmm -@pytest.mark.parametrize("use_translation_classes, use_fft, fft_backend", - [(False, False, None), (True, False, None), (True, True, "loopy"), - (True, True, "pyvkfft")]) +@pytest.mark.parametrize( + ("use_translation_classes", "use_fft", "fft_backend"), [ + (False, False, None), + (True, False, None), + (True, True, "loopy"), + (True, True, "pyvkfft"), + ]) @pytest.mark.parametrize( ("knl", "local_expn_class", "mpole_expn_class", "order_varies_with_level"), [ @@ -92,6 +96,9 @@ pytest_generate_tests = pytest_generate_tests_for_array_contexts([ def test_sumpy_fmm(actx_factory, knl, local_expn_class, mpole_expn_class, order_varies_with_level, use_translation_classes, use_fft, fft_backend, visualize=False): + if fft_backend == "pyvkfft": + pytest.importorskip("pyvkfft") + if visualize: logging.basicConfig(level=logging.INFO) @@ -399,7 +406,7 @@ def test_unified_single_and_double(actx_factory, visualize=False): strength_usages = [[0], [1], [0, 1]] alpha = np.linspace(0, 2*np.pi, nsources, np.float64) - dir_vec = np.vstack([np.cos(alpha), np.sin(alpha)]) + dir_vec = actx.from_numpy(np.vstack([np.cos(alpha), np.sin(alpha)])) results = [] for source_kernels, strength_usage in zip(source_kernel_vecs, strength_usages): @@ -528,7 +535,7 @@ def test_sumpy_fmm_exclude_self(actx_factory, visualize=False): 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) + target_to_source = actx.from_numpy(np.arange(tree.ntargets, dtype=np.int32)) self_extra_kwargs = {"target_to_source": target_to_source} target_kernels = [knl] @@ -597,7 +604,7 @@ def test_sumpy_axis_source_derivative(actx_factory, visualize=False): 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) + target_to_source = actx.from_numpy(np.arange(tree.ntargets, dtype=np.int32)) self_extra_kwargs = {"target_to_source": target_to_source} from sumpy.kernel import AxisTargetDerivative, AxisSourceDerivative @@ -665,7 +672,7 @@ def test_sumpy_target_point_multiplier(actx_factory, deriv_axes, visualize=False 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) + target_to_source = actx.from_numpy(np.arange(tree.ntargets, dtype=np.int32)) self_extra_kwargs = {"target_to_source": target_to_source} from sumpy.kernel import TargetPointMultiplier, AxisTargetDerivative diff --git a/test/test_kernels.py b/test/test_kernels.py index bf03f00d..018a0f0f 100644 --- a/test/test_kernels.py +++ b/test/test_kernels.py @@ -26,6 +26,7 @@ import sys import numpy as np import numpy.linalg as la +from pytools.obj_array import make_obj_array from pytools.convergence import PConvergenceVerifier from arraycontext import pytest_generate_tests_for_array_contexts from sumpy.array_context import ( # noqa: F401 @@ -76,20 +77,23 @@ def test_p2p(actx_factory, exclude_self): rng = np.random.default_rng(42) targets = rng.random(size=(dimensions, n)) sources = targets if exclude_self else rng.random(size=(dimensions, n)) - strengths = np.ones(n, dtype=np.float64) extra_kwargs = {} if exclude_self: - extra_kwargs["target_to_source"] = np.arange(n, dtype=np.int32) + extra_kwargs["target_to_source"] = ( + actx.from_numpy(np.arange(n, dtype=np.int32))) evt, (potential, x_derivative) = knl( - actx.queue, targets, sources, [strengths], + actx.queue, + actx.from_numpy(targets), + actx.from_numpy(sources), + [actx.from_numpy(strengths)], out_host=True, **extra_kwargs) + potential = actx.to_numpy(potential) potential_ref = np.empty_like(potential) - targets = targets.T sources = sources.T for itarg in range(n): @@ -146,21 +150,22 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class): rng = np.random.default_rng(14) center = np.array([2, 1, 0][:knl.dim], np.float64) - sources = ( + sources = actx.from_numpy( 0.7 * (-0.5 + rng.random(size=(knl.dim, nsources), dtype=np.float64)) + center[:, np.newaxis]) strengths = [ - np.ones(nsources, dtype=np.float64) * (1/nsources), - np.ones(nsources, dtype=np.float64) * (2/nsources) + actx.from_numpy(np.ones(nsources, dtype=np.float64) * (1/nsources)), + actx.from_numpy(np.ones(nsources, dtype=np.float64) * (2/nsources)) ] - source_boxes = np.array([0], dtype=np.int32) - box_source_starts = np.array([0], dtype=np.int32) - box_source_counts_nonchild = np.array([nsources], dtype=np.int32) + source_boxes = actx.from_numpy(np.array([0], dtype=np.int32)) + box_source_starts = actx.from_numpy(np.array([0], dtype=np.int32)) + box_source_counts_nonchild = ( + actx.from_numpy(np.array([nsources], dtype=np.int32))) alpha = np.linspace(0, 2*np.pi, nsources, np.float64) - dir_vec = np.vstack([np.cos(alpha), np.sin(alpha)]) + dir_vec = actx.from_numpy(np.vstack([np.cos(alpha), np.sin(alpha)])) from sumpy.expansion.local import LocalExpansionBase if issubclass(expn_class, LocalExpansionBase): @@ -170,6 +175,7 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class): centers = (np.array([0.0, 0.0, 0.0][:knl.dim], dtype=np.float64).reshape(knl.dim, 1) + center[:, np.newaxis]) + centers = actx.from_numpy(centers) rscale = 0.5 # pick something non-1 @@ -193,7 +199,7 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class): dir_vec=dir_vec, **extra_kwargs) - actual_result = mpoles + actual_result = actx.to_numpy(mpoles) # apply p2e separately expected_result = np.zeros_like(actual_result) @@ -217,6 +223,8 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class): rscale=rscale, out_host=True, **extra_source_kwargs) + mpoles = actx.to_numpy(mpoles) + expected_result += mpoles norm = la.norm(actual_result - expected_result)/la.norm(expected_result) @@ -302,21 +310,22 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative rng = np.random.default_rng(19) center = np.array([2, 1, 0][:knl.dim], np.float64) - sources = ( + sources = actx.from_numpy( 0.7 * (-0.5 + rng.random((knl.dim, nsources), dtype=np.float64)) + center[:, np.newaxis]) - strengths = np.ones(nsources, dtype=np.float64) / nsources + strengths = actx.from_numpy(np.ones(nsources, dtype=np.float64) / nsources) - source_boxes = np.array([0], dtype=np.int32) - box_source_starts = np.array([0], dtype=np.int32) - box_source_counts_nonchild = np.array([nsources], dtype=np.int32) + source_boxes = actx.from_numpy(np.array([0], dtype=np.int32)) + box_source_starts = actx.from_numpy(np.array([0], dtype=np.int32)) + box_source_counts_nonchild = ( + actx.from_numpy(np.array([nsources], dtype=np.int32))) extra_source_kwargs = extra_kwargs.copy() if isinstance(knl, DirectionalSourceDerivative): alpha = np.linspace(0, 2*np.pi, nsources, np.float64) dir_vec = np.vstack([np.cos(alpha), np.sin(alpha)]) - extra_source_kwargs["dir_vec"] = dir_vec + extra_source_kwargs["dir_vec"] = actx.from_numpy(dir_vec) from sumpy.visualization import FieldPlotter @@ -332,7 +341,8 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative dtype=np.float64).reshape(knl.dim, 1) + center[:, np.newaxis]) - targets = fp.points + centers = actx.from_numpy(centers) + targets = actx.from_numpy(make_obj_array(fp.points)) rscale = 0.5 # pick something non-1 @@ -355,10 +365,11 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative # {{{ apply e2p - ntargets = targets.shape[-1] + ntargets = fp.points.shape[-1] - box_target_starts = np.array([0], dtype=np.int32) - box_target_counts_nonchild = np.array([ntargets], dtype=np.int32) + box_target_starts = actx.from_numpy(np.array([0], dtype=np.int32)) + box_target_counts_nonchild = ( + actx.from_numpy(np.array([ntargets], dtype=np.int32))) evt, (pot, grad_x, ) = e2p( actx.queue, @@ -372,6 +383,8 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative rscale=rscale, out_host=True, **extra_kwargs) + pot = actx.to_numpy(pot) + grad_x = actx.to_numpy(grad_x) # }}} @@ -382,6 +395,8 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative targets, sources, (strengths,), out_host=True, **extra_source_kwargs) + pot_direct = actx.to_numpy(pot_direct) + grad_x_direct = actx.to_numpy(grad_x_direct) err_pot = la.norm((pot - pot_direct)/res**2) err_grad_x = la.norm((grad_x - grad_x_direct)/res**2) @@ -501,10 +516,11 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, # Just to make sure things also work away from the origin rng = np.random.default_rng(18) origin = np.array([2, 1, 0][:knl.dim], np.float64) - sources = ( + sources = actx.from_numpy( 0.7 * (-0.5 + rng.random((knl.dim, nsources), dtype=np.float64)) + origin[:, np.newaxis]) - strengths = np.ones(nsources, dtype=np.float64) * (1/nsources) + strengths = actx.from_numpy( + np.ones(nsources, dtype=np.float64) * (1/nsources)) pconv_verifier_p2m2p = PConvergenceVerifier() pconv_verifier_p2m2m2p = PConvergenceVerifier() @@ -514,8 +530,9 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, from sumpy.visualization import FieldPlotter eval_offset = np.array([5.5, 0.0, 0][:knl.dim]) + fp = FieldPlotter(eval_offset + origin, extent=0.3, npoints=res) - centers = (np.array( + centers = actx.from_numpy((np.array( [ # box 0: particles, first mpole here [0, 0, 0][:knl.dim], @@ -529,7 +546,7 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, # box 3: second local and eval here eval_offset ], - dtype=np.float64) + origin).T.copy() + dtype=np.float64) + origin).T.copy()) del eval_offset @@ -541,13 +558,15 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, nboxes = centers.shape[-1] def eval_at(e2p, source_box_nr, rscale): - e2p_target_boxes = np.array([source_box_nr], dtype=np.int32) + e2p_target_boxes = actx.from_numpy( + np.array([source_box_nr], dtype=np.int32)) # These are indexed by global box numbers. - e2p_box_target_starts = np.array([0, 0, 0, 0], dtype=np.int32) - e2p_box_target_counts_nonchild = np.array([0, 0, 0, 0], - dtype=np.int32) - e2p_box_target_counts_nonchild[source_box_nr] = ntargets + e2p_box_target_starts = actx.from_numpy( + np.array([0, 0, 0, 0], dtype=np.int32)) + e2p_box_target_counts_nonchild = actx.from_numpy( + np.array([0, 0, 0, 0], dtype=np.int32)) + e2p_box_target_counts_nonchild[source_box_nr] = fp.points.shape[-1] evt, (pot,) = e2p( actx.queue, @@ -565,6 +584,7 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, out_host=True, **extra_kwargs ) + pot = actx.to_numpy(pot) return pot @@ -584,8 +604,7 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, l2p = E2PFromSingleBox(actx.context, l_expn, target_kernels) p2p = P2P(actx.context, target_kernels, exclude_self=False) - fp = FieldPlotter(centers[:, -1], extent=0.3, npoints=res) - targets = fp.points + targets = actx.from_numpy(make_obj_array(fp.points)) # {{{ compute (direct) reference solution @@ -593,6 +612,7 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, actx.queue, targets, sources, (strengths,), out_host=True, **extra_kwargs) + pot_direct = actx.to_numpy(pot_direct) # }}} @@ -603,12 +623,13 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, # {{{ apply P2M - p2m_source_boxes = np.array([0], dtype=np.int32) + p2m_source_boxes = actx.from_numpy(np.array([0], dtype=np.int32)) # These are indexed by global box numbers. - p2m_box_source_starts = np.array([0, 0, 0, 0], dtype=np.int32) - p2m_box_source_counts_nonchild = np.array([nsources, 0, 0, 0], - dtype=np.int32) + p2m_box_source_starts = actx.from_numpy( + np.array([0, 0, 0, 0], dtype=np.int32)) + p2m_box_source_counts_nonchild = actx.from_numpy( + np.array([nsources, 0, 0, 0], dtype=np.int32)) evt, (mpoles,) = p2m(actx.queue, source_boxes=p2m_source_boxes, @@ -626,20 +647,18 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, # }}} - ntargets = targets.shape[-1] - pot = eval_at(m2p, 0, m1_rscale) - err = la.norm((pot - pot_direct)/res**2) + err = la.norm((pot - pot_direct) / res**2) err = err / (la.norm(pot_direct) / res**2) pconv_verifier_p2m2p.add_data_point(order, err) # {{{ apply M2M - m2m_target_boxes = np.array([1], dtype=np.int32) - m2m_src_box_starts = np.array([0, 1], dtype=np.int32) - m2m_src_box_lists = np.array([0], dtype=np.int32) + m2m_target_boxes = actx.from_numpy(np.array([1], dtype=np.int32)) + m2m_src_box_starts = actx.from_numpy(np.array([0, 1], dtype=np.int32)) + m2m_src_box_lists = actx.from_numpy(np.array([0], dtype=np.int32)) evt, (mpoles,) = m2m(actx.queue, src_expansions=mpoles, @@ -669,9 +688,9 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, # {{{ apply M2L - m2l_target_boxes = np.array([2], dtype=np.int32) - m2l_src_box_starts = np.array([0, 1], dtype=np.int32) - m2l_src_box_lists = np.array([1], dtype=np.int32) + m2l_target_boxes = actx.from_numpy(np.array([2], dtype=np.int32)) + m2l_src_box_starts = actx.from_numpy(np.array([0, 1], dtype=np.int32)) + m2l_src_box_lists = actx.from_numpy(np.array([1], dtype=np.int32)) evt, (mpoles,) = m2l(actx.queue, src_expansions=mpoles, @@ -700,9 +719,9 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class, # {{{ apply L2L - l2l_target_boxes = np.array([3], dtype=np.int32) - l2l_src_box_starts = np.array([0, 1], dtype=np.int32) - l2l_src_box_lists = np.array([2], dtype=np.int32) + l2l_target_boxes = actx.from_numpy(np.array([3], dtype=np.int32)) + l2l_src_box_starts = actx.from_numpy(np.array([0, 1], dtype=np.int32)) + l2l_src_box_lists = actx.from_numpy(np.array([2], dtype=np.int32)) evt, (mpoles,) = l2l(actx.queue, src_expansions=mpoles, diff --git a/test/test_qbx.py b/test/test_qbx.py index c2b61c3b..3ad439b9 100644 --- a/test/test_qbx.py +++ b/test/test_qbx.py @@ -86,19 +86,19 @@ def test_direct_qbx_vs_eigval(actx_factory, expn_class, visualize=False): h = 2 * np.pi / n - targets = unit_circle - sources = unit_circle + targets = actx.from_numpy(unit_circle) + sources = actx.from_numpy(unit_circle) radius = 7 * h - centers = unit_circle * (1 - radius) + centers = actx.from_numpy((1 - radius) * unit_circle) + expansion_radii = actx.from_numpy(radius * np.ones(n)) + strengths = (actx.from_numpy(sigma * h),) - expansion_radii = np.ones(n) * radius - - strengths = (sigma * h,) evt, (result_qbx,) = lpot( actx.queue, targets, sources, centers, strengths, expansion_radii=expansion_radii) + result_qbx = actx.to_numpy(result_qbx) eocrec.add_data_point(h, np.max(np.abs(result_ref - result_qbx))) @@ -157,23 +157,26 @@ def test_direct_qbx_vs_eigval_with_tgt_deriv( h = 2 * np.pi / n - targets = unit_circle - sources = unit_circle + targets = actx.from_numpy(unit_circle) + sources = actx.from_numpy(unit_circle) radius = 7 * h - centers = unit_circle * (1 - radius) - - expansion_radii = np.ones(n) * radius - - strengths = (sigma * h,) + centers = actx.from_numpy((1 - radius) * unit_circle) + expansion_radii = actx.from_numpy(radius * np.ones(n)) + strengths = (actx.from_numpy(sigma * h),) - evt, (result_qbx_dx,) = lpot_dx(actx.queue, + evt, (result_qbx_dx,) = lpot_dx( + actx.queue, targets, sources, centers, strengths, expansion_radii=expansion_radii) - evt, (result_qbx_dy,) = lpot_dy(actx.queue, + evt, (result_qbx_dy,) = lpot_dy( + actx.queue, targets, sources, centers, strengths, expansion_radii=expansion_radii) + result_qbx_dx = actx.to_numpy(result_qbx_dx) + result_qbx_dy = actx.to_numpy(result_qbx_dy) + normals = unit_circle result_qbx = normals[0] * result_qbx_dx + normals[1] * result_qbx_dy -- GitLab