Skip to content

Commit d1b10c7

Browse files
alexfiklinducer
authored andcommitted
tests: only send cl arrays to kernels
1 parent e7b455a commit d1b10c7

3 files changed

Lines changed: 100 additions & 71 deletions

File tree

test/test_fmm.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,13 @@
6262

6363
# {{{ test_sumpy_fmm
6464

65-
@pytest.mark.parametrize("use_translation_classes, use_fft, fft_backend",
66-
[(False, False, None), (True, False, None), (True, True, "loopy"),
67-
(True, True, "pyvkfft")])
65+
@pytest.mark.parametrize(
66+
("use_translation_classes", "use_fft", "fft_backend"), [
67+
(False, False, None),
68+
(True, False, None),
69+
(True, True, "loopy"),
70+
(True, True, "pyvkfft"),
71+
])
6872
@pytest.mark.parametrize(
6973
("knl", "local_expn_class", "mpole_expn_class",
7074
"order_varies_with_level"), [
@@ -92,6 +96,9 @@
9296
def test_sumpy_fmm(actx_factory, knl, local_expn_class, mpole_expn_class,
9397
order_varies_with_level, use_translation_classes, use_fft,
9498
fft_backend, visualize=False):
99+
if fft_backend == "pyvkfft":
100+
pytest.importorskip("pyvkfft")
101+
95102
if visualize:
96103
logging.basicConfig(level=logging.INFO)
97104

@@ -399,7 +406,7 @@ def test_unified_single_and_double(actx_factory, visualize=False):
399406
strength_usages = [[0], [1], [0, 1]]
400407

401408
alpha = np.linspace(0, 2*np.pi, nsources, np.float64)
402-
dir_vec = np.vstack([np.cos(alpha), np.sin(alpha)])
409+
dir_vec = actx.from_numpy(np.vstack([np.cos(alpha), np.sin(alpha)]))
403410

404411
results = []
405412
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):
528535
rng = np.random.default_rng(44)
529536
weights = actx.from_numpy(rng.random(nsources, dtype=np.float64))
530537

531-
target_to_source = np.arange(tree.ntargets, dtype=np.int32)
538+
target_to_source = actx.from_numpy(np.arange(tree.ntargets, dtype=np.int32))
532539
self_extra_kwargs = {"target_to_source": target_to_source}
533540

534541
target_kernels = [knl]
@@ -597,7 +604,7 @@ def test_sumpy_axis_source_derivative(actx_factory, visualize=False):
597604
rng = np.random.default_rng(12)
598605
weights = actx.from_numpy(rng.random(nsources, dtype=np.float64))
599606

600-
target_to_source = np.arange(tree.ntargets, dtype=np.int32)
607+
target_to_source = actx.from_numpy(np.arange(tree.ntargets, dtype=np.int32))
601608
self_extra_kwargs = {"target_to_source": target_to_source}
602609

603610
from sumpy.kernel import AxisTargetDerivative, AxisSourceDerivative
@@ -665,7 +672,7 @@ def test_sumpy_target_point_multiplier(actx_factory, deriv_axes, visualize=False
665672
rng = np.random.default_rng(12)
666673
weights = actx.from_numpy(rng.random(nsources, dtype=np.float64))
667674

668-
target_to_source = np.arange(tree.ntargets, dtype=np.int32)
675+
target_to_source = actx.from_numpy(np.arange(tree.ntargets, dtype=np.int32))
669676
self_extra_kwargs = {"target_to_source": target_to_source}
670677

671678
from sumpy.kernel import TargetPointMultiplier, AxisTargetDerivative

test/test_kernels.py

Lines changed: 68 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import numpy as np
2727
import numpy.linalg as la
2828

29+
from pytools.obj_array import make_obj_array
2930
from pytools.convergence import PConvergenceVerifier
3031
from arraycontext import pytest_generate_tests_for_array_contexts
3132
from sumpy.array_context import ( # noqa: F401
@@ -76,20 +77,23 @@ def test_p2p(actx_factory, exclude_self):
7677
rng = np.random.default_rng(42)
7778
targets = rng.random(size=(dimensions, n))
7879
sources = targets if exclude_self else rng.random(size=(dimensions, n))
79-
8080
strengths = np.ones(n, dtype=np.float64)
8181

8282
extra_kwargs = {}
8383

8484
if exclude_self:
85-
extra_kwargs["target_to_source"] = np.arange(n, dtype=np.int32)
85+
extra_kwargs["target_to_source"] = (
86+
actx.from_numpy(np.arange(n, dtype=np.int32)))
8687

8788
evt, (potential, x_derivative) = knl(
88-
actx.queue, targets, sources, [strengths],
89+
actx.queue,
90+
actx.from_numpy(targets),
91+
actx.from_numpy(sources),
92+
[actx.from_numpy(strengths)],
8993
out_host=True, **extra_kwargs)
94+
potential = actx.to_numpy(potential)
9095

9196
potential_ref = np.empty_like(potential)
92-
9397
targets = targets.T
9498
sources = sources.T
9599
for itarg in range(n):
@@ -146,21 +150,22 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class):
146150

147151
rng = np.random.default_rng(14)
148152
center = np.array([2, 1, 0][:knl.dim], np.float64)
149-
sources = (
153+
sources = actx.from_numpy(
150154
0.7 * (-0.5 + rng.random(size=(knl.dim, nsources), dtype=np.float64))
151155
+ center[:, np.newaxis])
152156

153157
strengths = [
154-
np.ones(nsources, dtype=np.float64) * (1/nsources),
155-
np.ones(nsources, dtype=np.float64) * (2/nsources)
158+
actx.from_numpy(np.ones(nsources, dtype=np.float64) * (1/nsources)),
159+
actx.from_numpy(np.ones(nsources, dtype=np.float64) * (2/nsources))
156160
]
157161

158-
source_boxes = np.array([0], dtype=np.int32)
159-
box_source_starts = np.array([0], dtype=np.int32)
160-
box_source_counts_nonchild = np.array([nsources], dtype=np.int32)
162+
source_boxes = actx.from_numpy(np.array([0], dtype=np.int32))
163+
box_source_starts = actx.from_numpy(np.array([0], dtype=np.int32))
164+
box_source_counts_nonchild = (
165+
actx.from_numpy(np.array([nsources], dtype=np.int32)))
161166

162167
alpha = np.linspace(0, 2*np.pi, nsources, np.float64)
163-
dir_vec = np.vstack([np.cos(alpha), np.sin(alpha)])
168+
dir_vec = actx.from_numpy(np.vstack([np.cos(alpha), np.sin(alpha)]))
164169

165170
from sumpy.expansion.local import LocalExpansionBase
166171
if issubclass(expn_class, LocalExpansionBase):
@@ -170,6 +175,7 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class):
170175
centers = (np.array([0.0, 0.0, 0.0][:knl.dim],
171176
dtype=np.float64).reshape(knl.dim, 1)
172177
+ center[:, np.newaxis])
178+
centers = actx.from_numpy(centers)
173179

174180
rscale = 0.5 # pick something non-1
175181

@@ -193,7 +199,7 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class):
193199
dir_vec=dir_vec,
194200
**extra_kwargs)
195201

