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))