From e97cb4e4513c28b3a84f4c0a05ba53298a2a8bf3 Mon Sep 17 00:00:00 2001 From: Andrey Prokopenko Date: Mon, 5 Feb 2024 16:54:15 -0500 Subject: [PATCH 1/5] Add helper functions to construct predicates --- src/ArborX.hpp | 1 + src/ArborX_BruteForce.hpp | 1 + src/ArborX_LinearBVH.hpp | 1 + src/details/ArborX_PredicateHelpers.hpp | 165 ++++++++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 src/details/ArborX_PredicateHelpers.hpp diff --git a/src/ArborX.hpp b/src/ArborX.hpp index d7e392ab4..f7bcee74c 100644 --- a/src/ArborX.hpp +++ b/src/ArborX.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include // FIXME: we include ArborX_DetailsUtils.hpp only for backward compatibility for diff --git a/src/ArborX_BruteForce.hpp b/src/ArborX_BruteForce.hpp index 13a6df174..e404a094c 100644 --- a/src/ArborX_BruteForce.hpp +++ b/src/ArborX_BruteForce.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/src/ArborX_LinearBVH.hpp b/src/ArborX_LinearBVH.hpp index c1b41dc98..bcc64631c 100644 --- a/src/ArborX_LinearBVH.hpp +++ b/src/ArborX_LinearBVH.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/src/details/ArborX_PredicateHelpers.hpp b/src/details/ArborX_PredicateHelpers.hpp new file mode 100644 index 000000000..abf4d580e --- /dev/null +++ b/src/details/ArborX_PredicateHelpers.hpp @@ -0,0 +1,165 @@ +/**************************************************************************** + * Copyright (c) 2017-2022 by the ArborX authors * + * All rights reserved. * + * * + * This file is part of the ArborX library. ArborX is * + * distributed under a BSD 3-clause license. For the licensing terms see * + * the LICENSE file in the top-level directory. * + * * + * SPDX-License-Identifier: BSD-3-Clause * + ****************************************************************************/ +#ifndef ARBORX_PREDICATE_HELPERS_HPP +#define ARBORX_PREDICATE_HELPERS_HPP + +#include +#include +#include +#include + +namespace ArborX +{ +namespace Experimental +{ + +template +struct PrimitivesIntersect +{ +private: + using Primitives = Details::AccessValues; + // FIXME: + // using Geometry = typename Primitives::value_type; + // static_assert(GeometryTraits::is_valid_geometry{}); + +public: + Primitives _primitives; +}; + +template +struct PrimitivesWithRadius +{ +private: + using Primitives = Details::AccessValues; + using Point = typename Primitives::value_type; + static_assert(GeometryTraits::is_point::value); + using Coordinate = typename GeometryTraits::coordinate_type::type; + +public: + Primitives _primitives; + Coordinate _r; + + PrimitivesWithRadius(UserPrimitives const &user_primitives, Coordinate r) + : _primitives(user_primitives) + , _r(r) + {} +}; + +template +struct PrimitivesNearestK +{ +private: + using Primitives = Details::AccessValues; + +public: + Primitives _primitives; + int _k; // not including self-collisions +}; + +template +auto intersect_geometries(Primitives const &primitives) +{ + Details::check_valid_access_traits(PrimitivesTag{}, primitives, + Details::DoNotCheckGetReturnType()); + return PrimitivesIntersect{primitives}; +} + +template +auto intersect_geometries_with_radius(Primitives const &primitives, + Coordinate r) +{ + Details::check_valid_access_traits(PrimitivesTag{}, primitives); + return PrimitivesWithRadius(primitives, r); +} + +template +auto nearest_k(Primitives const &primitives, int k) +{ + Details::check_valid_access_traits(PrimitivesTag{}, primitives); + return PrimitivesNearestK{primitives, k}; +} + +} // namespace Experimental + +template +struct AccessTraits, + PredicatesTag> +{ +private: + using Self = Experimental::PrimitivesIntersect; + +public: + using memory_space = typename Primitives::memory_space; + using size_type = typename memory_space::size_type; + + static KOKKOS_FUNCTION size_type size(Self const &x) + { + return x._primitives.size(); + } + static KOKKOS_FUNCTION auto get(Self const &x, size_type i) + { + return intersects(x._primitives(i)); + } +}; + +template +struct AccessTraits, + PredicatesTag> +{ +private: + using Self = Experimental::PrimitivesWithRadius; + +public: + using memory_space = typename Primitives::memory_space; + using size_type = typename memory_space::size_type; + + static KOKKOS_FUNCTION size_type size(Self const &x) + { + return x._primitives.size(); + } + static KOKKOS_FUNCTION auto get(Self const &x, size_type i) + { + auto const &point = x._primitives(i); + using Point = std::decay_t; + constexpr int dim = GeometryTraits::dimension_v; + using Coordinate = typename GeometryTraits::coordinate_type::type; + // FIXME reinterpret_cast is dangerous here if access traits return user + // point structure (e.g., struct MyPoint { float y; float x; }) + auto const &hyper_point = reinterpret_cast< + ExperimentalHyperGeometry::Point const &>(point); + return intersects( + ExperimentalHyperGeometry::Sphere(hyper_point, x._r)); + } +}; + +template +struct AccessTraits, PredicatesTag> +{ +private: + using Self = Experimental::PrimitivesNearestK; + +public: + using memory_space = typename Primitives::memory_space; + using size_type = typename memory_space::size_type; + + static KOKKOS_FUNCTION size_type size(Self const &x) + { + return x._primitives.size(); + } + static KOKKOS_FUNCTION auto get(Self const &x, size_type i) + { + return nearest(x._primitives(i), x._k); + } +}; + +} // namespace ArborX + +#endif From b13835cb15f3ea581d91ed150b1a271b9fabd5c2 Mon Sep 17 00:00:00 2001 From: Andrey Prokopenko Date: Wed, 7 Feb 2024 14:14:57 -0500 Subject: [PATCH 2/5] Replace suitable instances with helper predicate creation functions --- .../dbscan/ArborX_DBSCANVerification.hpp | 3 +- .../distributed_tree_driver.cpp | 58 +++---------------- .../example_molecular_dynamics.cpp | 29 ++-------- examples/raytracing/example_raytracing.cpp | 31 +--------- src/ArborX_DBSCAN.hpp | 45 +++----------- src/details/ArborX_DetailsFDBSCANDenseBox.hpp | 2 +- ...borX_DetailsMutualReachabilityDistance.hpp | 28 --------- src/details/ArborX_MinimumSpanningTree.hpp | 9 ++- src/details/ArborX_PredicateHelpers.hpp | 8 ++- .../ArborX_InterpMovingLeastSquares.hpp | 37 +----------- test/tstDetailsMutualReachabilityDistance.cpp | 4 +- test/tstNeighborList.cpp | 35 +---------- test/tstQueryTreeRay.cpp | 55 +----------------- 13 files changed, 49 insertions(+), 295 deletions(-) diff --git a/benchmarks/dbscan/ArborX_DBSCANVerification.hpp b/benchmarks/dbscan/ArborX_DBSCANVerification.hpp index 55f90285d..6395e1c75 100644 --- a/benchmarks/dbscan/ArborX_DBSCANVerification.hpp +++ b/benchmarks/dbscan/ArborX_DBSCANVerification.hpp @@ -314,7 +314,8 @@ bool verifyDBSCAN(ExecutionSpace exec_space, Primitives const &primitives, ArborX::BoundingVolumeHierarchy> bvh(exec_space, ArborX::Experimental::attach_indices(points)); - auto const predicates = Details::PrimitivesWithRadius{points, eps}; + auto const predicates = ArborX::Experimental::attach_indices( + ArborX::Experimental::intersect_geometries_with_radius(points, eps)); Kokkos::View indices("ArborX::DBSCAN::indices", 0); Kokkos::View offset("ArborX::DBSCAN::offset", 0); diff --git a/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp b/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp index 7aa9e7e29..c66ad4878 100644 --- a/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp +++ b/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp @@ -170,52 +170,6 @@ class TimeMonitor } }; -template -struct NearestNeighborsSearches -{ - Kokkos::View points; - int k; -}; -template -struct RadiusSearches -{ - Kokkos::View points; - double radius; -}; - -template -struct ArborX::AccessTraits, ArborX::PredicatesTag> -{ - using memory_space = typename DeviceType::memory_space; - static KOKKOS_FUNCTION std::size_t - size(RadiusSearches const &pred) - { - return pred.points.extent(0); - } - static KOKKOS_FUNCTION auto get(RadiusSearches const &pred, - std::size_t i) - { - return ArborX::intersects(ArborX::Sphere{pred.points(i), pred.radius}); - } -}; - -template -struct ArborX::AccessTraits, - ArborX::PredicatesTag> -{ - using memory_space = typename DeviceType::memory_space; - static KOKKOS_FUNCTION std::size_t - size(NearestNeighborsSearches const &pred) - { - return pred.points.extent(0); - } - static KOKKOS_FUNCTION auto - get(NearestNeighborsSearches const &pred, std::size_t i) - { - return ArborX::nearest(pred.points(i), pred.k); - } -}; - namespace bpo = boost::program_options; template @@ -421,8 +375,8 @@ int main_(std::vector const &args, MPI_Comm const comm) knn->start(); distributed_tree.query( ExecutionSpace{}, - NearestNeighborsSearches{random_queries, n_neighbors}, - values, offsets); + ArborX::Experimental::nearest_k(random_queries, n_neighbors), values, + offsets); knn->stop(); if (comm_rank == 0) @@ -457,9 +411,11 @@ int main_(std::vector const &args, MPI_Comm const comm) auto radius = time_monitor.getNewTimer("radius"); MPI_Barrier(comm); radius->start(); - distributed_tree.query(ExecutionSpace{}, - RadiusSearches{random_queries, r}, - values, offsets); + distributed_tree.query( + ExecutionSpace{}, + ArborX::Experimental::intersect_geometries_with_radius(random_queries, + r), + values, offsets); radius->stop(); if (comm_rank == 0) diff --git a/examples/molecular_dynamics/example_molecular_dynamics.cpp b/examples/molecular_dynamics/example_molecular_dynamics.cpp index 4d8125118..370b2b467 100644 --- a/examples/molecular_dynamics/example_molecular_dynamics.cpp +++ b/examples/molecular_dynamics/example_molecular_dynamics.cpp @@ -16,28 +16,6 @@ #include #include -template -struct Neighbors -{ - Kokkos::View _particles; - float _radius; -}; - -template -struct ArborX::AccessTraits, ArborX::PredicatesTag> -{ - using memory_space = MemorySpace; - using size_type = std::size_t; - static KOKKOS_FUNCTION size_type size(Neighbors const &x) - { - return x._particles.extent(0); - } - static KOKKOS_FUNCTION auto get(Neighbors const &x, size_type i) - { - return attach(intersects(Sphere{x._particles(i), x._radius}), (int)i); - } -}; - struct ExcludeSelfCollision { template @@ -119,8 +97,11 @@ int main(int argc, char *argv[]) Kokkos::View indices("Example::indices", 0); Kokkos::View offsets("Example::offsets", 0); - index.query(execution_space, Neighbors{particles, r}, - ExcludeSelfCollision{}, indices, offsets); + index.query( + execution_space, + ArborX::Experimental::attach_indices( + ArborX::Experimental::intersect_geometries_with_radius(particles, r)), + ExcludeSelfCollision{}, indices, offsets); Kokkos::View forces( Kokkos::view_alloc(execution_space, "Example::forces"), n); diff --git a/examples/raytracing/example_raytracing.cpp b/examples/raytracing/example_raytracing.cpp index f2ff595ed..162a9a7e7 100644 --- a/examples/raytracing/example_raytracing.cpp +++ b/examples/raytracing/example_raytracing.cpp @@ -107,14 +107,6 @@ struct ArborX::AccessTraits, namespace IntersectsBased { -/* - * Storage for the rays and access traits used in the query/traverse. - */ -template -struct Rays -{ - Kokkos::View _rays; -}; /* * IntersectedCell is a storage container for all intersections between rays and @@ -177,25 +169,6 @@ struct AccumulateRaySphereIntersections }; } // namespace IntersectsBased -template -struct ArborX::AccessTraits, - ArborX::PredicatesTag> -{ - using memory_space = MemorySpace; - using size_type = std::size_t; - - KOKKOS_FUNCTION - static size_type size(IntersectsBased::Rays const &rays) - { - return rays._rays.extent(0); - } - KOKKOS_FUNCTION - static auto get(IntersectsBased::Rays const &rays, size_type i) - { - return attach(intersects(rays._rays(i)), (int)i); - } -}; - int main(int argc, char *argv[]) { using ExecutionSpace = Kokkos::DefaultExecutionSpace; @@ -336,7 +309,9 @@ int main(int argc, char *argv[]) 0); Kokkos::View offsets("Example::offsets", 0); bvh.query( - exec_space, IntersectsBased::Rays{rays}, + exec_space, + ArborX::Experimental::attach_indices( + ArborX::Experimental::intersect_geometries(rays)), IntersectsBased::AccumulateRaySphereIntersections{boxes}, values, offsets); diff --git a/src/ArborX_DBSCAN.hpp b/src/ArborX_DBSCAN.hpp index 093953afc..de24c555a 100644 --- a/src/ArborX_DBSCAN.hpp +++ b/src/ArborX_DBSCAN.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace ArborX @@ -52,13 +53,6 @@ struct DBSCANCorePoints } }; -template -struct PrimitivesWithRadius -{ - Primitives _primitives; - float _r; -}; - struct WithinRadiusGetter { float _r; @@ -100,31 +94,6 @@ struct MixedBoxPrimitives } // namespace Details -template -struct AccessTraits, PredicatesTag> -{ - using memory_space = typename Primitives::memory_space; - using Predicates = Details::PrimitivesWithRadius; - - static KOKKOS_FUNCTION size_t size(Predicates const &w) - { - return w._primitives.size(); - } - static KOKKOS_FUNCTION auto get(Predicates const &w, size_t i) - { - auto const &point = w._primitives(i); - constexpr int dim = - GeometryTraits::dimension_v>; - // FIXME reinterpret_cast is dangerous here if access traits return user - // point structure (e.g., struct MyPoint { float y; float x; }) - auto const &hyper_point = - reinterpret_cast const &>(point); - return attach( - intersects(ExperimentalHyperGeometry::Sphere{hyper_point, w._r}), - (int)i); - } -}; - template struct AccessTraits, @@ -315,8 +284,8 @@ dbscan(ExecutionSpace const &exec_space, Primitives const &primitives, } else { - auto const predicates = - Details::PrimitivesWithRadius{points, eps}; + auto const predicates = ArborX::Experimental::attach_indices( + ArborX::Experimental::intersect_geometries_with_radius(points, eps)); // Determine core points Kokkos::Profiling::pushRegion("ArborX::DBSCAN::clusters::num_neigh"); @@ -437,8 +406,8 @@ dbscan(ExecutionSpace const &exec_space, Primitives const &primitives, // Perform the queries and build clusters through callback using CorePoints = Details::CCSCorePoints; Kokkos::Profiling::pushRegion("ArborX::DBSCAN::clusters::query"); - auto const predicates = - Details::PrimitivesWithRadius{points, eps}; + auto const predicates = Experimental::attach_indices( + Experimental::intersect_geometries_with_radius(points, eps)); bvh.query(exec_space, predicates, Details::FDBSCANDenseBoxCallback{points, eps}; + auto const predicates = Experimental::attach_indices( + Experimental::intersect_geometries_with_radius(points, eps)); bvh.query(exec_space, predicates, Details::FDBSCANDenseBoxCallback -struct NearestK -{ - Primitives primitives; - int k; // including self-collisions -}; - -} // namespace Details - -template -struct AccessTraits, PredicatesTag> -{ - using memory_space = typename Primitives::memory_space; - using size_type = typename memory_space::size_type; - static KOKKOS_FUNCTION size_type size(Details::NearestK const &x) - { - return x.primitives.size(); - } - static KOKKOS_FUNCTION auto get(Details::NearestK const &x, - size_type i) - { - return attach(nearest(x.primitives(i), x.k), i); - } -}; - -namespace Details -{ - template struct MutualReachability { diff --git a/src/details/ArborX_MinimumSpanningTree.hpp b/src/details/ArborX_MinimumSpanningTree.hpp index d61731957..6bd7b26cd 100644 --- a/src/details/ArborX_MinimumSpanningTree.hpp +++ b/src/details/ArborX_MinimumSpanningTree.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -66,9 +67,11 @@ struct MinimumSpanningTree Kokkos::Profiling::pushRegion("ArborX::MST::compute_core_distances"); Kokkos::View core_distances( "ArborX::MST::core_distances", n); - bvh.query(space, NearestK{points, k}, - MaxDistance{points, - core_distances}); + bvh.query( + space, + Experimental::attach_indices(Experimental::nearest_k(points, k)), + MaxDistance{points, + core_distances}); Kokkos::Profiling::popRegion(); MutualReachability mutual_reachability{ diff --git a/src/details/ArborX_PredicateHelpers.hpp b/src/details/ArborX_PredicateHelpers.hpp index abf4d580e..093e4a5a1 100644 --- a/src/details/ArborX_PredicateHelpers.hpp +++ b/src/details/ArborX_PredicateHelpers.hpp @@ -58,10 +58,13 @@ struct PrimitivesNearestK { private: using Primitives = Details::AccessValues; + // FIXME: + // using Geometry = typename Primitives::value_type; + // static_assert(GeometryTraits::is_valid_geometry{}); public: Primitives _primitives; - int _k; // not including self-collisions + int _k; }; template @@ -83,7 +86,8 @@ auto intersect_geometries_with_radius(Primitives const &primitives, template auto nearest_k(Primitives const &primitives, int k) { - Details::check_valid_access_traits(PrimitivesTag{}, primitives); + Details::check_valid_access_traits(PrimitivesTag{}, primitives, + Details::DoNotCheckGetReturnType()); return PrimitivesNearestK{primitives, k}; } diff --git a/src/interpolation/ArborX_InterpMovingLeastSquares.hpp b/src/interpolation/ArborX_InterpMovingLeastSquares.hpp index c11ffa9d2..08d2efe42 100644 --- a/src/interpolation/ArborX_InterpMovingLeastSquares.hpp +++ b/src/interpolation/ArborX_InterpMovingLeastSquares.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -30,14 +31,6 @@ namespace ArborX::Interpolation::Details { -// This is done to avoid a clash with another predicates access trait -template -struct MLSPredicateWrapper -{ - TargetAccess target_access; - int num_neighbors; -}; - // Functor used in the tree query to create the 2D source view and indices template struct MLSSearchNeighborsCallback @@ -63,30 +56,6 @@ struct MLSSearchNeighborsCallback } // namespace ArborX::Interpolation::Details -namespace ArborX -{ - -template -struct AccessTraits, - PredicatesTag> -{ - using Self = Interpolation::Details::MLSPredicateWrapper; - - KOKKOS_FUNCTION static auto size(Self const &tp) - { - return tp.target_access.size(); - } - - KOKKOS_FUNCTION static auto get(Self const &tp, int const i) - { - return attach(nearest(tp.target_access(i), tp.num_neighbors), i); - } - - using memory_space = typename TargetAccess::memory_space; -}; - -} // namespace ArborX - namespace ArborX::Interpolation { @@ -231,8 +200,8 @@ class MovingLeastSquares source_tree(space, ArborX::Experimental::attach_indices(source_access)); // Create the predicates - Details::MLSPredicateWrapper predicates{target_access, - _num_neighbors}; + auto predicates = Experimental::attach_indices( + Experimental::nearest_k(target_access, _num_neighbors)); // Create the callback Kokkos::View source_view( diff --git a/test/tstDetailsMutualReachabilityDistance.cpp b/test/tstDetailsMutualReachabilityDistance.cpp index f899bedc4..15d6680b1 100644 --- a/test/tstDetailsMutualReachabilityDistance.cpp +++ b/test/tstDetailsMutualReachabilityDistance.cpp @@ -41,7 +41,9 @@ auto compute_core_distances(ExecutionSpace exec_space, constexpr auto inf = ArborX::Details::KokkosExt::ArithmeticTraits::infinity::value; Kokkos::deep_copy(exec_space, distances, -inf); - bvh.query(exec_space, ArborX::Details::NearestK{points, k}, + auto predicates = ArborX::Experimental::attach_indices( + ArborX::Experimental::nearest_k(points, k)); + bvh.query(exec_space, predicates, ArborX::Details::MaxDistance{ points, distances}); diff --git a/test/tstNeighborList.cpp b/test/tstNeighborList.cpp index 31303bee8..0a9ab368a 100644 --- a/test/tstNeighborList.cpp +++ b/test/tstNeighborList.cpp @@ -46,35 +46,6 @@ struct Filter } }; -template -struct RadiusSearch -{ - Points points; - float radius; -}; - -} // namespace Test - -template -struct ArborX::AccessTraits, ArborX::PredicatesTag> -{ - using Self = Test::RadiusSearch; - using memory_space = typename Points::memory_space; - using size_type = typename Points::size_type; - static KOKKOS_FUNCTION size_type size(Self const &x) - { - return x.points.size(); - ; - } - static KOKKOS_FUNCTION auto get(Self const &x, size_type i) - { - return intersects(Sphere{x.points(i), x.radius}); - } -}; - -namespace Test -{ - template auto compute_reference(ExecutionSpace const &exec_space, Points const &points, float radius) @@ -82,9 +53,9 @@ auto compute_reference(ExecutionSpace const &exec_space, Points const &points, Kokkos::View offsets("Test::offsets", 0); Kokkos::View indices("Test::indices", 0); ArborX::BoundingVolumeHierarchy bvh(exec_space, points); - RadiusSearch predicates{points, radius}; - bvh.query(exec_space, ArborX::Experimental::attach_indices(predicates), - Filter{}, indices, offsets); + auto predicates = ArborX::Experimental::attach_indices( + ArborX::Experimental::intersect_geometries_with_radius(points, radius)); + bvh.query(exec_space, predicates, Filter{}, indices, offsets); ArborX::Details::expandHalfToFull(exec_space, offsets, indices); return make_compressed_storage( Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, offsets), diff --git a/test/tstQueryTreeRay.cpp b/test/tstQueryTreeRay.cpp index c91c548b3..c8bb01b1b 100644 --- a/test/tstQueryTreeRay.cpp +++ b/test/tstQueryTreeRay.cpp @@ -23,52 +23,6 @@ #include "ArborXTest_TreeTypeTraits.hpp" // clang-format on -template -struct NearestBoxToRay -{ - Kokkos::View rays; - int k; -}; - -template -struct BoxesIntersectedByRay -{ - Kokkos::View rays; -}; - -template -struct ArborX::AccessTraits, ArborX::PredicatesTag> -{ - using memory_space = typename DeviceType::memory_space; - static KOKKOS_FUNCTION int - size(NearestBoxToRay const &nearest_boxes) - { - return nearest_boxes.rays.size(); - } - static KOKKOS_FUNCTION auto - get(NearestBoxToRay const &nearest_boxes, int i) - { - return nearest(nearest_boxes.rays(i), nearest_boxes.k); - } -}; - -template -struct ArborX::AccessTraits, - ArborX::PredicatesTag> -{ - using memory_space = typename DeviceType::memory_space; - static KOKKOS_FUNCTION int - size(BoxesIntersectedByRay const &nearest_boxes) - { - return nearest_boxes.rays.size(); - } - static KOKKOS_FUNCTION auto - get(BoxesIntersectedByRay const &nearest_boxes, int i) - { - return intersects(nearest_boxes.rays(i)); - } -}; - BOOST_AUTO_TEST_SUITE(RayTraversals) BOOST_AUTO_TEST_CASE_TEMPLATE(test_ray_box_nearest, DeviceType, @@ -96,9 +50,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_ray_box_nearest, DeviceType, BOOST_TEST(intersects( ray, ArborX::Box{ArborX::Point{0, 0, 0}, ArborX::Point{1, 1, 1}})); - NearestBoxToRay predicates{device_rays, 1}; - - ARBORX_TEST_QUERY_TREE(exec_space, tree, predicates, + ARBORX_TEST_QUERY_TREE(exec_space, tree, + ArborX::Experimental::nearest_k(device_rays, 1), make_reference_solution({0}, {0, 1})); } @@ -124,10 +77,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_ray_box_intersection, DeviceType, Kokkos::View device_rays("rays", 1); Kokkos::deep_copy(exec_space, device_rays, ray); - BoxesIntersectedByRay predicates{device_rays}; - ARBORX_TEST_QUERY_TREE( - exec_space, tree, predicates, + exec_space, tree, ArborX::Experimental::intersect_geometries(device_rays), make_reference_solution({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {0, 10})); } BOOST_AUTO_TEST_SUITE_END() From 5bca30ebc1e728c9ca8285fb0ed5e9404f9b461f Mon Sep 17 00:00:00 2001 From: Andrey Prokopenko Date: Wed, 14 Feb 2024 12:32:46 -0500 Subject: [PATCH 3/5] Use class instead of struct --- src/details/ArborX_PredicateHelpers.hpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/details/ArborX_PredicateHelpers.hpp b/src/details/ArborX_PredicateHelpers.hpp index 093e4a5a1..a012ee814 100644 --- a/src/details/ArborX_PredicateHelpers.hpp +++ b/src/details/ArborX_PredicateHelpers.hpp @@ -22,9 +22,8 @@ namespace Experimental { template -struct PrimitivesIntersect +class PrimitivesIntersect { -private: using Primitives = Details::AccessValues; // FIXME: // using Geometry = typename Primitives::value_type; @@ -35,9 +34,8 @@ struct PrimitivesIntersect }; template -struct PrimitivesWithRadius +class PrimitivesWithRadius { -private: using Primitives = Details::AccessValues; using Point = typename Primitives::value_type; static_assert(GeometryTraits::is_point::value); @@ -54,9 +52,8 @@ struct PrimitivesWithRadius }; template -struct PrimitivesNearestK +class PrimitivesNearestK { -private: using Primitives = Details::AccessValues; // FIXME: // using Geometry = typename Primitives::value_type; From f6f24e1099fd0b6eb329dbffded09a4d807387bd Mon Sep 17 00:00:00 2001 From: Andrey Prokopenko Date: Wed, 14 Feb 2024 12:33:09 -0500 Subject: [PATCH 4/5] Restore AccessTraits in molecular dynamics example for user ease of use --- .../example_molecular_dynamics.cpp | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/examples/molecular_dynamics/example_molecular_dynamics.cpp b/examples/molecular_dynamics/example_molecular_dynamics.cpp index 370b2b467..cd3698300 100644 --- a/examples/molecular_dynamics/example_molecular_dynamics.cpp +++ b/examples/molecular_dynamics/example_molecular_dynamics.cpp @@ -16,6 +16,28 @@ #include #include +template +struct Neighbors +{ + Kokkos::View _particles; + float _radius; +}; + +template +struct ArborX::AccessTraits, ArborX::PredicatesTag> +{ + using memory_space = MemorySpace; + using size_type = std::size_t; + static KOKKOS_FUNCTION size_type size(Neighbors const &x) + { + return x._particles.extent(0); + } + static KOKKOS_FUNCTION auto get(Neighbors const &x, size_type i) + { + return intersects(Sphere{x._particles(i), x._radius}); + } +}; + struct ExcludeSelfCollision { template @@ -97,11 +119,10 @@ int main(int argc, char *argv[]) Kokkos::View indices("Example::indices", 0); Kokkos::View offsets("Example::offsets", 0); - index.query( - execution_space, - ArborX::Experimental::attach_indices( - ArborX::Experimental::intersect_geometries_with_radius(particles, r)), - ExcludeSelfCollision{}, indices, offsets); + index.query(execution_space, + ArborX::Experimental::attach_indices( + Neighbors{particles, r}), + ExcludeSelfCollision{}, indices, offsets); Kokkos::View forces( Kokkos::view_alloc(execution_space, "Example::forces"), n); From 0d7579c51bdbc46c07484f77d9c7034f6c4af2d0 Mon Sep 17 00:00:00 2001 From: Andrey Prokopenko Date: Thu, 29 Feb 2024 14:56:26 -0500 Subject: [PATCH 5/5] Rename predicate helpers --- benchmarks/dbscan/ArborX_DBSCANVerification.hpp | 2 +- .../distributed_tree_driver/distributed_tree_driver.cpp | 7 +++---- examples/raytracing/example_raytracing.cpp | 2 +- src/ArborX_DBSCAN.hpp | 6 +++--- src/details/ArborX_MinimumSpanningTree.hpp | 2 +- src/details/ArborX_PredicateHelpers.hpp | 7 +++---- src/interpolation/ArborX_InterpMovingLeastSquares.hpp | 2 +- test/tstDetailsMutualReachabilityDistance.cpp | 2 +- test/tstNeighborList.cpp | 2 +- test/tstQueryTreeRay.cpp | 4 ++-- 10 files changed, 17 insertions(+), 19 deletions(-) diff --git a/benchmarks/dbscan/ArborX_DBSCANVerification.hpp b/benchmarks/dbscan/ArborX_DBSCANVerification.hpp index 6395e1c75..42dfbca4e 100644 --- a/benchmarks/dbscan/ArborX_DBSCANVerification.hpp +++ b/benchmarks/dbscan/ArborX_DBSCANVerification.hpp @@ -315,7 +315,7 @@ bool verifyDBSCAN(ExecutionSpace exec_space, Primitives const &primitives, bvh(exec_space, ArborX::Experimental::attach_indices(points)); auto const predicates = ArborX::Experimental::attach_indices( - ArborX::Experimental::intersect_geometries_with_radius(points, eps)); + ArborX::Experimental::make_intersects(points, eps)); Kokkos::View indices("ArborX::DBSCAN::indices", 0); Kokkos::View offset("ArborX::DBSCAN::offset", 0); diff --git a/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp b/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp index c66ad4878..54f2de3f7 100644 --- a/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp +++ b/benchmarks/distributed_tree_driver/distributed_tree_driver.cpp @@ -375,7 +375,7 @@ int main_(std::vector const &args, MPI_Comm const comm) knn->start(); distributed_tree.query( ExecutionSpace{}, - ArborX::Experimental::nearest_k(random_queries, n_neighbors), values, + ArborX::Experimental::make_nearest(random_queries, n_neighbors), values, offsets); knn->stop(); @@ -413,9 +413,8 @@ int main_(std::vector const &args, MPI_Comm const comm) radius->start(); distributed_tree.query( ExecutionSpace{}, - ArborX::Experimental::intersect_geometries_with_radius(random_queries, - r), - values, offsets); + ArborX::Experimental::make_intersects(random_queries, r), values, + offsets); radius->stop(); if (comm_rank == 0) diff --git a/examples/raytracing/example_raytracing.cpp b/examples/raytracing/example_raytracing.cpp index 162a9a7e7..d0b302203 100644 --- a/examples/raytracing/example_raytracing.cpp +++ b/examples/raytracing/example_raytracing.cpp @@ -311,7 +311,7 @@ int main(int argc, char *argv[]) bvh.query( exec_space, ArborX::Experimental::attach_indices( - ArborX::Experimental::intersect_geometries(rays)), + ArborX::Experimental::make_intersects(rays)), IntersectsBased::AccumulateRaySphereIntersections{boxes}, values, offsets); diff --git a/src/ArborX_DBSCAN.hpp b/src/ArborX_DBSCAN.hpp index de24c555a..169c52f50 100644 --- a/src/ArborX_DBSCAN.hpp +++ b/src/ArborX_DBSCAN.hpp @@ -285,7 +285,7 @@ dbscan(ExecutionSpace const &exec_space, Primitives const &primitives, else { auto const predicates = ArborX::Experimental::attach_indices( - ArborX::Experimental::intersect_geometries_with_radius(points, eps)); + ArborX::Experimental::make_intersects(points, eps)); // Determine core points Kokkos::Profiling::pushRegion("ArborX::DBSCAN::clusters::num_neigh"); @@ -407,7 +407,7 @@ dbscan(ExecutionSpace const &exec_space, Primitives const &primitives, using CorePoints = Details::CCSCorePoints; Kokkos::Profiling::pushRegion("ArborX::DBSCAN::clusters::query"); auto const predicates = Experimental::attach_indices( - Experimental::intersect_geometries_with_radius(points, eps)); + Experimental::make_intersects(points, eps)); bvh.query(exec_space, predicates, Details::FDBSCANDenseBoxCallback{points, core_distances}); Kokkos::Profiling::popRegion(); diff --git a/src/details/ArborX_PredicateHelpers.hpp b/src/details/ArborX_PredicateHelpers.hpp index a012ee814..200b911ed 100644 --- a/src/details/ArborX_PredicateHelpers.hpp +++ b/src/details/ArborX_PredicateHelpers.hpp @@ -65,7 +65,7 @@ class PrimitivesNearestK }; template -auto intersect_geometries(Primitives const &primitives) +auto make_intersects(Primitives const &primitives) { Details::check_valid_access_traits(PrimitivesTag{}, primitives, Details::DoNotCheckGetReturnType()); @@ -73,15 +73,14 @@ auto intersect_geometries(Primitives const &primitives) } template -auto intersect_geometries_with_radius(Primitives const &primitives, - Coordinate r) +auto make_intersects(Primitives const &primitives, Coordinate r) { Details::check_valid_access_traits(PrimitivesTag{}, primitives); return PrimitivesWithRadius(primitives, r); } template -auto nearest_k(Primitives const &primitives, int k) +auto make_nearest(Primitives const &primitives, int k) { Details::check_valid_access_traits(PrimitivesTag{}, primitives, Details::DoNotCheckGetReturnType()); diff --git a/src/interpolation/ArborX_InterpMovingLeastSquares.hpp b/src/interpolation/ArborX_InterpMovingLeastSquares.hpp index 08d2efe42..f05fd1c52 100644 --- a/src/interpolation/ArborX_InterpMovingLeastSquares.hpp +++ b/src/interpolation/ArborX_InterpMovingLeastSquares.hpp @@ -201,7 +201,7 @@ class MovingLeastSquares // Create the predicates auto predicates = Experimental::attach_indices( - Experimental::nearest_k(target_access, _num_neighbors)); + Experimental::make_nearest(target_access, _num_neighbors)); // Create the callback Kokkos::View source_view( diff --git a/test/tstDetailsMutualReachabilityDistance.cpp b/test/tstDetailsMutualReachabilityDistance.cpp index 15d6680b1..879e5b6b3 100644 --- a/test/tstDetailsMutualReachabilityDistance.cpp +++ b/test/tstDetailsMutualReachabilityDistance.cpp @@ -42,7 +42,7 @@ auto compute_core_distances(ExecutionSpace exec_space, ArborX::Details::KokkosExt::ArithmeticTraits::infinity::value; Kokkos::deep_copy(exec_space, distances, -inf); auto predicates = ArborX::Experimental::attach_indices( - ArborX::Experimental::nearest_k(points, k)); + ArborX::Experimental::make_nearest(points, k)); bvh.query(exec_space, predicates, ArborX::Details::MaxDistance{ points, distances}); diff --git a/test/tstNeighborList.cpp b/test/tstNeighborList.cpp index 0a9ab368a..76a82947d 100644 --- a/test/tstNeighborList.cpp +++ b/test/tstNeighborList.cpp @@ -54,7 +54,7 @@ auto compute_reference(ExecutionSpace const &exec_space, Points const &points, Kokkos::View indices("Test::indices", 0); ArborX::BoundingVolumeHierarchy bvh(exec_space, points); auto predicates = ArborX::Experimental::attach_indices( - ArborX::Experimental::intersect_geometries_with_radius(points, radius)); + ArborX::Experimental::make_intersects(points, radius)); bvh.query(exec_space, predicates, Filter{}, indices, offsets); ArborX::Details::expandHalfToFull(exec_space, offsets, indices); return make_compressed_storage( diff --git a/test/tstQueryTreeRay.cpp b/test/tstQueryTreeRay.cpp index c8bb01b1b..7faffeddd 100644 --- a/test/tstQueryTreeRay.cpp +++ b/test/tstQueryTreeRay.cpp @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_ray_box_nearest, DeviceType, ray, ArborX::Box{ArborX::Point{0, 0, 0}, ArborX::Point{1, 1, 1}})); ARBORX_TEST_QUERY_TREE(exec_space, tree, - ArborX::Experimental::nearest_k(device_rays, 1), + ArborX::Experimental::make_nearest(device_rays, 1), make_reference_solution({0}, {0, 1})); } @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_ray_box_intersection, DeviceType, Kokkos::deep_copy(exec_space, device_rays, ray); ARBORX_TEST_QUERY_TREE( - exec_space, tree, ArborX::Experimental::intersect_geometries(device_rays), + exec_space, tree, ArborX::Experimental::make_intersects(device_rays), make_reference_solution({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {0, 10})); } BOOST_AUTO_TEST_SUITE_END()