196-
actual_result = mpoles
202+
actual_result = actx.to_numpy(mpoles)
197203

198204
# apply p2e separately
199205
expected_result = np.zeros_like(actual_result)
@@ -217,6 +223,8 @@ def test_p2e_multiple(actx_factory, base_knl, expn_class):
217223
rscale=rscale,
218224

219225
out_host=True, **extra_source_kwargs)
226+
mpoles = actx.to_numpy(mpoles)
227+
220228
expected_result += mpoles
221229

222230
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
302310

303311
rng = np.random.default_rng(19)
304312
center = np.array([2, 1, 0][:knl.dim], np.float64)
305-
sources = (
313+
sources = actx.from_numpy(
306314
0.7 * (-0.5 + rng.random((knl.dim, nsources), dtype=np.float64))
307315
+ center[:, np.newaxis])
308316

309-
strengths = np.ones(nsources, dtype=np.float64) / nsources
317+
strengths = actx.from_numpy(np.ones(nsources, dtype=np.float64) / nsources)
310318

311-
source_boxes = np.array([0], dtype=np.int32)
312-
box_source_starts = np.array([0], dtype=np.int32)
313-
box_source_counts_nonchild = np.array([nsources], dtype=np.int32)
319+
source_boxes = actx.from_numpy(np.array([0], dtype=np.int32))
320+
box_source_starts = actx.from_numpy(np.array([0], dtype=np.int32))
321+
box_source_counts_nonchild = (
322+
actx.from_numpy(np.array([nsources], dtype=np.int32)))
314323

315324
extra_source_kwargs = extra_kwargs.copy()
316325
if isinstance(knl, DirectionalSourceDerivative):
317326
alpha = np.linspace(0, 2*np.pi, nsources, np.float64)
318327
dir_vec = np.vstack([np.cos(alpha), np.sin(alpha)])
319-
extra_source_kwargs["dir_vec"] = dir_vec
328+
extra_source_kwargs["dir_vec"] = actx.from_numpy(dir_vec)
320329

321330
from sumpy.visualization import FieldPlotter
322331

@@ -332,7 +341,8 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative
332341
dtype=np.float64).reshape(knl.dim, 1)
333342
+ center[:, np.newaxis])
334343

