Skip to content

Commit 893c193

Browse files
[arcane,mesh] Corrige erreur si une même entité est présente sur plusieurs rangs après le tri.
Dans ce cas la liste envoyée n'était pas dans le même ordre que les derniers éléments ce qui pouvait introduire des incohérences.
1 parent 889a481 commit 893c193

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)