@@ -369,43 +369,66 @@ _processSortedInfos(ItemInternalMap& items_map)
369
369
const Int32 my_rank = pm->commRank ();
370
370
const Int32 nb_rank = pm->commSize ();
371
371
ConstArrayView<ItemOwnerInfo> items_owner_info = m_items_owner_info;
372
- const Int32 nb_sorted = items_owner_info.size ();
372
+ Int32 nb_sorted = items_owner_info.size ();
373
373
info () << " NbSorted=" << nb_sorted;
374
+ const bool is_last_rank = ((my_rank + 1 ) == nb_rank);
375
+ const bool is_first_rank = (my_rank == 0 );
376
+ const Int32 verbose_level = m_verbose_level;
374
377
375
378
// Comme les informations d'une entité peuvent être réparties sur plusieurs rangs
376
379
// après le tri, chaque rang envoie au rang suivant les informations
377
380
// de la dernière entité de sa liste.
381
+ // Il faut faire attention à bien envoyer la liste dans le même ordre trié pour
382
+ // garantir la cohérence car on va prendre le premier élément de la liste pour
383
+ // positionner le propriétaire.
378
384
379
385
UniqueArray<ItemOwnerInfo> items_owner_info_send_to_next;
380
- for (Int32 i = (nb_sorted - 1 ); i >= 0 ; --i) {
381
- const ItemOwnerInfo& x = items_owner_info[i];
382
- if (x.m_item_uid != items_owner_info[nb_sorted - 1 ].m_item_uid )
383
- break ;
384
- items_owner_info_send_to_next.add (x);
386
+ if (nb_sorted > 0 && !is_last_rank) {
387
+ Int32 send_index = nb_sorted;
388
+ Int64 last_uid = items_owner_info[nb_sorted - 1 ].m_item_uid ;
389
+ for (Int32 i = (nb_sorted - 1 ); i >= 0 ; --i) {
390
+ const ItemOwnerInfo& x = items_owner_info[i];
391
+ if (x.m_item_uid != last_uid) {
392
+ send_index = i + 1 ;
393
+ break ;
394
+ }
395
+ }
396
+ info () << " SendIndext=" << send_index << " nb_sorted=" << nb_sorted;
397
+ for (Int32 i = send_index; i < nb_sorted; ++i) {
398
+ const ItemOwnerInfo& x = items_owner_info[i];
399
+ items_owner_info_send_to_next.add (x);
400
+ if (verbose_level >= 2 )
401
+ info () << " AddSendToNext item_uid=" << x.m_item_uid << " owner=" << x.m_cell_owner
402
+ << " from_rank=" << x.m_item_sender_rank << " index=" << i;
403
+ }
385
404
}
386
405
Int32 nb_send_to_next = items_owner_info_send_to_next.size ();
387
406
info () << " NbSendToNext=" << nb_send_to_next;
388
407
389
408
Int32 nb_to_receive_from_previous = 0 ;
390
409
SmallArray<Parallel::Request> requests;
391
410
// Envoie et recoit les tailles des tableaux
392
- if (my_rank != (nb_rank - 1 ) )
411
+ if (!is_last_rank )
393
412
requests.add (pm->send (ConstArrayView<Int32>(1 , &nb_send_to_next), my_rank + 1 , false ));
394
- if (my_rank > 0 )
413
+ if (!is_first_rank )
395
414
requests.add (pm->recv (ArrayView<Int32>(1 , &nb_to_receive_from_previous), my_rank - 1 , false ));
396
415
397
416
pm->waitAllRequests (requests);
398
417
requests.clear ();
399
418
400
419
// Envoie le tableau au suivant et récupère celui du précédent.
401
420
UniqueArray<ItemOwnerInfo> items_owner_info_received_from_previous (nb_to_receive_from_previous);
402
- if (my_rank != (nb_rank - 1 ) )
421
+ if (!is_last_rank )
403
422
requests.add (ItemOwnerInfoSortTraits::send (pm, my_rank + 1 , items_owner_info_send_to_next));
404
- if (my_rank > 0 )
423
+ if (!is_first_rank )
405
424
requests.add (ItemOwnerInfoSortTraits::recv (pm, my_rank - 1 , items_owner_info_received_from_previous));
406
425
pm->waitAllRequests (requests);
407
426
408
- const Int32 verbose_level = m_verbose_level;
427
+ // Supprime de la liste les entités qu'on a envoyé au suivant
428
+ m_items_owner_info.resize (nb_sorted - nb_send_to_next);
429
+ items_owner_info = m_items_owner_info.view ();
430
+ nb_sorted = items_owner_info.size ();
431
+ info () << " NbRemaining=" << nb_sorted;
409
432
410
433
Int64 current_item_uid = NULL_ITEM_UNIQUE_ID;
411
434
Int32 current_item_owner = A_NULL_RANK;
@@ -419,28 +442,29 @@ _processSortedInfos(ItemInternalMap& items_map)
419
442
// On envoie ensuite à tous les rangs qui possèdent cette entité ce nouveau propriétaire.
420
443
// Le tableau envoyé contient une liste de couples (item_uid, item_new_owner).
421
444
impl::HashTableMap2<Int32, UniqueArray<Int64>> resend_items_owner_info_map;
422
- for (Int32 i = 0 ; i < nb_sorted; ++i) {
423
- const ItemOwnerInfo* first_ioi = &items_owner_info[i];
445
+ for (Int32 index = 0 ; index < (nb_sorted + nb_to_receive_from_previous); ++index ) {
446
+ const ItemOwnerInfo* first_ioi = nullptr ;
447
+ // Si \a i est inférieur à nb_to_receive_from_previous, on prend
448
+ // les informations de la liste recue.
449
+ if (index < nb_to_receive_from_previous)
450
+ first_ioi = &items_owner_info_received_from_previous[index ];
451
+ else
452
+ first_ioi = &items_owner_info[index - nb_to_receive_from_previous];
424
453
Int64 item_uid = first_ioi->m_item_uid ;
425
- // Si on est au début de la liste, prend l'entité envoyée par le rang précédent
426
- // si c'est la même que la nôtre.
427
- if (i == 0 && nb_to_receive_from_previous > 0 ) {
428
- ItemOwnerInfo* first_previous = &items_owner_info_received_from_previous[0 ];
429
- if (item_uid == first_previous->m_item_uid ) {
430
- first_ioi = first_previous;
431
- }
432
- }
454
+
433
455
// Si l'id courant est différent du précédent, on commence une nouvelle liste.
434
456
if (item_uid != current_item_uid) {
435
457
current_item_uid = item_uid;
436
458
current_item_owner = first_ioi->m_cell_owner ;
459
+ if (verbose_level >= 2 )
460
+ info () << " SetOwner from sorted index=" << index << " item_uid=" << current_item_uid << " new_owner=" << current_item_owner;
437
461
}
438
- Int32 orig_sender = items_owner_info[i]. m_item_sender_rank ;
462
+ Int32 orig_sender = first_ioi-> m_item_sender_rank ;
439
463
UniqueArray<Int64>& send_array = resend_items_owner_info_map[orig_sender];
440
464
send_array.add (current_item_uid);
441
465
send_array.add (current_item_owner);
442
466
if (verbose_level >= 2 )
443
- info () << " SEND i=" << i << " rank=" << orig_sender << " item_uid=" << current_item_uid << " new_owner=" << current_item_owner;
467
+ info () << " SEND i=" << index << " rank=" << orig_sender << " item_uid=" << current_item_uid << " new_owner=" << current_item_owner;
444
468
}
445
469
446
470
auto exchanger{ ParallelMngUtils::createExchangerRef (pm) };
@@ -484,7 +508,7 @@ _processSortedInfos(ItemInternalMap& items_map)
484
508
Int32 item_owner = CheckedConvert::toInt32 (receive_info[(z * 2 ) + 1 ]);
485
509
impl::ItemBase x = items_map.findItem (item_uid);
486
510
if (verbose_level >= 2 )
487
- info () << " SetOwner uid=" << item_uid << " new_owner" << item_owner;
511
+ info () << " SetOwner uid=" << item_uid << " new_owner= " << item_owner;
488
512
x.toMutable ().setOwner (item_owner, my_rank);
489
513
}
490
514
}
0 commit comments