/**************************************************************************** * 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_DETAILS_SORT_UTILS_HPP #define ARBORX_DETAILS_SORT_UTILS_HPP #include #include // iota #include // clone #include #include namespace ArborX::Details { // NOTE returns the permutation indices **and** sorts the input view template auto sortObjects(ExecutionSpace const &space, ViewType &view) { Kokkos::Profiling::pushRegion("ArborX::Sorting"); Kokkos::View permute( Kokkos::view_alloc(space, Kokkos::WithoutInitializing, "ArborX::Sorting::permute"), view.extent(0)); KokkosExt::iota(space, permute); KokkosExt::sortByKey(space, view, permute); Kokkos::Profiling::popRegion(); return permute; } // Helper functions and structs for applyPermutations namespace PermuteHelper { template struct CopyOp; template struct CopyOp { KOKKOS_INLINE_FUNCTION static void copy(DstViewType const &dst, size_t i_dst, SrcViewType const &src, size_t i_src) { dst(i_dst) = src(i_src); } }; template struct [[deprecated]] CopyOp { KOKKOS_INLINE_FUNCTION static void copy(DstViewType const &dst, size_t i_dst, SrcViewType const &src, size_t i_src) { for (unsigned int j = 0; j < dst.extent(1); j++) dst(i_dst, j) = src(i_src, j); } }; template struct [[deprecated]] CopyOp { KOKKOS_INLINE_FUNCTION static void copy(DstViewType const &dst, size_t i_dst, SrcViewType const &src, size_t i_src) { for (unsigned int j = 0; j < dst.extent(1); j++) for (unsigned int k = 0; k < dst.extent(2); k++) dst(i_dst, j, k) = src(i_src, j, k); } }; } // namespace PermuteHelper template void applyInversePermutation(ExecutionSpace const &space, PermutationView const &permutation, InputView const &input_view, OutputView const &output_view) { static_assert(std::is_integral_v); ARBORX_ASSERT(permutation.extent(0) == input_view.extent(0)); ARBORX_ASSERT(output_view.extent(0) == input_view.extent(0)); Kokkos::parallel_for( "ArborX::Sorting::inverse_permute", Kokkos::RangePolicy(space, 0, input_view.extent(0)), KOKKOS_LAMBDA(int i) { PermuteHelper::CopyOp::copy( output_view, permutation(i), input_view, i); }); } template void applyPermutation(ExecutionSpace const &space, PermutationView const &permutation, InputView const &input_view, OutputView const &output_view) { static_assert(std::is_integral_v); ARBORX_ASSERT(permutation.extent(0) == input_view.extent(0)); ARBORX_ASSERT(output_view.extent(0) == input_view.extent(0)); Kokkos::parallel_for( "ArborX::Sorting::permute", Kokkos::RangePolicy(space, 0, input_view.extent(0)), KOKKOS_LAMBDA(int i) { PermuteHelper::CopyOp::copy( output_view, i, input_view, permutation(i)); }); } template void applyPermutation(ExecutionSpace const &space, PermutationView const &permutation, View &view) { static_assert(std::is_integral_v); auto scratch_view = KokkosExt::clone(space, view); applyPermutation(space, permutation, scratch_view, view); } } // namespace ArborX::Details #endif