/**************************************************************************** * 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 * ****************************************************************************/ #include "ArborX_EnableDeviceTypes.hpp" // ARBORX_DEVICE_TYPES #include #include #include "BoostTest_CUDA_clang_workarounds.hpp" #include using namespace ArborX::Details; #include template struct PointCloud { ArborX::Point *data; int n; }; template struct ArborX::AccessTraits, ArborX::PrimitivesTag> { using Points = PointCloud; static KOKKOS_FUNCTION std::size_t size(Points const &points) { return points.n; } static KOKKOS_FUNCTION auto get(Points const &points, std::size_t i) { return points.data[i]; } using memory_space = MemorySpace; }; template struct PairPointIndexCloud { ArborX::Point *data; int n; }; template struct ArborX::AccessTraits, ArborX::PrimitivesTag> { using Points = PairPointIndexCloud; static KOKKOS_FUNCTION std::size_t size(Points const &points) { return points.n; } static KOKKOS_FUNCTION auto get(Points const &points, std::size_t i) { return ArborX::PairValueIndex{points.data[i], (int)i}; } using memory_space = MemorySpace; }; template struct SceneReductionFunctor { Indexables _indexables; KOKKOS_FUNCTION void operator()(int i, BoundingVolume &update) const { ArborX::Details::expand(update, _indexables(i)); } KOKKOS_FUNCTION void join(BoundingVolume &result, BoundingVolume const &update) { expand(result, update); } }; template inline void calculateBoundingBoxOfTheScene(ExecutionSpace const &space, Indexables const &indexables, Box &scene_bounding_box) { Kokkos::parallel_reduce( "ArborX::TreeConstruction::calculate_bounding_box_of_the_scene", Kokkos::RangePolicy(space, 0, indexables.size()), SceneReductionFunctor{indexables}, scene_bounding_box); } BOOST_AUTO_TEST_SUITE(IndexableGetterAccess) BOOST_AUTO_TEST_CASE_TEMPLATE(indexables, DeviceType, ARBORX_DEVICE_TYPES) { // Test that the two-level wrapping Data -> AccessValues -> Indexables by // using DefaultIndexableGetter works correctly. using ExecutionSpace = typename DeviceType::execution_space; using MemorySpace = typename DeviceType::memory_space; using ArborX::Details::equals; Kokkos::View points("Testing::points", 2); auto points_host = Kokkos::create_mirror_view(points); points_host(0) = {-1, -1, -1}; points_host(1) = {1, 1, 1}; Kokkos::deep_copy(points, points_host); ArborX::Box scene_bounding_box = ArborX::Box{{-1, -1, -1}, {1, 1, 1}}; using IndexableGetter = ArborX::Details::DefaultIndexableGetter; IndexableGetter indexable_getter; { PointCloud points_cloud{points.data(), (int)points.size()}; using Primitives = ArborX::Details::AccessValues; Primitives primitives(points_cloud); ArborX::Details::Indexables indexables{ primitives, indexable_getter}; ArborX::Box box; calculateBoundingBoxOfTheScene(ExecutionSpace{}, indexables, box); BOOST_TEST(equals(box, scene_bounding_box)); } { PairPointIndexCloud points_cloud{points.data(), (int)points.size()}; using Primitives = ArborX::Details::AccessValues; Primitives primitives(points_cloud); ArborX::Details::Indexables indexables{ primitives, indexable_getter}; ArborX::Box box; calculateBoundingBoxOfTheScene(ExecutionSpace{}, indexables, box); BOOST_TEST(equals(box, scene_bounding_box)); } } BOOST_AUTO_TEST_SUITE_END()