Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ItemGroupsSerializer2.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ItemGroupsSerializer2.cc (C) 2000-2024 */
9/* */
10/* Serialization of entity groups. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/String.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/CheckedConvert.h"
17#include "arcane/utils/FatalErrorException.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IParallelMng.h"
22#include "arcane/core/IItemFamily.h"
23#include "arcane/core/Item.h"
24#include "arcane/core/IParallelExchanger.h"
25#include "arcane/core/ISerializer.h"
26#include "arcane/core/ItemFamilySerializeArgs.h"
27
28#include "arcane/mesh/ItemGroupsSerializer2.h"
29
30#include <algorithm>
31#include <map>
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::mesh
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42ItemGroupsSerializer2::
43ItemGroupsSerializer2(IItemFamily* item_family, IParallelExchanger* exchanger)
44: TraceAccessor(item_family->traceMng())
45, m_exchanger(exchanger)
46, m_mesh(item_family->mesh())
47, m_item_family(item_family)
48{
49 // The list of groups in itemFamily()->groups() is not necessarily the
50 // same for all subdomains. We therefore use a std::map to sort them
51 // alphabetically so that everything in m_groups_to_exchange is in the same order.
52 std::map<String, ItemGroup> group_set;
53
54 for (ItemGroupCollection::Enumerator i_group(itemFamily()->groups()); ++i_group;) {
55 ItemGroup group = *i_group;
56 if (group.internal()->needSynchronization()) {
57 group_set.insert(std::make_pair(group.name(), group));
58 }
59 }
60
61 for (const auto& iter : group_set) {
62 const ItemGroup& group = iter.second;
63 m_groups_to_exchange.add(group);
64 }
65}
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
70ItemGroupsSerializer2::
71~ItemGroupsSerializer2()
72{
73}
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78void ItemGroupsSerializer2::
79serialize(const ItemFamilySerializeArgs& args)
80{
81 ISerializer* sbuf = args.serializer();
82 Int32 rank = args.rank();
83 // NOTE: for the moment args.localIds() is not used.
84 switch (sbuf->mode()) {
85 case ISerializer::ModeReserve:
86 sbuf->reserveInt64(1);
87 sbuf->reserveSpan(eBasicDataType::Int64, m_items_to_send[rank].size());
88 break;
89 case ISerializer::ModePut:
90 sbuf->putInt64(m_items_to_send[rank].size());
91 sbuf->putSpan(m_items_to_send[rank]);
92 break;
93 case ISerializer::ModeGet:
94 ARCANE_FATAL("Do no call this method for deserialization. Use method get()");
95 }
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101void ItemGroupsSerializer2::
102get(ISerializer* sbuf, Int64Array& items_in_groups_uid)
103{
104 // Retrieves the list of uniqueId() of the group entities
105 Int64 nb_item_in_groups = sbuf->getInt64();
106 items_in_groups_uid.resize(nb_item_in_groups);
107 sbuf->getSpan(items_in_groups_uid);
108
109 info(4) << "Receiving groups family=" << itemFamily()->fullName()
110 << " n=" << nb_item_in_groups << " entities";
111
112 Integer local_index = 0;
113 UniqueArray<Int32> items_in_group_local_id;
114 [[maybe_unused]] Int32 group_index = 0;
115 for (ItemGroupList::Enumerator i_group(m_groups_to_exchange); ++i_group; ++group_index) {
116 ItemGroup group = *i_group;
117 // The first element of the array contains the number of items
118 Integer nb_item_in_group = CheckedConvert::toInteger(items_in_groups_uid[local_index]);
119 ++local_index;
120 if (nb_item_in_group != 0) {
121 Int64ArrayView items_in_group(nb_item_in_group, &items_in_groups_uid[local_index]);
122#if 0
123 info() << "Unserialize group " << group.name() << " index=" << group_index << " nb item " << nb_item_in_group;
124 for( Integer z=0; z<nb_item_in_group; ++z ){
125 info() << "UID = " << items_in_group[z];
126 }
127#endif
128 items_in_group_local_id.resize(nb_item_in_group);
129 itemFamily()->itemsUniqueIdToLocalId(items_in_group_local_id, items_in_group);
130 group.addItems(items_in_group_local_id);
131 }
132 local_index += nb_item_in_group;
133 }
134}
135
136/*---------------------------------------------------------------------------*/
137/*---------------------------------------------------------------------------*/
138
139void ItemGroupsSerializer2::
140prepareData(ConstArrayView<SharedArray<Int32>> items_exchange)
141{
142 IParallelMng* pm = m_mesh->parallelMng();
143
144 {
145 // Checks that everyone has the same number of groups
146 // TODO: it should also check that they are the same.
147 // TODO: this test can be removed if we are sure everything is OK.
148 Integer nb_group = m_groups_to_exchange.count();
149 Integer total_nb_group = pm->reduce(Parallel::ReduceMax, nb_group);
150 if (nb_group != total_nb_group) {
151 for (ItemGroupList::Enumerator i_group(m_groups_to_exchange); ++i_group;) {
152 ItemGroup group = *i_group;
153 info() << "Group: " << group.name();
154 }
155 fatal() << "Number of groups different between subdomains"
156 << " family=" << itemFamily()->fullName()
157 << " current=" << nb_group
158 << " max=" << total_nb_group;
159 }
160 }
161
162 Integer nb_sub_domain = pm->commSize();
163 // Contains for each processor the list of uniqueId() of the group entities
164 // to be transferred
165 m_items_to_send.resize(nb_sub_domain);
166 UniqueArray<Integer> first_items_to_send(m_items_to_send.size());
167 first_items_to_send.fill(0);
168
169 UniqueArray<bool> items_in_exchange(itemFamily()->maxLocalId());
170
171 Int32ConstArrayView send_sub_domains(m_exchanger->senderRanks());
172 for (Integer i = 0, is = send_sub_domains.size(); i < is; ++i) {
173 Integer dest_sub_domain = send_sub_domains[i];
174 items_in_exchange.fill(false);
175 Int32ConstArrayView items_exchange_lid(items_exchange[dest_sub_domain]);
176 for (Integer z = 0, zs = items_exchange_lid.size(); z < zs; ++z)
177 items_in_exchange[items_exchange_lid[z]] = true;
178
179 for (ItemGroupList::Enumerator i_group(m_groups_to_exchange); ++i_group;) {
180 ItemGroup group = *i_group;
181 info(4) << "Serialize group " << group.name();
182 first_items_to_send[dest_sub_domain] = m_items_to_send[dest_sub_domain].size();
183 m_items_to_send[dest_sub_domain].add(NULL_ITEM_ID);
184
185 //_prepareData(group,m_items_to_send);
186
187 ENUMERATE_ITEM (iitem, group) {
188 if (items_in_exchange[iitem.itemLocalId()])
189 m_items_to_send[dest_sub_domain].add((*iitem).uniqueId().asInt64());
190 }
191
192 Integer first_item = first_items_to_send[dest_sub_domain];
193 Integer last_item = m_items_to_send[dest_sub_domain].size() - 1;
194 info(5) << "Serialize for subdomain " << dest_sub_domain
195 << " first " << first_item << " last " << last_item;
196 m_items_to_send[dest_sub_domain][first_item] = last_item - first_item;
197 }
198 }
199}
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
204} // End namespace Arcane::mesh
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour itérer sur les entités du maillage.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:451
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:482