From 757c77348ff4a21881ea12591609e0fed4e4db4b Mon Sep 17 00:00:00 2001 From: Damien L-G Date: Mon, 2 Jan 2023 14:39:45 -0500 Subject: [PATCH 1/2] Implement expand half to full (neighbor list) --- .../ArborX_DetailsExpandHalfToFull.hpp | 67 ++++++++++++++++ test/CMakeLists.txt | 1 + test/tstDetailsExpandHalfToFull.cpp | 78 +++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 src/details/ArborX_DetailsExpandHalfToFull.hpp create mode 100644 test/tstDetailsExpandHalfToFull.cpp diff --git a/src/details/ArborX_DetailsExpandHalfToFull.hpp b/src/details/ArborX_DetailsExpandHalfToFull.hpp new file mode 100644 index 000000000..33e48e1f9 --- /dev/null +++ b/src/details/ArborX_DetailsExpandHalfToFull.hpp @@ -0,0 +1,67 @@ +/**************************************************************************** + * 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 * + ****************************************************************************/ + +#ifndef ARBORX_DETAILS_EXPAND_HALF_TO_FULL_HPP +#define ARBORX_DETAILS_EXPAND_HALF_TO_FULL_HPP + +#include +#include + +#include + +namespace ArborX::Details +{ + +template +void expandHalfToFull(ExecutionSpace const &space, Offsets &offsets, + Indices &indices) +{ + Kokkos::Profiling::pushRegion("ArborX::Experimental::HalfToFull"); + typename Offsets::const_type const offsets_orig = offsets; + typename Indices::const_type const indices_orig = indices; + + auto const n = offsets.extent(0) - 1; + offsets = KokkosExt::cloneWithoutInitializingNorCopying(space, offsets_orig); + Kokkos::deep_copy(space, offsets, 0); + Kokkos::parallel_for( + "ArborX::Experimental::HalfToFull::count", + Kokkos::RangePolicy(space, 0, n), KOKKOS_LAMBDA(int i) { + for (int j = offsets_orig(i); j < offsets_orig(i + 1); ++j) + { + int const k = indices_orig(j); + Kokkos::atomic_increment(&offsets(i)); + Kokkos::atomic_increment(&offsets(k)); + } + }); + exclusivePrefixSum(space, offsets); + + auto const m = KokkosExt::lastElement(space, offsets); + KokkosExt::reallocWithoutInitializing(space, indices, m); + + Offsets counts( + Kokkos::view_alloc(space, "ArborX::Experimental::HalfToFull::count"), n); + Kokkos::parallel_for( + "ArborX::Experimental::HalfToFull::rewrite", + Kokkos::RangePolicy(space, 0, n), KOKKOS_LAMBDA(int i) { + auto const offsets_i = offsets(i); + for (int j = offsets_orig(i); j < offsets_orig(i + 1); ++j) + { + int const k = indices_orig(j); + indices(offsets_i + Kokkos::atomic_fetch_inc(&counts(i))) = k; + indices(offsets(k) + Kokkos::atomic_fetch_inc(&counts(k))) = i; + } + }); + Kokkos::Profiling::popRegion(); +} + +} // namespace ArborX::Details + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 61cddc41f..e08347c19 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -205,6 +205,7 @@ add_test(NAME ArborX_Test_DetailsClusteringHelpers COMMAND ./ArborX_Test_Details add_executable(ArborX_Test_SpecializedTraversals.exe tstDetailsHalfTraversal.cpp + tstDetailsExpandHalfToFull.cpp utf_main.cpp ) target_link_libraries(ArborX_Test_SpecializedTraversals.exe PRIVATE ArborX Boost::unit_test_framework) diff --git a/test/tstDetailsExpandHalfToFull.cpp b/test/tstDetailsExpandHalfToFull.cpp new file mode 100644 index 000000000..bcc0a0b72 --- /dev/null +++ b/test/tstDetailsExpandHalfToFull.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** + * 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 * + ****************************************************************************/ + +// clang-format off +#include "boost_ext/CompressedStorageComparison.hpp" +// clang-format on + +#include "ArborXTest_StdVectorToKokkosView.hpp" +#include "ArborX_EnableDeviceTypes.hpp" // ARBORX_DEVICE_TYPES +#include "ArborX_EnableViewComparison.hpp" +#include + +#include "BoostTest_CUDA_clang_workarounds.hpp" +#include + +namespace Test +{ +using ArborXTest::toView; + +template +auto expand(ExecutionSpace space, std::vector const &offsets_host, + std::vector const &indices_host) +{ + auto offsets = toView(offsets_host, "Test::offsets"); + auto indices = toView(indices_host, "Test::indices"); + ArborX::Details::expandHalfToFull(space, offsets, indices); + + return make_compressed_storage( + Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, offsets), + Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, indices)); +} + +#define ARBORX_TEST_EXPAND_HALF_TO_FULL(exec_space, offsets_in, indices_in, \ + offsets_out, indices_out) \ + BOOST_TEST(Test::expand(exec_space, offsets_in, indices_in) == \ + make_compressed_storage(offsets_out, indices_out), \ + boost::test_tools::per_element()) + +} // namespace Test + +BOOST_AUTO_TEST_CASE_TEMPLATE(expand_half_to_full, DeviceType, + ARBORX_DEVICE_TYPES) +{ + using ExecutionSpace = typename DeviceType::execution_space; + ExecutionSpace exec_space; + + ARBORX_TEST_EXPAND_HALF_TO_FULL(exec_space, (std::vector{0}), + (std::vector{}), (std::vector{0}), + (std::vector{})); + + // (0,0) -> (0,0)(0,0) + ARBORX_TEST_EXPAND_HALF_TO_FULL( + exec_space, (std::vector{0, 1}), (std::vector{0}), + (std::vector{0, 2}), (std::vector{0, 0})); + + // (0,0)(0,0) -> (0,0)(0,0)(0,0)(0,0) + ARBORX_TEST_EXPAND_HALF_TO_FULL( + exec_space, (std::vector{0, 2}), (std::vector{0, 0}), + (std::vector{0, 4}), (std::vector{0, 0, 0, 0})); + + // (0,0)(0,1) -> (0,0)(0,1)(0,0)(1,0) + ARBORX_TEST_EXPAND_HALF_TO_FULL( + exec_space, (std::vector{0, 2, 2}), (std::vector{0, 1}), + (std::vector{0, 3, 4}), (std::vector{0, 1, 0, 0})); + + // (1,0) -> (0,1)(1,0) + ARBORX_TEST_EXPAND_HALF_TO_FULL( + exec_space, (std::vector{0, 0, 1, 1, 1}), (std::vector{0}), + (std::vector{0, 1, 2, 2, 2}), (std::vector{1, 0})); +} From f77318f0cfebf4eeeed750f5cceeb87fa979de28 Mon Sep 17 00:00:00 2001 From: Damien L-G Date: Mon, 2 Jan 2023 14:45:12 -0500 Subject: [PATCH 2/2] Fixup is_forward_iterable declaration --- test/boost_ext/CompressedStorageComparison.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/boost_ext/CompressedStorageComparison.hpp b/test/boost_ext/CompressedStorageComparison.hpp index eb4bc06a8..10979d570 100644 --- a/test/boost_ext/CompressedStorageComparison.hpp +++ b/test/boost_ext/CompressedStorageComparison.hpp @@ -13,6 +13,7 @@ #define ARBORX_BOOST_TEST_COMPRESSED_STORAGE_COMPARISON_HPP #include +#include #include #include