31 template<
typename MergeType>
34 template<
typename _ValueType,
typename _Compare,
typename _Distance>
35 void merge (_ValueType *in, _ValueType *out,
36 _Distance *disps,
int nproc, _Compare comp) {
38 MergeType *m =
static_cast<MergeType *
>(
this);
39 m->real_merge (in, out, disps, nproc, comp);
43 MergeType *m =
static_cast<MergeType *
>(
this);
44 return m->real_description ();
52 string s(
"Flat merge");
53 return const_cast<char*
>(s.c_str());
56 template<
typename _ValueType,
typename _Compare,
typename _Distance>
58 _Distance *disps,
int nproc, _Compare comp) {
60 _Distance heads[nproc];
61 copy (disps, disps + nproc, heads);
62 for (
int i = 0; i < disps[nproc]; ++i) {
64 for (
int j = 0; j < nproc; ++j) {
65 if (heads[j] < disps[j+1]
67 || comp (in[heads[j]], in[heads[min_head]]))) {
71 out[i] = in[heads[min_head]++];
81 string s(
"Tree merge");
82 return const_cast<char*
>(s.c_str());
85 template<
typename _ValueType,
typename _Compare,
typename _Distance>
87 _Distance *disps,
int nproc, _Compare comp) {
91 for (nproc_p = 1; nproc_p < nproc; nproc_p *= 2);
92 _Distance disps_p[nproc_p + 1];
93 copy (disps, disps + nproc + 1, disps_p);
94 fill (disps_p + nproc + 1, disps_p + nproc_p + 1, disps[nproc]);
97 for (
int i = 1; i * 2 < nproc_p + 1; i = i * 2) {
98 for (
int j = 0; j + 2*i < nproc_p + 1; j += 2*i) {
99 inplace_merge (in + disps_p[j],
101 in + disps_p[j + 2*i],
107 in + disps_p[merged], in + disps_p[nproc_p],
116 string s (
"Out-of-place tree merge");
117 return const_cast<char*
>(s.c_str());
121 template<
typename _RandomAccessIter,
typename _Compare,
typename _Distance>
122 void real_merge (_RandomAccessIter in, _RandomAccessIter out,
123 _Distance *disps,
int nproc, _Compare comp) {
126 copy (in, in + disps[nproc], out);
130 _RandomAccessIter bufs[2] = { in, out };
131 _Distance *locs =
new _Distance[nproc];
132 for (
int i = 0; i < nproc; ++i) {
138 _Distance stride = next * 2;
142 for (_Distance i = 0; i + next < nproc; i += stride) {
143 _Distance end_ind = min (i + stride, (_Distance) nproc);
146 bufs[locs[i]] + disps[i + next],
147 bufs[locs[i + next]] + disps[i + next],
148 bufs[locs[i + next]] + disps[end_ind],
149 bufs[1 - locs[i]] + disps[i],
151 locs[i] = 1 - locs[i];
161 bufs[locs[next]] + disps[next],
162 bufs[locs[next]] + disps[nproc],
164 }
else if (locs[next] == 0) {
166 std::merge (std::reverse_iterator<_RandomAccessIter> (in + disps[nproc]),
167 std::reverse_iterator<_RandomAccessIter> (in + disps[next]),
168 std::reverse_iterator<_RandomAccessIter> (out + disps[next]),
169 std::reverse_iterator<_RandomAccessIter> (out),
170 std::reverse_iterator<_RandomAccessIter> (out + disps[nproc]),
174 std::inplace_merge (out, out + disps[next], out + disps[nproc], comp);
183 class FunnelMerge2 :
public Merge<FunnelMerge2> {
185 char *real_description () {
186 return (
"Funnel(2) merge");
189 template<
typename _RandomAccessIter,
typename _Compare,
typename _Distance>
190 void real_merge (_RandomAccessIter in, _RandomAccessIter out,
191 _Distance *disps,
int nproc, _Compare comp) {
194 copy (in, in + disps[nproc], out);
200 for (
int i=0; i<nproc; ++i) {
201 merger.
add_stream (in + disps[i], in + disps[i+1]);
208 class FunnelMerge4 :
public Merge<FunnelMerge4> {
210 char *real_description () {
211 std::string s (
"Funnel(4) merge");
212 return const_cast<char*
>(s.c_str());
215 template<
typename _RandomAccessIter,
typename _Compare,
typename _Distance>
216 void real_merge (_RandomAccessIter in, _RandomAccessIter out,
217 _Distance *disps,
int nproc, _Compare comp) {
220 copy (in, in + disps[nproc], out);
226 for (
int i=0; i<nproc; ++i) {
227 merger.
add_stream (in + disps[i], in + disps[i+1]);
char * real_description()
void merge(_ValueType *in, _ValueType *out, _Distance *disps, int nproc, _Compare comp)
char * real_description()
void real_merge(_ValueType *in, _ValueType *out, _Distance *disps, int nproc, _Compare comp)
void add_stream(RanIt begin, RanIt end)
void merge(T A_, T A_last, T B_, T B_last, T C_, int p, StrictWeakOrdering comp)
void real_merge(_RandomAccessIter in, _RandomAccessIter out, _Distance *disps, int nproc, _Compare comp)
void real_merge(_ValueType *in, _ValueType *out, _Distance *disps, int nproc, _Compare comp)
char * real_description()