void bitonic_split(_Iterator begin, _Iterator end, _Compare comp, const mxx::comm& comm, int partner, int dir) { typedef typename std::iterator_traits<_Iterator>::value_type T; size_t np = std::distance(begin, end); //std::cout << "[Rank " << comm.rank() << "]: split with partner= " << partner << ", dir=" << dir << std::endl; std::vector<T> recv_buf(np); std::vector<T> merge_buf(np); // send/recv mxx::datatype dt = mxx::get_datatype<T>(); MPI_Sendrecv(&*begin, np, dt.type(), partner, 0, &recv_buf[0], np, dt.type(), partner, 0, comm, MPI_STATUS_IGNORE); // merge in `dir` direction into merge buffer if ((dir == asc && partner > comm.rank()) || (dir == desc && partner < comm.rank())) { // forward merge and keep the `np` smaller elements _Iterator l = begin; typename std::vector<T>::iterator r = recv_buf.begin(); typename std::vector<T>::iterator o = merge_buf.begin(); for (size_t i = 0; i < np; ++i) { if (comp(*l, *r)) { *o = *l; ++o; ++l; } else { *o = *r; ++o; ++r; } } } else { // backward merge and keep the `np` larger elements _Iterator l = begin+np-1; typename std::vector<T>::iterator r = recv_buf.begin()+np-1; typename std::vector<T>::iterator o = merge_buf.begin()+np-1; for (size_t i = 0; i < np; ++i) { if (comp(*l, *r)) { *o = *r; --o; --r; } else { *o = *l; --o; --l; } } } // copy results into local buffer std::copy(merge_buf.begin(), merge_buf.end(), begin); }
int main() { int ret = 0, num_line = 0, i = 0; char ** const target_buf; char *inbuf = { "abcdef,acccd,eeee,aaaa,e3eeeee,sssss," }; ret = merge_buf(inbuf, &num_line, &target_buf); if (ret == 0) { for (i = 0; i < num_line; i++) printf("%s\n", target_buf[i]); printf("共有%d行\n", num_line); } ret = target_buf_free(&target_buf, num_line); if (ret == 0) { printf("SUCCESS!!!\n"); } return 0; }
template<class T, class LEQ> void merge_sort_leq (array<T>& a) { array<T> merge_buf(N(a)); merge_sort_sub<T, LEQ> (a, 0, N(a), merge_buf); }