Consider support for segmented reductions and sorts specified by count-value representation
- Dominant language
- C++
- Stars
- 2.5k
- Forks
- 486
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 295
Description
Consider this API:
```
// fills an array with runs of keys specified by the count of each run
// count_by_key is the inverse of fill_by_count
template
OutputIterator fill_by_count(InputIterator1 counts_first, InputIterator1 counts_last, InputIterator2 values_first, OutputIterator result);
// reduces contiguous runs of keys into their count
// fill_by_count is the inverse of count_by_key
template
OutputIterator count_by_key(InputIterator first, InputIterator last, OutputIterator result, Compare comp);
// count_by_key may be a bad name because it is not a vectorized version of thrust::count count_unique? unique_count?
// reduces contiguous runs of elements. each run is specified by its count
// counts come first like keys
template
OutputIterator reduce_by_count(counts_first, counts_last, values_first, result, binary_op);
// reduces contiguous runs of elements. each run's size is n, except for the last partial run
// values come first (cf. fill_n) because the last run could be partial
// XXX should n come first to match the previous?
template
OutputIterator reduce_by_count(values_first, values_last, Size n, OutputIterator result, BinaryFunction binary_op);
// sorts contiguous runs of elements. each run's is specified by its count
template
void sort_by_count(RandomAccessIterator1 counts_first, RandomAccessIterator1 counts_last, RandomAccessIterator2 values_first, Compare comp);
// sorts contiguous runs of elements. each run's size is n, except for the last partial run
template
void sort_by_count(RandomAccessIterator first, RandomAccessIterator last, Size n, Compare comp);
```
Why a count-value structure?
- The mapping between keys and counts is obvious (there are two functions which are inverses of the other)
- The important special case of uniform counts is easy for the user to find (it's just an overload)
and for the backend to target.
Why not a pairs of offsets, or range of ranges, or similar structure?
Because it forces the user to specify redundant data in the common case (continguous, non-overlapping values). It's easy to mess this up. There's no possibility of this kind of error with a count-value format (unless the user just gets the counts wrong). Indirection could be achieved as normal with a `permutation_iterator`.
Doesn't the count-value format imply that the implementation of each algorithm first has to perform an exclusive scan?
Under what conditions would an initial scan be expensive compared to the operation being performed?
If we preferred a different representation more convenient for the backend, would that simply force the user to perform the scan himself?
Contributor guide
Assessment
This issue has not been assessed yet.