Arcane  v3.14.10.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-2023 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/IMemoryRessourceMng.h"
21#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/accelerator/core/Runner.h"
41
42#include "arcane/impl/DataSynchronizeInfo.h"
43#include "arcane/impl/internal/VariableSynchronizerComputeList.h"
44#include "arcane/impl/internal/IBufferCopier.h"
45
46#include <algorithm>
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51namespace Arcane
52{
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57extern "C++" Ref<IDataSynchronizeImplementationFactory>
58arcaneCreateSimpleVariableSynchronizerFactory(IParallelMng* pm);
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
69{
71 {
72 public:
73
75 : m_synchronizer_mng(sync_mng)
76 , m_allocator(allocator)
77 , m_buffer(sync_mng->createSynchronizeBuffer(allocator))
78 {
79 }
80 ~ScopedBuffer() noexcept(false)
81 {
82 m_synchronizer_mng->releaseSynchronizeBuffer(m_allocator, m_buffer.get());
83 }
84
85 public:
86
87 IVariableSynchronizerMngInternal* m_synchronizer_mng = nullptr;
88 IMemoryAllocator* m_allocator = nullptr;
89 Ref<MemoryBuffer> m_buffer;
90 };
91
92 public:
93
95 IMemoryAllocator* allocator)
96 : m_variable_synchronizer(var_syncer)
97 , m_variable_synchronizer_mng(var_syncer->synchronizeMng())
98 , m_dispatcher(IDataSynchronizeDispatcher::create(bi))
99 , m_multi_dispatcher(IDataSynchronizeMultiDispatcher::create(bi))
100 , m_event_args(var_syncer)
101 , m_allocator(allocator)
102 {
103 if (!m_dispatcher)
104 ARCANE_FATAL("No synchronizer created");
105 if (!m_multi_dispatcher)
106 ARCANE_FATAL("No multi synchronizer created");
107 }
109 {
110 delete m_multi_dispatcher;
111 }
112
113 public:
114
115 void compute()
116 {
117 m_dispatcher->compute();
118 m_multi_dispatcher->compute();
119 }
120
121 void initialize(IVariable* var)
122 {
123 _reset();
124 m_event_args.initialize(var);
125 _addVariable(var);
126 }
127
128 void initialize(const VariableCollection& vars)
129 {
130 _reset();
131 m_event_args.initialize(vars);
132 for (VariableCollectionEnumerator v(vars); ++v;)
133 _addVariable(*v);
134 }
135
136 Int32 nbVariable() const { return m_variables.size(); }
137 ConstArrayView<IVariable*> variables() const { return m_variables; }
138
141 {
142 Int32 nb_var = m_variables.size();
143 if (nb_var == 0)
144 return;
145 if (nb_var == 1) {
146 bool is_compare_sync = m_variable_synchronizer_mng->isSynchronizationComparisonEnabled();
147 m_synchronize_result = synchronizeData(m_data_list[0], is_compare_sync);
148 }
149 if (nb_var >= 2) {
150 ScopedBuffer tmp_buf(m_variable_synchronizer_mng->_internalApi(), m_allocator);
151 m_multi_dispatcher->setSynchronizeBuffer(tmp_buf.m_buffer);
152 m_multi_dispatcher->synchronize(m_variables);
153 }
154 for (IVariable* var : m_variables)
155 var->setIsSynchronized();
156 }
157
159 {
160 ScopedBuffer tmp_buf(m_variable_synchronizer_mng->_internalApi(), m_allocator);
161 m_dispatcher->setSynchronizeBuffer(tmp_buf.m_buffer);
162 m_dispatcher->beginSynchronize(data, is_compare_sync);
163 return m_dispatcher->endSynchronize();
164 }
165 const DataSynchronizeResult& result() const { return m_synchronize_result; }
166 VariableSynchronizerEventArgs& eventArgs() { return m_event_args; }
167
168 private:
169
170 IVariableSynchronizer* m_variable_synchronizer = nullptr;
171 IVariableSynchronizerMng* m_variable_synchronizer_mng = nullptr;
172 Ref<IDataSynchronizeDispatcher> m_dispatcher;
173 IDataSynchronizeMultiDispatcher* m_multi_dispatcher = nullptr;
174 VariableSynchronizerEventArgs m_event_args;
175 UniqueArray<IVariable*> m_variables;
176 UniqueArray<INumericDataInternal*> m_data_list;
177 DataSynchronizeResult m_synchronize_result;
178 IMemoryAllocator* m_allocator = nullptr;
179
180 private:
181
182 void _reset()
183 {
184 m_variables.clear();
185 m_data_list.clear();
186 }
187
188 void _addVariable(IVariable* var)
189 {
190 INumericDataInternal* numapi = var->data()->_commonInternal()->numericData();
191 if (!numapi)
192 ARCANE_FATAL("Variable '{0}' can not be synchronized because it is not a numeric data", var->name());
193 m_variables.add(var);
194 m_data_list.add(numapi);
195 }
196};
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201VariableSynchronizer::
202VariableSynchronizer(IParallelMng* pm, const ItemGroup& group,
203 Ref<IDataSynchronizeImplementationFactory> implementation_factory)
204: TraceAccessor(pm->traceMng())
205, m_parallel_mng(pm)
206, m_item_group(group)
207{
208 m_sync_info = DataSynchronizeInfo::create();
209 m_partial_sync_info = DataSynchronizeInfo::create();
210
211 if (!implementation_factory.get())
212 implementation_factory = arcaneCreateSimpleVariableSynchronizerFactory(pm);
213 m_implementation_factory = implementation_factory;
214
215 m_variable_synchronizer_mng = group.itemFamily()->mesh()->variableMng()->synchronizerMng();
216
217 {
218 String s = platform::getEnvironmentVariable("ARCANE_ALLOW_MULTISYNC");
219 if (s == "0" || s == "FALSE" || s == "false")
220 m_allow_multi_sync = false;
221 }
222 {
223 String s = platform::getEnvironmentVariable("ARCANE_TRACE_SYNCHRONIZE");
224 if (s == "1" || s == "TRUE" || s == "true")
225 m_trace_sync = true;
226 }
227
228 // Indique si on vérifie la cohérence des variables synchronisées
229 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_CHECK_SYNCHRONIZE_COHERENCE",true))
230 m_is_check_coherence = (v.value()!=0);
231
232 m_default_message = _buildMessage();
233 m_partial_message = makeRef<SyncMessage>(_buildMessage(m_partial_sync_info));
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239VariableSynchronizer::
240~VariableSynchronizer()
241{
242 delete m_sync_timer;
243 delete m_default_message;
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249VariableSynchronizer::SyncMessage* VariableSynchronizer::
250_buildMessage()
251{
252 auto* internal_pm = m_parallel_mng->_internalApi();
253 Runner* runner = internal_pm->defaultRunner();
254 bool is_accelerator_aware = internal_pm->isAcceleratorAware();
255
256 if (runner && is_accelerator_aware) {
257 m_runner = runner;
258 }
259
260 return _buildMessage(m_sync_info);
261}
262
263/*---------------------------------------------------------------------------*/
264/*---------------------------------------------------------------------------*/
265
266VariableSynchronizer::SyncMessage* VariableSynchronizer::
267_buildMessage(Ref<DataSynchronizeInfo>& sync_info)
268{
269 GroupIndexTable* table = nullptr;
270 if (!m_item_group.isAllItems())
271 table = m_item_group.localIdToIndex().get();
272
273 Ref<IBufferCopier> buffer_copier;
274 if (table)
275 buffer_copier = makeRef<IBufferCopier>(new TableBufferCopier(table));
276 else
277 buffer_copier = makeRef<IBufferCopier>(new DirectBufferCopier());
278
279 auto* internal_pm = m_parallel_mng->_internalApi();
280
281 IMemoryAllocator* allocator = nullptr;
282 // Si le IParallelMng gère la mémoire des accélérateurs alors on alloue le
283 // buffer sur le device. On pourrait utiliser la mémoire managée mais certaines
284 // implémentations MPI (i.e: BXI) ne le supportent pas.
285 if (m_runner) {
286 buffer_copier->setRunQueue(internal_pm->defaultQueue());
288 }
289
290 // Créé une instance de l'implémentation
291 Ref<IDataSynchronizeImplementation> sync_impl = m_implementation_factory->createInstance();
292 sync_impl->setDataSynchronizeInfo(sync_info.get());
293
294 DataSynchronizeDispatcherBuildInfo bi(m_parallel_mng, sync_impl, sync_info, buffer_copier);
295 return new SyncMessage(bi, this, allocator);
296}
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
304compute()
305{
307 computer.compute();
308
310 m_default_message->compute();
311 if (m_is_verbose)
312 info() << "End compute dispatcher Date=" << platform::getCurrentDateTime();
313}
314
315/*---------------------------------------------------------------------------*/
316/*---------------------------------------------------------------------------*/
317
318void VariableSynchronizer::
319_doSynchronize(SyncMessage* message)
320{
321 IParallelMng* pm = m_parallel_mng;
322 ITimeStats* ts = pm->timeStats();
323 Timer::Phase tphase(ts, TP_Communication);
324
326
327 // Envoi l'évènement de début de la synchro
328 VariableSynchronizerEventArgs& event_args = message->eventArgs();
329 _sendBeginEvent(event_args);
330
331 {
332 Timer::Sentry ts2(m_sync_timer);
333 message->synchronize();
334 }
335
336 Int32 nb_var = message->nbVariable();
337 // Si une seule variable, affiche le résutat de la comparaison de
338 // la synchronisation
339 if (nb_var == 1 && m_variable_synchronizer_mng->isSynchronizationComparisonEnabled()) {
340 eDataSynchronizeCompareStatus s = message->result().compareStatus();
343 }
346 }
347 }
348
349 // Fin de la synchro
350 _sendEndEvent(event_args);
351}
352
353/*---------------------------------------------------------------------------*/
354/*---------------------------------------------------------------------------*/
355
356void VariableSynchronizer::
357_rebuildMessage(Int32ConstArrayView local_ids)
358{
359 // Si les localIds n'ont pas changés depuis le dernier appel, on conserve
360 // les informations de synchronisation déjà calculées
361
362 if (local_ids == m_partial_local_ids.constView()) {
363 //debug(Trace::High) << "Proc " << m_parallel_mng->commRank() << " infos for partial synchronisations are up to date";
364 return;
365 }
366
367 //debug(Trace::High) << "Proc " << m_parallel_mng->commRank() << " recompute infos for partial synchronisations";
368
369 m_partial_local_ids.copy(local_ids);
370
371 UniqueArray<bool> flags(m_item_group.itemFamily()->maxLocalId());
372 flags.fill(false);
373
374 for (Int32 lid : local_ids) {
375 flags[lid] = true;
376 }
377
378 Int32ConstArrayView comm_ranks = m_sync_info->communicatingRanks();
379 Int32 nb_comm_ranks = comm_ranks.size();
380
381 const DataSynchronizeBufferInfoList& send_info = m_sync_info->sendInfo();
382 const DataSynchronizeBufferInfoList& recv_info = m_sync_info->receiveInfo();
383
384 m_partial_sync_info = DataSynchronizeInfo::create();
385
386 if (!local_ids.empty()) {
387
388 UniqueArray<Int32> recv_grp;
389 UniqueArray<Int32> send_grp;
390
391 for (Int32 index = 0; index < nb_comm_ranks; ++index) {
392 Int32 target_rank = comm_ranks[index];
393 ConstArrayView<Int32> send_lids = send_info.localIds(index);
394 ConstArrayView<Int32> recv_lids = recv_info.localIds(index);
395
396 recv_grp.clear();
397 send_grp.clear();
398
399 for (Int32 lid : recv_lids) {
400 if (flags[lid]) {
401 recv_grp.add(lid);
402 }
403 }
404
405 for (Int32 lid : send_lids) {
406 if (flags[lid]) {
407 send_grp.add(lid);
408 }
409 }
410
411 if ((!send_grp.empty()) || (!recv_grp.empty())) {
412 // Ajoute les informations sur les echanges avec le rang target_rank
413 m_partial_sync_info->add(VariableSyncInfo(send_grp, recv_grp, target_rank));
414 }
415 }
416 }
417
418 m_partial_sync_info->recompute();
419 m_partial_message = makeRef<SyncMessage>(_buildMessage(m_partial_sync_info));
420 m_partial_message->compute();
421}
422
423/*---------------------------------------------------------------------------*/
424/*---------------------------------------------------------------------------*/
425
426void VariableSynchronizer::
427_synchronize(IVariable* var, SyncMessage* message)
428{
429 message->initialize(var);
430
431 IParallelMng* pm = m_parallel_mng;
432 if (m_is_check_coherence)
433 MessagePassing::namedBarrier(pm,var->name());
434 debug(Trace::High) << " Proc " << pm->commRank() << " Sync variable " << var->fullName();
435 if (m_trace_sync) {
436 info() << " Synchronize variable " << var->fullName()
437 << " stack=" << platform::getStackTrace();
438 }
439 _doSynchronize(message);
440}
441
442/*---------------------------------------------------------------------------*/
443/*---------------------------------------------------------------------------*/
444
447{
448 _synchronize(var, m_default_message);
449}
450
451/*---------------------------------------------------------------------------*/
452/*---------------------------------------------------------------------------*/
453
456{
457 _rebuildMessage(local_ids);
458 _synchronize(var, m_partial_message.get());
459}
460
461/*---------------------------------------------------------------------------*/
462/*---------------------------------------------------------------------------*/
463
466{
467 if (vars.empty())
468 return;
469
470 const bool use_multi = m_allow_multi_sync;
472 _synchronizeMulti(vars, m_default_message);
473 }
474 else {
476 _synchronize(*ivar, m_default_message);
477 }
478 }
479}
480
481/*---------------------------------------------------------------------------*/
482/*---------------------------------------------------------------------------*/
483
486{
487 if (vars.empty())
488 return;
489
490 _rebuildMessage(local_ids);
491
492 const bool use_multi = m_allow_multi_sync;
494 _synchronizeMulti(vars, m_partial_message.get());
495 }
496 else {
498 _synchronize(*ivar, m_partial_message.get());
499 }
500 }
501
502}
503
504/*---------------------------------------------------------------------------*/
505/*---------------------------------------------------------------------------*/
506
507DataSynchronizeResult VariableSynchronizer::
508_synchronize(INumericDataInternal* data, bool is_compare_sync)
509{
510 return m_default_message->synchronizeData(data, is_compare_sync);
511}
512
513/*---------------------------------------------------------------------------*/
514/*---------------------------------------------------------------------------*/
515
518{
520 INumericDataInternal* numapi = data->_commonInternal()->numericData();
521 if (!numapi)
522 ARCANE_FATAL("Data can not be synchronized because it is not a numeric data");
523 _synchronize(numapi, false);
524}
525
526/*---------------------------------------------------------------------------*/
527/*---------------------------------------------------------------------------*/
528
531{
532 info(4) << "** VariableSynchronizer::changeLocalIds() group=" << m_item_group.name();
533 m_sync_info->changeLocalIds(old_to_new_ids);
534 m_default_message->compute();
535 // Force le recalcul des informations pour les synchronisations partielles
536 _rebuildMessage(Int32ConstArrayView());
537}
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
550{
551 if (vars.count() == 1)
552 return false;
553 ItemGroup group;
554 bool is_set = false;
556 IVariable* var = *ivar;
557 if (var->isPartial())
558 return false;
559 ItemGroup var_group = var->itemGroup();
560 if (!is_set) {
561 group = var_group;
562 is_set = true;
563 }
564 if (group != var_group)
565 return false;
566 }
567 return true;
568}
569
570/*---------------------------------------------------------------------------*/
571/*---------------------------------------------------------------------------*/
572
573void VariableSynchronizer::
574_synchronizeMulti(const VariableCollection& vars, SyncMessage* message)
575{
576 message->initialize(vars);
577
578 IParallelMng* pm = m_parallel_mng;
579 debug(Trace::High) << " Proc " << pm->commRank() << " MultiSync variable";
580 if (m_trace_sync) {
581 info() << " MultiSynchronize"
582 << " stack=" << platform::getStackTrace();
583 }
584
585 _doSynchronize(message);
586}
587
588/*---------------------------------------------------------------------------*/
589/*---------------------------------------------------------------------------*/
590
593{
594 return m_sync_info->communicatingRanks();
595}
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
601sharedItems(Int32 index)
602{
603 return m_sync_info->sendInfo().localIds(index);
604}
605
606/*---------------------------------------------------------------------------*/
607/*---------------------------------------------------------------------------*/
608
610ghostItems(Int32 index)
611{
612 return m_sync_info->receiveInfo().localIds(index);
613}
614
615/*---------------------------------------------------------------------------*/
616/*---------------------------------------------------------------------------*/
617
618void VariableSynchronizer::
619_sendBeginEvent(VariableSynchronizerEventArgs& args)
620{
621 _checkCreateTimer();
622 args.setState(VariableSynchronizerEventArgs::State::BeginSynchronize);
623 _sendEvent(args);
624}
625
626/*---------------------------------------------------------------------------*/
627/*---------------------------------------------------------------------------*/
628
629void VariableSynchronizer::
630_sendEndEvent(VariableSynchronizerEventArgs& args)
631{
632 ARCANE_CHECK_POINTER(m_sync_timer);
633 Real elapsed_time = m_sync_timer->lastActivationTime();
634 m_parallel_mng->stat()->add("Synchronize", elapsed_time, 1);
635 args.setState(VariableSynchronizerEventArgs::State::EndSynchronize);
636 args.setElapsedTime(elapsed_time);
637 _sendEvent(args);
638}
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
642
643void VariableSynchronizer::
644_sendEvent(VariableSynchronizerEventArgs& args)
645{
646 m_variable_synchronizer_mng->onSynchronized().notify(args);
647 m_on_synchronized.notify(args);
648}
649
650/*---------------------------------------------------------------------------*/
651/*---------------------------------------------------------------------------*/
652
653void VariableSynchronizer::
654_checkCreateTimer()
655{
656 if (!m_sync_timer)
657 m_sync_timer = new Timer(m_parallel_mng->timerMng(), "SyncTimer", Timer::TimerReal);
658}
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
671{
672 if (m_runner)
673 m_runner->setAsCurrentDevice();
674}
675
676/*---------------------------------------------------------------------------*/
677/*---------------------------------------------------------------------------*/
678
679} // namespace Arcane
680
681/*---------------------------------------------------------------------------*/
682/*---------------------------------------------------------------------------*/
#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.
void setAsCurrentDevice()
Positionne le device associé à cette instance comme le device par défaut du contexte.
Definition Runner.cc:411
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
virtual IMemoryAllocator * getAllocator(eMemoryRessource r)=0
Allocateur mémoire pour la ressource r.
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:120
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.
void namedBarrier(IParallelMng *pm, const String &name)
Effectue une barrière nommée de nom name.
Definition Parallel.cc:59
IMemoryRessourceMng * getDataMemoryRessourceMng()
Gestionnaire de ressource mémoire pour les données.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
@ Device
Alloue sur le device.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
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.