Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ItemGroupsSynchronize.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/* ItemGroupsSynchronize.cc (C) 2000-2025 */
9/* */
10/* Group synchronizations. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/ItemGroupsSynchronize.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/Math.h"
18
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IItemFamily.h"
22#include "arcane/core/VariableBuildInfo.h"
23#include "arcane/core/ItemPrinter.h"
24
25#include "arcane/mesh/CommonItemGroupFilterer.h"
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane::mesh
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
38: TraceAccessor(item_family->traceMng())
39, m_item_family(item_family)
40, m_var(VariableBuildInfo(item_family, "MeshItemGroupSynchronize",
41 IVariable::PNoDump | IVariable::PNoRestore),
42 item_family->itemKind())
43{
44 _setGroups();
45}
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
52: TraceAccessor(item_family->traceMng())
53, m_item_family(item_family)
54, m_var(VariableBuildInfo(item_family, "MeshItemGroupSynchronize",
55 IVariable::PNoDump | IVariable::PNoRestore),
56 item_family->itemKind())
57, m_groups(groups)
58{
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64ItemGroupsSynchronize::
65~ItemGroupsSynchronize()
66{
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72void ItemGroupsSynchronize::
73_setGroups()
74{
75 // Constructing the list of groups
76 m_groups.clear();
77 for (const ItemGroup& group : m_item_family->groups()) {
78 if (!group.internal()->needSynchronization())
79 continue;
80 m_groups.add(group);
81 }
82}
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
89{
90 ItemGroup all_items = m_item_family->allItems();
91
92 // Constructing the list of groups
94 CommonItemGroupFilterer group_filterer(m_item_family);
95 for (ItemGroup group : m_groups) {
96 ARCANE_ASSERT((!group.null()), ("Null group in ItemGroupsSynchronize"));
97 groups.add(group);
98 group_filterer.addGroupToFilter(group);
99 }
100 // TODO: check if it shouldn't be done every time
101 // This way we are sure that the groups are properly sorted
102 if (arcaneIsCheck())
103 group_filterer.applyFiltering();
104
105 Int32UniqueArray group_items; // Array storing the list of evolving items
106 group_items.reserve(m_item_family->maxLocalId());
107
108 const Integer max_aggregate_size =
109 sizeof(IntAggregator) * 8 - 1; // To stay within the positive integer space
110 const Integer aggregate_count =
111 (groups.size() / max_aggregate_size) +
112 ((groups.size() % max_aggregate_size) ? 1 : 0);
113
114 for (Integer i_aggregate = 0; i_aggregate < aggregate_count; ++i_aggregate) {
115 const Integer first_group = i_aggregate * max_aggregate_size;
116 const Integer current_aggregate_size = math::min(max_aggregate_size,
117 groups.size() - first_group);
118 m_var.fill(0); // Initialization of the parallel array
119 for (Integer i_group = 0; i_group < current_aggregate_size; ++i_group) {
120 const IntAggregator current_mask = static_cast<IntAggregator>(1) << i_group;
121 ItemGroup group = groups[first_group + i_group];
122 ENUMERATE_ITEM (iitem, group) {
123 m_var[iitem] |= current_mask;
124 }
125 }
126
127 // Sharing group content info on the aggregate
128 m_var.synchronize();
129
130 for (Integer i_group = 0; i_group < current_aggregate_size; ++i_group) {
131 const IntAggregator current_mask = static_cast<IntAggregator>(1) << i_group;
132 ItemGroup group = groups[first_group + i_group];
133 const Integer current_size = group.size();
134 if (group.internal()->hasInfoObserver()) {
135 // Switching to incremental mode
136 // Searching for missing items
137 group_items.clear();
138 ENUMERATE_ITEM (iitem, group) {
139 if ((m_var[iitem] & current_mask) == 0) {
140 group_items.add(iitem.itemLocalId());
141 }
142 else {
143 m_var[iitem] &= ~current_mask; // marks as already existing in the group
144 }
145 }
146 Integer removed_size = group_items.size();
147 group.removeItems(group_items);
148 // Searching for new items
149 group_items.clear();
150 ENUMERATE_ITEM (iitem, all_items) {
151 if ((m_var[iitem] & current_mask) != 0) {
152 group_items.add(iitem.itemLocalId());
153 }
154 }
155 group.addItems(group_items);
156 debug() << "Incremental synchronization for the group <" << group.name() << ">"
157 << " old=" << current_size << " new=" << group.size()
158 << " added=" << group_items.size() << " removed=" << removed_size;
159 }
160 else {
161 // We use the direct assignment mode for groups
162 group_items.clear();
163 ENUMERATE_ITEM (iitem, all_items) {
164 if ((m_var[iitem] & current_mask) != 0) {
165 group_items.add(iitem.itemLocalId());
166 }
167 }
168 // Preserving previous behavior: uses createGroup and not findGroup + setItems
169 group.setItems(group_items);
170 debug() << "Direct synchronization for the group <" << group.name() << ">"
171 << " old=" << current_size << " new=" << group.size();
172 }
173 }
174 }
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
182{
183 // TODO: check that all sub-domains have the same groups.
184 Integer nb_diff = 0;
185 for (const ItemGroup& group : m_item_family->groups()) {
186 if (group.isOwn())
187 continue;
188 m_var.fill(0);
189 ENUMERATE_ITEM (i_item, group) {
190 m_var[*i_item] = 1;
191 }
192 Integer diff = m_var.checkIfSync(10);
193 if (diff != 0) {
194 error() << "Group is not in sync (name=" << group.name()
195 << ", nb_diff=" << diff << ")";
196 }
197 nb_diff += diff;
198 }
199 return nb_diff;
200}
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
205} // End namespace Arcane::mesh
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
Types and macros for iterating over mesh entities.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
Integer size() const
Number of elements in the vector.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
void clear()
Removes all elements from the collection.
Interface of an entity family.
Definition IItemFamily.h:83
virtual ItemGroupCollection groups() const =0
Collection of groups in this family.
Interface of a variable.
Definition IVariable.h:40
bool hasInfoObserver() const
Indicates if the content of this group is observed.
Mesh entity group.
Definition ItemGroup.h:51
ItemGroupImpl * internal() const
Returns the group implementation.
Definition ItemGroup.h:125
const String & name() const
Group name.
Definition ItemGroup.h:81
void removeItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Removes entities.
Definition ItemGroup.cc:462
Integer size() const
Number of elements in the group.
Definition ItemGroup.h:93
void setItems(Int32ConstArrayView items_local_id)
Sets the entities of the group.
Definition ItemGroup.cc:484
void addItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Adds entities.
Definition ItemGroup.cc:439
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage error() const
Flow for an error message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Parameters necessary for building a variable.
Utility class for common groups across all parts of a mesh.
void applyFiltering()
Filters the common groups.
Integer checkSynchronize()
Checks if the groups are synchronized.
ItemGroupsSynchronize(IItemFamily *item_family)
Create an instance to synchronize all groups of the family item_family.
Int32 IntAggregator
Type used for aggregating group communications.
void synchronize()
Synchronizes the groups.
__host__ __device__ Real2 min(Real2 a, Real2 b)
Returns the minimum of two Real2.
Definition MathUtils.h:346
bool arcaneIsCheck()
True if running in check mode.
Definition Misc.cc:66
Collection< ItemGroup > ItemGroupCollection
Collection of mesh item groups.
Int32 Integer
Type representing an integer.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:341