2020THE SOFTWARE.
2121"""
2222
23+ import pytest
2324import sys
2425from dataclasses import dataclass
25- from typing import Any , Callable
26+ from typing import Any , Callable , Dict
2627
2728import numpy as np
2829import numpy .linalg as la
2930
31+ from arraycontext import pytest_generate_tests_for_array_contexts
32+ from sumpy .array_context import ( # noqa: F401
33+ PytestPyOpenCLArrayContextFactory , _acf )
34+
3035import sumpy .toys as t
3136import sumpy .symbolic as sym
3237
33- import pytest
34- import pyopencl as cl # noqa: F401
35- from pyopencl .tools import ( # noqa
36- pytest_generate_tests_for_pyopencl as pytest_generate_tests )
37-
38- from sumpy .kernel import (LaplaceKernel , HelmholtzKernel ,
39- BiharmonicKernel , YukawaKernel , StokesletKernel , StressletKernel ,
40- ElasticityKernel , LineOfCompressionKernel , ExpressionKernel )
41- from sumpy .expansion .diff_op import (make_identity_diff_op , gradient ,
42- divergence , laplacian , concat , as_scalar_pde , curl , diff )
38+ from sumpy .kernel import (
39+ Kernel ,
40+ LaplaceKernel ,
41+ HelmholtzKernel ,
42+ BiharmonicKernel ,
43+ YukawaKernel ,
44+ StokesletKernel ,
45+ StressletKernel ,
46+ ElasticityKernel ,
47+ LineOfCompressionKernel ,
48+ ExpressionKernel )
49+ from sumpy .expansion .diff_op import (
50+ make_identity_diff_op , concat , as_scalar_pde , diff ,
51+ gradient , divergence , laplacian , curl )
52+
53+ import logging
54+ logger = logging .getLogger (__name__ )
55+
56+ pytest_generate_tests = pytest_generate_tests_for_array_contexts ([
57+ PytestPyOpenCLArrayContextFactory ,
58+ ])
4359
4460
4561# {{{ pde check for kernels
4662
63+ @dataclass (frozen = True )
4764class KernelInfo :
48- def __init__ (self , kernel , ** kwargs ):
49- self .kernel = kernel
50- self .extra_kwargs = kwargs
51- diff_op = self .kernel .get_pde_as_diff_op ()
52- assert len (diff_op .eqs ) == 1
53- eq = diff_op .eqs [0 ]
54- self .eq = eq
65+ kernel : Kernel
66+ extra_kwargs : Dict [str , Any ]
67+
68+ @property
69+ def nderivs (self ):
70+ return max (sum (ident .mi ) for ident in self .eq .keys ())
71+
72+ @property
73+ def diff_op (self ):
74+ op = self .kernel .get_pde_as_diff_op ()
75+ assert len (op .eqs ) == 1
76+ return op
77+
78+ @property
79+ def eq (self ):
80+ return self .diff_op [0 ]
5581
5682 def pde_func (self , cp , pot ):
5783 subs_dict = {sym .Symbol (k ): v for k , v in self .extra_kwargs .items ()}
@@ -63,10 +89,6 @@ def pde_func(self, cp, pot):
6389 result += lresult * float (sym .sympify (coeff ).xreplace (subs_dict ))
6490 return result
6591
66- @property
67- def nderivs (self ):
68- return max (sum (ident .mi ) for ident in self .eq .keys ())
69-
7092
7193@pytest .mark .parametrize ("knl_info" , [
7294 KernelInfo (BiharmonicKernel (2 )),
@@ -93,15 +115,17 @@ def nderivs(self):
93115 KernelInfo (LineOfCompressionKernel (3 , 0 ), mu = 5 , nu = 0.2 ),
94116 KernelInfo (LineOfCompressionKernel (3 , 1 ), mu = 5 , nu = 0.2 ),
95117 ])
96- def test_pde_check_kernels (ctx_factory , knl_info , order = 5 ):
118+ def test_pde_check_kernels (actx_factory , knl_info , order = 5 ):
119+ actx = actx_factory ()
120+
97121 dim = knl_info .kernel .dim
98- tctx = t .ToyContext (ctx_factory () , knl_info .kernel ,
122+ tctx = t .ToyContext (actx . context , knl_info .kernel ,
99123 extra_source_kwargs = knl_info .extra_kwargs )
100124
101- np .random .seed ( 17 )
125+ rng = np .random .default_rng ( 42 )
102126 pt_src = t .PointSources (
103127 tctx ,
104- np .random . rand ( dim , 50 ) - 0.5 ,
128+ rng .random ( size = ( dim , 50 ) ) - 0.5 ,
105129 np .ones (50 ))
106130
107131 from pytools .convergence import EOCRecorder
@@ -117,12 +141,14 @@ def test_pde_check_kernels(ctx_factory, knl_info, order=5):
117141 err = la .norm (pde )
118142 eoc_rec .add_data_point (h , err )
119143
120- print ( eoc_rec )
144+ logger . info ( "eoc: \n %s" , eoc_rec )
121145 assert eoc_rec .order_estimate () > order - knl_info .nderivs + 1 - 0.1
122146
123147# }}}
124148
125149
150+ # {{{ test_pde_check
151+
126152@pytest .mark .parametrize ("dim" , [1 , 2 , 3 ])
127153def test_pde_check (dim , order = 4 ):
128154 from sumpy .point_calculus import CalculusPatch
@@ -138,15 +164,19 @@ def test_pde_check(dim, order=4):
138164 err = la .norm (df_num - df_true )
139165 eoc_rec .add_data_point (h , err )
140166
141- print ( eoc_rec )
167+ logger . info ( "eoc: \n %s" , eoc_rec )
142168 assert eoc_rec .order_estimate () > order - 2 - 0.1
143169
170+ # }}}
171+
144172
173+ # {{{ test_order_finder
174+
175+ @dataclass (frozen = True )
145176class FakeTree :
146- def __init__ (self , dimensions , root_extent , stick_out_factor ):
147- self .dimensions = dimensions
148- self .root_extent = root_extent
149- self .stick_out_factor = stick_out_factor
177+ dimensions : int
178+ root_extent : float
179+ stick_out_factor : float
150180
151181
152182@pytest .mark .parametrize ("knl" , [
@@ -161,7 +191,7 @@ def test_order_finder(knl):
161191 orders = [
162192 ofind (knl , frozenset ([("k" , 5 )]), tree , level )
163193 for level in range (30 )]
164- print ( orders )
194+ logger . info ( "orders: %s" , orders )
165195
166196 # Order should not increase with level
167197 assert (np .diff (orders ) <= 0 ).all ()
@@ -180,11 +210,13 @@ def test_fmmlib_order_finder(knl):
180210 orders = [
181211 ofind (knl , frozenset ([("k" , 5 )]), tree , level )
182212 for level in range (30 )]
183- print ( orders )
213+ logger . info ( "orders: %s" , orders )
184214
185215 # Order should not increase with level
186216 assert (np .diff (orders ) <= 0 ).all ()
187217
218+ # }}}
219+
188220
189221# {{{ expansion toys p2e2e2p test cases
190222
@@ -193,7 +225,7 @@ def approx_convergence_factor(orders, errors):
193225 return np .exp (poly [0 ])
194226
195227
196- @dataclass
228+ @dataclass ( frozen = True )
197229class P2E2E2PTestCase :
198230 source : np .ndarray
199231 target : np .ndarray
@@ -243,12 +275,14 @@ def dim(self):
243275# }}}
244276
245277
278+ # {{{ test_toy_p2e2e2p
279+
246280ORDERS_P2E2E2P = (3 , 4 , 5 )
247281RTOL_P2E2E2P = 1e-2
248282
249283
250284@pytest .mark .parametrize ("case" , P2E2E2P_TEST_CASES )
251- def test_toy_p2e2e2p (ctx_factory , case ):
285+ def test_toy_p2e2e2p (actx_factory , case ):
252286 dim = case .dim
253287
254288 src = case .source .reshape (dim , - 1 )
@@ -269,8 +303,8 @@ def test_toy_p2e2e2p(ctx_factory, case):
269303
270304 from sumpy .expansion import VolumeTaylorExpansionFactory
271305
272- cl_ctx = ctx_factory ()
273- ctx = t .ToyContext (cl_ctx ,
306+ actx = actx_factory ()
307+ ctx = t .ToyContext (actx . context ,
274308 LaplaceKernel (dim ),
275309 expansion_factory = VolumeTaylorExpansionFactory ())
276310
@@ -289,6 +323,10 @@ def test_toy_p2e2e2p(ctx_factory, case):
289323 assert conv_factor <= min (1 , case_conv_factor * (1 + RTOL_P2E2E2P )), \
290324 (conv_factor , case_conv_factor * (1 + RTOL_P2E2E2P ))
291325
326+ # }}}
327+
328+
329+ # {{{ test_cse_matvec
292330
293331def test_cse_matvec ():
294332 from sumpy .expansion import CSEMatVecOperator
@@ -309,16 +347,21 @@ def test_cse_matvec():
309347 op = CSEMatVecOperator (input_coeffs , output_coeffs , shape = (4 , 2 ))
310348 m = np .array ([[2 , 0 ], [6 , 0 ], [0 , 1 ], [30 , 16 ]])
311349
312- vec = np .random .random (2 )
350+ rng = np .random .default_rng (42 )
351+ vec = rng .random (2 )
313352 expected_result = m @ vec
314353 actual_result = op .matvec (vec )
315354 assert np .allclose (expected_result , actual_result )
316355
317- vec = np . random .random (4 )
356+ vec = rng .random (4 )
318357 expected_result = m .T @ vec
319358 actual_result = op .transpose_matvec (vec )
320359 assert np .allclose (expected_result , actual_result )
321360
361+ # }}}
362+
363+
364+ # {{{ test_diff_op_stokes
322365
323366def test_diff_op_stokes ():
324367 from sumpy .symbolic import symbols , Function
@@ -341,6 +384,10 @@ def test_diff_op_stokes():
341384
342385 assert expected_output == actual_output
343386
387+ # }}}
388+
389+
390+ # {{{ test_as_scalar_pde_stokes
344391
345392def test_as_scalar_pde_stokes ():
346393 diff_op = make_identity_diff_op (3 , 4 )
@@ -350,13 +397,17 @@ def test_as_scalar_pde_stokes():
350397
351398 # velocity components in Stokes should satisfy Biharmonic
352399 for i in range (3 ):
353- print ( as_scalar_pde (pde , i ))
354- print ( laplacian (laplacian (u [i ])))
400+ logger . info ( "pde \n %s" , as_scalar_pde (pde , i ))
401+ logger . info ( " \n %s" , laplacian (laplacian (u [i ])))
355402 assert as_scalar_pde (pde , i ) == laplacian (laplacian (u [0 ]))
356403
357404 # pressure should satisfy Laplace
358405 assert as_scalar_pde (pde , 3 ) == laplacian (u [0 ])
359406
407+ # }}}
408+
409+
410+ # {{{ test_as_scalar_pde_maxwell
360411
361412def test_as_scalar_pde_maxwell ():
362413 from sumpy .symbolic import symbols
@@ -374,6 +425,10 @@ def test_as_scalar_pde_maxwell():
374425 assert as_scalar_pde (pde , i ) == \
375426 laplacian (op [0 ]) - mu * epsilon * diff (diff (op [0 ], t ), t )
376427
428+ # }}}
429+
430+
431+ # {{{ test_as_scalar_pde_elasticity
377432
378433def test_as_scalar_pde_elasticity ():
379434
@@ -408,6 +463,10 @@ def test_as_scalar_pde_elasticity():
408463 assert scalar_pde == laplacian (laplacian (diff_op [0 ]))
409464 assert scalar_pde .order == 4
410465
466+ # }}}
467+
468+
469+ # {{{ test_elasticity_new
411470
412471def test_elasticity_new ():
413472 from pickle import dumps , loads
@@ -424,6 +483,10 @@ def test_elasticity_new():
424483 assert not isinstance (knl , StokesletKernel )
425484 assert loads (dumps (knl )) == knl
426485
486+ # }}}
487+
488+
489+ # {{{ test_weird_kernel
427490
428491w = make_identity_diff_op (2 )
429492
@@ -457,15 +520,13 @@ def get_pde_as_diff_op(self):
457520
458521 assert fft_size == order
459522
523+ # }}}
460524
461- # You can test individual routines by typing
462- # $ python test_misc.py 'test_p2p(cl.create_some_context)'
463525
464526if __name__ == "__main__" :
465527 if len (sys .argv ) > 1 :
466528 exec (sys .argv [1 ])
467529 else :
468- from pytest import main
469- main ([__file__ ])
530+ pytest .main ([__file__ ])
470531
471532# vim: fdm=marker
0 commit comments