335-
targets = fp.points
344+
centers = actx.from_numpy(centers)
345+
targets = actx.from_numpy(make_obj_array(fp.points))
336346

337347
rscale = 0.5 # pick something non-1
338348

@@ -355,10 +365,11 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative
355365

356366
# {{{ apply e2p
357367

358-
ntargets = targets.shape[-1]
368+
ntargets = fp.points.shape[-1]
359369

360-
box_target_starts = np.array([0], dtype=np.int32)
361-
box_target_counts_nonchild = np.array([ntargets], dtype=np.int32)
370+
box_target_starts = actx.from_numpy(np.array([0], dtype=np.int32))
371+
box_target_counts_nonchild = (
372+
actx.from_numpy(np.array([ntargets], dtype=np.int32)))
362373

363374
evt, (pot, grad_x, ) = e2p(
364375
actx.queue,
@@ -372,6 +383,8 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative
372383
rscale=rscale,
373384

374385
out_host=True, **extra_kwargs)
386+
pot = actx.to_numpy(pot)
387+
grad_x = actx.to_numpy(grad_x)
375388

376389
# }}}
377390

@@ -382,6 +395,8 @@ def test_p2e2p(actx_factory, base_knl, expn_class, order, with_source_derivative
382395
targets, sources, (strengths,),
383396
out_host=True,
384397
**extra_source_kwargs)
398+
pot_direct = actx.to_numpy(pot_direct)
399+
grad_x_direct = actx.to_numpy(grad_x_direct)
385400

