From 8cabc711dbe7219a26c3aea11be2a9e949ee6f7a Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 8 Dec 2024 10:29:47 +0200 Subject: [PATCH 1/7] primitives: move check to __init__ --- pytential/symbolic/primitives.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pytential/symbolic/primitives.py b/pytential/symbolic/primitives.py index d7f3c4eb6..8ac4d3b6c 100644 --- a/pytential/symbolic/primitives.py +++ b/pytential/symbolic/primitives.py @@ -611,14 +611,6 @@ def __new__(cls, operand: Operand | None = None, dofdesc: DOFDescriptor | None = None, ) -> "NumReferenceDerivative": - if isinstance(ref_axes, int): - warn(f"Passing an 'int' as 'ref_axes' to {cls.__name__!r} " - "is deprecated and will result in an error in 2025. Pass the " - "well-formatted tuple '((ref_axes, 1),)' instead.", - DeprecationWarning, stacklevel=2) - - ref_axes = ((ref_axes, 1),) - if isinstance(operand, np.ndarray | MultiVector): warn(f"Passing {type(operand)} directly to {cls.__name__!r} " "is deprecated and will result in an error from 2025. Use " @@ -641,6 +633,14 @@ def __init__(self, ref_axes: tuple[tuple[int, int], ...], operand: ArithmeticExpression, dofdesc: DOFDescriptorLike) -> None: + if isinstance(ref_axes, int): + warn(f"Passing an 'int' as 'ref_axes' to {type(self).__name__!r} " + "is deprecated and will result in an error in 2025. Pass the " + "well-formatted tuple '((ref_axes, 1),)' instead.", + DeprecationWarning, stacklevel=2) + + ref_axes = ((ref_axes, 1),) + if not isinstance(ref_axes, tuple): raise ValueError(f"'ref_axes' must be a tuple: {type(ref_axes)}") From 7892098c146aa0d09df10472f5d1f1defca9e8c6 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 8 Dec 2024 10:31:49 +0200 Subject: [PATCH 2/7] primitives: pass DOFDescriptor to classes --- pytential/symbolic/primitives.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pytential/symbolic/primitives.py b/pytential/symbolic/primitives.py index 8ac4d3b6c..8d3ac3df1 100644 --- a/pytential/symbolic/primitives.py +++ b/pytential/symbolic/primitives.py @@ -856,12 +856,13 @@ def shape_operator(ambient_dim, dim=None, dofdesc=None): def _element_size(ambient_dim, dim=None, dofdesc=None): # A broken quasi-1D approximation of 1D element size. Do not use. - if dim is None: dim = ambient_dim - 1 + dofdesc = as_dofdesc(dofdesc) return elementwise_sum( - area_element(ambient_dim=ambient_dim, dim=dim) * QWeight(), + area_element(ambient_dim=ambient_dim, dim=dim, dofdesc=dofdesc) + * QWeight(dofdesc), dofdesc)**(1/dim) @@ -1167,8 +1168,9 @@ def h_min(ambient_dim, dim=None, dofdesc=None): def weights_and_area_elements(ambient_dim, dim=None, dofdesc=None): """Combines :func:`area_element` and :class:`QWeight`.""" - + dofdesc = as_dofdesc(dofdesc) area = area_element(ambient_dim, dim=dim, dofdesc=dofdesc) + return cse(area * QWeight(dofdesc=dofdesc), "weights_area_elements", cse_scope.DISCRETIZATION) From 3a6131eadd9217b607ec10209d0b2c6ce5cbbf42 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 8 Dec 2024 10:34:33 +0200 Subject: [PATCH 3/7] primitives: add for_each_expression to __all__ --- pytential/symbolic/primitives.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pytential/symbolic/primitives.py b/pytential/symbolic/primitives.py index 8d3ac3df1..a30dce493 100644 --- a/pytential/symbolic/primitives.py +++ b/pytential/symbolic/primitives.py @@ -104,6 +104,8 @@ .. autoclass:: ArithmeticExpressionT +.. autoclass:: QBXForcedLimit + .. class:: P See :class:`pytools.P` @@ -329,6 +331,10 @@ __all__ = ( "Expression", + "Operand", + "ArithmeticExpressionT", + "QBXForcedLimit", + "for_each_expression", "ErrorExpression", @@ -395,7 +401,7 @@ def make_stringifier(self, originating_stringifier=None): Operand: TypeAlias = ( ArithmeticExpression | np.ndarray[Any, np.dtype[Any]] | MultiVector) -QBXForcedLimit = int | Literal["avg"] | None +QBXForcedLimit: TypeAlias = int | Literal["avg"] | None # NOTE: this will likely live in pymbolic at some point, but for now we take it! ArithmeticExpressionT = TypeVar("ArithmeticExpressionT", bound=ArithmeticExpression) From 69155c39f196d9cfa1660a565ce2a9c29bae1a59 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 8 Dec 2024 10:39:39 +0200 Subject: [PATCH 4/7] primitives: do not use unhashable lists for centers --- pytential/symbolic/execution.py | 2 +- pytential/symbolic/primitives.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pytential/symbolic/execution.py b/pytential/symbolic/execution.py index 378951cbe..396be4b06 100644 --- a/pytential/symbolic/execution.py +++ b/pytential/symbolic/execution.py @@ -249,7 +249,7 @@ def map_interpolation(self, expr): if isinstance(operand, (*self.array_context.array_types, - list, np.ndarray, DOFArray)): + list, tuple, np.ndarray, DOFArray)): conn = self.places.get_connection(expr.from_dd, expr.to_dd) return conn(operand) elif isinstance(operand, int | float | complex | np.number): diff --git a/pytential/symbolic/primitives.py b/pytential/symbolic/primitives.py index a30dce493..0c78b7820 100644 --- a/pytential/symbolic/primitives.py +++ b/pytential/symbolic/primitives.py @@ -1144,10 +1144,10 @@ def expansion_centers(ambient_dim, side, dim=None, dofdesc=None): def interleaved_expansion_centers(ambient_dim, dim=None, dofdesc=None): - centers = [ + centers = ( expansion_centers(ambient_dim, -1, dim=dim, dofdesc=dofdesc), expansion_centers(ambient_dim, +1, dim=dim, dofdesc=dofdesc) - ] + ) source = as_dofdesc(dofdesc) target = source.copy(granularity=GRANULARITY_CENTER) From ee4aafc40d148c0d9e69638a81e1c4563bf761df Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 8 Dec 2024 11:07:03 +0200 Subject: [PATCH 5/7] examples: remove force_device_scalars --- examples/cost.py | 4 ++-- examples/fmm-error.py | 2 +- examples/helmholtz-dirichlet.py | 2 +- examples/laplace-dirichlet-3d.py | 2 +- examples/laplace-dirichlet-simple.py | 2 +- examples/layerpot-3d.py | 2 +- examples/layerpot.py | 2 +- examples/scaling-study.py | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/cost.py b/examples/cost.py index f24b93a3c..008de5f05 100644 --- a/examples/cost.py +++ b/examples/cost.py @@ -115,7 +115,7 @@ def get_test_density(actx, density_discr): def calibrate_cost_model(ctx): queue = cl.CommandQueue(ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) cost_model = QBXCostModel() model_results = [] @@ -153,7 +153,7 @@ def calibrate_cost_model(ctx): def test_cost_model(ctx, calibration_params): queue = cl.CommandQueue(ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) cost_model = QBXCostModel() for lpot_source in test_geometries(actx): diff --git a/examples/fmm-error.py b/examples/fmm-error.py index 92345ca62..5671d133a 100644 --- a/examples/fmm-error.py +++ b/examples/fmm-error.py @@ -15,7 +15,7 @@ def main(): import pyopencl as cl cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) target_order = 16 qbx_order = 3 diff --git a/examples/helmholtz-dirichlet.py b/examples/helmholtz-dirichlet.py index b55314200..b3d400e62 100644 --- a/examples/helmholtz-dirichlet.py +++ b/examples/helmholtz-dirichlet.py @@ -29,7 +29,7 @@ def main(mesh_name="ellipse", visualize=False): import pyopencl as cl cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import ellipse, make_curve_mesh from functools import partial diff --git a/examples/laplace-dirichlet-3d.py b/examples/laplace-dirichlet-3d.py index 417500029..d63a64eec 100644 --- a/examples/laplace-dirichlet-3d.py +++ b/examples/laplace-dirichlet-3d.py @@ -27,7 +27,7 @@ def main(mesh_name="torus", visualize=False): import pyopencl as cl cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) if mesh_name == "torus": rout = 10 diff --git a/examples/laplace-dirichlet-simple.py b/examples/laplace-dirichlet-simple.py index f01c97c25..6c121b141 100644 --- a/examples/laplace-dirichlet-simple.py +++ b/examples/laplace-dirichlet-simple.py @@ -28,7 +28,7 @@ def main(mesh_name="starfish", visualize=False): import pyopencl as cl cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import ellipse, make_curve_mesh, starfish from functools import partial diff --git a/examples/layerpot-3d.py b/examples/layerpot-3d.py index 5cbec6101..8c2d9deaf 100644 --- a/examples/layerpot-3d.py +++ b/examples/layerpot-3d.py @@ -21,7 +21,7 @@ def main(mesh_name="ellipsoid"): import pyopencl as cl cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) if mesh_name == "ellipsoid": cad_file_name = "geometries/ellipsoid.step" diff --git a/examples/layerpot.py b/examples/layerpot.py index cd476a25c..55ffbb56c 100644 --- a/examples/layerpot.py +++ b/examples/layerpot.py @@ -23,7 +23,7 @@ def main(curve_fn=starfish, visualize=True): import pyopencl as cl cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import make_curve_mesh mesh = make_curve_mesh( diff --git a/examples/scaling-study.py b/examples/scaling-study.py index ee7e6964c..569442873 100644 --- a/examples/scaling-study.py +++ b/examples/scaling-study.py @@ -58,7 +58,7 @@ def timing_run(nx, ny, visualize=False): import pyopencl as cl cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) - actx = PyOpenCLArrayContext(queue, force_device_scalars=True) + actx = PyOpenCLArrayContext(queue) mesh = make_mesh(nx=nx, ny=ny, visualize=visualize) From df2ce79c4943e79c9d683db91759e478386d55ec Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 8 Dec 2024 20:44:55 +0200 Subject: [PATCH 6/7] mapper: use full DOFDescriptor in tagger --- pytential/symbolic/mappers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pytential/symbolic/mappers.py b/pytential/symbolic/mappers.py index 33300cbc6..669048077 100644 --- a/pytential/symbolic/mappers.py +++ b/pytential/symbolic/mappers.py @@ -296,8 +296,8 @@ class LocationTagger(CSECachingMapperMixin[Expression, []], """Used internally by :class:`ToTargetTagger`.""" def __init__(self, default_target, default_source): - self.default_source = default_source - self.default_target = default_target + self.default_source = prim.as_dofdesc(default_source) + self.default_target = prim.as_dofdesc(default_target) def map_common_subexpression_uncached(self, expr) -> Expression: # Mypy 1.13 complains about this: From 42e5733f3a2483222fc9948bd13a0bcfbb38be0c Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 8 Dec 2024 20:48:56 +0200 Subject: [PATCH 7/7] target_specific: mark functions as noexcept --- pytential/qbx/target_specific/impl.pyx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pytential/qbx/target_specific/impl.pyx b/pytential/qbx/target_specific/impl.pyx index 88d6052f8..e950b7bb7 100644 --- a/pytential/qbx/target_specific/impl.pyx +++ b/pytential/qbx/target_specific/impl.pyx @@ -129,7 +129,7 @@ def h3dall_wrapper(nterms, z, scale, hs, hders): # {{{ helpers -cdef void legvals(double x, int n, double[] vals, double[] derivs) nogil: +cdef void legvals(double x, int n, double[] vals, double[] derivs) noexcept nogil: """Compute the values of the Legendre polynomial up to order n at x. Optionally, if derivs is non-NULL, compute the values of the derivative too. @@ -189,7 +189,7 @@ cdef void ts_helmholtz_precompute( double complex k, double complex[] jvals, double complex[] jderivs, - double *jscale) nogil: + double *jscale) noexcept nogil: """Evaluate the source-invariant Bessel terms of the Helmholtz target-specific expansion.""" @@ -224,7 +224,7 @@ cdef double complex ts_laplace_s( double[3] center, double[3] target, double complex charge, - int order) nogil: + int order) noexcept nogil: """Evaluate the target-specific expansion of the Laplace single-layer kernel.""" cdef: @@ -278,7 +278,7 @@ cdef void ts_laplace_sp( double[3] center, double[3] target, double complex charge, - int order) nogil: + int order) noexcept nogil: """Evaluate the target-specific expansion of the gradient of the Laplace single-layer kernel.""" @@ -324,7 +324,7 @@ cdef double complex ts_laplace_d( double[3] target, double[3] dipole, double complex dipstr, - int order) nogil: + int order) noexcept nogil: """Evaluate the target-specific expansion of the Laplace double-layer kernel.""" cdef: @@ -370,7 +370,7 @@ cdef double complex ts_helmholtz_s( int order, double complex k, double complex[] jvals, - double jscale) nogil: + double jscale) noexcept nogil: """Evaluate the target-specific expansion of the Helmholtz single-layer kernel.""" @@ -429,7 +429,7 @@ cdef void ts_helmholtz_sp( double complex k, double complex[] jvals, double complex[] jderivs, - double jscale) nogil: + double jscale) noexcept nogil: """Evaluate the target-specific expansion of the gradient of the Helmholtz single-layer kernel.""" @@ -501,7 +501,7 @@ cdef double complex ts_helmholtz_d( int order, double complex k, double complex[] jvals, - double jscale) nogil: + double jscale) noexcept nogil: """Evaluate the target-specific expansion of the Helmholtz double-layer kernel."""