Skip to content

Commit 3baf7a4

Browse files
Merge pull request #2019 from arcaneframework/dev/gg-fix-itemsownerbuilder-when-info-on-several-ranks
Fix error in `ItemsOwnerBuilder` when an sorted `Item` was present on several ranks
2 parents 889a481 + 893c193 commit 3baf7a4

File tree

1 file changed

+48
-24
lines changed

1 file changed

+48
-24
lines changed

arcane/src/arcane/mesh/ItemsOwnerBuilder.cc

+48-24
Original file line numberDiff line numberDiff line change
@@ -369,43 +369,66 @@ _processSortedInfos(ItemInternalMap& items_map)
369369
const Int32 my_rank = pm->commRank();
370370
const Int32 nb_rank = pm->commSize();
371371
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();
373373
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;
374377

375378
// Comme les informations d'une entité peuvent être réparties sur plusieurs rangs
376379
// après le tri, chaque rang envoie au rang suivant les informations
377380
// 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.
378384

379385
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+
}
385404
}
386405
Int32 nb_send_to_next = items_owner_info_send_to_next.size();
387406
info() << "NbSendToNext=" << nb_send_to_next;
388407

389408
Int32 nb_to_receive_from_previous = 0;
390409
SmallArray<Parallel::Request> requests;
391410
// Envoie et recoit les tailles des tableaux
392-
if (my_rank != (nb_rank - 1))
411+
if (!is_last_rank)
393412
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)
395414
requests.add(pm->recv(ArrayView<Int32>(1, &nb_to_receive_from_previous), my_rank - 1, false));
396415

397416
pm->waitAllRequests(requests);
398417
requests.clear();
399418

400419
// Envoie le tableau au suivant et récupère celui du précédent.
401420
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)
403422
requests.add(ItemOwnerInfoSortTraits::send(pm, my_rank + 1, items_owner_info_send_to_next));
404-
if (my_rank > 0)
423+
if (!is_first_rank)
405424
requests.add(ItemOwnerInfoSortTraits::recv(pm, my_rank - 1, items_owner_info_received_from_previous));
406425
pm->waitAllRequests(requests);
407426

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;
409432

410433
Int64 current_item_uid = NULL_ITEM_UNIQUE_ID;
411434
Int32 current_item_owner = A_NULL_RANK;
@@ -419,28 +442,29 @@ _processSortedInfos(ItemInternalMap& items_map)
419442
// On envoie ensuite à tous les rangs qui possèdent cette entité ce nouveau propriétaire.
420443
// Le tableau envoyé contient une liste de couples (item_uid, item_new_owner).
421444
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];
424453
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+
433455
// Si l'id courant est différent du précédent, on commence une nouvelle liste.
434456
if (item_uid != current_item_uid) {
435457
current_item_uid = item_uid;
436458
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;
437461
}
438-
Int32 orig_sender = items_owner_info[i].m_item_sender_rank;
462+
Int32 orig_sender = first_ioi->m_item_sender_rank;
439463
UniqueArray<Int64>& send_array = resend_items_owner_info_map[orig_sender];
440464
send_array.add(current_item_uid);
441465
send_array.add(current_item_owner);
442466
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;
444468
}
445469

446470
auto exchanger{ ParallelMngUtils::createExchangerRef(pm) };
@@ -484,7 +508,7 @@ _processSortedInfos(ItemInternalMap& items_map)
484508
Int32 item_owner = CheckedConvert::toInt32(receive_info[(z * 2) + 1]);
485509
impl::ItemBase x = items_map.findItem(item_uid);
486510
if (verbose_level >= 2)
487-
info() << "SetOwner uid=" << item_uid << " new_owner" << item_owner;
511+
info() << "SetOwner uid=" << item_uid << " new_owner=" << item_owner;
488512
x.toMutable().setOwner(item_owner, my_rank);
489513
}
490514
}

0 commit comments

Comments
 (0)