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>
46 static_assert( Impl::deprecated( Kokkos::is_device<MemorySpace>() ) );
49 using device_type [[deprecated]] =
typename memory_space::device_type;
55 using CountView = Kokkos::View<const int*, memory_space>;
57 using OffsetView = Kokkos::View<size_type*, memory_space>;
79 , _nbin( counts.extent( 0 ) )
82 , _permute_vector( permute_vector )
90 KOKKOS_INLINE_FUNCTION
98 KOKKOS_INLINE_FUNCTION
106 KOKKOS_INLINE_FUNCTION
109 return _offsets( bin_id );
116 KOKKOS_INLINE_FUNCTION
119 return _permute_vector( tuple_id );
125 KOKKOS_INLINE_FUNCTION
131 KOKKOS_INLINE_FUNCTION
146struct is_binning_data :
public std::false_type
150template <
typename MemorySpace>
151struct is_binning_data<
BinningData<MemorySpace>> :
public std::true_type
157template <
typename MemorySpace>
158struct is_binning_data<const
BinningData<MemorySpace>> :
public std::true_type
167template <
class KeyViewType,
class Comparator,
168 class ExecutionSpace =
typename KeyViewType::execution_space>
170 const bool sort_within_bins,
const std::size_t begin,
171 const std::size_t end )
173 Kokkos::Profiling::ScopedRegion region(
"Cabana::BinSort" );
174 using memory_space =
typename KeyViewType::memory_space;
177 Kokkos::BinSort<KeyViewType, Comparator> bin_sort( keys, begin, end, comp,
179 bin_sort.create_permute_vector();
182 bin_sort.get_bin_offsets(),
183 bin_sort.get_permute_vector() );
188template <
class KeyViewType,
189 class ExecutionSpace =
typename KeyViewType::execution_space>
190Kokkos::MinMaxScalar<typename KeyViewType::non_const_value_type>
191keyMinMax( KeyViewType keys,
const std::size_t begin,
const std::size_t end )
193 Kokkos::Profiling::ScopedRegion region(
"Cabana::keyMinMax" );
195 using memory_space =
typename KeyViewType::memory_space;
198 using KeyValueType =
typename KeyViewType::non_const_value_type;
199 Kokkos::MinMaxScalar<KeyValueType> result;
200 Kokkos::MinMax<KeyValueType> reducer( result );
201 Kokkos::parallel_reduce(
202 "Cabana::keyMinMax", Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
203 KOKKOS_LAMBDA( std::size_t i,
decltype( result )& local_minmax ) {
204 auto const val = keys( i );
205 if ( val < local_minmax.min_val )
207 local_minmax.min_val = val;
209 if ( val > local_minmax.max_val )
211 local_minmax.max_val = val;
223template <
class KeyViewType,
224 class ExecutionSpace =
typename KeyViewType::execution_space>
226 const bool sort_within_bins,
const std::size_t begin,
227 const std::size_t end )
234 Kokkos::BinOp1D<KeyViewType> comp( nbin, key_bounds.min_val,
235 key_bounds.max_val );
239 keys, comp, sort_within_bins, begin, end );
262template <
class KeyViewType,
class Comparator,
263 class ExecutionSpace =
typename KeyViewType::execution_space>
265 KeyViewType keys, Comparator comp,
const std::size_t begin,
266 const std::size_t end,
267 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
271 keys, comp,
true, begin, end );
272 return bin_data.permuteVector();
289template <
class KeyViewType,
class Comparator,
290 class ExecutionSpace =
typename KeyViewType::execution_space>
292 KeyViewType keys, Comparator comp,
293 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
316template <
class KeyViewType,
class Comparator,
317 class ExecutionSpace =
typename KeyViewType::execution_space>
319 KeyViewType keys, Comparator comp,
const std::size_t begin,
320 const std::size_t end,
321 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
345template <
class KeyViewType,
class Comparator,
346 class ExecutionSpace =
typename KeyViewType::execution_space>
348 KeyViewType keys, Comparator comp,
349 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
353 keys, comp,
false, 0, keys.extent( 0 ) );
369template <
class KeyViewType,
370 class ExecutionSpace =
typename KeyViewType::execution_space>
371auto sortByKey( KeyViewType keys,
const std::size_t begin,
372 const std::size_t end,
373 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
376 int nbin = ( end - begin ) / 2;
391template <
class KeyViewType,
392 class ExecutionSpace =
typename KeyViewType::execution_space>
394 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
416template <
class KeyViewType,
417 class ExecutionSpace =
typename KeyViewType::execution_space>
418auto binByKey( KeyViewType keys,
const int nbin,
const std::size_t begin,
419 const std::size_t end,
420 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
424 keys, nbin,
false, begin, end );
440template <
class KeyViewType,
441 class ExecutionSpace =
typename KeyViewType::execution_space>
443 typename std::enable_if<( Kokkos::is_view<KeyViewType>::value ),
447 keys, nbin,
false, 0, keys.extent( 0 ) );
462template <
class SliceType,
463 class ExecutionSpace =
typename SliceType::execution_space>
465 SliceType
slice,
const std::size_t begin,
const std::size_t end,
468 Kokkos::View<
typename SliceType::value_type*,
469 typename SliceType::memory_space>
470 keys( Kokkos::ViewAllocateWithoutInitializing(
"slice_keys" ),
486template <
class SliceType,
487 class ExecutionSpace =
typename SliceType::execution_space>
509template <
class SliceType,
510 class ExecutionSpace =
typename SliceType::execution_space>
512 SliceType
slice,
const int nbin,
const std::size_t begin,
513 const std::size_t end,
516 Kokkos::View<
typename SliceType::value_type*,
517 typename SliceType::memory_space>
518 keys( Kokkos::ViewAllocateWithoutInitializing(
"slice_keys" ),
536template <
class SliceType,
537 class ExecutionSpace =
typename SliceType::execution_space>
539 SliceType
slice,
const int nbin,
554template <
class BinningDataType,
class AoSoA_t,
555 class ExecutionSpace =
typename BinningDataType::execution_space>
557 const BinningDataType& binning_data, AoSoA_t& aosoa,
558 typename std::enable_if<( is_binning_data<BinningDataType>::value &&
562 Kokkos::Profiling::ScopedRegion region(
"Cabana::permute" );
564 using memory_space =
typename BinningDataType::memory_space;
567 auto begin = binning_data.rangeBegin();
568 auto end = binning_data.rangeEnd();
570 using memory_space =
typename BinningDataType::memory_space;
571 Kokkos::View<typename AoSoA_t::tuple_type*, memory_space> scratch_tuples(
572 Kokkos::ViewAllocateWithoutInitializing(
"scratch_tuples" ),
575 auto permute_to_scratch = KOKKOS_LAMBDA(
const std::size_t i )
577 scratch_tuples( i - begin ) =
578 aosoa.getTuple( binning_data.permutation( i - begin ) );
580 Kokkos::parallel_for(
"Cabana::kokkosBinSort::permute_to_scratch",
581 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
582 permute_to_scratch );
585 auto copy_back = KOKKOS_LAMBDA(
const std::size_t i )
587 aosoa.setTuple( i, scratch_tuples( i - begin ) );
589 Kokkos::parallel_for(
"Cabana::kokkosBinSort::copy_back",
590 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
605template <
class BinningDataType,
class SliceType,
606 class ExecutionSpace =
typename BinningDataType::execution_space>
608 const BinningDataType& binning_data, SliceType&
slice,
609 typename std::enable_if<( is_binning_data<BinningDataType>::value &&
613 Kokkos::Profiling::ScopedRegion region(
"Cabana::permute" );
615 using memory_space =
typename BinningDataType::memory_space;
618 auto begin = binning_data.rangeBegin();
619 auto end = binning_data.rangeEnd();
622 std::size_t num_comp = 1;
623 for ( std::size_t d = 2; d <
slice.viewRank(); ++d )
624 num_comp *=
slice.extent( d );
627 auto slice_data =
slice.data();
629 Kokkos::View<typename SliceType::value_type**, memory_space> scratch_array(
630 Kokkos::ViewAllocateWithoutInitializing(
"scratch_array" ), end - begin,
633 auto permute_to_scratch = KOKKOS_LAMBDA(
const std::size_t i )
635 auto permute_i = binning_data.permutation( i - begin );
636 auto s = SliceType::index_type::s( permute_i );
637 auto a = SliceType::index_type::a( permute_i );
638 std::size_t slice_offset = s *
slice.stride( 0 ) + a;
639 for ( std::size_t n = 0; n < num_comp; ++n )
640 scratch_array( i - begin, n ) =
641 slice_data[slice_offset + SliceType::vector_length * n];
643 Kokkos::parallel_for(
"Cabana::kokkosBinSort::permute_to_scratch",
644 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
645 permute_to_scratch );
648 auto copy_back = KOKKOS_LAMBDA(
const std::size_t i )
650 auto s = SliceType::index_type::s( i );
651 auto a = SliceType::index_type::a( i );
652 std::size_t slice_offset = s *
slice.stride( 0 ) + a;
653 for ( std::size_t n = 0; n < num_comp; ++n )
654 slice_data[slice_offset + SliceType::vector_length * n] =
655 scratch_array( i - begin, n );
657 Kokkos::parallel_for(
"Cabana::kokkosBinSort::copy_back",
658 Kokkos::RangePolicy<ExecutionSpace>( begin, end ),
675template <
class BinningDataType,
class ViewType,
676 class DeviceType =
typename BinningDataType::device_type>
678 const BinningDataType& binning_data, ViewType& view,
679 typename std::enable_if<( is_binning_data<BinningDataType>::value &&
680 Kokkos::is_view<ViewType>::value ),
683 Kokkos::Profiling::pushRegion(
"Cabana::permute" );
685 auto begin = binning_data.rangeBegin();
686 auto end = binning_data.rangeEnd();
689 std::size_t num_comp = 1;
690 for ( std::size_t d = 1; d < view.rank; ++d )
691 num_comp *= view.extent( d );
693 Kokkos::View<typename ViewType::value_type**, DeviceType> scratch(
694 Kokkos::ViewAllocateWithoutInitializing(
"scratch" ), end - begin,
697 auto permute_to_scratch = KOKKOS_LAMBDA(
const std::size_t i )
699 auto permute_i = binning_data.permutation( i - begin );
700 for ( std::size_t n = 0; n < num_comp; ++n )
701 scratch( i - begin, n ) = view( permute_i, n );
704 Kokkos::RangePolicy<typename DeviceType::execution_space>( begin, end );
705 Kokkos::parallel_for(
"Cabana::kokkosBinSort::permute_to_scratch", policy,
706 permute_to_scratch );
709 auto copy_back = KOKKOS_LAMBDA(
const std::size_t i )
711 for ( std::size_t n = 0; n < num_comp; ++n )
712 view( i, n ) = scratch( i - begin, n );
714 Kokkos::parallel_for(
"Cabana::kokkosBinSort::copy_back", policy,
718 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:169
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:225
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:191
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:107
Kokkos::View< const int *, memory_space > CountView
Binning view type.
Definition Cabana_Sort.hpp:55
BinningData()
Default constructor.
Definition Cabana_Sort.hpp:60
typename memory_space::execution_space execution_space
Default execution space.
Definition Cabana_Sort.hpp:51
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:99
KOKKOS_INLINE_FUNCTION std::size_t rangeBegin() const
The beginning tuple index in the binning.
Definition Cabana_Sort.hpp:126
KOKKOS_INLINE_FUNCTION std::size_t rangeEnd() const
The ending tuple index in the binning.
Definition Cabana_Sort.hpp:132
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:117
Kokkos::View< size_type *, memory_space > OffsetView
Offset view type.
Definition Cabana_Sort.hpp:57
typename memory_space::size_type size_type
Memory space size type.
Definition Cabana_Sort.hpp:53
KOKKOS_INLINE_FUNCTION int numBin() const
Get the number of bins.
Definition Cabana_Sort.hpp:91
typename MemorySpace::memory_space memory_space
Memory space.
Definition Cabana_Sort.hpp:44
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:74
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:418
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:870
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:371
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:737
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:264
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:318
Definition Cabana_Types.hpp:88
AoSoA static type checker.
Definition Cabana_AoSoA.hpp:61
Slice static type checker.
Definition Cabana_Slice.hpp:861