14#include "arcane/utils/TraceAccessor.h"
15#include "arcane/utils/FatalErrorException.h"
17#include "arcane/core/IParallelMng.h"
18#include "arcane/core/parallel/BitonicSort.h"
32, m_parallel_mng(parallel_mng)
39template <
typename KeyType,
typename KeyTypeTraits>
void BitonicSort<KeyType, KeyTypeTraits>::
40_init(ConstArrayView<KeyType> keys)
42 m_init_size = keys.size();
46 m_size = m_parallel_mng->reduce(Parallel::ReduceMax, m_init_size);
48 m_keys.resize(m_size);
49 m_key_ranks.resize(m_size);
50 m_key_indexes.resize(m_size);
52 Int32 rank = m_parallel_mng->commRank();
56 for (Integer i = 0; i < m_init_size; ++i) {
59 m_key_ranks[i] = rank;
64 KeyType max_value = KeyTypeTraits::maxValue();
65 for (Int64 i = m_init_size; i < m_size; i++) {
66 m_keys[i] = max_value;
67 m_key_indexes[i] = -1;
68 m_key_ranks[i] = rank;
85template <
typename KeyType,
typename KeyTypeTraits>
void
86BitonicSort<KeyType, KeyTypeTraits>::
93 info() <<
"BITONIC_SORT (64bit) want_rank?=" << m_want_index_and_rank
95 <<
" memsize=" <<
sizeof(KeyType) * m_size
96 <<
" structsize=" <<
sizeof(KeyType);
104 Int32 nb_rank = m_parallel_mng->commSize();
105 while (nb_rank > test) {
112 for (
Int32 ilevel = 0; ilevel < nb_level; ++ilevel) {
116 for (
Int32 jproc = 0; jproc < nb_rank; jproc += size) {
117 _mergeLevels(jproc, size);
125 for (
Integer i = 0; i < m_size; ++i) {
126 if (!KeyTypeTraits::isValid(m_keys[i])) {
132 info() <<
"END_BITONIC_SORT nb_merge=" << m_nb_merge;
134 m_keys.resize(m_size);
135 m_key_ranks.resize(m_size);
136 m_key_indexes.resize(m_size);
151template <
typename KeyType,
typename KeyTypeTraits>
void
156 for (
Int32 i = 0; i < size / 2; ++i)
157 _mergeProcessors(begin + i, begin + size - 1 - i);
163 Int32 div_size = size;
164 while (div_size > 1) {
166 for (
Int32 iproc = 0; iproc < size; iproc += div_size)
167 _separator(begin + iproc, div_size);
176template <
typename KeyType,
typename KeyTypeTraits>
void BitonicSort<KeyType, KeyTypeTraits>::
177_separator(Int32 begin, Int32 size)
179 for (Int32 i = 0; i < size / 2; ++i)
180 _mergeProcessors(begin + i, begin + i + size / 2);
199template <
typename KeyType,
typename KeyTypeTraits>
void BitonicSort<KeyType, KeyTypeTraits>::
200_mergeProcessors(Int32 iproc1, Int32 iproc2)
202 if (iproc1 >= iproc2)
203 ARCANE_FATAL(
"Invalid merge iproc1={0} iproc2={1}", iproc1, iproc2);
205 Int32 my_rank = m_parallel_mng->commRank();
207 if (iproc2 >= m_parallel_mng->commSize())
210 bool is_proc2 = (iproc2 == my_rank);
211 bool is_proc1 = (iproc1 == my_rank);
213 if (!is_proc1 && !is_proc2)
216 info() <<
"SORT iproc1=" << iproc1 <<
" iproc2=" << iproc2;
219 const Int64 buf_size = m_size;
220 const bool is_want_index_rank = m_want_index_and_rank;
227 UniqueArray<KeyType> send_keys(m_keys);
228 UniqueArray<Request> requests;
229 requests.add(KeyTypeTraits::send(m_parallel_mng, iproc1, send_keys));
230 if (is_want_index_rank) {
231 requests.add(m_parallel_mng->send(m_key_indexes, iproc1,
false));
232 requests.add(m_parallel_mng->send(m_key_ranks, iproc1,
false));
235 requests.add(KeyTypeTraits::recv(m_parallel_mng, iproc1, m_keys));
236 if (is_want_index_rank) {
237 requests.add(m_parallel_mng->recv(m_key_indexes, iproc1,
false));
238 requests.add(m_parallel_mng->recv(m_key_ranks, iproc1,
false));
240 m_parallel_mng->waitAllRequests(requests);
249 UniqueArray<KeyType> buf2(buf_size);
255 if (is_want_index_rank) {
256 buf2_proc.resize(buf_size);
257 buf2_local_id.resize(buf_size);
260 Request recv_request = KeyTypeTraits::recv(m_parallel_mng, iproc2, buf2);
261 m_parallel_mng->waitAllRequests(ArrayView<Request>(1, &recv_request));
262 if (is_want_index_rank) {
263 m_parallel_mng->recv(buf2_local_id, iproc2);
264 m_parallel_mng->recv(buf2_proc, iproc2);
268 buf2.add(KeyTypeTraits::maxValue());
271 Int64 total_size = m_size + buf_size;
272 UniqueArray<KeyType> buf_merge(total_size);
273 UniqueArray<Int32> buf_proc_merge;
274 UniqueArray<Int32> buf_local_id_merge;
275 if (is_want_index_rank) {
276 buf_proc_merge.resize(total_size);
277 buf_local_id_merge.resize(total_size);
281 info() <<
"SIZE=" << buf_size <<
" total=" << total_size <<
" m_size=" << m_size
282 <<
" proc2=" << iproc2 <<
" init-size=" << m_init_size;
289 for (Int64 i = 0; i < total_size; ++i) {
290 if (cursor1 >= m_size || (KeyTypeTraits::compareLess(buf2[cursor2], m_keys[cursor1]) && cursor2 < buf_size)) {
291 buf_merge[i] = buf2[cursor2];
292 if (is_want_index_rank) {
293 buf_local_id_merge[i] = buf2_local_id[cursor2];
294 buf_proc_merge[i] = buf2_proc[cursor2];
299 buf_merge[i] = m_keys[cursor1];
300 if (is_want_index_rank) {
301 buf_local_id_merge[i] = m_key_indexes[cursor1];
302 buf_proc_merge[i] = m_key_ranks[cursor1];
307 buf2.resize(buf_size);
310 for (Integer ii = 0; ii < buf_size; ii++) {
311 buf2[ii] = buf_merge[m_size + ii];
312 if (is_want_index_rank) {
313 buf2_local_id[ii] = buf_local_id_merge[m_size + ii];
314 buf2_proc[ii] = buf_proc_merge[m_size + ii];
317 Request send_request = KeyTypeTraits::send(m_parallel_mng, iproc2, buf2);
318 m_parallel_mng->waitAllRequests(ArrayView<Request>(1, &send_request));
319 if (is_want_index_rank) {
320 m_parallel_mng->send(buf2_local_id, iproc2);
321 m_parallel_mng->send(buf2_proc, iproc2);
325 for (Integer i = 0; i < buf_size; i++) {
326 m_keys[i] = buf_merge[i];
327 if (is_want_index_rank) {
328 m_key_indexes[i] = buf_local_id_merge[i];
329 m_key_ranks[i] = buf_proc_merge[i];
343template <
typename KeyType,
typename KeyTypeTraits>
void BitonicSort<KeyType, KeyTypeTraits>::
351 Int64 l = m_size / 2;
352 Int64 ir = m_size - 1;
356 Integer tmp_local_id = NULL_ITEM_LOCAL_ID;
357 Integer tmp_proc = A_NULL_RANK;
363 tmp_local_id = m_key_indexes[l];
364 tmp_proc = m_key_ranks[l];
368 tmp_local_id = m_key_indexes[ir];
369 tmp_proc = m_key_ranks[ir];
371 m_keys[ir] = m_keys[0];
372 m_key_indexes[ir] = m_key_indexes[0];
373 m_key_ranks[ir] = m_key_ranks[0];
377 m_key_indexes[0] = tmp_local_id;
378 m_key_ranks[0] = tmp_proc;
385 if (j < ir && KeyTypeTraits::compareLess(m_keys[j], m_keys[j + 1]))
387 if (KeyTypeTraits::compareLess(rra, m_keys[j])) {
388 m_keys[i] = m_keys[j];
389 m_key_indexes[i] = m_key_indexes[j];
390 m_key_ranks[i] = m_key_ranks[j];
399 m_key_indexes[i] = tmp_local_id;
400 m_key_ranks[i] = tmp_proc;
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Vue constante d'un tableau de type T.
Interface du gestionnaire de parallélisme pour un sous-domaine.
Algorithme de tri bitonique parallèle.
ConstArrayView< KeyType > keys() const override
Après un tri, retourne la liste des éléments de ce rang.
Classe d'accès aux traces.
TraceMessage info() const
Flot pour un message d'information.
Implémentation de la concurrence.
Int32 Integer
Type représentant un entier.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
std::int32_t Int32
Type entier signé sur 32 bits.