From 41074ae9df5e0f8eedd5064a9274f6fc3b9633a3 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 22 Feb 2018 14:39:52 -0600 Subject: [PATCH 1/3] Improve max-level error message (Closes #22) --- boxtree/tree_build.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 2566dc4..42bc3bd 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -540,8 +540,12 @@ class TreeBuilder(object): assert level == len(level_used_box_counts) assert level == len(level_leaf_counts) - if level > np.iinfo(self.box_level_dtype).max: - raise RuntimeError("level count exceeded maximum") + assert np.iinfo(self.box_level_dtype).max >= np.finfo(coord_dtype).mnant + if level > np.finfo(coord_dtype).nmant: + raise RuntimeError("Level count exceeded number of significant " + "bits in coordinate dtype. That means that a large number " + "of particles was indistinguishable up to floating point " + "precision (because they ended up in the same box).") common_args = ((morton_bin_counts, morton_nrs, box_start_flags, -- GitLab From 81d56c9a342983c57c6ab93644fa7d347c56680c Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 22 Feb 2018 15:14:34 -0600 Subject: [PATCH 2/3] Fix max-levels error, add test --- boxtree/tree_build.py | 8 ++++++-- test/test_tree.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 42bc3bd..3fec8dc 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -36,6 +36,10 @@ import logging logger = logging.getLogger(__name__) +class MaxLevelsExceeded(RuntimeError): + pass + + class TreeBuilder(object): def __init__(self, context): """ @@ -540,9 +544,9 @@ class TreeBuilder(object): assert level == len(level_used_box_counts) assert level == len(level_leaf_counts) - assert np.iinfo(self.box_level_dtype).max >= np.finfo(coord_dtype).mnant + assert np.iinfo(self.box_level_dtype).max >= np.finfo(coord_dtype).nmant if level > np.finfo(coord_dtype).nmant: - raise RuntimeError("Level count exceeded number of significant " + raise MaxLevelsExceeded("Level count exceeded number of significant " "bits in coordinate dtype. That means that a large number " "of particles was indistinguishable up to floating point " "precision (because they ended up in the same box).") diff --git a/test/test_tree.py b/test/test_tree.py index f68a885..cf5e110 100644 --- a/test/test_tree.py +++ b/test/test_tree.py @@ -1122,6 +1122,25 @@ def test_same_tree_with_zero_weight_particles(ctx_factory, dims): # }}} +# {{{ test_max_levels_error + +def test_max_levels_error(ctx_factory): + ctx = ctx_factory() + queue = cl.CommandQueue(ctx) + + from boxtree import TreeBuilder + tb = TreeBuilder(ctx) + + logging.basicConfig(level=logging.INFO) + + sources = [cl.array.zeros(queue, 11, float) for i in range(2)] + from boxtree.tree_build import MaxLevelsExceeded + with pytest.raises(MaxLevelsExceeded): + tree, _ = tb(queue, sources, max_particles_in_box=10, debug=True) + +# }}} + + # You can test individual routines by typing # $ python test_tree.py 'test_routine(cl.create_some_context)' -- GitLab From 667cf7e63de6be8a433ead447178b397d718752e Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 22 Feb 2018 15:22:15 -0600 Subject: [PATCH 3/3] Improve nmax_levels logic --- boxtree/tree_build.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 3fec8dc..b03c336 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -458,7 +458,8 @@ class TreeBuilder(object): queue, box_parent_ids.data, np.zeros((), dtype=box_parent_ids.dtype)) prep_events.append(evt) - nlevels_max = np.iinfo(self.box_level_dtype).max + nlevels_max = np.finfo(coord_dtype).nmant + 1 # num bits in the significand + assert nlevels_max <= np.iinfo(self.box_level_dtype).max # level -> starting box on level level_start_box_nrs_dev, evt = zeros(nlevels_max, dtype=box_id_dtype) @@ -544,8 +545,7 @@ class TreeBuilder(object): assert level == len(level_used_box_counts) assert level == len(level_leaf_counts) - assert np.iinfo(self.box_level_dtype).max >= np.finfo(coord_dtype).nmant - if level > np.finfo(coord_dtype).nmant: + if level + 1 >= nlevels_max: # level is zero-based raise MaxLevelsExceeded("Level count exceeded number of significant " "bits in coordinate dtype. That means that a large number " "of particles was indistinguishable up to floating point " -- GitLab