Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
VariableSynchronizer.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/* VariableSynchronizer.cc (C) 2000-2024 */
9/* */
10/* Variable synchronization service. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/VariableSynchronizer.h"
15
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/NotSupportedException.h"
18#include "arcane/utils/FatalErrorException.h"
19#include "arcane/utils/ITraceMng.h"
20#include "arcane/utils/ValueConvert.h"
22#include "arcane/utils/internal/MemoryBuffer.h"
23
24#include "arcane/core/VariableSynchronizerEventArgs.h"
25#include "arcane/core/IParallelMng.h"
26#include "arcane/core/IItemFamily.h"
27#include "arcane/core/ItemPrinter.h"
28#include "arcane/core/IVariable.h"
29#include "arcane/core/IData.h"
30#include "arcane/core/VariableCollection.h"
31#include "arcane/core/Timer.h"
32#include "arcane/core/IMesh.h"
33#include "arcane/core/IVariableMng.h"
34#include "arcane/core/IVariableSynchronizerMng.h"
35#include "arcane/core/parallel/IStat.h"
36#include "arcane/core/internal/IDataInternal.h"
37#include "arcane/core/internal/IParallelMngInternal.h"
38#include "arcane/core/internal/IVariableSynchronizerMngInternal.h"
39
40#include "arcane/impl/DataSynchronizeInfo.h"
41#include "arcane/impl/internal/VariableSynchronizerComputeList.h"
42#include "arcane/impl/internal/IBufferCopier.h"
43
44#include <algorithm>
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
49namespace Arcane
50{
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
56arcaneCreateSimpleVariableSynchronizerFactory(IParallelMng* pm);
57
58/*---------------------------------------------------------------------------*/
59/*---------------------------------------------------------------------------*/
60
68{
69 class ScopedBuffer
70 {
71 public:
72
73 ScopedBuffer(IVariableSynchronizerMngInternal* sync_mng, IMemoryAllocator* allocator)
74 : m_synchronizer_mng(sync_mng)
75 , m_allocator(allocator)
76 , m_buffer(sync_mng->createSynchronizeBuffer(allocator))
77 {
78 }
79 ~ScopedBuffer() noexcept(false)
80 {
81 m_synchronizer_mng->releaseSynchronizeBuffer(m_allocator, m_buffer.get());
82 }
83
84 public:
85
86 IVariableSynchronizerMngInternal* m_synchronizer_mng = nullptr;
87 IMemoryAllocator* m_allocator = nullptr;
88 Ref<MemoryBuffer> m_buffer;
89 };
90
91 public:
92
93 SyncMessage(const DataSynchronizeDispatcherBuildInfo& bi, VariableSynchronizer* var_syncer,
94 IMemoryAllocator* allocator)
95 : m_variable_synchronizer_mng(var_syncer->synchronizeMng())
96 , m_dispatcher(IDataSynchronizeDispatcher::create(bi))
97 , m_multi_dispatcher(IDataSynchronizeMultiDispatcher::create(bi))
98 , m_event_args(var_syncer)
99 , m_allocator(allocator)
100 {
101 if (!m_dispatcher)
102 ARCANE_FATAL("No synchronizer created");
103 if (!m_multi_dispatcher)
104 ARCANE_FATAL("No multi synchronizer created");
105 }
107 {
108 delete m_multi_dispatcher;
109 }
110
111 public:
112
113 void compute()
114 {
115 m_dispatcher->compute();
116 m_multi_dispatcher->compute();
117 }
118
119 void initialize(IVariable* var)
120 {
121 _reset();
122 m_event_args.initialize(var);
123 _addVariable(var);
124 }
125
126 void initialize(const VariableCollection& vars)
127 {
128 _reset();
129 m_event_args.initialize(vars);
130 for (VariableCollectionEnumerator v(vars); ++v;)
131 _addVariable(*v);
132 }
133
134 Int32 nbVariable() const { return m_variables.size(); }
135 ConstArrayView<IVariable*> variables() const { return m_variables; }
136
139 {
140 Int32 nb_var = m_variables.size();
141 if (nb_var == 0)
142 return;
143 if (nb_var == 1) {
144 bool is_compare_sync = m_variable_synchronizer_mng->isSynchronizationComparisonEnabled();
145 m_synchronize_result = synchronizeData(m_data_list[0], is_compare_sync);
146 }
147 if (nb_var >= 2) {
148 ScopedBuffer tmp_buf(m_variable_synchronizer_mng->_internalApi(), m_allocator);
149 m_multi_dispatcher->setSynchronizeBuffer(tmp_buf.m_buffer);
150 m_multi_dispatcher->synchronize(m_variables);
151 }
152 for (IVariable* var : m_variables)
153 var->setIsSynchronized();
154 }
155
157 {
158 ScopedBuffer tmp_buf(m_variable_synchronizer_mng->_internalApi(), m_allocator);
159 m_dispatcher->setSynchronizeBuffer(tmp_buf.m_buffer);
160 m_dispatcher->beginSynchronize(data, is_compare_sync);
161 return m_dispatcher->endSynchronize();
162 }
163 const DataSynchronizeResult& result() const { return m_synchronize_result; }
164 VariableSynchronizerEventArgs& eventArgs() { return m_event_args; }
165
166 private:
167
168 IVariableSynchronizerMng* m_variable_synchronizer_mng = nullptr;
169 Ref<IDataSynchronizeDispatcher> m_dispatcher;
170 IDataSynchronizeMultiDispatcher* m_multi_dispatcher = nullptr;
171 VariableSynchronizerEventArgs m_event_args;
172 UniqueArray<IVariable*> m_variables;
173 UniqueArray<INumericDataInternal*> m_data_list;
174 DataSynchronizeResult m_synchronize_result;
175 IMemoryAllocator* m_allocator = nullptr;
176
177 private:
178
179 void _reset()
180 {
181 m_variables.clear();
182 m_data_list.clear();
183 }
184
185 void _addVariable(IVariable* var)
186 {
187 INumericDataInternal* numapi = var->data()->_commonInternal()->numericData();
188 if (!numapi)
189 ARCANE_FATAL("Variable '{0}' can not be synchronized because it is not a numeric data", var->name());
190 m_variables.add(var);
191 m_data_list.add(numapi);
192 }
193};
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198VariableSynchronizer::
199VariableSynchronizer(IParallelMng* pm, const ItemGroup& group,
200 Ref<IDataSynchronizeImplementationFactory> implementation_factory)
201: TraceAccessor(pm->traceMng())
202, m_parallel_mng(pm)
203, m_item_group(group)
204{
205 m_sync_info = DataSynchronizeInfo::create();
206 m_partial_sync_info = DataSynchronizeInfo::create();
207
208 if (!implementation_factory.get())
209 implementation_factory = arcaneCreateSimpleVariableSynchronizerFactory(pm);
210 m_implementation_factory = implementation_factory;
211
212 m_variable_synchronizer_mng = group.itemFamily()->mesh()->variableMng()->synchronizerMng();
213
214 {
215 String s = platform::getEnvironmentVariable("ARCANE_ALLOW_MULTISYNC");
216 if (s == "0" || s == "FALSE" || s == "false")
217 m_allow_multi_sync = false;
218 }
219 {
220 String s = platform::getEnvironmentVariable("ARCANE_TRACE_SYNCHRONIZE");
221 if (s == "1" || s == "TRUE" || s == "true")
222 m_trace_sync = true;
223 }
224
225 // Indicates whether the coherence of synchronized variables is checked
226 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_CHECK_SYNCHRONIZE_COHERENCE", true))
227 m_is_check_coherence = (v.value() != 0);
228
229 m_default_message = _buildMessage();
230 m_partial_message = makeRef<SyncMessage>(_buildMessage(m_partial_sync_info));
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
236VariableSynchronizer::
237~VariableSynchronizer()
238{
239 delete m_sync_timer;
240 delete m_default_message;
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
246VariableSynchronizer::SyncMessage* VariableSynchronizer::
247_buildMessage()
248{
249 auto* internal_pm = m_parallel_mng->_internalApi();
250 Runner runner = internal_pm->runner();
251 bool is_accelerator_aware = internal_pm->isAcceleratorAware();
252
253 if (runner.isInitialized() && is_accelerator_aware) {
254 m_runner = runner;
255 }
256
257 return _buildMessage(m_sync_info);
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
263VariableSynchronizer::SyncMessage* VariableSynchronizer::
264_buildMessage(Ref<DataSynchronizeInfo>& sync_info)
265{
266 GroupIndexTable* table = nullptr;
267 if (!m_item_group.isAllItems())
268 table = m_item_group.localIdToIndex().get();
269
270 Ref<IBufferCopier> buffer_copier;
271 if (table)
272 buffer_copier = makeRef<IBufferCopier>(new TableBufferCopier(table));
273 else
274 buffer_copier = makeRef<IBufferCopier>(new DirectBufferCopier());
275
276 auto* internal_pm = m_parallel_mng->_internalApi();
277
278 IMemoryAllocator* allocator = nullptr;
279 // If the IParallelMng manages accelerator memory, the buffer is allocated
280 // on the device. We could use managed memory, but some MPI implementations
281 // (i.e.: BXI) do not support it.
282 if (m_runner.isInitialized()) {
283 buffer_copier->setRunQueue(internal_pm->queue());
284 allocator = MemoryUtils::getAllocator(eMemoryRessource::Device);
285 }
286
287 // Create an instance of the implementation
288 Ref<IDataSynchronizeImplementation> sync_impl = m_implementation_factory->createInstance();
289 sync_impl->setDataSynchronizeInfo(sync_info.get());
290
291 DataSynchronizeDispatcherBuildInfo bi(m_parallel_mng, sync_impl, sync_info, buffer_copier);
292 return new SyncMessage(bi, this, allocator);
293}
294
295/*---------------------------------------------------------------------------*/
296/*---------------------------------------------------------------------------*/
297
302compute()
303{
304 VariableSynchronizerComputeList computer(this);
305 computer.compute();
306
308 m_default_message->compute();
309 if (m_is_verbose)
310 info() << "End compute dispatcher Date=" << platform::getCurrentDateTime();
311}
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316void VariableSynchronizer::
317_doSynchronize(SyncMessage* message)
318{
319 IParallelMng* pm = m_parallel_mng;
320 ITimeStats* ts = pm->timeStats();
321 Timer::Phase tphase(ts, TP_Communication);
322
324
325 // Send the start synchronization event
326 VariableSynchronizerEventArgs& event_args = message->eventArgs();
327 _sendBeginEvent(event_args);
328
329 {
330 Timer::Sentry ts2(m_sync_timer);
331 message->synchronize();
332 }
333
334 Int32 nb_var = message->nbVariable();
335 // If there is only one variable, display the result of the comparison
336 // synchronization
337 if (nb_var == 1 && m_variable_synchronizer_mng->isSynchronizationComparisonEnabled()) {
338 eDataSynchronizeCompareStatus s = message->result().compareStatus();
341 }
344 }
345 }
346
347 // End of synchronization
348 _sendEndEvent(event_args);
349}
350
351/*---------------------------------------------------------------------------*/
352/*---------------------------------------------------------------------------*/
353
354void VariableSynchronizer::
355_rebuildMessage(Int32ConstArrayView local_ids)
356{
357 // If the localIds have not changed since the last call, we keep
358 // the synchronization information already calculated
359
360 if (local_ids == m_partial_local_ids.constView()) {
361 //debug(Trace::High) << "Proc " << m_parallel_mng->commRank() << " infos for partial synchronisations are up to date";
362 return;
363 }
364
365 //debug(Trace::High) << "Proc " << m_parallel_mng->commRank() << " recompute infos for partial synchronisations";
366
367 m_partial_local_ids.copy(local_ids);
368
369 UniqueArray<bool> flags(m_item_group.itemFamily()->maxLocalId());
370 flags.fill(false);
371
372 for (Int32 lid : local_ids) {
373 flags[lid] = true;
374 }
375
376 Int32ConstArrayView comm_ranks = m_sync_info->communicatingRanks();
377 Int32 nb_comm_ranks = comm_ranks.size();
378
379 const DataSynchronizeBufferInfoList& send_info = m_sync_info->sendInfo();
380 const DataSynchronizeBufferInfoList& recv_info = m_sync_info->receiveInfo();
381
382 m_partial_sync_info = DataSynchronizeInfo::create();
383
384 if (!local_ids.empty()) {
385
386 UniqueArray<Int32> recv_grp;
387 UniqueArray<Int32> send_grp;
388
389 for (Int32 index = 0; index < nb_comm_ranks; ++index) {
390 Int32 target_rank = comm_ranks[index];
391 ConstArrayView<Int32> send_lids = send_info.localIds(index);
392 ConstArrayView<Int32> recv_lids = recv_info.localIds(index);
393
394 recv_grp.clear();
395 send_grp.clear();
396
397 for (Int32 lid : recv_lids) {
398 if (flags[lid]) {
399 recv_grp.add(lid);
400 }
401 }
402
403 for (Int32 lid : send_lids) {
404 if (flags[lid]) {
405 send_grp.add(lid);
406 }
407 }
408
409 if ((!send_grp.empty()) || (!recv_grp.empty())) {
410 // Adds information about exchanges with target_rank
411 m_partial_sync_info->add(VariableSyncInfo(send_grp, recv_grp, target_rank));
412 }
413 }
414 }
415
416 m_partial_sync_info->recompute();
417 m_partial_message = makeRef<SyncMessage>(_buildMessage(m_partial_sync_info));
418 m_partial_message->compute();
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
424void VariableSynchronizer::
425_synchronize(IVariable* var, SyncMessage* message)
426{
427 message->initialize(var);
428
429 IParallelMng* pm = m_parallel_mng;
430 if (m_is_check_coherence)
431 MessagePassing::namedBarrier(pm, var->name());
432 debug(Trace::High) << " Proc " << pm->commRank() << " Sync variable " << var->fullName();
433 if (m_trace_sync) {
434 info() << " Synchronize variable " << var->fullName()
435 << " stack=" << platform::getStackTrace();
436 }
437 _doSynchronize(message);
438}
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
442
445{
446 _synchronize(var, m_default_message);
447}
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
454{
455 _rebuildMessage(local_ids);
456 _synchronize(var, m_partial_message.get());
457}
458
459/*---------------------------------------------------------------------------*/
460/*---------------------------------------------------------------------------*/
461
464{
465 if (vars.empty())
466 return;
467
468 const bool use_multi = m_allow_multi_sync;
469 if (use_multi && _canSynchronizeMulti(vars)) {
470 _synchronizeMulti(vars, m_default_message);
471 }
472 else {
473 for (VariableCollection::Enumerator ivar(vars); ++ivar;) {
474 _synchronize(*ivar, m_default_message);
475 }
476 }
477}
478
479/*---------------------------------------------------------------------------*/
480/*---------------------------------------------------------------------------*/
481
484{
485 if (vars.empty())
486 return;
487
488 _rebuildMessage(local_ids);
489
490 const bool use_multi = m_allow_multi_sync;
491 if (use_multi && _canSynchronizeMulti(vars)) {
492 _synchronizeMulti(vars, m_partial_message.get());
493 }
494 else {
495 for (VariableCollection::Enumerator ivar(vars); ++ivar;) {
496 _synchronize(*ivar, m_partial_message.get());
497 }
498 }
499}
500
501/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
504DataSynchronizeResult VariableSynchronizer::
505_synchronize(INumericDataInternal* data, bool is_compare_sync)
506{
507 return m_default_message->synchronizeData(data, is_compare_sync);
508}
509
510/*---------------------------------------------------------------------------*/
511/*---------------------------------------------------------------------------*/
512
515{
518 if (!numapi)
519 ARCANE_FATAL("Data can not be synchronized because it is not a numeric data");
520 _synchronize(numapi, false);
521}
522
523/*---------------------------------------------------------------------------*/
524/*---------------------------------------------------------------------------*/
525
528{
529 info(4) << "** VariableSynchronizer::changeLocalIds() group=" << m_item_group.name();
530 m_sync_info->changeLocalIds(old_to_new_ids);
531 m_default_message->compute();
532 // Forces recalculation of information for partial synchronizations
533 _rebuildMessage(Int32ConstArrayView());
534}
535
536/*---------------------------------------------------------------------------*/
537/*---------------------------------------------------------------------------*/
538
548{
549 if (vars.count() == 1)
550 return false;
551 ItemGroup group;
552 bool is_set = false;
553 for (VariableCollection::Enumerator ivar(vars); ++ivar;) {
554 IVariable* var = *ivar;
555 if (var->isPartial())
556 return false;
557 ItemGroup var_group = var->itemGroup();
558 if (!is_set) {
559 group = var_group;
560 is_set = true;
561 }
562 if (group != var_group)
563 return false;
564 }
565 return true;
566}
567
568/*---------------------------------------------------------------------------*/
569/*---------------------------------------------------------------------------*/
570
571void VariableSynchronizer::
572_synchronizeMulti(const VariableCollection& vars, SyncMessage* message)
573{
574 message->initialize(vars);
575
576 IParallelMng* pm = m_parallel_mng;
577 debug(Trace::High) << " Proc " << pm->commRank() << " MultiSync variable";
578 if (m_trace_sync) {
579 info() << " MultiSynchronize"
580 << " stack=" << platform::getStackTrace();
581 }
582
583 _doSynchronize(message);
584}
585
586/*---------------------------------------------------------------------------*/
587/*---------------------------------------------------------------------------*/
588
591{
592 return m_sync_info->communicatingRanks();
593}
594
595/*---------------------------------------------------------------------------*/
596/*---------------------------------------------------------------------------*/
597
599sharedItems(Int32 index)
600{
601 return m_sync_info->sendInfo().localIds(index);
602}
603
604/*---------------------------------------------------------------------------*/
605/*---------------------------------------------------------------------------*/
606
608ghostItems(Int32 index)
609{
610 return m_sync_info->receiveInfo().localIds(index);
611}
612
613/*---------------------------------------------------------------------------*/
614/*---------------------------------------------------------------------------*/
615
616void VariableSynchronizer::
617_sendBeginEvent(VariableSynchronizerEventArgs& args)
618{
619 _checkCreateTimer();
620 args.setState(VariableSynchronizerEventArgs::State::BeginSynchronize);
621 _sendEvent(args);
622}
623
624/*---------------------------------------------------------------------------*/
625/*---------------------------------------------------------------------------*/
626
627void VariableSynchronizer::
628_sendEndEvent(VariableSynchronizerEventArgs& args)
629{
630 ARCANE_CHECK_POINTER(m_sync_timer);
631 Real elapsed_time = m_sync_timer->lastActivationTime();
632 m_parallel_mng->stat()->add("Synchronize", elapsed_time, 1);
633 args.setState(VariableSynchronizerEventArgs::State::EndSynchronize);
634 args.setElapsedTime(elapsed_time);
635 _sendEvent(args);
636}
637
638/*---------------------------------------------------------------------------*/
639/*---------------------------------------------------------------------------*/
640
641void VariableSynchronizer::
642_sendEvent(VariableSynchronizerEventArgs& args)
643{
644 m_variable_synchronizer_mng->onSynchronized().notify(args);
645 m_on_synchronized.notify(args);
646}
647
648/*---------------------------------------------------------------------------*/
649/*---------------------------------------------------------------------------*/
650
651void VariableSynchronizer::
652_checkCreateTimer()
653{
654 if (!m_sync_timer)
655 m_sync_timer = new Timer(m_parallel_mng->timerMng(), "SyncTimer", Timer::TimerReal);
656}
657
658/*---------------------------------------------------------------------------*/
659/*---------------------------------------------------------------------------*/
660
670{
671 if (m_runner.isInitialized())
672 m_runner.setAsCurrentDevice();
673}
674
675/*---------------------------------------------------------------------------*/
676/*---------------------------------------------------------------------------*/
677
678} // namespace Arcane
679
680/*---------------------------------------------------------------------------*/
681/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Memory and allocator management functions.
constexpr Integer size() const noexcept
Number of elements in the array.
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Info to build a DataSynchronizeDispatcher.
Information about the result of a synchronization.
virtual INumericDataInternal * numericData()
Generic interface for numeric data (nullptr if the data is not numeric).
Interface to manage the synchronization of a data item.
Interface for synchronizing a list of variables.
virtual void compute()=0
Recalculates the necessary information after an update to the DataSynchronizeInfo.
Interface of a data item.
Definition IData.h:34
virtual IDataInternal * _commonInternal()=0
Interface for an 'IData' of a numeric type.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual ITimeStats * timeStats() const =0
Associated statistics manager (can be null).
virtual IStat * stat()=0
Statistics manager.
Interface managing execution time statistics.
Definition ITimeStats.h:44
Internal Arcane API for IVariableSynchronizerMng.
Interface of a variable.
Definition IVariable.h:40
virtual bool isPartial() const =0
Indicates if the variable is partial.
virtual ItemGroup itemGroup() const =0
Associated mesh group.
Mesh entity group.
Definition ItemGroup.h:51
virtual void add(const String &name, double elapsed_time, Int64 msg_size)=0
Adds a statistic.
Reference to an instance.
Positions the phase of the currently executing action.
Definition Timer.h:142
Sentinel for the timer. The sentinel associated with a timer allows it to be triggered upon its const...
Definition Timer.h:90
@ TimerReal
Timer using real time.
Definition Timer.h:77
Real lastActivationTime() const
Returns the time (in seconds) spent during the last activation of the timer.
Definition Timer.h:243
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
void compute()
Creation of the synchronization element list.
Arguments for the event notifying a variable synchronization.
@ Different
Different values before and after synchronization.
@ Same
Same values before and after synchronization.
void setCompareStatus(Int32 i, CompareStatus v)
Sets the comparison status of the i-th variable.
void synchronize()
Performs the synchronization.
void changeLocalIds(Int32ConstArrayView old_to_new_ids) override
Called when the local IDs of the entities are modified.
void compute() override
Creation of the list of synchronization elements.
bool _canSynchronizeMulti(const VariableCollection &vars)
Indicates if the variables in the list vars can be synchronized at once.
Int32ConstArrayView ghostItems(Int32 index) override
List of local IDs of ghost entities with a subdomain.
Int32ConstArrayView sharedItems(Int32 index) override
List of local IDs of entities shared with a subdomain.
void _setCurrentDevice()
Positions the device associated with our RunQueue as the current device.
void synchronizeData(IData *data) override
Synchronizes the data data.
void synchronize(IVariable *var) override
Synchronizes the variable var in blocking mode.
Int32ConstArrayView communicatingRanks() override
Ranks of subdomains with which communication occurs.
IMemoryAllocator * getAllocator(eMemoryResource mem_resource)
Default allocator for the resource mem_resource.
void namedBarrier(IParallelMng *pm, const String &name)
Performs a named barrier with name name.
Definition Parallel.cc:61
String getStackTrace()
Returns a string containing the call stack.
String getCurrentDateTime()
Current date and time in ISO 8601 format.
String getEnvironmentVariable(const String &name)
Environment variable named name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
eDataSynchronizeCompareStatus
Comparison of ghost entity values before/after synchronization.
@ Different
Different values before and after synchronization.
@ Same
Same values before and after synchronization.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.