From 158002f81afd627216d3694f2a4132698d70fef4 Mon Sep 17 00:00:00 2001 From: xywei Date: Thu, 8 Feb 2018 10:03:49 -0600 Subject: [PATCH 1/6] Re-apply changes, with minimal diff (cherry picked from commit d1bce1dcc1206ded0880d861d28387a925a51313) --- boxtree/tree_build.py | 51 +++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 1647bfc..9014fb5 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -83,7 +83,7 @@ class TreeBuilder(object): targets=None, source_radii=None, target_radii=None, stick_out_factor=None, refine_weights=None, max_leaf_refine_weight=None, wait_for=None, - extent_norm=None, + extent_norm=None, bbox=None, **kwargs): """ :arg queue: a :class:`pyopencl.CommandQueue` instance @@ -123,6 +123,10 @@ class TreeBuilder(object): execution. :arg extent_norm: ``"l2"`` or ``"linf"``. Indicates the norm with respect to which particle stick-out is measured. See :attr:`Tree.extent_norm`. + :arg bbox: Bounding box of the same type as returned by + *boxtree.bounding_box.make_bounding_box_dtype*. + When given, this bounding box is used for tree + building. Otherwise, the bounding box is determined from particles. :arg kwargs: Used internally for debugging. :returns: a tuple ``(tree, event)``, where *tree* is an instance of @@ -342,22 +346,45 @@ class TreeBuilder(object): # {{{ find and process bounding box - bbox, _ = self.bbox_finder(srcntgts, srcntgt_radii, wait_for=wait_for) - bbox = bbox.get() + if bbox is None: + bbox, _ = self.bbox_finder(srcntgts, srcntgt_radii, wait_for=wait_for) + bbox = bbox.get() - root_extent = max( + root_extent = max( bbox["max_"+ax] - bbox["min_"+ax] for ax in axis_names) * (1+TreeBuilder.ROOT_EXTENT_STRETCH_FACTOR) - # make bbox square and slightly larger at the top, to ensure scaled - # coordinates are always < 1 - bbox_min = np.empty(dimensions, coord_dtype) - for i, ax in enumerate(axis_names): - bbox_min[i] = bbox["min_"+ax] + # make bbox square and slightly larger at the top, to ensure scaled + # coordinates are always < 1 + bbox_min = np.empty(dimensions, coord_dtype) + for i, ax in enumerate(axis_names): + bbox_min[i] = bbox["min_"+ax] - bbox_max = bbox_min + root_extent - for i, ax in enumerate(axis_names): - bbox["max_"+ax] = bbox_max[i] + bbox_max = bbox_min + root_extent + for i, ax in enumerate(axis_names): + bbox["max_"+ax] = bbox_max[i] + else: + # Validate that bbox is a superset of particle-derived bbox + bbox_auto, _ = self.bbox_finder( + srcntgts, srcntgt_radii, wait_for=wait_for) + bbox_auto = bbox_auto.get() + + bbox_min = np.empty(dimensions, coord_dtype) + bbox_max = np.empty(dimensions, coord_dtype) + + for i, ax in enumerate(axis_names): + bbox_min[i] = bbox["min_" + ax] + bbox_max[i] = bbox["max_" + ax] + assert bbox_min[i] < bbox_max[i] + assert bbox_min[i] <= bbox_auto["min_" + ax] + assert bbox_max[i] >= bbox_auto["max_" + ax] + + # bbox must be a square + bbox_exts = bbox_max - bbox_min + for ext in bbox_exts: + assert abs(ext - bbox_exts[0]) < 1e-15 + + root_extent = bbox_exts[0] # }}} -- GitLab From 5605a1648423e862304966cd5ba7792a7c8be6d6 Mon Sep 17 00:00:00 2001 From: xywei Date: Sat, 30 Jun 2018 17:27:44 +0800 Subject: [PATCH 2/6] Address https://gitlab.tiker.net/inducer/boxtree/merge_requests/40#note_22136 --- boxtree/tree_build.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 9014fb5..52dc1f9 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -126,7 +126,11 @@ class TreeBuilder(object): :arg bbox: Bounding box of the same type as returned by *boxtree.bounding_box.make_bounding_box_dtype*. When given, this bounding box is used for tree - building. Otherwise, the bounding box is determined from particles. + building. Otherwise, the bounding box is determined from particles + in such a way that it is square and is slightly larger at the top (so + that scaled coordinates are always < 1). + When supplied, the bounding box must be square and have all the + particles in its closure. :arg kwargs: Used internally for debugging. :returns: a tuple ``(tree, event)``, where *tree* is an instance of -- GitLab From dc31a33c21bd76b69e6c328be2d937a5621117a4 Mon Sep 17 00:00:00 2001 From: xywei Date: Mon, 10 Sep 2018 12:54:30 -0500 Subject: [PATCH 3/6] Add support for numpy array as bbox --- boxtree/tree_build.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 52dc1f9..3f491e2 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -123,8 +123,11 @@ class TreeBuilder(object): execution. :arg extent_norm: ``"l2"`` or ``"linf"``. Indicates the norm with respect to which particle stick-out is measured. See :attr:`Tree.extent_norm`. - :arg bbox: Bounding box of the same type as returned by - *boxtree.bounding_box.make_bounding_box_dtype*. + :arg bbox: Bounding box of either type: + 1. A dim-by-2 array, with each row to be [min, max] coordinates + in its corresponding axis direction. + 2. (Internal use only) of the same type as returned by + *boxtree.bounding_box.make_bounding_box_dtype*. When given, this bounding box is used for tree building. Otherwise, the bounding box is determined from particles in such a way that it is square and is slightly larger at the top (so @@ -373,6 +376,18 @@ class TreeBuilder(object): srcntgts, srcntgt_radii, wait_for=wait_for) bbox_auto = bbox_auto.get() + # Convert numpy array to bbox_type + if not isinstance(bbox, type(bbox_auto)): + if issinstance(bbox, np.ndarrayJ): + bbox_bak = bbox.copy() + for i, ax in enumeriate(axis_names): + pass + + else: + raise NotImplementedError("Unsupported bounding box type: " + + str(type(bbox))) + + # bbox must cover bbox_auto bbox_min = np.empty(dimensions, coord_dtype) bbox_max = np.empty(dimensions, coord_dtype) -- GitLab From c53065fd86e8ef2e6a343a9f1ea8097d6a36274b Mon Sep 17 00:00:00 2001 From: xywei Date: Mon, 10 Sep 2018 13:59:39 -0500 Subject: [PATCH 4/6] Build bbox from numpy array --- boxtree/tree_build.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 3f491e2..e106766 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -380,9 +380,10 @@ class TreeBuilder(object): if not isinstance(bbox, type(bbox_auto)): if issinstance(bbox, np.ndarrayJ): bbox_bak = bbox.copy() + bbox = np.empty(1, bbox_auto.dtype) for i, ax in enumeriate(axis_names): - pass - + bbox['min_'+ax] = bbox_bak[i][0] + bbox['max_'+ax] = bbox_bak[i][1] else: raise NotImplementedError("Unsupported bounding box type: " + str(type(bbox))) -- GitLab From a251520bbca289bd55538b1608d26f4f3614075a Mon Sep 17 00:00:00 2001 From: xywei Date: Mon, 10 Sep 2018 14:16:32 -0500 Subject: [PATCH 5/6] Fix branching condition --- boxtree/tree_build.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index e106766..85ef75d 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -376,17 +376,19 @@ class TreeBuilder(object): srcntgts, srcntgt_radii, wait_for=wait_for) bbox_auto = bbox_auto.get() - # Convert numpy array to bbox_type - if not isinstance(bbox, type(bbox_auto)): - if issinstance(bbox, np.ndarrayJ): + # Convert unstructured numpy array to bbox_type + if issinstance(bbox, np.ndarrayJ): + if len(bbox) == dimensions: bbox_bak = bbox.copy() bbox = np.empty(1, bbox_auto.dtype) for i, ax in enumeriate(axis_names): bbox['min_'+ax] = bbox_bak[i][0] bbox['max_'+ax] = bbox_bak[i][1] else: - raise NotImplementedError("Unsupported bounding box type: " - + str(type(bbox))) + assert len(bbox) == 1 + else: + raise NotImplementedError("Unsupported bounding box type: " + + str(type(bbox))) # bbox must cover bbox_auto bbox_min = np.empty(dimensions, coord_dtype) -- GitLab From 9db71a7a3f1584ff408def523fedcb1ee6c9469e Mon Sep 17 00:00:00 2001 From: xywei Date: Mon, 10 Sep 2018 14:19:10 -0500 Subject: [PATCH 6/6] Bug fix --- boxtree/tree_build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boxtree/tree_build.py b/boxtree/tree_build.py index 85ef75d..9670487 100644 --- a/boxtree/tree_build.py +++ b/boxtree/tree_build.py @@ -377,11 +377,11 @@ class TreeBuilder(object): bbox_auto = bbox_auto.get() # Convert unstructured numpy array to bbox_type - if issinstance(bbox, np.ndarrayJ): + if isinstance(bbox, np.ndarray): if len(bbox) == dimensions: bbox_bak = bbox.copy() bbox = np.empty(1, bbox_auto.dtype) - for i, ax in enumeriate(axis_names): + for i, ax in enumerate(axis_names): bbox['min_'+ax] = bbox_bak[i][0] bbox['max_'+ax] = bbox_bak[i][1] else: -- GitLab