From 38f77a0c6269148413658f05bd9f22213c60da03 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 21 Jul 2024 16:49:00 +0300 Subject: [PATCH 1/4] pyproject: move project metadata --- pyproject.toml | 78 ++++++++++++++++++++++++++++++++++++++++++++++---- setup.py | 54 ---------------------------------- 2 files changed, 73 insertions(+), 59 deletions(-) delete mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml index 94e5369d..1ed81968 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,74 @@ +[build-system] +build-backend = "setuptools.build_meta" +requires = [ + "setuptools>=63", +] + +[project] +name = "boxtree" +version = "2023.1" +description = "Quadtree/octree building in Python and OpenCL" +readme = "README.rst" +license = { text = "MIT" } +authors = [ + { name = "Andreas Kloeckner", email = "inform@tiker.net" }, +] +requires-python = ">=3.8" +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Other Audience", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Scientific/Engineering :: Visualization", + "Topic :: Software Development :: Libraries", + "Topic :: Utilities", +] +dependencies = [ + "arraycontext>=2021.1", + "cgen>=2020.1", + "mako", + "pymbolic>=2022.2", + "pyopencl>=2022.1", + "pytools>=2022.1", +] + +[project.optional-dependencies] +doc = [ + "furo", + "sphinx-copybutton", + "sphinx>=4", +] +fmmlib = [ + "pyfmmlib>=2023.1", +] +meshmode = [ + "loopy>=2024.1", + "meshmode>=2021.2", + "modepy>=2021.1", +] +test = [ + "pylint", + "pytest", + "ruff", +] + +[project.urls] +Documentation = "https://documen.tician.de/boxtree" +Repository = "https://github.com/inducer/boxtree" + +[tool.setuptools.packages.find] +include = [ + "boxtree*", +] + [tool.ruff] -target-version = "py38" preview = true [tool.ruff.lint] @@ -65,7 +134,6 @@ extend-ignore-re = [ [tool.typos.default.extend-words] # arange like np.arange arange = "arange" - # as in mis-implements mis = "mis" @@ -78,7 +146,7 @@ extend-exclude = [ [tool.pytest.ini_options] markers = [ "opencl: uses OpenCL", - "geo_lookup: test geometric lookups", - "area_query: test area queries", - "mpi: test distributed FMM", + "geo_lookup: tests geometric lookups", + "area_query: tests area queries", + "mpi: tests distributed FMM", ] diff --git a/setup.py b/setup.py deleted file mode 100644 index 1f8158a6..00000000 --- a/setup.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python - - -def main(): - from setuptools import find_packages, setup - - version_dict = {} - version_filename = "boxtree/version.py" - with open(version_filename) as version_file: - exec(compile(version_file.read(), version_filename, "exec"), version_dict) - - setup( - name="boxtree", - version=version_dict["VERSION_TEXT"], - description="Quadtree/octree building in Python and OpenCL", - long_description=open("README.rst").read(), - author="Andreas Kloeckner", - author_email="inform@tiker.net", - license="MIT", - url="https://documen.tician.de/boxtree/", - classifiers=[ - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Intended Audience :: Other Audience", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: MIT License", - "Natural Language :: English", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Information Analysis", - "Topic :: Scientific/Engineering :: Mathematics", - "Topic :: Scientific/Engineering :: Visualization", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities", - ], - packages=find_packages(), - python_requires="~=3.8", - install_requires=[ - "Mako>=0.7.3", - - "pytools>=2018.4", - "pyopencl>=2018.2.2", - "cgen>=2013.1.2", - "arraycontext>=2021.1", - ], - extras_require={ - "test": ["pytest>=2.3"], - }, - ) - - -if __name__ == "__main__": - main() From b571e9b5e6d2c15e814ea6ddc6af161609c74f26 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 21 Jul 2024 16:51:11 +0300 Subject: [PATCH 2/4] version: use importlib --- boxtree/version.py | 17 +++++++++++++++-- doc/conf.py | 14 ++++---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/boxtree/version.py b/boxtree/version.py index 0f73bd5f..2f4b987f 100644 --- a/boxtree/version.py +++ b/boxtree/version.py @@ -1,2 +1,15 @@ -VERSION = (2023, 1) -VERSION_TEXT = ".".join(str(i) for i in VERSION) +from importlib import metadata +from typing import Tuple + + +def _parse_version(version: str) -> Tuple[Tuple[int, ...], str]: + import re + + m = re.match("^([0-9.]+)([a-z0-9]*?)$", VERSION_TEXT) + assert m is not None + + return tuple(int(nr) for nr in m.group(1).split(".")), m.group(2) + + +VERSION_TEXT = metadata.version("boxtree") +VERSION, VERSION_STATUS = _parse_version(VERSION_TEXT) diff --git a/doc/conf.py b/doc/conf.py index 6e264555..dea65bb4 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,3 +1,5 @@ +import sys +from importlib import metadata from urllib.request import urlopen @@ -7,13 +9,8 @@ exec(compile(_inf.read(), _conf_url, "exec"), globals()) copyright = "2013-21, Andreas Kloeckner" - -ver_dic = {} -exec(compile(open("../boxtree/version.py").read(), "../boxtree/version.py", "exec"), - ver_dic) -version = ".".join(str(x) for x in ver_dic["VERSION"]) -# The full version, including alpha/beta/rc tags. -release = ver_dic["VERSION_TEXT"] +release = metadata.version("boxtree") +version = ".".join(release.split(".")[:2]) intersphinx_mapping = { "arraycontext": ("https://documen.tician.de/arraycontext", None), @@ -37,7 +34,4 @@ # docstring can be read by sphinx when building meshmode, a dependent package), # this needs a setting of the same name across all packages involved, that's # why this name is as global-sounding as it is. -import sys - - sys._BUILDING_SPHINX_DOCS = True From 1550bf41bbc052dbd01c5b3cb70682c89946e23c Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 21 Jul 2024 16:54:08 +0300 Subject: [PATCH 3/4] MANIFEST: ignore git files --- MANIFEST.in | 18 ++++++++---------- doc/.gitignore | 1 - examples/.gitignore | 1 - 3 files changed, 8 insertions(+), 12 deletions(-) delete mode 100644 doc/.gitignore delete mode 100644 examples/.gitignore diff --git a/MANIFEST.in b/MANIFEST.in index d8a72e19..90194e9a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,14 +1,12 @@ -include test/*.py -include examples/*.py - +include doc/*.sh include doc/*.rst -include doc/Makefile -include doc/*.py +include doc/*.tikz include doc/images/*.png -include doc/_static/*.css -include doc/_templates/*.html +include doc/Makefile -include configure.py -include Makefile.in +include LICENSE include README.rst -include requirements.txt + +prune .github +exclude .gitlab-ci.yml +exclude .gitignore diff --git a/doc/.gitignore b/doc/.gitignore deleted file mode 100644 index e35d8850..00000000 --- a/doc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_build diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index e33609d2..00000000 --- a/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.png From e778a631c54cdb83e05ab51850074613fb1ba263 Mon Sep 17 00:00:00 2001 From: Alexandru Fikl Date: Sun, 21 Jul 2024 19:11:08 +0300 Subject: [PATCH 4/4] ruff: enable and fix remaining rules --- boxtree/bounding_box.py | 6 +---- boxtree/cost.py | 6 +---- boxtree/distributed/__init__.py | 6 +---- boxtree/pyfmmlib_integration.py | 16 ++++--------- boxtree/tools.py | 9 +++---- boxtree/tree.py | 2 +- boxtree/tree_build.py | 23 ++++++------------ boxtree/tree_build_kernels.py | 2 +- boxtree/visualization.py | 8 +++++-- examples/cost_model.py | 8 ++++--- pyproject.toml | 25 +++++++++----------- test/test_cost_model.py | 6 +++-- test/test_distributed.py | 42 ++++++++++++++++----------------- test/test_fmm.py | 18 ++++---------- test/test_tools.py | 5 ++-- test/test_traversal.py | 2 +- test/test_tree_of_boxes.py | 5 ++-- 17 files changed, 77 insertions(+), 112 deletions(-) diff --git a/boxtree/bounding_box.py b/boxtree/bounding_box.py index 550586be..c38fd1e4 100644 --- a/boxtree/bounding_box.py +++ b/boxtree/bounding_box.py @@ -158,11 +158,7 @@ def __call__(self, particles, radii, wait_for=None): from pytools import single_valued coord_dtype = single_valued(coord.dtype for coord in particles) - if radii is None: - radii_tuple = () - else: - radii_tuple = (radii,) - + radii_tuple = () if radii is None else (radii,) knl = self.get_kernel(dimensions, coord_dtype, # have_radii: radii is not None) diff --git a/boxtree/cost.py b/boxtree/cost.py index f3641d2d..0b29c03f 100644 --- a/boxtree/cost.py +++ b/boxtree/cost.py @@ -154,11 +154,7 @@ def make_pde_aware_translation_cost_model(dim, nlevels): p_fmm = np.array([var("p_fmm_lev%d" % i) for i in range(nlevels)]) ncoeffs_fmm = (p_fmm + 1) ** (dim - 1) - if dim == 3: - uses_point_and_shoot = True - else: - uses_point_and_shoot = False - + uses_point_and_shoot = dim == 3 return FMMTranslationCostModel( ncoeffs_fmm_by_level=ncoeffs_fmm, uses_point_and_shoot=uses_point_and_shoot diff --git a/boxtree/distributed/__init__.py b/boxtree/distributed/__init__.py index 9eeed5c7..495a47a6 100644 --- a/boxtree/distributed/__init__.py +++ b/boxtree/distributed/__init__.py @@ -197,11 +197,7 @@ def make_distributed_wrangler( global_trav_dev, _ = traversal_builder(queue, global_tree_dev) global_trav_host = global_trav_dev.get(queue) - - if tree_in_device_memory: - global_trav = global_trav_dev - else: - global_trav = global_trav_host + global_trav = global_trav_dev if tree_in_device_memory else global_trav_host # }}} diff --git a/boxtree/pyfmmlib_integration.py b/boxtree/pyfmmlib_integration.py index d566d003..df44dc7c 100644 --- a/boxtree/pyfmmlib_integration.py +++ b/boxtree/pyfmmlib_integration.py @@ -213,10 +213,8 @@ def wrapper(*args, **kwargs): def wrapper(*args, **kwargs): kwargs["iffld"] = self.ifgrad pot, fld = rout(*args, **kwargs) - if self.ifgrad: - grad = -fld - else: - grad = 0 + grad = -fld if self.ifgrad else 0 + return pot, grad # Doesn't work in in Py2 @@ -254,11 +252,7 @@ def wrapper(*args, **kwargs): if (ier != 0).any(): raise RuntimeError(f"{name} failed with nonzero ier") - if self.ifgrad: - grad = -fld - else: - grad = 0 - + grad = -fld if self.ifgrad else 0 return pot, grad # Doesn't work in in Py2 @@ -604,11 +598,11 @@ def mem_estimate(order): ier, rotmatf = ( rotmat_builder(rotmat_order, m2l_rotation_angles)) - assert (0 == ier).all() + assert (ier == 0).all() ier, rotmatb = ( rotmat_builder(rotmat_order, -m2l_rotation_angles)) - assert (0 == ier).all() + assert (ier == 0).all() return (rotmatf, rotmatb, rotmat_order) diff --git a/boxtree/tools.py b/boxtree/tools.py index 55b2ce6d..91505cc7 100644 --- a/boxtree/tools.py +++ b/boxtree/tools.py @@ -51,7 +51,7 @@ def realloc_array(queue, allocator, new_shape, ary, zero_fill=False, wait_for=No if wait_for is None: wait_for = [] - if zero_fill: + if zero_fill: # noqa: SIM108 array_maker = cl.array.zeros else: array_maker = cl.array.empty @@ -491,7 +491,7 @@ def __call__(self, queue, allocator, new_shape, ary, src_indices=None, if debug: assert int(cl.array.max(dst_indices).get()) < new_shape - if zero_fill: + if zero_fill: # noqa: SIM108 array_maker = cl.array.zeros else: array_maker = cl.array.empty @@ -897,10 +897,7 @@ def with_queue(self, queue): def svm_capable(self): svm_capabilities = \ self.queue.device.get_info(cl.device_info.SVM_CAPABILITIES) - if svm_capabilities & cl.device_svm_capabilities.FINE_GRAIN_BUFFER != 0: - return True - else: - return False + return svm_capabilities & cl.device_svm_capabilities.FINE_GRAIN_BUFFER != 0 @property def host(self): diff --git a/boxtree/tree.py b/boxtree/tree.py index 70209e52..e7764431 100644 --- a/boxtree/tree.py +++ b/boxtree/tree.py @@ -892,7 +892,7 @@ def link_point_sources(queue, tree, point_source_starts, point_sources, tree_attrs = {} for attr_name in tree.__class__.fields: - try: + try: # noqa: SIM105 tree_attrs[attr_name] = getattr(tree, attr_name) except AttributeError: pass diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index e1e84b02..381d6b8f 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -175,10 +175,7 @@ def __call__(self, queue, particles, kind="adaptive", raise ValueError(f"unknown tree kind '{kind}'") # we'll modify this below, so copy it - if wait_for is None: - wait_for = [] - else: - wait_for = list(wait_for) + wait_for = [] if wait_for is None else list(wait_for) dimensions = len(particles) @@ -301,10 +298,7 @@ def zeros(shape, dtype): "dtype") def combine_srcntgt_arrays(ary1, ary2=None): - if ary2 is None: - dtype = ary1.dtype - else: - dtype = ary2.dtype + dtype = ary1.dtype if ary2 is None else ary2.dtype result = empty(nsrcntgts, dtype) if (ary1 is None) or (ary2 is None): @@ -365,7 +359,7 @@ def combine_srcntgt_arrays(ary1, ary2=None): event, = refine_weights.events prep_events.append(event) max_leaf_refine_weight = max_particles_in_box - elif specified_refine_weights: + elif specified_refine_weights: # noqa: SIM102 if refine_weights.dtype != refine_weight_dtype: raise TypeError( f"refine_weights must have dtype '{refine_weight_dtype}'") @@ -373,7 +367,7 @@ def combine_srcntgt_arrays(ary1, ary2=None): if max_leaf_refine_weight < cl.array.max(refine_weights).get(): raise ValueError( "entries of refine_weights cannot exceed max_leaf_refine_weight") - if 0 > cl.array.min(refine_weights).get(): + if cl.array.min(refine_weights).get() < 0: raise ValueError("all entries of refine_weights must be nonnegative") if max_leaf_refine_weight <= 0: raise ValueError("max_leaf_refine_weight must be positive") @@ -607,10 +601,7 @@ def fin_debug(s): tree_build_proc = ProcessLogger(logger, "tree build") - if total_refine_weight > max_leaf_refine_weight: - level = 1 - else: - level = 0 + level = 1 if total_refine_weight > max_leaf_refine_weight else 0 # INVARIANTS -- Upon entry to this loop: # @@ -1461,7 +1452,7 @@ def make_arange(start, offset=level_used_box_count): wait_for=wait_for) wait_for = [evt] - if srcntgts_have_extent: + if srcntgts_have_extent: # noqa: SIM102 if debug: assert ( box_srcntgt_counts_nonchild.get() @@ -1471,7 +1462,7 @@ def make_arange(start, offset=level_used_box_count): if debug: usi_host = user_source_ids.get() assert (usi_host < nsources).all() - assert (0 <= usi_host).all() + assert (usi_host >= 0).all() del usi_host sti_host = srcntgt_target_ids.get() diff --git a/boxtree/tree_build_kernels.py b/boxtree/tree_build_kernels.py index 3f83e389..c7b89295 100644 --- a/boxtree/tree_build_kernels.py +++ b/boxtree/tree_build_kernels.py @@ -1393,7 +1393,7 @@ def get_tree_build_kernel_info(context, dimensions, coord_dtype, """ level_restrict = (kind == "adaptive-level-restricted") - adaptive = not (kind == "non-adaptive") + adaptive = (kind != "non-adaptive") # {{{ preparation diff --git a/boxtree/visualization.py b/boxtree/visualization.py index 4d467dab..445e3bb1 100644 --- a/boxtree/visualization.py +++ b/boxtree/visualization.py @@ -171,6 +171,10 @@ def get_tikz_for_tree(self): # {{{ traversal plotting def _draw_box_list(tree_plotter, ibox, starts, lists, key_to_box=None, **kwargs): + rng = kwargs.pop("rng", None) + if rng is None: + rng = np.random.default_rng() + default_facecolor = "blue" if key_to_box is not None: @@ -183,7 +187,7 @@ def _draw_box_list(tree_plotter, ibox, starts, lists, key_to_box=None, **kwargs) "edgecolor": getattr(kwargs, "facecolor", default_facecolor), "fill": False, "alpha": 0.5, - "shrink_factor": -0.1+0.1*np.random.rand(), + "shrink_factor": -0.1+0.1*rng.random(), } tree_plotter.draw_box(ibox, **actual_kwargs) return @@ -198,7 +202,7 @@ def _draw_box_list(tree_plotter, ibox, starts, lists, key_to_box=None, **kwargs) "facecolor": default_facecolor, "linewidth": 0, "alpha": 0.5, - "shrink_factor": 0.1 + np.random.rand()*0.2, + "shrink_factor": 0.1 + rng.random()*0.2, } actual_kwargs.update(kwargs) print(actual_kwargs["facecolor"], ibox, lists[start:end]) diff --git a/examples/cost_model.py b/examples/cost_model.py index 05d942cf..1ba73850 100644 --- a/examples/cost_model.py +++ b/examples/cost_model.py @@ -32,6 +32,7 @@ def demo_cost_model(): Kernel, ) + rng = np.random.default_rng(seed=42) nsources_list = [1000, 2000, 3000, 4000, 5000] ntargets_list = [1000, 2000, 3000, 4000, 5000] dims = 3 @@ -56,8 +57,9 @@ def fmm_level_to_order(tree, ilevel): targets = p_normal(queue, ntargets, dims, dtype, seed=18) from pyopencl.clrandom import PhiloxGenerator - rng = PhiloxGenerator(queue.context, seed=22) - target_radii = rng.uniform( + + clrng = PhiloxGenerator(queue.context, seed=22) + target_radii = clrng.uniform( queue, ntargets, a=0, b=0.05, dtype=dtype ).get() @@ -90,7 +92,7 @@ def fmm_level_to_order(tree, ilevel): timing_data = {} from boxtree.fmm import drive_fmm - src_weights = np.random.rand(tree.nsources).astype(tree.coord_dtype) + src_weights = rng.random(size=tree.nsources, dtype=tree.coord_dtype) drive_fmm(wrangler, (src_weights,), timing_data=timing_data) timing_results.append(timing_data) diff --git a/pyproject.toml b/pyproject.toml index 1ed81968..52ec0338 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,25 +78,21 @@ extend-select = [ "E", # pycodestyle "F", # pyflakes "G", # flake8-logging-format + "I", # flake8-isort "N", # pep8-naming "NPY", # numpy "Q", # flake8-quotes - "I", # flake8-isort - "UP", # pyupgrade "RUF", # ruff - - # TODO - # "W", # pycodestyle - # "SIM", + "SIM", # flake8-simplify + "UP", # pyupgrade + "W", # pycodestyle ] extend-ignore = [ "C90", # McCabe complexity "E221", # multiple spaces before operator "E226", # missing whitespace around arithmetic operator "E402", # module-level import not at top of file - - # TODO - "NPY002", # legacy numpy rng + "SIM223", # simplify `False and ...` conditional ] [tool.ruff.lint.flake8-quotes] @@ -119,12 +115,13 @@ known-local-folder = [ "boxtree", ] lines-after-imports = 2 -# required-imports = ["from __future__ import annotations"] -[tool.ruff.lint.per-file-ignores] -"doc/**/*.py" = ["I002"] -"examples/**/*.py" = ["I002"] -"setup.py" = ["I002"] +# TODO: enable postponed annotations at some point +# required-imports = ["from __future__ import annotations"] +# [tool.ruff.lint.per-file-ignores] +# "doc/**/*.py" = ["I002"] +# "examples/**/*.py" = ["I002"] +# "setup.py" = ["I002"] [tool.typos.default] extend-ignore-re = [ diff --git a/test/test_cost_model.py b/test/test_cost_model.py index df80527a..985a408f 100644 --- a/test/test_cost_model.py +++ b/test/test_cost_model.py @@ -383,6 +383,8 @@ def test_estimate_calibration_params(actx_factory): Kernel, ) + rng = np.random.default_rng(seed=42) + nsources_list = [1000, 2000, 3000, 4000] ntargets_list = [1000, 2000, 3000, 4000] dims = 3 @@ -437,7 +439,7 @@ def fmm_level_to_order(tree, ilevel): timing_data = {} from boxtree.fmm import drive_fmm - src_weights = np.random.rand(tree.nsources).astype(tree.coord_dtype) + src_weights = rng.random(size=tree.nsources, dtype=tree.coord_dtype) drive_fmm(wrangler, (src_weights,), timing_data=timing_data) timing_results.append(timing_data) @@ -564,7 +566,7 @@ def test_cost_model_op_counts_agree_with_constantone_wrangler( timing_data = {} from boxtree.fmm import drive_fmm - src_weights = np.random.rand(tree.nsources).astype(tree.coord_dtype) + src_weights = rng.random(size=tree.nsources, dtype=tree.coord_dtype) drive_fmm(wrangler, (src_weights,), timing_data=timing_data) cost_model = FMMCostModel( diff --git a/test/test_distributed.py b/test/test_distributed.py index 28b81b03..ce975926 100644 --- a/test/test_distributed.py +++ b/test/test_distributed.py @@ -173,13 +173,13 @@ def test_against_shared( from boxtree.tools import run_mpi run_mpi(__file__, num_processes, { - "PYTEST": "shared", - "dims": dims, - "nsources": nsources, - "ntargets": ntargets, "OMP_NUM_THREADS": 1, - "tmp_cache_basedir": tmp_path / "boxtree_distributed_test", - "communicate_mpoles_via_allreduce": communicate_mpoles_via_allreduce + "_BOXTREE_TEST_NAME": "shared", + "_BOXTREE_TEST_DIMS": dims, + "_BOXTREE_TEST_NSOURCES": nsources, + "_BOXTREE_TEST_NTARGETS": ntargets, + "_BOXTREE_TEST_TMP_CACHE_BASEDIR": tmp_path / "boxtree_distributed_test", + "_BOXTREE_TEST_MPOLES_ALLREDUCE": communicate_mpoles_via_allreduce }) # }}} @@ -275,13 +275,13 @@ def test_constantone(tmp_path, num_processes, dims, nsources, ntargets): from boxtree.tools import run_mpi run_mpi(__file__, num_processes, { - "PYTEST": "constantone", - "dims": dims, - "nsources": nsources, - "ntargets": ntargets, "OMP_NUM_THREADS": 1, - "tmp_cache_basedir": tmp_path / "boxtree_distributed_test", - "communicate_mpoles_via_allreduce": False + "_BOXTREE_TEST_NAME": "constantone", + "_BOXTREE_TEST_DIMS": dims, + "_BOXTREE_TEST_NSOURCES": nsources, + "_BOXTREE_TEST_NTARGETS": ntargets, + "_BOXTREE_TEST_TMP_CACHE_BASEDIR": tmp_path / "boxtree_distributed_test", + "_BOXTREE_TEST_MPOLES_ALLREDUCE": False }) # }}} @@ -289,22 +289,22 @@ def test_constantone(tmp_path, num_processes, dims, nsources, ntargets): if __name__ == "__main__": dtype = np.float64 - tmp_cache_basedir = os.environ.get("tmp_cache_basedir", _cachedir()) + tmp_cache_basedir = os.environ.get("_BOXTREE_TEST_TMP_CACHE_BASEDIR", _cachedir()) - if "PYTEST" in os.environ: - dims = int(os.environ["dims"]) - nsources = int(os.environ["nsources"]) - ntargets = int(os.environ["ntargets"]) + if "_BOXTREE_TEST_DIMS" in os.environ: + dims = int(os.environ["_BOXTREE_TEST_DIMS"]) + nsources = int(os.environ["_BOXTREE_TEST_NSOURCES"]) + ntargets = int(os.environ["_BOXTREE_TEST_NTARGETS"]) communicate_mpoles_via_allreduce = ( - True if os.environ["communicate_mpoles_via_allreduce"] == "True" - else False) + os.environ["_BOXTREE_TEST_MPOLES_ALLREDUCE"] == "True" + ) - if os.environ["PYTEST"] == "shared": + if os.environ["_BOXTREE_TEST_NAME"] == "shared": _test_against_shared( tmp_cache_basedir, dims, nsources, ntargets, dtype, communicate_mpoles_via_allreduce=communicate_mpoles_via_allreduce) - elif os.environ["PYTEST"] == "constantone": + elif os.environ["_BOXTREE_TEST_NAME"] == "constantone": _test_constantone(tmp_cache_basedir, dims, nsources, ntargets, dtype) else: if len(sys.argv) > 1: diff --git a/test/test_fmm.py b/test/test_fmm.py index e1ec616d..dccd0d02 100644 --- a/test/test_fmm.py +++ b/test/test_fmm.py @@ -426,16 +426,10 @@ def test_pyfmmlib_fmm(actx_factory, dims, use_dipoles, helmholtz_k): rng = np.random.default_rng(20) weights = rng.uniform(0.0, 1.0, (nsources,)) - if use_dipoles: - np.random.seed(13) - dipole_vec = np.random.randn(dims, nsources) - else: - dipole_vec = None + rng = np.random.default_rng(seed=42) + dipole_vec = rng.normal(size=(dims, nsources)) if use_dipoles else None - if dims == 2 and helmholtz_k == 0: - base_order = 20 - else: - base_order = 10 + base_order = 20 if (dims == 2 and helmholtz_k == 0) else 10 def fmm_level_to_order(tree, lev): result = base_order @@ -608,11 +602,7 @@ def fmm_level_to_order(tree, lev): rel_err = la.norm(pot - ref_pot, np.inf) / la.norm(ref_pot, np.inf) logger.info("relative l2 error vs fmmlib direct: %g", rel_err) - if dims == 2: - error_bound = (1/2) ** (1 + order) - else: - error_bound = (3/4) ** (1 + order) - + error_bound = (1/2) ** (1 + order) if dims == 2 else (3/4) ** (1 + order) assert rel_err < error_bound, rel_err # }}} diff --git a/test/test_tools.py b/test/test_tools.py index 631ad4d5..e75af7f3 100644 --- a/test/test_tools.py +++ b/test/test_tools.py @@ -122,15 +122,14 @@ def test_masked_matrix_compression(actx_factory, order): def test_masked_list_compression(actx_factory): actx = actx_factory() + rng = np.random.default_rng(seed=42) from boxtree.tools import MaskCompressorKernel listcompr = MaskCompressorKernel(actx.context) n = 20 - np.random.seed(15) - - arr = (np.random.rand(n) > 0.5).astype(np.int8) + arr = (rng.random(n) > 0.5).astype(np.int8) d_arr = actx.from_numpy(arr) arr_list, _evt = listcompr(actx.queue, d_arr) diff --git a/test/test_traversal.py b/test/test_traversal.py index 703b6123..3988f46a 100644 --- a/test/test_traversal.py +++ b/test/test_traversal.py @@ -107,7 +107,7 @@ def test_tree_connectivity(actx_factory, dims, sources_are_targets): assert ibox in nbl for jbox in nbl: - assert np.all(0 == children[jbox]), (ibox, jbox, children[jbox]) + assert np.all(children[jbox] == 0), (ibox, jbox, children[jbox]) logger.info("list 1 consists of source boxes") diff --git a/test/test_tree_of_boxes.py b/test/test_tree_of_boxes.py index e671eb9c..33bdefd5 100644 --- a/test/test_tree_of_boxes.py +++ b/test/test_tree_of_boxes.py @@ -98,8 +98,9 @@ def make_global_leaf_quadrature(actx, tob, order): def test_uniform_tree_of_boxes(actx_factory, dim, order, nlevels): actx = actx_factory() - lower_bounds = np.random.rand(dim) - radius = np.random.rand() + 0.1 + rng = np.random.default_rng(seed=42) + lower_bounds = rng.random(dim) + radius = rng.random() + 0.1 upper_bounds = lower_bounds + radius tob = make_tree_of_boxes_root((lower_bounds, upper_bounds))