/**************************************************************************** * Copyright (c) 2017-2023 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 * ****************************************************************************/ #include "ArborXTest_StdVectorToKokkosView.hpp" #include "ArborX_EnableDeviceTypes.hpp" // ARBORX_DEVICE_TYPES #include "ArborX_EnableViewComparison.hpp" #include #include #include #include "BoostTest_CUDA_clang_workarounds.hpp" #include namespace Test { using ArborXTest::toView; template auto compute_core_distances(ExecutionSpace exec_space, std::vector const &points_host, int k) { auto points = toView(points_host, "Test::points"); ARBORX_ASSERT(points.extent_int(0) >= k); using MemorySpace = typename ExecutionSpace::memory_space; ArborX::BoundingVolumeHierarchy> bvh{exec_space, ArborX::Experimental::attach_indices(points)}; Kokkos::View distances( Kokkos::view_alloc(Kokkos::WithoutInitializing, "Test::core_distances"), bvh.size()); constexpr auto inf = ArborX::Details::KokkosExt::ArithmeticTraits::infinity::value; Kokkos::deep_copy(exec_space, distances, -inf); auto predicates = ArborX::Experimental::attach_indices( ArborX::Experimental::make_nearest(points, k)); bvh.query(exec_space, predicates, ArborX::Details::MaxDistance{ points, distances}); return Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, distances); } #define ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, points, k, ref) \ BOOST_TEST(Test::compute_core_distances(exec_space, points, k) == ref, \ boost::test_tools::per_element()) template auto compute_mutual_reachability_distances( ExecutionSpace exec_space, std::vector const &core_distances_host, std::vector> const &edges_host, std::vector const &distances_host) -> Kokkos::View { auto core_distances = toView(core_distances_host, "Test::core_distances"); auto edges = toView(edges_host, "Test::edges"); auto distances = toView(distances_host, "Test::distances"); auto const n = edges.size(); Kokkos::View mutual_reachability_distances( Kokkos::view_alloc(Kokkos::WithoutInitializing, "Test::mutual_reachability_distances"), n); ArborX::Details::MutualReachability const distance_mutual_reach{core_distances}; Kokkos::parallel_for( "Test::compute_mutual_reachability_distances", Kokkos::RangePolicy(exec_space, 0, n), KOKKOS_LAMBDA(int i) { mutual_reachability_distances(i) = distance_mutual_reach( edges(i).first, edges(i).second, distances(i)); }); return Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, mutual_reachability_distances); } #define ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( \ exec_space, core_distances, edges, distances, ref) \ BOOST_TEST(Test::compute_mutual_reachability_distances( \ exec_space, core_distances, edges, distances) == ref, \ boost::test_tools::per_element()) } // namespace Test BOOST_AUTO_TEST_SUITE(MutualReachabilityDistance) BOOST_AUTO_TEST_CASE_TEMPLATE(compute_core_distances, DeviceType, ARBORX_DEVICE_TYPES) { using ExecutionSpace = typename DeviceType::execution_space; ExecutionSpace exec_space; std::vector points{ {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {4, 0, 0}, }; ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, points, 1, (std::vector{0, 0, 0, 0, 0})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, points, 2, (std::vector{1, 1, 1, 1, 1})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, points, 3, (std::vector{2, 1, 1, 1, 2})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, points, 4, (std::vector{3, 2, 2, 2, 3})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, points, 5, (std::vector{4, 3, 2, 3, 4})); std::vector non_equidistant_points{ {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {6, 0, 0}, {10, 0, 0}, }; ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, non_equidistant_points, 2, (std::vector{1, 1, 1, 1, 3, 4})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, non_equidistant_points, 3, (std::vector{2, 1, 1, 2, 4, 7})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, non_equidistant_points, 4, (std::vector{3, 2, 2, 3, 4, 8})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, non_equidistant_points, 5, (std::vector{6, 5, 4, 3, 5, 9})); ARBORX_TEST_COMPUTE_CORE_DISTANCES(exec_space, non_equidistant_points, 6, (std::vector{10, 9, 8, 7, 6, 10})); } BOOST_AUTO_TEST_CASE_TEMPLATE(compute_mutual_reachability_distances, DeviceType, ARBORX_DEVICE_TYPES) { using ExecutionSpace = typename DeviceType::execution_space; ExecutionSpace exec_space; { // equidistant points // 0 1 2 3 4 //[0] [1] [2] [3] [4] std::vector> edges{{0, 1}, {0, 2}, {0, 3}, {0, 4}, {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}}; std::vector distances{1, 2, 3, 4, 1, 2, 3, 1, 2, 1}; ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{1, 1, 1, 1, 1}), edges, distances, (std::vector{1, 2, 3, 4, 1, 2, 3, 1, 2, 1})); ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{2, 1, 1, 1, 2}), edges, distances, (std::vector{2, 2, 3, 4, 1, 2, 3, 1, 2, 2})); ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{3, 2, 2, 2, 3}), edges, distances, (std::vector{3, 3, 3, 4, 2, 2, 3, 2, 3, 3})); ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{4, 3, 2, 3, 4}), edges, distances, (std::vector{4, 4, 4, 4, 3, 3, 4, 3, 4, 4})); } { // non-equidistant points // 0 1 2 3 4 5 6 7 8 9 10 //[0] [1] [2] [3] [4] [5] std::vector> edges{ {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}, {3, 4}, {3, 5}, {4, 5}}; std::vector distances{1, 2, 3, 6, 10, 1, 2, 5, 9, 1, 4, 8, 3, 7, 4}; ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{1, 1, 1, 1, 3, 4}), edges, distances, (std::vector{1, 2, 3, 6, 10, 1, 2, 5, 9, 1, 4, 8, 3, 7, 4})); ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{2, 1, 1, 2, 4, 7}), edges, distances, (std::vector{2, 2, 3, 6, 10, 1, 2, 5, 9, 2, 4, 8, 4, 7, 7})); ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{3, 2, 2, 3, 4, 8}), edges, distances, (std::vector{3, 3, 3, 6, 10, 2, 3, 5, 9, 3, 4, 8, 4, 8, 8})); ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{6, 5, 4, 3, 5, 9}), edges, distances, (std::vector{6, 6, 6, 6, 10, 5, 5, 5, 9, 4, 5, 9, 5, 9, 9})); ARBORX_TEST_COMPUTE_MUTUAL_REACHABILITY_DISTANCES( exec_space, (std::vector{10, 9, 8, 7, 6, 10}), edges, distances, (std::vector{10, 10, 10, 10, 10, 9, 9, 9, 10, 8, 8, 10, 7, 10, 10})); } } BOOST_AUTO_TEST_SUITE_END()