16#ifndef CABANA_SORT_HPP
17#define CABANA_SORT_HPP
24#include <Kokkos_Core.hpp>
25#include <Kokkos_Profiling_ScopedRegion.hpp>
26#include <Kokkos_Sort.hpp>
37template <
class MemorySpace>
43 static_assert( Kokkos::is_memory_space<MemorySpace>() );
50 using CountView = Kokkos::View<const int*, memory_space>;
52 using OffsetView = Kokkos::View<size_type*, memory_space>;
74 , _nbin( counts.extent( 0 ) )
77 , _permute_vector( permute_vector )
85 KOKKOS_INLINE_FUNCTION
93 KOKKOS_INLINE_FUNCTION
101 KOKKOS_INLINE_FUNCTION
104 return _offsets( bin_id );
111 KOKKOS_INLINE_FUNCTION
114 return _permute_vector( tuple_id );
120 KOKKOS_INLINE_FUNCTION
126 KOKKOS_INLINE_FUNCTION
141struct is_binning_data :
public std::false_type
145template <
typename MemorySpace>
146struct is_binning_data<
BinningData<MemorySpace>> :
public std::true_type
152template <
typename MemorySpace>
153struct is_binning_data<const
BinningData<MemorySpace>> :
public std::true_type
162template <
class KeyViewType,
class Comparator,
163 class ExecutionSpace =
typename KeyViewType::execution_space>
165 const bool sort_within_bins,
const std::size_t begin,
166 const std::size_t end )
168 Kokkos::Profiling::ScopedRegion region(
"Cabana::BinSort" );
169 using memory_space =
typename KeyViewType::memory_space;
172 Kokkos::BinSort<KeyViewType, Comparator> bin_sort( keys, begin, end, comp,
174 bin_sort.create_permute_vector();
177 bin_sort.get_bin_offsets(),
178 bin_sort.get_permute_vector() );
183template <
class KeyViewType,
184 class ExecutionSpace =
typename KeyViewType::execution_space>
185Kokkos::MinMaxScalar<typename KeyViewType::non_const_value_type>
186keyMinMax( KeyViewType keys,
const std::size_t begin,
const std::size_t end )
188 Kokkos::Profiling::ScopedRegion region(
"Cabana::keyMinMax" );
190 using memory_space =
typename KeyViewType::memory_space;
193 using KeyValueType =
typename KeyViewType::non_const_value_type;
194 Kokkos::MinMaxScalar<KeyValueType> result;
195 Kokkos::MinMax<KeyValueType> reducer( result );
196 Kokkos::parallel_reduce(
197 "Cabana::keyMinMax", Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
198 KOKKOS_LAMBDA( std::size_t i,
decltype( result )& local_minmax ) {
199 auto const val = keys( i );
200 if ( val < local_minmax.min_val )
202 local_minmax.min_val = val;
204 if ( val > local_minmax.max_val )
206 local_minmax.max_val = val;
218template <
class KeyViewType,
219 class ExecutionSpace =
typename KeyViewType::execution_space>
221 const bool sort_within_bins,
const std::size_t begin,
222 const std::size_t end )
229 Kokkos::BinOp1D<KeyViewType> comp( nbin, key_bounds.min_val,
230 key_bounds.max_val );
234 keys, comp, sort_within_bins, begin, end );
257template <
class KeyViewType,
class Comparator,
258 class ExecutionSpace =
typename KeyViewType::execution_space>
260 KeyViewType keys, Comparator comp,
const std::size_t begin,
261 const std::size_t end,
262 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
266 keys, comp,
true, begin, end );
267 return bin_data.permuteVector();
284template <
class KeyViewType,
class Comparator,
285 class ExecutionSpace =
typename KeyViewType::execution_space>
287 KeyViewType keys, Comparator comp,
288 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
311template <
class KeyViewType,
class Comparator,
312 class ExecutionSpace =
typename KeyViewType::execution_space>
314 KeyViewType keys, Comparator comp,
const std::size_t begin,
315 const std::size_t end,
316 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
340template <
class KeyViewType,
class Comparator,
341 class ExecutionSpace =
typename KeyViewType::execution_space>
343 KeyViewType keys, Comparator comp,
344 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
348 keys, comp,
false, 0, keys.extent( 0 ) );
364template <
class KeyViewType,
365 class ExecutionSpace =
typename KeyViewType::execution_space>
366auto sortByKey( KeyViewType keys,
const std::size_t begin,
367 const std::size_t end,
368 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
371 int nbin = ( end - begin ) / 2;
386template <
class KeyViewType,
387 class ExecutionSpace =
typename KeyViewType::execution_space>
389 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
411template <
class KeyViewType,
412 class ExecutionSpace =
typename KeyViewType::execution_space>
413auto binByKey( KeyViewType keys,
const int nbin,
const std::size_t begin,
414 const std::size_t end,
415 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
419 keys, nbin,
false, begin, end );
435template <
class KeyViewType,
436 class ExecutionSpace =
typename KeyViewType::execution_space>
438 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
442 keys, nbin,
false, 0, keys.extent( 0 ) );
457template <
class SliceType,
458 class ExecutionSpace =
typename SliceType::execution_space>
460 SliceType
slice,
const std::size_t begin,
const std::size_t end,
463 Kokkos::View<
typename SliceType::value_type*,
464 typename SliceType::memory_space>
465 keys( Kokkos::ViewAllocateWithoutInitializing(
"slice_keys" ),
481template <
class SliceType,
482 class ExecutionSpace =
typename SliceType::execution_space>
504template <
class SliceType,
505 class ExecutionSpace =
typename SliceType::execution_space>
507 SliceType
slice,
const int nbin,
const std::size_t begin,
508 const std::size_t end,
511 Kokkos::View<
typename SliceType::value_type*,
512 typename SliceType::memory_space>
513 keys( Kokkos::ViewAllocateWithoutInitializing(
"slice_keys" ),
531template <
class SliceType,
532 class ExecutionSpace =
typename SliceType::execution_space>
534 SliceType
slice,
const int nbin,
549template <
class BinningDataType,
class AoSoA_t,
550 class ExecutionSpace =
typename BinningDataType::execution_space>
552 const BinningDataType& binning_data, AoSoA_t& aosoa,
553 typename std::enable_if<( is_binning_data<BinningDataType>::value &&
557 Kokkos::Profiling::ScopedRegion region(
"Cabana::permute" );
559 using memory_space =
typename BinningDataType::memory_space;
562 auto begin = binning_data.rangeBegin();
563 auto end = binning_data.rangeEnd();
565 using memory_space =
typename BinningDataType::memory_space;
566 Kokkos::View<typename AoSoA_t::tuple_type*, memory_space> scratch_tuples(
567 Kokkos::ViewAllocateWithoutInitializing(
"scratch_tuples" ),
570 auto permute_to_scratch = KOKKOS_LAMBDA(
const std::size_t i )
572 scratch_tuples( i - begin ) =
573 aosoa.getTuple( binning_data.permutation( i - begin ) );
575 Kokkos::parallel_for(
"Cabana::kokkosBinSort::permute_to_scratch",
576 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
577 permute_to_scratch );
580 auto copy_back = KOKKOS_LAMBDA(
const std::size_t i )
582 aosoa.setTuple( i, scratch_tuples( i - begin ) );
584 Kokkos::parallel_for(
"Cabana::kokkosBinSort::copy_back",
585 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
600template <
class BinningDataType,
class SliceType,
601 class ExecutionSpace =
typename BinningDataType::execution_space>
603 const BinningDataType& binning_data, SliceType&
slice,
604 typename std::enable_if<( is_binning_data<BinningDataType>::value &&
608 Kokkos::Profiling::ScopedRegion region(
"Cabana::permute" );
610 using memory_space =
typename BinningDataType::memory_space;
613 auto begin = binning_data.rangeBegin();
614 auto end = binning_data.rangeEnd();
617 std::size_t num_comp = 1;
618 for ( std::size_t d = 2; d <
slice.viewRank(); ++d )
619 num_comp *=
slice.extent( d );
622 auto slice_data =
slice.data();
624 Kokkos::View<typename SliceType::value_type**, memory_space> scratch_array(
625 Kokkos::ViewAllocateWithoutInitializing(
"scratch_array" ), end - begin,
628 auto permute_to_scratch = KOKKOS_LAMBDA(
const std::size_t i )
630 auto permute_i = binning_data.permutation( i - begin );
631 auto s = SliceType::index_type::s( permute_i );
632 auto a = SliceType::index_type::a( permute_i );
633 std::size_t slice_offset = s *
slice.stride( 0 ) + a;
634 for ( std::size_t n = 0; n < num_comp; ++n )
635 scratch_array( i - begin, n ) =
636 slice_data[slice_offset + SliceType::vector_length * n];
638 Kokkos::parallel_for(
"Cabana::kokkosBinSort::permute_to_scratch",
639 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
640 permute_to_scratch );
643 auto copy_back = KOKKOS_LAMBDA(
const std::size_t i )
645 auto s = SliceType::index_type::s( i );
646 auto a = SliceType::index_type::a( i );
647 std::size_t slice_offset = s *
slice.stride( 0 ) + a;
648 for ( std::size_t n = 0; n < num_comp; ++n )
649 slice_data[slice_offset + SliceType::vector_length * n] =
650 scratch_array( i - begin, n );
652 Kokkos::parallel_for(
"Cabana::kokkosBinSort::copy_back",
653 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
670template <
class BinningDataType,
class ViewType,
671 class MemorySpace =
typename BinningDataType::memory_space>
673 const BinningDataType& binning_data, ViewType& view,
674 typename std::enable_if<( is_binning_data<BinningDataType>::value &&
675 Kokkos::is_view<ViewType>::value ),
678 Kokkos::Profiling::pushRegion(
"Cabana::permute" );
680 auto begin = binning_data.rangeBegin();
681 auto end = binning_data.rangeEnd();
684 std::size_t num_comp = 1;
685 for ( std::size_t d = 1; d < view.rank; ++d )
686 num_comp *= view.extent( d );
688 Kokkos::View<typename ViewType::value_type**, MemorySpace> scratch(
689 Kokkos::ViewAllocateWithoutInitializing(
"scratch" ), end - begin,
692 auto permute_to_scratch = KOKKOS_LAMBDA(
const std::size_t i )
694 auto permute_i = binning_data.permutation( i - begin );
695 for ( std::size_t n = 0; n < num_comp; ++n )
696 scratch( i - begin, n ) = view( permute_i, n );
699 Kokkos::RangePolicy<typename BinningDataType::execution_space>( begin,
701 Kokkos::parallel_for(
"Cabana::kokkosBinSort::permute_to_scratch", policy,
702 permute_to_scratch );
705 auto copy_back = KOKKOS_LAMBDA(
const std::size_t i )
707 for ( std::size_t n = 0; n < num_comp; ++n )
708 view( i, n ) = scratch( i - begin, n );
710 Kokkos::parallel_for(
"Cabana::kokkosBinSort::copy_back", policy,
714 Kokkos::Profiling::popRegion();
Array-of-Struct-of-Arrays particle data structure.
AoSoA and slice extensions for Kokkos deep copy and mirrors.
Slice a single particle property from an AoSoA.
auto kokkosBinSort(KeyViewType keys, Comparator comp, const bool sort_within_bins, const std::size_t begin, const std::size_t end)
Definition Cabana_Sort.hpp:164
auto kokkosBinSort1d(KeyViewType keys, const int nbin, const bool sort_within_bins, const std::size_t begin, const std::size_t end)
Definition Cabana_Sort.hpp:220
Kokkos::MinMaxScalar< typename KeyViewType::non_const_value_type > keyMinMax(KeyViewType keys, const std::size_t begin, const std::size_t end)
Given a set of keys, find the minimum and maximum over the given range.
Definition Cabana_Sort.hpp:186
Data describing the bin sizes and offsets resulting from a binning operation.
Definition Cabana_Sort.hpp:39
KOKKOS_INLINE_FUNCTION size_type binOffset(const size_type bin_id) const
Given a bin get the tuple index at which it sorts.
Definition Cabana_Sort.hpp:102
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_Sort.hpp:42
Kokkos::View< const int *, memory_space > CountView
Binning view type.
Definition Cabana_Sort.hpp:50
BinningData()
Default constructor.
Definition Cabana_Sort.hpp:55
typename memory_space::execution_space execution_space
Default execution space.
Definition Cabana_Sort.hpp:46
KOKKOS_INLINE_FUNCTION int binSize(const size_type bin_id) const
Given a bin get the number of tuples it contains.
Definition Cabana_Sort.hpp:94
KOKKOS_INLINE_FUNCTION std::size_t rangeBegin() const
The beginning tuple index in the binning.
Definition Cabana_Sort.hpp:121
KOKKOS_INLINE_FUNCTION std::size_t rangeEnd() const
The ending tuple index in the binning.
Definition Cabana_Sort.hpp:127
KOKKOS_INLINE_FUNCTION size_type permutation(const size_type tuple_id) const
Given a local tuple id in the binned layout, get the id of the tuple in the old (unbinned) layout.
Definition Cabana_Sort.hpp:112
Kokkos::View< size_type *, memory_space > OffsetView
Offset view type.
Definition Cabana_Sort.hpp:52
typename memory_space::size_type size_type
Memory space size type.
Definition Cabana_Sort.hpp:48
KOKKOS_INLINE_FUNCTION int numBin() const
Get the number of bins.
Definition Cabana_Sort.hpp:86
BinningData(const std::size_t begin, const std::size_t end, CountView counts, OffsetView offsets, OffsetView permute_vector)
Constructor initializing from Kokkos BinSort data.
Definition Cabana_Sort.hpp:69
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
auto binByKey(KeyViewType keys, const int nbin, const std::size_t begin, const std::size_t end, typename std::enable_if<(Kokkos::is_view< KeyViewType >::value), int >::type *=0)
Bin an AoSoA over a subset of its range based on the associated key values and number of bins....
Definition Cabana_Sort.hpp:413
void copySliceToView(ExecutionSpace exec_space, ViewType &view, const SliceType &slice, const std::size_t begin, const std::size_t end, typename std::enable_if< 2==SliceType::kokkos_view::traits::dimension::rank, int * >::type=0)
Copy from slice to View. Rank-0.
Definition Cabana_Slice.hpp:877
auto sortByKey(KeyViewType keys, const std::size_t begin, const std::size_t end, typename std::enable_if<(Kokkos::is_view< KeyViewType >::value), int >::type *=0)
Sort an AoSoA over a subset of its range based on the associated key values.
Definition Cabana_Sort.hpp:366
void permute(LinkedCellListType &linked_cell_list, PositionType &positions, typename std::enable_if<(is_linked_cell_list< LinkedCellListType >::value &&(is_aosoa< PositionType >::value||is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value)), int >::type *=0)
Given a linked cell list permute positions.
Definition Cabana_LinkedCellList.hpp:730
AoSoA_t::template member_slice_type< M > slice(const AoSoA_t &aosoa, const std::string &slice_label="")
Create a slice from an AoSoA.
Definition Cabana_AoSoA.hpp:77
auto sortByKeyWithComparator(KeyViewType keys, Comparator comp, const std::size_t begin, const std::size_t end, typename std::enable_if<(Kokkos::is_view< KeyViewType >::value), int >::type *=0)
Sort an AoSoA over a subset of its range using a general comparator over the given Kokkos View of key...
Definition Cabana_Sort.hpp:259
auto binByKeyWithComparator(KeyViewType keys, Comparator comp, const std::size_t begin, const std::size_t end, typename std::enable_if<(Kokkos::is_view< KeyViewType >::value), int >::type *=0)
Bin an AoSoA over a subset of its range using a general comparator over the given Kokkos View of keys...
Definition Cabana_Sort.hpp:313
Definition Cabana_Types.hpp:88
AoSoA static type checker.
Definition Cabana_AoSoA.hpp:61
Slice static type checker.
Definition Cabana_Slice.hpp:868