Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
VariableSynchronizerComputeList.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/* VariableSynchronizerComputeList.cc (C) 2000-2024 */
9/* */
10/* Calculation of the list of entities to synchronize. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/VariableSynchronizerComputeList.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/PlatformUtils.h"
19#include "arcane/utils/OStringStream.h"
20#include "arcane/utils/ValueConvert.h"
21
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/ItemPrinter.h"
25
26#include "arcane/impl/DataSynchronizeInfo.h"
27#include "arcane/impl/internal/VariableSynchronizer.h"
28
29#include <algorithm>
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40VariableSynchronizerComputeList::
41VariableSynchronizerComputeList(VariableSynchronizer* var_sync)
42: TraceAccessor(var_sync->traceMng())
43, m_synchronizer(var_sync)
44, m_parallel_mng(var_sync->m_parallel_mng)
45, m_item_group(var_sync->m_item_group)
46, m_is_verbose(var_sync->m_is_verbose)
47{
48 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_DEBUG_VARIABLESYNCHRONIZERCOMPUTELIST", true))
49 m_is_debug = (v.value() != 0);
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
74void VariableSynchronizerComputeList::
75compute()
76{
77 const bool is_debug = m_is_debug;
78 IItemFamily* item_family = m_item_group.itemFamily();
79 Int32 my_rank = m_parallel_mng->commRank();
80 Int32 nb_rank = m_parallel_mng->commSize();
81
82 m_is_verbose = traceMng()->verbosityLevel() >= 4;
83
84 UniqueArray<SharedArray<Int32>> boundary_items(nb_rank);
85
86 info() << "Compute synchronize informations group=" << m_item_group.name()
87 << " family=" << item_family->fullName()
88 << " group size=" << m_item_group.size()
89 << " is_verbose=" << m_is_verbose;
90
91 {
92 Integer nb_error = 0;
93 Int64UniqueArray bad_items_uid;
94 ENUMERATE_ITEM (i, m_item_group) {
95 Item item = *i;
96 impl::ItemBase item_internal = item.itemBase();
97 Int32 owner = item_internal.owner();
98 if (owner == my_rank)
99 continue;
100 Int64 uid = item_internal.uniqueId().asInt64();
101 if (owner == A_NULL_RANK || owner >= nb_rank) {
102 ++nb_error;
103 if (nb_error < 10)
104 bad_items_uid.add(uid);
105 continue;
106 }
107 if (is_debug) {
108 info() << "Add entity uid=" << uid
109 << " lid=" << item_internal.localId() << " to the subdomain " << owner;
110 }
111 boundary_items[owner].add(item_internal.localId());
112 }
113 if (nb_error != 0) {
114 for (Int64 uid : bad_items_uid) {
115 info() << "ERROR: The entity uid=" << uid
116 << " group=" << m_item_group.name() << " doesn't belong to "
117 << "any subdomain or belong to an invalid subdomain";
118 }
119 ARCANE_FATAL("Error while creating synchronization information nb_error={0}", nb_error);
120 }
121 }
122
123 _createList(boundary_items);
124
125 if (is_debug)
126 _printSyncList();
127
128 info() << "End compute synchronize information group=" << m_item_group.name()
129 << " Date=" << platform::getCurrentDateTime();
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
135void VariableSynchronizerComputeList::
136_createList(UniqueArray<SharedArray<Int32>>& boundary_items)
137{
138 const bool is_debug = m_is_debug;
139 DataSynchronizeInfo* sync_info = m_synchronizer->m_sync_info.get();
140
141 sync_info->clear();
142
143 IItemFamily* item_family = m_item_group.itemFamily();
144 IParallelMng* pm = m_parallel_mng;
145 Int32 my_rank = pm->commRank();
146 Int32 nb_rank = pm->commSize();
147 info(4) << "VariableSynchronizer::createList() begin for group=" << m_item_group.name();
148
149 Real time_begin = platform::getRealTime();
150 Real time_before_all_gather = 0.0;
151 Real time_after_all_gather = 0.0;
152 Real time_before_sendrecv = 0.0;
153 Real time_after_sendrecv = 0.0;
154 Real time_after_sendrecv_wait = 0.0;
155
156 // Table of neighborhood known by ghost items.
157 // This is not necessarily the final list for sync_info->communicatingRanks() in the case
158 // of non-symmetric ghost/shared relationship between processors (if one of them is 0)
159 // The complementary processing appears after the "Communication Reciprocity" section
160 Int32UniqueArray communicating_ghost_ranks;
161 for (Integer i = 0; i < nb_rank; ++i) {
162 if (boundary_items[i].empty())
163 continue;
164 communicating_ghost_ranks.add(i);
165 if (is_debug) {
166 ItemInfoListView items_internal(item_family);
167 for (Integer z = 0, zs = boundary_items[i].size(); z < zs; ++z) {
168 Item item = items_internal[boundary_items[i][z]];
169 info() << "Item uid=" << item.uniqueId() << ",lid=" << item.localId();
170 }
171 }
172 }
173
174 Integer nb_comm_rank = communicating_ghost_ranks.size();
175
176 Int32UniqueArray nb_ghost(nb_rank);
177 Int32UniqueArray nb_share(nb_rank);
178 nb_ghost.fill(0);
179
180 // Maximum number of connected subdomains. Used to dimension
181 // the arrays for the allGather()
182 Integer max_comm_rank = pm->reduce(Parallel::ReduceMax, nb_comm_rank);
183 debug() << "communicating sub domains my=" << nb_comm_rank
184 << " max=" << max_comm_rank;
185
186 // List of ghost cell groups.
187 UniqueArray<SharedArray<Int32>> ghost_group_list(boundary_items.size());
188
189 // Retrieves the lists of ghost entities.
190 for (Integer i = 0; i < nb_comm_rank; ++i) {
191 Int32 current_rank = communicating_ghost_ranks[i];
192 SharedArray<Int32>& ghost_grp = boundary_items[current_rank];
193 ghost_group_list[i] = ghost_grp;
194 nb_ghost[current_rank] = ghost_grp.size();
195 }
196
197 UniqueArray<ShareRankInfo> share_rank_info;
198 UniqueArray<GhostRankInfo> ghost_rank_info;
199 {
200 Integer gather_size = 1 + (max_comm_rank * 2);
201 Int32UniqueArray global_ghost_info(gather_size * nb_rank);
202 {
203 // Each subdomain constructs an array indicating for
204 // each group of ghost elements, the concerned processor and
205 // the number of elements in this group.
206 // This array will then be gathered across all subdomains
207 // (by an allGather()) so that each subdomain can iterate through it
208 // and then know who owns its shared cells.
209 Int32UniqueArray local_ghost_info(gather_size);
210 Integer pos = 0;
211 local_ghost_info[pos++] = nb_comm_rank; // Indicates the number of elements in the array
212 debug() << "Send local info " << nb_comm_rank;
213 for (Integer index = 0, s = communicating_ghost_ranks.size(); index < s; ++index) {
214 local_ghost_info[pos++] = communicating_ghost_ranks[index];
215 local_ghost_info[pos++] = ghost_group_list[index].size();
216 debug() << "Send local info i=" << index << " target=" << communicating_ghost_ranks[index]
217 << " nb=" << ghost_group_list[index].size();
218 }
219 time_before_all_gather = platform::getRealTime();
220 if (m_is_verbose) {
221 info() << "AllGather size() " << local_ghost_info.size()
222 << ' ' << global_ghost_info.size()
223 << " begin_date=" << platform::getCurrentDateTime();
224 }
225 pm->allGather(local_ghost_info, global_ghost_info);
226 time_after_all_gather = platform::getRealTime();
227 if (m_is_verbose) {
228 info() << "AllGather end_date=" << platform::getCurrentDateTime();
229 }
230 }
231 {
232 for (Integer index = 0, s = nb_rank; index < s; ++index) {
233 Integer pos = gather_size * index;
234 Integer sub_size = global_ghost_info[pos++];
235 for (Integer sub_index = 0; sub_index < sub_size; ++sub_index) {
236 Integer proc_id = global_ghost_info[pos++];
237 Integer nb_elem = global_ghost_info[pos++];
238 if (proc_id == my_rank) {
239 if (is_debug) {
240 info() << "Get for share group " << index << ' ' << nb_elem;
241 }
242 share_rank_info.add(ShareRankInfo(index, nb_elem));
243 }
244 }
245 }
246 }
247
248 {
249 // Created the infos concerning the ghost cells
250 Integer nb_send = communicating_ghost_ranks.size();
251 ghost_rank_info.resize(nb_send);
252 for (Integer i = 0; i < nb_send; ++i) {
253 SharedArray<Int32> gr = ghost_group_list[i];
254 ghost_rank_info[i].setInfos(communicating_ghost_ranks[i], gr);
255 }
256 }
257 }
258 //pm->barrier();
259 ItemInfoListView items_internal(item_family);
260 {
261 {
262 // Communication Reciprocity
263 // For synchronizations to work correctly, it is necessary that
264 // 'share_rank_info' and 'ghost_rank_info' have
265 // the same number of elements. If this is not the case, it means
266 // that a processor 'n' owns shared cells with proc 'm'
267 // without this being reciprocal. If this is the case, we add
268 // a reference to this subdomain in 'share_rank_info'
269 // with no elements to send.
270 Integer nb_recv = share_rank_info.size();
271 Integer nb_send = ghost_rank_info.size();
272
273 if (is_debug) {
274 info() << "Infos before auto add: send " << nb_send << " recv " << nb_recv;
275 for (Integer i = 0; i < ghost_rank_info.size(); ++i) {
276 const GhostRankInfo& asdi = ghost_rank_info[i];
277 info() << "Ghost: " << i << asdi.nbItem() << ' ' << asdi.rank();
278 }
279 for (Integer i = 0; i < share_rank_info.size(); ++i) {
280 const ShareRankInfo& asdi = share_rank_info[i];
281 info() << "Shared: " << i << ' ' << asdi.nbItem() << ' ' << asdi.rank();
282 }
283 }
284
285 for (Integer i = 0; i < nb_send; ++i) {
286 Integer proc_id = ghost_rank_info[i].rank();
287 Integer z = 0;
288 for (; z < nb_recv; ++z)
289 if (share_rank_info[z].rank() == proc_id)
290 break;
291 debug(Trace::Highest) << "CHECKS " << proc_id << ' ' << z << ' ' << nb_recv;
292 if (z == nb_recv) {
293 debug() << "Add communication with the subdomain " << proc_id;
294 share_rank_info.add(ShareRankInfo(proc_id));
295 }
296 }
297
298 for (Integer i = 0; i < nb_recv; ++i) {
299 Integer proc_id = share_rank_info[i].rank();
300 Integer z = 0;
301 for (; z < nb_send; ++z)
302 if (ghost_rank_info[z].rank() == proc_id)
303 break;
304 debug(Trace::Highest) << "CHECKR " << proc_id << ' ' << z << ' ' << nb_send;
305 if (z == nb_send) {
306 debug() << "Add communication with subdomain " << proc_id;
307 ghost_rank_info.add(GhostRankInfo(proc_id));
308 }
309 }
310
311 if (ghost_rank_info.size() != share_rank_info.size()) {
312 ARCANE_FATAL("Problem with the number of subdomain shared ({0}) and ghosts ({1})",
313 share_rank_info.size(), ghost_rank_info.size());
314 }
315 // Sort the array by increasing subdomain number.
316 std::sort(std::begin(share_rank_info), std::end(share_rank_info));
317 std::sort(std::begin(ghost_rank_info), std::end(ghost_rank_info));
318 }
319
320 // OK, now we know the list of subdomains that possess
321 // the shared cells of this subdomain and conversely, the list of
322 // subdomains interested in the own cells of this subdomain.
323 // All that remains is to send and receive the corresponding information.
324 // To do this, and to avoid deadlocks, we first send the info
325 // for the subdomains whose number is less than this subdomain.
326 Integer nb_comm_proc = ghost_rank_info.size();
327 info(4) << "Number of communicating processors: " << nb_comm_proc;
329 time_before_sendrecv = platform::getRealTime();
330 {
331 //Integer nb_recv = share_rank_info.size();
332
333 // Sort the array by increasing subdomain number.
334 for (Integer i = 0; i < ghost_rank_info.size(); ++i) {
335 const GhostRankInfo& asdi = ghost_rank_info[i];
336 debug() << "Ghost: " << i << " " << asdi.nbItem() << ' ' << asdi.rank();
337 }
338 for (Integer i = 0; i < share_rank_info.size(); ++i) {
339 const ShareRankInfo& asdi = share_rank_info[i];
340 debug() << "Shared: " << i << " " << asdi.nbItem() << ' ' << asdi.rank();
341 }
342 Integer current_send_index = 0;
343 Integer current_recv_index = 0;
344 for (Integer i = 0; i < nb_comm_proc * 2; ++i) {
345 Integer send_proc = nb_rank;
346 Integer recv_proc = nb_rank;
347 if (current_send_index != nb_comm_proc)
348 send_proc = ghost_rank_info[current_send_index].rank();
349 if (current_recv_index != nb_comm_proc)
350 recv_proc = ghost_rank_info[current_recv_index].rank();
351 bool do_send = true;
352 if (send_proc == recv_proc) {
353 if (send_proc < my_rank)
354 do_send = true;
355 else
356 do_send = false;
357 }
358 else if (send_proc < recv_proc)
359 do_send = true;
360 else
361 do_send = false;
362 if (do_send) {
363 GhostRankInfo& asdi = ghost_rank_info[current_send_index];
364 asdi.resize();
365 Int64ArrayView uids = asdi.uniqueIds();
366 Int32ConstArrayView asdi_local_ids = asdi.localIds();
367 //Integer zindex = 0;
368 Integer nb_local = asdi_local_ids.size();
369 for (Integer z = 0, zs = nb_local; z < zs; ++z) {
370 //for( ItemGroup::const_iter z(asdi.group()); z.hasNext(); ++z, ++zindex ){
371 const Item& elem = items_internal[asdi_local_ids[z]];
372 uids[z] = elem.uniqueId().asInt64();
373 }
374 if (is_debug) {
375 info() << "Number of elements that will be sent to the subdomain " << send_proc
376 << " " << nb_local << " elements";
377 for (Integer z = 0; z < nb_local; ++z) {
378 info() << "Unique id " << uids[z];
379 }
380 }
381 debug() << "Send proc " << send_proc;
382 if (!uids.empty())
383 requests.add(pm->send(uids, send_proc, false));
384 ++current_send_index;
385 }
386 else {
387 ShareRankInfo& asdi = share_rank_info[current_recv_index];
388 asdi.resize();
389 Int64ArrayView items_unique_id = asdi.uniqueIds();
390 debug() << "Recv proc " << recv_proc;
391 //TODO use non-blocking.
392 if (!items_unique_id.empty())
393 pm->recv(items_unique_id, recv_proc);
394 //String group_name(share_name);
395 //group_name += recv_proc;
396
397 SharedArray<Int32> items_local_id(items_unique_id.size());
398 item_family->itemsUniqueIdToLocalId(items_local_id, items_unique_id);
399 SharedArray<Int32> share_group = items_local_id;
400 debug() << "Creating shared entities for the subdomain " << recv_proc
401 << " with " << items_local_id.size() << " entities";
402 //ItemGroup share_group = mesh->itemFamily(item_kind)->createGroup(group_name,items_local_id,true);
403 //share_group.setLocalToSubDomain(true);
404 asdi.setLocalIds(share_group);
405 if (is_debug) {
406 for (Integer z = 0, zs = share_group.size(); z < zs; ++z) {
407 const Item& item = items_internal[share_group[z]];
408 info() << "Item uid=" << item.uniqueId() << ",lid=" << item.localId();
409 }
410 }
411 ++current_recv_index;
412 }
413 }
414 time_after_sendrecv = platform::getRealTime();
415 if (m_is_verbose) {
416 info() << "Wait requests n=" << requests.size()
417 << " begin_date=" << platform::getCurrentDateTime();
418 }
419 pm->waitAllRequests(requests);
420 time_after_sendrecv_wait = platform::getRealTime();
421 if (m_is_verbose) {
422 info() << "Wait requests end_date=" << platform::getCurrentDateTime();
423 }
424 }
425 }
426 _checkValid(ghost_rank_info, share_rank_info);
427 sync_info->recompute();
428
429 // Verify that all ghosts have been found
430 for (Integer i = 0, n = sync_info->size(); i < n; ++i) {
431 Int32 target_rank = sync_info->targetRank(i);
432 if (sync_info->receiveInfo().nbItem(i) != boundary_items[target_rank].size())
433 ARCANE_FATAL("Inconsistent ghost count");
434 }
435
436 info() << "VariableSynchronize:: end compute list group=" << m_item_group.name()
437 << " t_init=" << Trace::Precision(4, time_before_all_gather - time_begin, true)
438 << " t_allgather=" << Trace::Precision(4, time_after_all_gather - time_before_all_gather, true)
439 << " t_sendrecv=" << Trace::Precision(4, time_after_sendrecv_wait - time_before_sendrecv, true)
440 << " t_wait=" << Trace::Precision(4, time_after_sendrecv_wait - time_after_sendrecv, true);
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
446void VariableSynchronizerComputeList::
447_checkValid(ArrayView<GhostRankInfo> ghost_rank_info,
448 ArrayView<ShareRankInfo> share_rank_info)
449{
450 const bool is_debug = m_is_debug;
451 Integer nb_comm_proc = ghost_rank_info.size();
452 Integer nb_error = 0;
453 bool has_error = false;
454 const Integer max_error = 10; // Max number of errors displayed.
455 Int32 my_rank = m_parallel_mng->commRank();
456 IItemFamily* item_family = m_item_group.itemFamily();
457 ItemInfoListView items_internal(item_family);
458
459 // Array used to mark elements that are either
460 // owned by the subdomain or ghost.
461 // Normally, if the data is consistent, this should mark
462 // all elements.
463 // NOTE: this is only useful if \a itemGroup() equals allItems()
464 UniqueArray<bool> marked_elem(item_family->maxLocalId());
465 marked_elem.fill(false);
466 // Mark elements owned by the subdomain
467 ENUMERATE_ITEM (i_item, m_item_group) {
468 Item item = *i_item;
469 if (item.isOwn()) {
470 marked_elem[item.localId()] = true;
471 if (is_debug) {
472 info() << "Own Item " << ItemPrinter(item);
473 }
474 }
475 }
476
477 for (Integer i_comm = 0; i_comm < nb_comm_proc; ++i_comm) {
478 GhostRankInfo& ghost_info = ghost_rank_info[i_comm];
479 ShareRankInfo& share_info = share_rank_info[i_comm];
480 if (ghost_info.rank() != share_info.rank()) {
481 ARCANE_FATAL("Inconsistency between the subdomain numbers ghost_rank={0} share_rank={1}",
482 ghost_info.rank(), share_info.rank());
483 }
484 Integer current_proc = ghost_info.rank();
485 Int32ConstArrayView ghost_grp = ghost_info.localIds();
486 Int32ConstArrayView share_grp = share_info.localIds();
487
488 if (share_grp.empty() && ghost_grp.empty()) {
489 error() << "Shared and ghosts groups null for the subdomain " << current_proc;
490 has_error = true;
491 continue;
492 }
493 if (current_proc == my_rank) {
494 error() << "Error in the communication pattern: "
495 << "the processor can't communicate with itself";
496 has_error = true;
497 continue;
498 }
499
500 // Mark elements of the shared group
501 for (Integer z = 0, zs = ghost_grp.size(); z < zs; ++z) {
502 const Item& elem = items_internal[ghost_grp[z]];
503 bool is_marked = marked_elem[elem.localId()];
504 if (is_marked) {
505 // The element should not already be marked.
506 if (nb_error < max_error)
507 error() << "The entity " << ItemPrinter(elem) << " belongs to another ghost group "
508 << "or is owned by the subdomain.";
509 ++nb_error;
510 continue;
511 }
512 marked_elem[elem.localId()] = true;
513 }
514
515 m_synchronizer->m_sync_info->add(VariableSyncInfo(share_grp, ghost_grp, current_proc));
516 }
517
518 // Verify that all elements are marked
519 ENUMERATE_ITEM (i, m_item_group) {
520 Item item = *i;
521 if (!marked_elem[item.localId()]) {
522 if (nb_error < max_error) {
523 error() << "The entity " << ItemPrinter(item)
524 << " doesn't belong to the subdomain or any ghost group.";
525 }
526 ++nb_error;
527 }
528 }
529
530 // If there is an error, we stop.
531 if (nb_error != 0) {
532 has_error = true;
533 if (nb_error >= max_error)
534 error() << nb_error << " total elements are incorrectly dealt with";
535 }
536 if (has_error)
537 ARCANE_FATAL("Error while creating the exchange structures of the family={0}",
538 item_family->fullName());
539}
540
541/*---------------------------------------------------------------------------*/
542/*---------------------------------------------------------------------------*/
543
544void VariableSynchronizerComputeList::
545_printSyncList()
546{
547 DataSynchronizeInfo* sync_info = m_synchronizer->m_sync_info.get();
548 Integer nb_comm = sync_info->size();
549 info() << "SYNC LIST FOR GROUP : " << m_item_group.fullName() << " N=" << nb_comm;
550 OStringStream ostr;
551 IItemFamily* item_family = m_item_group.itemFamily();
552 ItemInfoListView items_internal(item_family);
553 for (Integer i = 0; i < nb_comm; ++i) {
554 Int32 target_rank = sync_info->targetRank(i);
555 ostr() << " TARGET=" << target_rank << '\n';
556 Int32ConstArrayView share_ids = sync_info->sendInfo().localIds(i);
557 ostr() << "\t\tSHARE(lid,uid) n=" << share_ids.size() << " :";
558 for (Integer z = 0, zs = share_ids.size(); z < zs; ++z) {
559 Item item = items_internal[share_ids[z]];
560 ostr() << " (" << item.localId() << "," << item.uniqueId() << ")";
561 }
562 ostr() << "\n";
563 Int32ConstArrayView ghost_ids = sync_info->receiveInfo().localIds(i);
564 ostr() << "\t\tGHOST(lid,uid) n=" << ghost_ids.size() << " :";
565 for (Integer z = 0, zs = ghost_ids.size(); z < zs; ++z) {
566 Item item = items_internal[ghost_ids[z]];
567 ostr() << " (" << item.localId() << "," << item.uniqueId() << ")";
568 }
569 ostr() << "\n";
570 }
571 info() << ostr.str();
572}
573
574/*---------------------------------------------------------------------------*/
575/*---------------------------------------------------------------------------*/
576
577} // namespace Arcane
578
579/*---------------------------------------------------------------------------*/
580/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
constexpr Integer size() const noexcept
Returns the size of the array.
constexpr bool empty() const noexcept
Returns true if the array is empty (zero dimension).
void fill(ConstReferenceType value)
Fills the array with the value value.
void resize(Int64 s)
Changes the number of elements in the array to s.
void add(ConstReferenceType val)
Adds element val to the end of the array.
constexpr Integer size() const noexcept
Number of elements in the array.
Int32 nbItem(Int32 index) const
Number of entities for rank index.
Information necessary to synchronize entities across a group.
Int32 targetRank(Int32 index) const
Rank of the index-th target.
void recompute()
Notifies the instance that the values have changed.
const DataSynchronizeBufferInfoList & receiveInfo() const
Receive (ghost) information.
Interface of an entity family.
Definition IItemFamily.h:83
virtual Int32 maxLocalId() const =0
virtual String fullName() const =0
Full family name (with the mesh's name).
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converts an array of unique numbers to local numbers.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Performs an all-gather operation across all processors. This is a collective operation....
virtual void waitAllRequests(ArrayView< Request > rvalues)=0
Blocks while waiting for the rvalues requests to complete.
virtual char reduce(eReduceType rt, char v)=0
Performs a reduction of type rt on the real v and returns the value.
ItemUniqueId uniqueId() const
Unique number of the entity.
Int32 owner() const
Number of the owning subdomain of the entity.
Int32 localId() const
Local number (in the subdomain) of the entity.
View of a list to obtain information about entities.
Utility class for printing information about an entity.
Definition ItemPrinter.h:35
Base class for a mesh element.
Definition Item.h:84
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
constexpr bool isOwn() const
true if the entity belongs to the subdomain
Definition Item.h:267
impl::ItemBase itemBase() const
Internal part of the entity.
Definition Item.h:383
1D vector of data with reference semantics.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
Formatting real numbers with a given precision.
1D data vector with value semantics (STL style).
void _createList(UniqueArray< SharedArray< Int32 > > &boundary_items)
Interface of a variable synchronization service.
@ ReduceMax
Maximum of values.
Real getRealTime()
Real time used in seconds.
String getCurrentDateTime()
Current date and time in ISO 8601 format.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:451
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:339
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:341
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.