File indexing completed on 2026-04-09 07:49:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #pragma once
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 #include <thrust/device_vector.h>
0061 #include <thrust/reduce.h>
0062 #include <thrust/gather.h>
0063 #include <thrust/scan.h>
0064 #include <thrust/fill.h>
0065 #include <thrust/copy.h>
0066 #include <iostream>
0067
0068 #ifdef DEBUG
0069 #include <cassert>
0070 #include <iterator>
0071 template <typename Vector>
0072 void print(const std::string& s, const Vector& v)
0073 {
0074 typedef typename Vector::value_type T;
0075
0076 std::cout << s;
0077 thrust::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, " "));
0078 std::cout << std::endl;
0079 }
0080 #endif
0081
0082
0083 template <typename InputIterator,
0084 typename OutputIterator>
0085 void iexpand(InputIterator counts_first,
0086 InputIterator counts_last,
0087 OutputIterator output_first,
0088 OutputIterator output_last)
0089 {
0090 typedef typename thrust::iterator_difference<InputIterator>::type difference_type;
0091
0092 difference_type counts_size = thrust::distance(counts_first, counts_last);
0093 difference_type output_size = thrust::distance(output_first, output_last);
0094
0095 #ifdef DEBUG
0096 std::cout << "iexpand "
0097 << " counts_size " << counts_size
0098 << " output_size " << output_size
0099 << std::endl ;
0100 #endif
0101
0102
0103 thrust::device_vector<difference_type> output_offsets(counts_size, 0);
0104
0105 thrust::exclusive_scan(counts_first, counts_last, output_offsets.begin());
0106 #ifdef DEBUG
0107 print(
0108 " scan the counts to obtain output offsets for each input element \n"
0109 " exclusive_scan of input counts creating output_offsets of transitions \n"
0110 " exclusive_scan is a cumsum that excludes current value \n"
0111 " 1st result element always 0, last input value ignored \n"
0112 " (output_offsets) \n"
0113 , output_offsets );
0114
0115 difference_type output_size2 = thrust::reduce(counts_first, counts_last);
0116 assert( output_size == output_size2 );
0117 #endif
0118
0119
0120 thrust::scatter_if
0121 (thrust::counting_iterator<difference_type>(0),
0122 thrust::counting_iterator<difference_type>(counts_size),
0123 output_offsets.begin(),
0124 counts_first,
0125 output_first);
0126
0127 #ifdef DEBUG
0128 printf(
0129 " scatter the nonzero counts into their corresponding output positions \n"
0130 " scatter_if( first, last, map, stencil, output ) \n"
0131 " conditionally copies elements from a source range (indices 0:N-1) into an output array according to a map \n"
0132 " condition dictated by a stencil (input counts) which must be non-zero to be true \n"
0133 " map provides indices of where to put the indice values in the output \n"
0134 );
0135 #endif
0136
0137 thrust::inclusive_scan
0138 (output_first,
0139 output_last,
0140 output_first,
0141 thrust::maximum<difference_type>());
0142
0143 #ifdef DEBUG
0144 printf(
0145 " compute max-scan over the output indices, filling in the holes \n"
0146 " inclusive_scan is a cumsum that includes current value \n"
0147 " providing an binary operator (maximum) replaces the default of plus \n"
0148 " because the empties are init to 0 this will fill in the empties to the right \n"
0149 );
0150 #endif
0151
0152
0153 }
0154
0155
0156