386401
err_pot = la.norm((pot - pot_direct)/res**2)
387402
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,
501516
# Just to make sure things also work away from the origin
502517
rng = np.random.default_rng(18)
503518
origin = np.array([2, 1, 0][:knl.dim], np.float64)
504-
sources = (
519+
sources = actx.from_numpy(
505520
0.7 * (-0.5 + rng.random((knl.dim, nsources), dtype=np.float64))
506521
+ origin[:, np.newaxis])
507-
strengths = np.ones(nsources, dtype=np.float64) * (1/nsources)
522+
strengths = actx.from_numpy(
523+
np.ones(nsources, dtype=np.float64) * (1/nsources))
508524

509525
pconv_verifier_p2m2p = PConvergenceVerifier()
510526
pconv_verifier_p2m2m2p = PConvergenceVerifier()
@@ -514,8 +530,9 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class,
514530
from sumpy.visualization import FieldPlotter
515531

516532
eval_offset = np.array([5.5, 0.0, 0][:knl.dim])
533+
fp = FieldPlotter(eval_offset + origin, extent=0.3, npoints=res)
517534

518-
centers = (np.array(
535+
centers = actx.from_numpy((np.array(
519536
[
520537
# box 0: particles, first mpole here
521538
[0, 0, 0][:knl.dim],
@@ -529,7 +546,7 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class,
529546
# box 3: second local and eval here
530547
eval_offset
531548
],
532-
dtype=np.float64) + origin).T.copy()
549+
dtype=np.float64) + origin).T.copy())
533550

534551
del eval_offset
535552

@@ -541,13 +558,15 @@ def test_translations(actx_factory, knl, local_expn_class, mpole_expn_class,
541558
nboxes = centers.shape[-1]
542559

543560
def eval_at(e2p, source_box_nr, rscale):
544-
e2p_target_boxes = np.array([source_box_nr], dtype=np.int32)
561+
e2p_target_boxes = actx.from_numpy(
562+
np.array([source_box_nr], dtype=np.int32))
545563

546564
# These are indexed by global box numbers.
547-
e2p_box_target_starts = np.array([0, 0, 0, 0], dtype=np.int32)
548-
e2p_box_target_counts_nonchild = np.array([0, 0, 0, 0],
549-
dtype=np.int32)
550-
e2p_box_target_counts_nonchild[source_box_nr] = ntargets
565+
e2p_box_target_starts = actx.from_numpy(
566+
np.array([0, 0, 0, 0], dtype=np.int32))
567+
e2p_box_target_counts_nonchild = actx.from_numpy(
568+
np.array([0, 0, 0, 0], dtype=np.int32))
569+
e2p_box_target_counts_nonchild[source_box_nr] = fp.points.shape[-1]
551570

552571
evt, (pot,) = e2p(
553572
actx.queue,
@@ -565,6 +584,7 @@ def eval_at(e2p, source_box_nr, rscale):
565584

566585
out_host=True, **extra_kwargs
567586
)
587+
pot = actx.to_numpy(pot)
568588

569589
return pot
570590

@@ -584,15 +604,15 @@ def eval_at(e2p, source_box_nr, rscale):
584604
l2p = E2PFromSingleBox(actx.context, l_expn, target_kernels)
585605
p2p = P2P(actx.context, target_kernels, exclude_self=False)
586606

587-
fp = FieldPlotter(centers[:, -1], extent=0.3, npoints=res)
588-
targets = fp.points
607+
targets = actx.from_numpy(make_obj_array(fp.points))
589608

590609
# {{{ compute (direct) reference solution
591610

592611
evt, (pot_direct,) = p2p(
593612
actx.queue,
594613
targets, sources, (strengths,),
595614
out_host=True, **extra_kwargs)
615+
pot_direct = actx.to_numpy(pot_direct)
596616

597617
# }}}
598618

@@ -603,12 +623,13 @@ def eval_at(e2p, source_box_nr, rscale):
603623

604624
# {{{ apply P2M
605625

606-
p2m_source_boxes = np.array([0], dtype=np.int32)
626+
p2m_source_boxes = actx.from_numpy(np.array([0], dtype=np.int32))
607627

608628
# These are indexed by global box numbers.
609-
p2m_box_source_starts = np.array([0, 0, 0, 0], dtype=np.int32)
610-
p2m_box_source_counts_nonchild = np.array([nsources, 0, 0, 0],
611-
dtype=np.int32)
629+
p2m_box_source_starts = actx.from_numpy(
630+
np.array([0, 0, 0, 0], dtype=np.int32))
631+
p2m_box_source_counts_nonchild = actx.from_numpy(
632+
np.array([nsources, 0, 0, 0], dtype=np.int32))
612633

613634
evt, (mpoles,) = p2m(actx.queue,
614635
source_boxes=p2m_source_boxes,
@@ -626,20 +647,18 @@ def eval_at(e2p, source_box_nr, rscale):
626647

627648
# }}}
628649

629-
ntargets = targets.shape[-1]
630-
631650
pot = eval_at(m2p, 0, m1_rscale)
632651

633-
err = la.norm((pot - pot_direct)/res**2)
652+
err = la.norm((pot - pot_direct) / res**2)
634653
err = err / (la.norm(pot_direct) / res**2)
635654

636655
pconv_verifier_p2m2p.add_data_point(order, err)
637656

638657
# {{{ apply M2M
639658

640-
m2m_target_boxes = np.array([1], dtype=np.int32)
641-
m2m_src_box_starts = np.array([0, 1], dtype=np.int32)
642-
m2m_src_box_lists = np.array([0], dtype=np.int32)
659+
m2m_target_boxes = actx.from_numpy(np.array([1], dtype=np.int32))
660+
m2m_src_box_starts = actx.from_numpy(np.array([0, 1], dtype=np.int32))
661+
m2m_src_box_lists = actx.from_numpy(np.array([0], dtype=np.int32))
643662

644663
evt, (mpoles,) = m2m(actx.queue,
645664
src_expansions=mpoles,
@@ -669,9 +688,9 @@ def eval_at(e2p, source_box_nr, rscale):
669688

670689
# {{{ apply M2L
671690

672-
m2l_target_boxes = np.array([2], dtype=np.int32)
673-
m2l_src_box_starts = np.array([0, 1], dtype=np.int32)
674-
m2l_src_box_lists = np.array([1], dtype=np.int32)
691+
m2l_target_boxes = actx.from_numpy(np.array([2], dtype=np.int32))
692+
m2l_src_box_starts = actx.from_numpy(np.array([0, 1], dtype=np.int32))
693+
m2l_src_box_lists = actx.from_numpy(np.array([1], dtype=np.int32))
675694

676695
evt, (mpoles,) = m2l(actx.queue,
677696
src_expansions=mpoles,
@@ -700,9 +719,9 @@ def eval_at(e2p, source_box_nr, rscale):
700719

701720
# {{{ apply L2L
702721

703-
l2l_target_boxes = np.array([3], dtype=np.int32)
704-
l2l_src_box_starts = np.array([0, 1], dtype=np.int32)
705-
l2l_src_box_lists = np.array([2], dtype=np.int32)
722+
l2l_target_boxes = actx.from_numpy(np.array([3], dtype=np.int32))
723+
l2l_src_box_starts = actx.from_numpy(np.array([0, 1], dtype=np.int32))
724+
l2l_src_box_lists = actx.from_numpy(np.array([2], dtype=np.int32))
706725

707726
evt, (mpoles,) = l2l(actx.queue,
708727
src_expansions=mpoles,

0 commit comments

Comments
 (0)