Arcane  v3.15.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
VariableSynchronizer.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* Service de synchronisation des variables. */
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
55extern "C++" Ref<IDataSynchronizeImplementationFactory>
56arcaneCreateSimpleVariableSynchronizerFactory(IParallelMng* pm);
57
58/*---------------------------------------------------------------------------*/
59/*---------------------------------------------------------------------------*/
67{
69 {
70 public:
71
73 : m_synchronizer_mng(sync_mng)
74 , m_allocator(allocator)
75 , m_buffer(sync_mng->createSynchronizeBuffer(allocator))
76 {
77 }
78 ~ScopedBuffer() noexcept(false)
79 {
80 m_synchronizer_mng->releaseSynchronizeBuffer(m_allocator, m_buffer.get());
81 }
82
83 public:
84
85 IVariableSynchronizerMngInternal* m_synchronizer_mng = nullptr;
86 IMemoryAllocator* m_allocator = nullptr;
87 Ref<MemoryBuffer> m_buffer;
88 };
89
90 public:
91
93 IMemoryAllocator* allocator)
94 : m_variable_synchronizer_mng(var_syncer->synchronizeMng())
95 , m_dispatcher(IDataSynchronizeDispatcher::create(bi))
96 , m_multi_dispatcher(IDataSynchronizeMultiDispatcher::create(bi))
97 , m_event_args(var_syncer)
98 , m_allocator(allocator)
99 {
100 if (!m_dispatcher)
101 ARCANE_FATAL("No synchronizer created");
102 if (!m_multi_dispatcher)
103 ARCANE_FATAL("No multi synchronizer created");
104 }
106 {
107 delete m_multi_dispatcher;
108 }
109
110 public:
111
112 void compute()
113 {
114 m_dispatcher->compute();
115 m_multi_dispatcher->compute();
116 }
117
118 void initialize(IVariable* var)
119 {
120 _reset();
121 m_event_args.initialize(var);
122 _addVariable(var);
123 }
124
125 void initialize(const VariableCollection& vars)
126 {
127 _reset();
128 m_event_args.initialize(vars);
129 for (VariableCollectionEnumerator v(vars); ++v;)
130 _addVariable(*v);
131 }
132
133 Int32 nbVariable() const { return m_variables.size(); }
134 ConstArrayView<IVariable*> variables() const { return m_variables; }
135
138 {
139 Int32 nb_var = m_variables.size();
140 if (nb_var == 0)
141 return;
142 if (nb_var == 1) {
143 bool is_compare_sync = m_variable_synchronizer_mng->isSynchronizationComparisonEnabled();
144 m_synchronize_result = synchronizeData(m_data_list[0], is_compare_sync);
145 }
146 if (nb_var >= 2) {
147 ScopedBuffer tmp_buf(m_variable_synchronizer_mng->_internalApi(), m_allocator);
148 m_multi_dispatcher->setSynchronizeBuffer(tmp_buf.m_buffer);
149 m_multi_dispatcher->synchronize(m_variables);
150 }
151 for (IVariable* var : m_variables)
152 var->setIsSynchronized();
153 }
154
156 {
157 ScopedBuffer tmp_buf(m_variable_synchronizer_mng->_internalApi(), m_allocator);
158 m_dispatcher->setSynchronizeBuffer(tmp_buf.m_buffer);
159 m_dispatcher->beginSynchronize(data, is_compare_sync);
160 return m_dispatcher->endSynchronize();
161 }
162 const DataSynchronizeResult& result() const { return m_synchronize_result; }
163 VariableSynchronizerEventArgs& eventArgs() { return m_event_args; }
164
165 private:
166
167 IVariableSynchronizerMng* m_variable_synchronizer_mng = nullptr;
168 Ref<IDataSynchronizeDispatcher> m_dispatcher;
169 IDataSynchronizeMultiDispatcher* m_multi_dispatcher = nullptr;
170 VariableSynchronizerEventArgs m_event_args;
171 UniqueArray<IVariable*> m_variables;
172 UniqueArray<INumericDataInternal*> m_data_list;
173 DataSynchronizeResult m_synchronize_result;
174 IMemoryAllocator* m_allocator = nullptr;
175
176 private:
177
178 void _reset()
179 {
180 m_variables.clear();
181 m_data_list.clear();
182 }
183
184 void _addVariable(IVariable* var)
185 {
186 INumericDataInternal* numapi = var->data()->_commonInternal()->numericData();
187 if (!numapi)
188 ARCANE_FATAL("Variable '{0}' can not be synchronized because it is not a numeric data", var->name());
189 m_variables.add(var);
190 m_data_list.add(numapi);
191 }
192};
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
197VariableSynchronizer::
198VariableSynchronizer(IParallelMng* pm, const ItemGroup& group,
199 Ref<IDataSynchronizeImplementationFactory> implementation_factory)
200: TraceAccessor(pm->traceMng())
201, m_parallel_mng(pm)
202, m_item_group(group)
203{
204 m_sync_info = DataSynchronizeInfo::create();
205 m_partial_sync_info = DataSynchronizeInfo::create();
206
207 if (!implementation_factory.get())
208 implementation_factory = arcaneCreateSimpleVariableSynchronizerFactory(pm);
209 m_implementation_factory = implementation_factory;
210
211 m_variable_synchronizer_mng = group.itemFamily()->mesh()->variableMng()->synchronizerMng();
212
213 {
214 String s = platform::getEnvironmentVariable("ARCANE_ALLOW_MULTISYNC");
215 if (s == "0" || s == "FALSE" || s == "false")
216 m_allow_multi_sync = false;
217 }
218 {
219 String s = platform::getEnvironmentVariable("ARCANE_TRACE_SYNCHRONIZE");
220 if (s == "1" || s == "TRUE" || s == "true")
221 m_trace_sync = true;
222 }
223
224 // Indique si on vérifie la cohérence des variables synchronisées
225 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_CHECK_SYNCHRONIZE_COHERENCE",true))
226 m_is_check_coherence = (v.value()!=0);
227
228 m_default_message = _buildMessage();
229 m_partial_message = makeRef<SyncMessage>(_buildMessage(m_partial_sync_info));
230}
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235VariableSynchronizer::
236~VariableSynchronizer()
237{
238 delete m_sync_timer;
239 delete m_default_message;
240}
241
242/*---------------------------------------------------------------------------*/
243/*---------------------------------------------------------------------------*/
244
245VariableSynchronizer::SyncMessage* VariableSynchronizer::
246_buildMessage()
247{
248 auto* internal_pm = m_parallel_mng->_internalApi();
249 Runner runner = internal_pm->runner();
250 bool is_accelerator_aware = internal_pm->isAcceleratorAware();
251
252 if (runner.isInitialized() && is_accelerator_aware) {
253 m_runner = runner;
254 }
255
256 return _buildMessage(m_sync_info);
257}
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
261
262VariableSynchronizer::SyncMessage* VariableSynchronizer::
263_buildMessage(Ref<DataSynchronizeInfo>& sync_info)
264{
265 GroupIndexTable* table = nullptr;
266 if (!m_item_group.isAllItems())
267 table = m_item_group.localIdToIndex().get();
268
269 Ref<IBufferCopier> buffer_copier;
270 if (table)
271 buffer_copier = makeRef<IBufferCopier>(new TableBufferCopier(table));
272 else
273 buffer_copier = makeRef<IBufferCopier>(new DirectBufferCopier());
274
275 auto* internal_pm = m_parallel_mng->_internalApi();
276
277 IMemoryAllocator* allocator = nullptr;
278 // Si le IParallelMng gère la mémoire des accélérateurs alors on alloue le
279 // buffer sur le device. On pourrait utiliser la mémoire managée mais certaines
280 // implémentations MPI (i.e: BXI) ne le supportent pas.
281 if (m_runner.isInitialized()) {
282 buffer_copier->setRunQueue(internal_pm->queue());
283 allocator = MemoryUtils::getAllocator(eMemoryRessource::Device);
284 }
285
286 // Créé une instance de l'implémentation
287 Ref<IDataSynchronizeImplementation> sync_impl = m_implementation_factory->createInstance();
288 sync_impl->setDataSynchronizeInfo(sync_info.get());
289
290 DataSynchronizeDispatcherBuildInfo bi(m_parallel_mng, sync_impl, sync_info, buffer_copier);
291 return new SyncMessage(bi, this, allocator);
292}
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
300compute()
301{
303 computer.compute();
304
306 m_default_message->compute();
307 if (m_is_verbose)
308 info() << "End compute dispatcher Date=" << platform::getCurrentDateTime();
309}
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313
314void VariableSynchronizer::
315_doSynchronize(SyncMessage* message)
316{
317 IParallelMng* pm = m_parallel_mng;
318 ITimeStats* ts = pm->timeStats();
319 Timer::Phase tphase(ts, TP_Communication);
320
322
323 // Envoi l'évènement de début de la synchro
324 VariableSynchronizerEventArgs& event_args = message->eventArgs();
325 _sendBeginEvent(event_args);
326
327 {
328 Timer::Sentry ts2(m_sync_timer);
329 message->synchronize();
330 }
331
332 Int32 nb_var = message->nbVariable();
333 // Si une seule variable, affiche le résutat de la comparaison de
334 // la synchronisation
335 if (nb_var == 1 && m_variable_synchronizer_mng->isSynchronizationComparisonEnabled()) {
336 eDataSynchronizeCompareStatus s = message->result().compareStatus();
339 }
342 }
343 }
344
345 // Fin de la synchro
346 _sendEndEvent(event_args);
347}
348
349/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
352void VariableSynchronizer::
353_rebuildMessage(Int32ConstArrayView local_ids)
354{
355 // Si les localIds n'ont pas changés depuis le dernier appel, on conserve
356 // les informations de synchronisation déjà calculées
357
358 if (local_ids == m_partial_local_ids.constView()) {
359 //debug(Trace::High) << "Proc " << m_parallel_mng->commRank() << " infos for partial synchronisations are up to date";
360 return;
361 }
362
363 //debug(Trace::High) << "Proc " << m_parallel_mng->commRank() << " recompute infos for partial synchronisations";
364
365 m_partial_local_ids.copy(local_ids);
366
367 UniqueArray<bool> flags(m_item_group.itemFamily()->maxLocalId());
368 flags.fill(false);
369
370 for (Int32 lid : local_ids) {
371 flags[lid] = true;
372 }
373
374 Int32ConstArrayView comm_ranks = m_sync_info->communicatingRanks();
375 Int32 nb_comm_ranks = comm_ranks.size();
376
377 const DataSynchronizeBufferInfoList& send_info = m_sync_info->sendInfo();
378 const DataSynchronizeBufferInfoList& recv_info = m_sync_info->receiveInfo();
379
380 m_partial_sync_info = DataSynchronizeInfo::create();
381
382 if (!local_ids.empty()) {
383
384 UniqueArray<Int32> recv_grp;
385 UniqueArray<Int32> send_grp;
386
387 for (Int32 index = 0; index < nb_comm_ranks; ++index) {
388 Int32 target_rank = comm_ranks[index];
389 ConstArrayView<Int32> send_lids = send_info.localIds(index);
390 ConstArrayView<Int32> recv_lids = recv_info.localIds(index);
391
392 recv_grp.clear();
393 send_grp.clear();
394
395 for (Int32 lid : recv_lids) {
396 if (flags[lid]) {
397 recv_grp.add(lid);
398 }
399 }
400
401 for (Int32 lid : send_lids) {
402 if (flags[lid]) {
403 send_grp.add(lid);
404 }
405 }
406
407 if ((!send_grp.empty()) || (!recv_grp.empty())) {
408 // Ajoute les informations sur les echanges avec le rang target_rank
409 m_partial_sync_info->add(VariableSyncInfo(send_grp, recv_grp, target_rank));
410 }
411 }
412 }
413
414 m_partial_sync_info->recompute();
415 m_partial_message = makeRef<SyncMessage>(_buildMessage(m_partial_sync_info));
416 m_partial_message->compute();
417}
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
422void VariableSynchronizer::
423_synchronize(IVariable* var, SyncMessage* message)
424{
425 message->initialize(var);
426
427 IParallelMng* pm = m_parallel_mng;
428 if (m_is_check_coherence)
429 MessagePassing::namedBarrier(pm,var->name());
430 debug(Trace::High) << " Proc " << pm->commRank() << " Sync variable " << var->fullName();
431 if (m_trace_sync) {
432 info() << " Synchronize variable " << var->fullName()
433 << " stack=" << platform::getStackTrace();
434 }
435 _doSynchronize(message);
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
443{
444 _synchronize(var, m_default_message);
445}
446
447/*---------------------------------------------------------------------------*/
448/*---------------------------------------------------------------------------*/
449
452{
453 _rebuildMessage(local_ids);
454 _synchronize(var, m_partial_message.get());
455}
456
457/*---------------------------------------------------------------------------*/
458/*---------------------------------------------------------------------------*/
459
462{
463 if (vars.empty())
464 return;
465
466 const bool use_multi = m_allow_multi_sync;
468 _synchronizeMulti(vars, m_default_message);
469 }
470 else {
472 _synchronize(*ivar, m_default_message);
473 }
474 }
475}
476
477/*---------------------------------------------------------------------------*/
478/*---------------------------------------------------------------------------*/
479
482{
483 if (vars.empty())
484 return;
485
486 _rebuildMessage(local_ids);
487
488 const bool use_multi = m_allow_multi_sync;
490 _synchronizeMulti(vars, m_partial_message.get());
491 }
492 else {
494 _synchronize(*ivar, m_partial_message.get());
495 }
496 }
497
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
503DataSynchronizeResult VariableSynchronizer::
504_synchronize(INumericDataInternal* data, bool is_compare_sync)
505{
506 return m_default_message->synchronizeData(data, is_compare_sync);
507}
508
509/*---------------------------------------------------------------------------*/
510/*---------------------------------------------------------------------------*/
511
514{
516 INumericDataInternal* numapi = data->_commonInternal()->numericData();
517 if (!numapi)
518 ARCANE_FATAL("Data can not be synchronized because it is not a numeric data");
519 _synchronize(numapi, false);
520}
521
522/*---------------------------------------------------------------------------*/
523/*---------------------------------------------------------------------------*/
524
527{
528 info(4) << "** VariableSynchronizer::changeLocalIds() group=" << m_item_group.name();
529 m_sync_info->changeLocalIds(old_to_new_ids);
530 m_default_message->compute();
531 // Force le recalcul des informations pour les synchronisations partielles
532 _rebuildMessage(Int32ConstArrayView());
533}
534
535/*---------------------------------------------------------------------------*/
536/*---------------------------------------------------------------------------*/
546{
547 if (vars.count() == 1)
548 return false;
549 ItemGroup group;
550 bool is_set = false;
552 IVariable* var = *ivar;
553 if (var->isPartial())
554 return false;
555 ItemGroup var_group = var->itemGroup();
556 if (!is_set) {
557 group = var_group;
558 is_set = true;
559 }
560 if (group != var_group)
561 return false;
562 }
563 return true;
564}
565
566/*---------------------------------------------------------------------------*/
567/*---------------------------------------------------------------------------*/
568
569void VariableSynchronizer::
570_synchronizeMulti(const VariableCollection& vars, SyncMessage* message)
571{
572 message->initialize(vars);
573
574 IParallelMng* pm = m_parallel_mng;
575 debug(Trace::High) << " Proc " << pm->commRank() << " MultiSync variable";
576 if (m_trace_sync) {
577 info() << " MultiSynchronize"
578 << " stack=" << platform::getStackTrace();
579 }
580
581 _doSynchronize(message);
582}
583
584/*---------------------------------------------------------------------------*/
585/*---------------------------------------------------------------------------*/
586
589{
590 return m_sync_info->communicatingRanks();
591}
592
593/*---------------------------------------------------------------------------*/
594/*---------------------------------------------------------------------------*/
595
597sharedItems(Int32 index)
598{
599 return m_sync_info->sendInfo().localIds(index);
600}
601
602/*---------------------------------------------------------------------------*/
603/*---------------------------------------------------------------------------*/
604
606ghostItems(Int32 index)
607{
608 return m_sync_info->receiveInfo().localIds(index);
609}
610
611/*---------------------------------------------------------------------------*/
612/*---------------------------------------------------------------------------*/
613
614void VariableSynchronizer::
615_sendBeginEvent(VariableSynchronizerEventArgs& args)
616{
617 _checkCreateTimer();
618 args.setState(VariableSynchronizerEventArgs::State::BeginSynchronize);
619 _sendEvent(args);
620}
621
622/*---------------------------------------------------------------------------*/
623/*---------------------------------------------------------------------------*/
624
625void VariableSynchronizer::
626_sendEndEvent(VariableSynchronizerEventArgs& args)
627{
628 ARCANE_CHECK_POINTER(m_sync_timer);
629 Real elapsed_time = m_sync_timer->lastActivationTime();
630 m_parallel_mng->stat()->add("Synchronize", elapsed_time, 1);
631 args.setState(VariableSynchronizerEventArgs::State::EndSynchronize);
632 args.setElapsedTime(elapsed_time);
633 _sendEvent(args);
634}
635
636/*---------------------------------------------------------------------------*/
637/*---------------------------------------------------------------------------*/
638
639void VariableSynchronizer::
640_sendEvent(VariableSynchronizerEventArgs& args)
641{
642 m_variable_synchronizer_mng->onSynchronized().notify(args);
643 m_on_synchronized.notify(args);
644}
645
646/*---------------------------------------------------------------------------*/
647/*---------------------------------------------------------------------------*/
648
649void VariableSynchronizer::
650_checkCreateTimer()
651{
652 if (!m_sync_timer)
653 m_sync_timer = new Timer(m_parallel_mng->timerMng(), "SyncTimer", Timer::TimerReal);
654}
655
656/*---------------------------------------------------------------------------*/
657/*---------------------------------------------------------------------------*/
667{
668 if (m_runner.isInitialized())
669 m_runner.setAsCurrentDevice();
670}
671
672/*---------------------------------------------------------------------------*/
673/*---------------------------------------------------------------------------*/
674
675} // namespace Arcane
676
677/*---------------------------------------------------------------------------*/
678/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions de gestion mémoire et des allocateurs.
bool isInitialized() const
Indique si l'instance a été initialisée.
Definition Runner.cc:311
void setAsCurrentDevice()
Positionne le device associé à cette instance comme le device par défaut du contexte.
Definition Runner.cc:414
Infos pour construire un DataSynchronizeDispatcher.
Informations sur le résultat d'une synchronisation.
Interface pour gérer la synchronisation d'une donnée.
Interface de la synchronisation d'une liste de variables.
virtual void setSynchronizeBuffer(Ref< MemoryBuffer > buffer)=0
Positionne le buffer de synchronisation.
virtual void compute()=0
Recalcule les informations nécessaires après une mise à jour des informations de DataSynchronizeInfo.
Interface d'une donnée.
Definition IData.h:33
virtual IDataInternal * _commonInternal()=0
virtual Int32 maxLocalId() const =0
Interface pour un 'IData' d'un type numérique.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual ITimeStats * timeStats() const =0
Gestionnaire de statistiques associé (peut être nul)
virtual IStat * stat()=0
Gestionnaire des statistiques.
virtual ITimerMng * timerMng() const =0
Gestionnaire de timers.
virtual IParallelMngInternal * _internalApi()=0
API interne à Arcane.
Interface gérant les statistiques sur les temps d'exécution.
Definition ITimeStats.h:48
API interne à Arcane de IVariableSynchronizerMng.
virtual bool isSynchronizationComparisonEnabled() const =0
Indique si on effectue les comparaisons des valeurs avant et après synchronisation.
Interface d'une variable.
Definition IVariable.h:54
Groupe d'entités de maillage.
Definition ItemGroup.h:49
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
SharedPtrT< GroupIndexTable > localIdToIndex() const
Table des local ids vers une position pour toutes les entités du groupe.
Definition ItemGroup.h:292
IItemFamily * itemFamily() const
Famille d'entité à laquelle appartient ce groupe (0 pour le group nul)
Definition ItemGroup.h:123
bool isAllItems() const
Indique si le groupe est celui de toutes les entités.
Definition ItemGroup.cc:609
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
Positionne la phase de l'action en cours d'exécution.
Definition Timer.h:128
Sentinelle pour le timer. La sentinelle associée à un timer permet de déclancher celui-ci au moment d...
Definition Timer.h:89
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Real lastActivationTime() const
Retourne le temps (en secondes) passé lors de la dernière activation du timer.
Definition Timer.h:219
Collection de variables.
Calcule de la liste des entités à synchroniser.
Arguments de l'évènement notifiant une synchronisation de variables.
@ Different
Valeurs différentes avant et après la synchronisation.
@ Same
Même valeurs avant et après la synchronisation.
void setCompareStatus(Int32 i, CompareStatus v)
Positionne l'état de comparaison de la i-ème variable.
void synchronize()
Effectue la synchronisation.
Interface d'un service de synchronisation de variable.
void changeLocalIds(Int32ConstArrayView old_to_new_ids) override
Appelé lorsque les numéros locaux des entités sont modifiés.
void compute() override
Création de la liste des éléments de synchronisation.
bool _canSynchronizeMulti(const VariableCollection &vars)
Indique si les variables de la liste vars peuvent être synchronisées en une seule fois.
Int32ConstArrayView ghostItems(Int32 index) override
Liste des ids locaux des entités fantômes avec un sous-domaine.
Int32ConstArrayView sharedItems(Int32 index) override
Liste des ids locaux des entités partagées avec un sous-domaine.
void _setCurrentDevice()
Positionne le device associé à notre RunQueue comme le device courant.
void synchronizeData(IData *data) override
Synchronise la donnée data.
void synchronize(IVariable *var) override
Synchronise la variable var en mode bloquant.
Int32ConstArrayView communicatingRanks() override
Rangs des sous-domaines avec lesquels on communique.
void copy(Span< const T > rhs)
Copie les valeurs de rhs dans l'instance.
ConstArrayView< T > constView() const
Vue constante sur ce tableau.
Vue constante d'un tableau de type T.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
IMemoryAllocator * getAllocator(eMemoryResource mem_resource)
Allocateur par défaut pour la ressource mem_resource.
void namedBarrier(IParallelMng *pm, const String &name)
Effectue une barrière nommée de nom name.
Definition Parallel.cc:59
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:693
eDataSynchronizeCompareStatus
Comparaison des valeurs des entités fantômes avant/après une synchronisation.
@ Different
Valeurs différentes avant et après la synchronisation.
@ Same
Même valeurs avant et après la synchronisation.