From faaab9362896a2bd3ca4f1ee8e26c52d500ff6da Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Fri, 12 Jan 2018 15:14:25 -0600 Subject: [PATCH 1/2] Assign a refine weight of zero to QBX needing targets. This improves FMM balancing (closes #72) --- pytential/qbx/geometry.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pytential/qbx/geometry.py b/pytential/qbx/geometry.py index e9e7fd92..7116edd2 100644 --- a/pytential/qbx/geometry.py +++ b/pytential/qbx/geometry.py @@ -494,11 +494,17 @@ class QBXFMMGeometryData(object): self.coord_dtype) target_radii[:self.ncenters] = self.expansion_radii() - # FIXME: https://gitlab.tiker.net/inducer/pytential/issues/72 - # refine_weights = cl.array.zeros(queue, nparticles, dtype=np.int32) - # refine_weights[:nsources] = 1 refine_weights = cl.array.empty(queue, nparticles, dtype=np.int32) - refine_weights.fill(1) + + # Assign a weight of 1 to all sources, QBX centers, and conventional + # (non-QBX) targets. Assign a weight of 0 to all targets that need + # QBX centers. The potential at the latter targets is mediated + # entirely by the QBX center, so as a matter of evaluation cost, + # their location in the tree is irrelevant. + refine_weights[:-target_info.ntargets] = 1 + user_ttc = self.user_target_to_center().with_queue(queue) + refine_weights[-target_info.ntargets:] = ( + user_ttc == target_state.NO_QBX_NEEDED).astype(np.int32) refine_weights.finish() @@ -679,8 +685,7 @@ class QBXFMMGeometryData(object): if a center needs to be used, but none was found. See :meth:`center_to_tree_targets` for the reverse look-up table. - Shape: ``[ntargets]`` of :attr:`boxtree.Tree.particle_id_dtype`, with extra - values from :class:`target_state` allowed. Targets occur in user order. + Shape: ``[ntargets]`` of :class:`numpy.int32`. Targets occur in user order. """ from pytential.qbx.target_assoc import associate_targets_to_qbx_centers tgt_info = self.target_info() @@ -689,7 +694,7 @@ class QBXFMMGeometryData(object): with cl.CommandQueue(self.cl_context) as queue: target_side_prefs = (self - .target_side_preferences()[self.ncenters:].get(queue=queue)) + .target_side_preferences()[self.ncenters:].get(queue=queue)) target_discrs_and_qbx_sides = [( PointsTarget(tgt_info.targets[:, self.ncenters:]), @@ -706,9 +711,7 @@ class QBXFMMGeometryData(object): target_association_tolerance=( self.target_association_tolerance)) - tree = self.tree() - - result = cl.array.empty(queue, tgt_info.ntargets, tree.particle_id_dtype) + result = cl.array.empty(queue, tgt_info.ntargets, np.int32) result[:self.ncenters].fill(target_state.NO_QBX_NEEDED) result[self.ncenters:] = tgt_assoc_result.target_to_center @@ -727,7 +730,11 @@ class QBXFMMGeometryData(object): with cl.CommandQueue(self.cl_context) as queue: logger.info("build center -> targets lookup table: start") - tree_ttc = cl.array.empty_like(user_ttc).with_queue(queue) + user_ttc = (user_ttc + .with_queue(queue) + .astype(self.tree().particle_id_dtype)) + + tree_ttc = cl.array.empty_like(user_ttc) tree_ttc[self.tree().sorted_target_ids] = user_ttc filtered_tree_ttc = cl.array.empty(queue, tree_ttc.shape, tree_ttc.dtype) -- GitLab From 6187aba2170a0e6e306df27a49f95b18ed00c8e7 Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Sat, 13 Jan 2018 00:01:12 -0600 Subject: [PATCH 2/2] user_target_to_center(): Use the same dtype as target_to_center --- pytential/qbx/geometry.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pytential/qbx/geometry.py b/pytential/qbx/geometry.py index 7116edd2..ca53df5a 100644 --- a/pytential/qbx/geometry.py +++ b/pytential/qbx/geometry.py @@ -685,7 +685,8 @@ class QBXFMMGeometryData(object): if a center needs to be used, but none was found. See :meth:`center_to_tree_targets` for the reverse look-up table. - Shape: ``[ntargets]`` of :class:`numpy.int32`. Targets occur in user order. + Shape: ``[ntargets]`` of :attr:`boxtree.Tree.particle_id_dtype`, with extra + values from :class:`target_state` allowed. Targets occur in user order. """ from pytential.qbx.target_assoc import associate_targets_to_qbx_centers tgt_info = self.target_info() @@ -711,7 +712,8 @@ class QBXFMMGeometryData(object): target_association_tolerance=( self.target_association_tolerance)) - result = cl.array.empty(queue, tgt_info.ntargets, np.int32) + result = cl.array.empty(queue, tgt_info.ntargets, + tgt_assoc_result.target_to_center.dtype) result[:self.ncenters].fill(target_state.NO_QBX_NEEDED) result[self.ncenters:] = tgt_assoc_result.target_to_center @@ -730,11 +732,7 @@ class QBXFMMGeometryData(object): with cl.CommandQueue(self.cl_context) as queue: logger.info("build center -> targets lookup table: start") - user_ttc = (user_ttc - .with_queue(queue) - .astype(self.tree().particle_id_dtype)) - - tree_ttc = cl.array.empty_like(user_ttc) + tree_ttc = cl.array.empty_like(user_ttc).with_queue(queue) tree_ttc[self.tree().sorted_target_ids] = user_ttc filtered_tree_ttc = cl.array.empty(queue, tree_ttc.shape, tree_ttc.dtype) -- GitLab