From 3c231aabb3983997551037aaabfd2cff483b1308 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 26 Jul 2023 19:35:36 -0500 Subject: [PATCH 1/5] Ignore memory profiler files --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index b450b3b75..daf719e6f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,7 @@ pytential/_git_rev.py *.so pytential/qbx/target_specific/impl.c + +mprofile_*.dat +memray-*.bin +memray-*.html From 95b03a537a2760e570b9f931658d46a304786891 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 26 Jul 2023 19:38:56 -0500 Subject: [PATCH 2/5] Use loopy kernel executor to avoid keeping CL contexts alive through caches --- pytential/qbx/direct.py | 2 +- pytential/qbx/geometry.py | 7 ++++--- pytential/qbx/interactions.py | 8 ++++---- pytential/unregularized.py | 4 +++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pytential/qbx/direct.py b/pytential/qbx/direct.py index 7e8cc5369..3bb59708b 100644 --- a/pytential/qbx/direct.py +++ b/pytential/qbx/direct.py @@ -109,7 +109,7 @@ def get_kernel(self): def __call__(self, queue, targets, sources, centers, strengths, expansion_radii, **kwargs): from sumpy.tools import is_obj_array_like - knl = self.get_cached_optimized_kernel( + knl = self.get_cached_kernel_executor( targets_is_obj_array=is_obj_array_like(targets), sources_is_obj_array=is_obj_array_like(sources), centers_is_obj_array=is_obj_array_like(centers)) diff --git a/pytential/qbx/geometry.py b/pytential/qbx/geometry.py index 0c1005f77..53f4b43a3 100644 --- a/pytential/qbx/geometry.py +++ b/pytential/qbx/geometry.py @@ -137,7 +137,8 @@ def copy_targets_kernel(self): knl = lp.tag_array_axes(knl, "points", "sep, C") knl = lp.tag_array_axes(knl, "targets", "stride:auto, stride:1") - return lp.tag_inames(knl, {"dim": "ilp"}) + knl = lp.tag_inames(knl, {"dim": "ilp"}) + return knl.executor(self._setup_actx.context) @property @memoize_method @@ -192,7 +193,7 @@ def qbx_center_to_target_box_lookup(self, particle_id_dtype, box_id_dtype): knl = lp.split_iname(knl, "ibox", 128, inner_tag="l.0", outer_tag="g.0") - return knl + return knl.executor(self._setup_actx.context) @property @memoize_method @@ -253,7 +254,7 @@ def pick_used_centers(self): lang_version=MOST_RECENT_LANGUAGE_VERSION) knl = lp.split_iname(knl, "i", 128, inner_tag="l.0", outer_tag="g.0") - return knl + return knl.executor(self._setup_actx.context) @property @memoize_method diff --git a/pytential/qbx/interactions.py b/pytential/qbx/interactions.py index 90f3e7f1f..eb39c9a6f 100644 --- a/pytential/qbx/interactions.py +++ b/pytential/qbx/interactions.py @@ -153,7 +153,7 @@ def __call__(self, queue, **kwargs): qbx_centers = kwargs.pop("qbx_centers") from sumpy.tools import is_obj_array_like - return self.get_cached_optimized_kernel( + return self.get_cached_kernel_executor( is_sources_obj_array=is_obj_array_like(sources), is_centers_obj_array=is_obj_array_like(qbx_centers), )(queue, sources=sources, qbx_centers=qbx_centers, **kwargs) @@ -272,7 +272,7 @@ def __call__(self, queue, **kwargs): from sumpy.tools import is_obj_array_like qbx_centers = kwargs.pop("qbx_centers") - return self.get_cached_optimized_kernel( + return self.get_cached_kernel_executor( is_centers_obj_array=is_obj_array_like(qbx_centers), )(queue, centers=centers, qbx_centers=qbx_centers, @@ -382,7 +382,7 @@ def __call__(self, queue, **kwargs): from sumpy.tools import is_obj_array_like qbx_centers = kwargs.pop("qbx_centers") - return self.get_cached_optimized_kernel( + return self.get_cached_kernel_executor( is_centers_obj_array=is_obj_array_like(qbx_centers), )(queue, centers=centers, qbx_centers=qbx_centers, @@ -499,7 +499,7 @@ def __call__(self, queue, **kwargs): qbx_centers = kwargs.pop("qbx_centers") from sumpy.tools import is_obj_array_like - return self.get_cached_optimized_kernel( + return self.get_cached_kernel_executor( is_targets_obj_array=is_obj_array_like(targets), is_centers_obj_array=is_obj_array_like(qbx_centers), )(queue, targets=targets, qbx_centers=qbx_centers, **kwargs) diff --git a/pytential/unregularized.py b/pytential/unregularized.py index 08239a2d9..a8f0902a3 100644 --- a/pytential/unregularized.py +++ b/pytential/unregularized.py @@ -331,7 +331,9 @@ def copy_targets_kernel(self): knl = lp.tag_array_axes(knl, "points", "sep, C") knl = lp.tag_array_axes(knl, "targets", "stride:auto, stride:1") - return lp.tag_inames(knl, {"dim": "ilp"}) + knl = lp.tag_inames(knl, {"dim": "ilp"}) + + return knl.executor(self.cl_context) @property @memoize_method From d3018f3254a36fdbd0589fcddc771b84ee8a3916 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 26 Jul 2023 19:41:59 -0500 Subject: [PATCH 3/5] Add a pytest teardown_function in an effort to save memory --- pytential/utils.py | 26 ++++++++++++++++++++++++++ test/test_beltrami.py | 3 +++ test/test_cost_model.py | 4 +++- test/test_global_qbx.py | 3 +++ test/test_layer_pot.py | 17 +++++------------ test/test_layer_pot_eigenvalues.py | 3 +++ test/test_layer_pot_identity.py | 7 +++---- test/test_linalg_proxy.py | 3 +++ test/test_linalg_skeletonization.py | 3 +++ test/test_linalg_utils.py | 3 +++ test/test_matrix.py | 19 +++---------------- test/test_maxwell.py | 3 +++ test/test_scalar_int_eq.py | 7 +++---- test/test_stokes.py | 3 +++ test/test_symbolic.py | 3 +++ test/test_target_specific_qbx.py | 3 +++ test/test_tools.py | 3 +++ 17 files changed, 76 insertions(+), 37 deletions(-) diff --git a/pytential/utils.py b/pytential/utils.py index 1863a30fd..99613f249 100644 --- a/pytential/utils.py +++ b/pytential/utils.py @@ -1,5 +1,6 @@ __copyright__ = """ Copyright (C) 2020 Matt Wala +Copyright (C) 2023 University of Illinois Board of Trustees """ __license__ = """ @@ -22,6 +23,8 @@ THE SOFTWARE. """ +import sys + def sort_arrays_together(*arys, key=None): """Sort a sequence of arrays by considering them @@ -32,4 +35,27 @@ def sort_arrays_together(*arys, key=None): """ return zip(*sorted(zip(*arys), key=key)) + +def pytest_teardown_function(): + from pyopencl.tools import clear_first_arg_caches + clear_first_arg_caches() + + from sympy.core.cache import clear_cache + clear_cache() + + import sumpy + sumpy.code_cache.clear_in_mem_cache() + + from loopy import clear_in_mem_caches + clear_in_mem_caches() + + import gc + gc.collect() + + if sys.platform.startswith("linux"): + import ctypes + libc = ctypes.CDLL("libc.so.6") + libc.malloc_trim(0) + + # vim: foldmethod=marker diff --git a/test/test_beltrami.py b/test/test_beltrami.py index 4d9908eb0..e61a98001 100644 --- a/test/test_beltrami.py +++ b/test/test_beltrami.py @@ -38,6 +38,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_cost_model.py b/test/test_cost_model.py index c3ae726c7..384761cfb 100644 --- a/test/test_cost_model.py +++ b/test/test_cost_model.py @@ -36,7 +36,6 @@ from pytential.qbx.cost import ( QBXCostModel, _PythonQBXCostModel, make_pde_aware_translation_cost_model ) - from meshmode import _acf # noqa: F401 from arraycontext import pytest_generate_tests_for_array_contexts from meshmode.array_context import PytestPyOpenCLArrayContextFactory @@ -44,6 +43,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_global_qbx.py b/test/test_global_qbx.py index ae88c920b..86f43c00f 100644 --- a/test/test_global_qbx.py +++ b/test/test_global_qbx.py @@ -45,6 +45,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_layer_pot.py b/test/test_layer_pot.py index 409eedea2..8227b93e2 100644 --- a/test/test_layer_pot.py +++ b/test/test_layer_pot.py @@ -1,3 +1,5 @@ +from __future__ import annotations + __copyright__ = "Copyright (C) 2013 Andreas Kloeckner" __license__ = """ @@ -38,6 +40,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) @@ -82,10 +87,6 @@ def test_off_surface_eval(actx_factory, use_fmm, visualize=False): actx = actx_factory() - # prevent cache 'splosion - from sympy.core.cache import clear_cache - clear_cache() - nelements = 30 target_order = 8 qbx_order = 3 @@ -149,10 +150,6 @@ def test_off_surface_eval_vs_direct(actx_factory, do_plot=False): actx = actx_factory() - # prevent cache 'splosion - from sympy.core.cache import clear_cache - clear_cache() - nelements = 300 target_order = 8 qbx_order = 3 @@ -235,10 +232,6 @@ def test_single_plus_double_with_single_fmm(actx_factory, do_plot=False): actx = actx_factory() - # prevent cache 'splosion - from sympy.core.cache import clear_cache - clear_cache() - nelements = 300 target_order = 8 qbx_order = 3 diff --git a/test/test_layer_pot_eigenvalues.py b/test/test_layer_pot_eigenvalues.py index 6e2b47b4c..07fb010e5 100644 --- a/test/test_layer_pot_eigenvalues.py +++ b/test/test_layer_pot_eigenvalues.py @@ -37,6 +37,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_layer_pot_identity.py b/test/test_layer_pot_identity.py index 4422d68a0..01b132e0b 100644 --- a/test/test_layer_pot_identity.py +++ b/test/test_layer_pot_identity.py @@ -39,6 +39,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) @@ -234,10 +237,6 @@ def test_identity_convergence(actx_factory, case, visualize=False): actx = actx_factory() - # prevent cache 'splosion - from sympy.core.cache import clear_cache - clear_cache() - target_order = 8 from pytools.convergence import EOCRecorder diff --git a/test/test_linalg_proxy.py b/test/test_linalg_proxy.py index 3acb87aea..99029b63d 100644 --- a/test/test_linalg_proxy.py +++ b/test/test_linalg_proxy.py @@ -40,6 +40,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_linalg_skeletonization.py b/test/test_linalg_skeletonization.py index b3b181b39..346d13ee9 100644 --- a/test/test_linalg_skeletonization.py +++ b/test/test_linalg_skeletonization.py @@ -40,6 +40,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_linalg_utils.py b/test/test_linalg_utils.py index 7309f21f4..05d94a225 100644 --- a/test/test_linalg_utils.py +++ b/test/test_linalg_utils.py @@ -32,6 +32,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_matrix.py b/test/test_matrix.py index 3151cbfba..3ab15ad47 100644 --- a/test/test_matrix.py +++ b/test/test_matrix.py @@ -43,6 +43,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) @@ -76,10 +79,6 @@ def test_build_matrix(actx_factory, k, curve_fn, op_type, visualize=False): actx = actx_factory() - # prevent cache 'splosion - from sympy.core.cache import clear_cache - clear_cache() - case = extra.CurveTestCase( name="curve", knl_class_or_helmholtz_k=k, @@ -196,10 +195,6 @@ def test_build_matrix_conditioning(actx_factory, side, op_type, visualize=False) actx = actx_factory() - # prevent cache explosion - from sympy.core.cache import clear_cache - clear_cache() - case = extra.CurveTestCase( name="ellipse", curve_fn=lambda t: ellipse(3.0, t), @@ -306,10 +301,6 @@ def test_cluster_builder(actx_factory, ambient_dim, actx = actx_factory() - # prevent cache explosion - from sympy.core.cache import clear_cache - clear_cache() - if ambient_dim == 2: case = extra.CurveTestCase( name="ellipse", @@ -425,10 +416,6 @@ def test_build_matrix_fixed_stage(actx_factory, actx = actx_factory() - # prevent cache explosion - from sympy.core.cache import clear_cache - clear_cache() - case = extra.CurveTestCase( name="starfish", curve_fn=NArmedStarfish(5, 0.25), diff --git a/test/test_maxwell.py b/test/test_maxwell.py index 88750a82e..2ae5a782e 100644 --- a/test/test_maxwell.py +++ b/test/test_maxwell.py @@ -39,6 +39,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_scalar_int_eq.py b/test/test_scalar_int_eq.py index 38f61d72c..fa6bb7481 100644 --- a/test/test_scalar_int_eq.py +++ b/test/test_scalar_int_eq.py @@ -42,6 +42,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) @@ -477,10 +480,6 @@ def test_integral_equation(actx_factory, case, visualize=False): actx = actx_factory() - # prevent cache 'splosion - from sympy.core.cache import clear_cache - clear_cache() - from pytools.convergence import EOCRecorder logger.info("\n%s", str(case)) diff --git a/test/test_stokes.py b/test/test_stokes.py index d1446fbbf..989bd872f 100644 --- a/test/test_stokes.py +++ b/test/test_stokes.py @@ -40,6 +40,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_symbolic.py b/test/test_symbolic.py index 28eb887cf..f9e447eb3 100644 --- a/test/test_symbolic.py +++ b/test/test_symbolic.py @@ -40,6 +40,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_target_specific_qbx.py b/test/test_target_specific_qbx.py index d6c544842..45b8ccdb0 100644 --- a/test/test_target_specific_qbx.py +++ b/test/test_target_specific_qbx.py @@ -35,6 +35,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) diff --git a/test/test_tools.py b/test/test_tools.py index 7f795a2ed..757b449c2 100644 --- a/test/test_tools.py +++ b/test/test_tools.py @@ -33,6 +33,9 @@ import logging logger = logging.getLogger(__name__) +from pytential.utils import ( # noqa: F401 + pytest_teardown_function as teardown_function) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ PytestPyOpenCLArrayContextFactory, ]) From e478085f0a505a7187601512abf7e1919019386e Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 26 Jul 2023 19:42:32 -0500 Subject: [PATCH 4/5] Remove a debug print in test_single_plus_double_with_single_fmm --- test/test_layer_pot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_layer_pot.py b/test/test_layer_pot.py index 8227b93e2..b5a3950c9 100644 --- a/test/test_layer_pot.py +++ b/test/test_layer_pot.py @@ -292,7 +292,6 @@ def test_single_plus_double_with_single_fmm(actx_factory, do_plot=False): fmm_sigma = fmm_density_discr.zeros(actx) + 1 fmm_bound_op = bind(places, op, auto_where=("fmm_qbx", "target")) - print(fmm_bound_op.code) fmm_fld_in_vol = fmm_bound_op(actx, sigma=fmm_sigma) err = actx.np.fabs(fmm_fld_in_vol - direct_fld_in_vol) From d36078870cbe26252c1b72be3e1750227c533827 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 26 Jul 2023 19:42:51 -0500 Subject: [PATCH 5/5] Gently bump tolerance in test_off_surface_eval --- test/test_layer_pot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_layer_pot.py b/test/test_layer_pot.py index b5a3950c9..010ddfd25 100644 --- a/test/test_layer_pot.py +++ b/test/test_layer_pot.py @@ -138,7 +138,7 @@ def test_off_surface_eval(actx_factory, use_fmm, visualize=False): pt.colorbar() pt.show() - assert linf_err < 1e-3 + assert linf_err < 2e-3 # }}}