Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
BasicParticleExchanger.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/* BasicParticleExchanger.cc (C) 2000-2023 */
9/* */
10/* Echangeur de particules. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/BasicParticleExchanger.h"
15
16/*
17 * NOTE:
18 * Dans exchangeItems(), le tableau new_particle_local_ids
19 * n'est valide que si le compactage n'est pas actif pour la famille de
20 * particules (c'est toujours le cas avec l'implémentation actuelle).
21 * Pour qu'il soit valide dans tous les cas, il faudrait lors
22 * de la désérialisation des messages, créer toutes les entités
23 * en une fois, mettre à jour ce tableau \a new_particle_local_ids
24 * et ensuite mettre à jour les variables.
25 */
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane::mesh
30{
31
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36BasicParticleExchanger::
37BasicParticleExchanger(const ServiceBuildInfo& sbi)
38: ArcaneBasicParticleExchangerObject(sbi)
39{
40}
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45BasicParticleExchanger::
46~BasicParticleExchanger()
47{
48 // TODO: ne pas lancer d'exception dans le destructeur.
49 if (!m_pending_messages.empty() || !m_waiting_messages.empty())
50 pwarning() << String::format("Pending or waiting messages nb_pending={0} nb_waiting={1}",
51 m_pending_messages.size(),m_waiting_messages.size());
52 delete m_timer;
53}
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58void BasicParticleExchanger::
59initialize(IItemFamily* item_family)
60{
62
63 m_item_family = item_family;
64 m_parallel_mng = item_family->mesh()->parallelMng();
65 m_rank = m_parallel_mng->commRank();
66 m_timer = new Timer(m_parallel_mng->timerMng(),"BasicParticleExchanger",Timer::TimerReal);
67
68 if (options())
69 m_max_nb_message_without_reduce = options()->maxNbMessageWithoutReduce();
70
71 info() << "Initialize BasicParticleExchanger family=" << item_family->name();
72 info() << "-- MaxNbMessageWithoutReduce = " << m_max_nb_message_without_reduce;
73}
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78void BasicParticleExchanger::
79_clearMessages()
80{
81 for( auto msg : m_accumulate_infos )
82 delete msg;
83 m_accumulate_infos.clear();
84}
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89void BasicParticleExchanger::
90beginNewExchange(Integer i_nb_particle)
91{
92 _checkInitialized();
93 String function_id = "BasicParticleExchanger::beginNewExchange >>> ";
94 IParallelMng* pm = m_parallel_mng;
95
96 if (options()){
97 m_debug_exchange_items_level = options()->debugExchangeItemsLevel();
98 m_max_nb_message_without_reduce = options()->maxNbMessageWithoutReduce();
99 }
100
101 m_nb_loop = 0;
102 m_last_nb_to_exchange = 0;
103 m_exchange_finished = false;
104 m_print_info = false;
105 m_current_nb_reduce = 0;
106 m_nb_particle_send = 0;
107
108 //TODO: utiliser un tag spécifique pour cet échange.
110 Int64 min_nb_particle = 0;
111 Int64 max_nb_particle = 0;
112 Int64 nb_total_particle = 0;
113 Int32 min_rank = 0;
114 Int32 max_rank = 0;
117 //m_nb_total_particle = pm->reduce(Parallel::ReduceSum,nb_particle);
118 if (m_verbose_level>=1)
119 info() << function_id << "** NB PARTICLES IN VOL total=" << nb_total_particle
120 << " min=" << min_nb_particle << " max=" << max_nb_particle
121 << " min_rank=" << min_rank << " max_rank=" << max_rank
122 << " date=" << platform::getCurrentDateTime();
123
124 m_nb_total_particle_finish_exchange = 0;
125
126 // Récupère la liste des variables à transférer.
127 // Il s'agit des variables qui ont la même famille que celle passée
128 // en paramètre.
129 // IMPORTANT: tous les sous-domaines doivent avoir ces mêmes variables
130 m_variables_to_exchange.clear();
131 m_item_family->usedVariables(m_variables_to_exchange);
132 m_variables_to_exchange.sortByName(true);
133}
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
138void BasicParticleExchanger::
139sendItems(Integer nb_particle_finish_exchange,
142{
143 ARCANE_UNUSED(nb_particle_finish_exchange);
144
145 m_nb_particle_send = local_ids.size();
146 {
147 Timer::Sentry ts(m_timer);
148 _generateSendItems(local_ids,sub_domains_to_send);
149 }
150 info(5) << A_FUNCINFO << "sendItems " << m_timer->lastActivationTime();
151
152 _sendPendingMessages();
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158bool BasicParticleExchanger::
159exchangeItems(Integer nb_particle_finish_exchange,
163 IFunctor* functor)
164{
165 ++m_nb_loop;
167
168 if (!item_group.null())
169 item_group.clear();
170
171 return _waitMessages(0,item_group,nullptr,functor);
172}
173
174/*---------------------------------------------------------------------------*/
175/*---------------------------------------------------------------------------*/
176
177bool BasicParticleExchanger::
178exchangeItems(Integer nb_particle_finish_exchange,
182 IFunctor* functor)
183{
184 ++m_nb_loop;
186
188 new_particle_local_ids->clear();
189
190 return _waitMessages(0,ItemGroup(),new_particle_local_ids,functor);
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
195
196void BasicParticleExchanger::
197_generateSendItems(Int32ConstArrayView local_ids,
199{
200 Timer::Phase tphase(subDomain(),TP_Communication);
201
202 IMesh* mesh = m_item_family->mesh();
203
204 String func_name("BasicParticleExchanger::sendItems()");
205
207 mesh->cellFamily()->getCommunicatingSubDomains(communicating_sub_domains);
208
210 //Integer max_sub_domain_id = 0;
212 // Infos pour chaque sous-domaine connecté
213 //_clearMessages();
214 m_accumulate_infos.clear();
215 m_accumulate_infos.resize(nb_connected_sub_domain);
216 for( Integer i=0; i<nb_connected_sub_domain; ++i ){
217 m_accumulate_infos[i] = new SerializeMessage(m_rank,communicating_sub_domains[i],
218 ISerializeMessage::MT_Send);
219#if 0
220 // Utile uniquement pour tester le timeout avec blocage
221 if (m_rank==0 && i==0){
222 warning() << " WRONG MESSAGE";
224 ISerializeMessage::MT_Recv);
225 m_pending_messages.add(sm);
226 }
227#endif
228 }
229
230 _addItemsToSend(local_ids,sub_domains_to_send,communicating_sub_domains,ids_to_send);
231
232 if (m_debug_exchange_items_level>=1){
233 info() << "-- Subdomain " << m_rank << ". NB to send: " << local_ids.size()
234 << " NB connected subdomain: " << nb_connected_sub_domain;
235 debug() << "NB connected subdomain for " << m_rank << " : " << m_accumulate_infos.size();
236 for( Integer i=0, s=m_accumulate_infos.size(); i<s; ++i ){
237 debug() << "NB for the subdomain " << m_accumulate_infos[i]->destRank()
238 << " " << ids_to_send[i].size();
239 }
240 }
241
242 Int64UniqueArray items_to_send_uid;
243 Int64UniqueArray items_to_send_cells_uid; // Uniquement pour les particules;
244
245 for( Integer j=0; j<nb_connected_sub_domain; ++j ){
246 ISerializeMessage* sm = m_accumulate_infos[j];
247 // En mode bloquant, envoie toujours le message car le destinataire a posté
248 // un message de réception. Sinon, le message n'a besoin d'être envoyé que
249 // s'il contient des particules.
250 _serializeMessage(sm,ids_to_send[j],items_to_send_uid,
251 items_to_send_cells_uid);
252
253 m_pending_messages.add(sm);
254
255 // En mode bloquant, il faut un message de réception par envoie
256 auto* recv_sm = new SerializeMessage(m_rank,sm->destination().value(),
257 ISerializeMessage::MT_Recv);
258 m_pending_messages.add(recv_sm);
259 }
260
261 m_accumulate_infos.clear();
262 // Détruit les entités qui viennent d'être envoyées
263 m_item_family->toParticleFamily()->removeParticles(local_ids);
264 m_item_family->endUpdate();
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270void BasicParticleExchanger::
271_addItemsToSend(Int32ConstArrayView local_ids,
272 Int32ConstArrayView sub_domains_to_send,
273 Int32ConstArrayView communicating_sub_domains,
274 UniqueArray< SharedArray<Int32> >& ids_to_send)
275{
276 const Int32 debug_exchange_items_level = m_debug_exchange_items_level;
277 Int32 nb_connected_sub_domain = ids_to_send.size();
278 // Cherche pour chaque élément à quel sous-domaine il doit être transféré.
279 // Cette recherche se fait en se basant sur les \a local_ids
280 Int32 id_size = local_ids.size();
281 for( Integer i=0; i<id_size; ++i ){
282 Int32 item_local_id = local_ids[i];
283 Int32 sd_to_send = sub_domains_to_send[i];
284 if (sd_to_send==m_rank)
285 // Il s'agit d'une entité propre à ce sous-domaine
286 ARCANE_FATAL("The entity with local index {0} should not be sent to its own subdomain",
287 item_local_id);
288 // Recherche l'index du sous-domaine auquel l'entité appartient
289 // dans la liste \a sync_list
290 // TODO: utiliser une table indirect (tableau alloué au nombre de sous-domaines)
291 Integer sd_index = nb_connected_sub_domain;
292 for( Integer i_sd=0; i_sd<nb_connected_sub_domain; ++i_sd )
293 if (sd_to_send==communicating_sub_domains[i_sd]){
294 sd_index = i_sd;
295 break;
296 }
297 if (sd_index==nb_connected_sub_domain)
298 ARCANE_FATAL("Internal: bad rank index");
299 ids_to_send[sd_index].add(item_local_id);
300 if (debug_exchange_items_level>=1)
301 pinfo() << "ADD ITEM TO SEND lid=" << item_local_id << " sd_index=" << sd_index
302 << " sd=" << communicating_sub_domains[sd_index] << " n=" << ids_to_send[sd_index].size()
303 << " begin=" << ids_to_send[sd_index].data();
304 }
305 if (debug_exchange_items_level>=1)
306 for( Integer i=0; i<nb_connected_sub_domain; ++i )
307 pinfo() << "SEND INFO sd_index=" << i
308 << " sd=" << communicating_sub_domains[i] << " n=" << ids_to_send[i].size()
309 << " begin=" << ids_to_send[i].data();
310
311 if ((debug_exchange_items_level>=1 && m_print_info) || debug_exchange_items_level>=2){
312 IParallelMng* pm = m_parallel_mng;
313 Int32 rank = pm->commRank();
314 ParticleInfoListView items(m_item_family);
315 Integer nb_print = math::min(5,id_size);
316 for( Integer i=0; i<nb_print; ++i ){
317 Particle part(items[local_ids[i]]);
318 pinfo() << " RANK=" << rank << " LID=" << local_ids[i] << " SD=" << sub_domains_to_send[i]
319 << " uid=" << part.uniqueId() << " cell=" << ItemPrinter(part.cell());
320 }
321 pm->barrier();
322 }
323}
324
325/*---------------------------------------------------------------------------*/
326/*---------------------------------------------------------------------------*/
327
328bool BasicParticleExchanger::
330{
331 return _waitMessages(nb_pending_particle,ItemGroup(),new_particle_local_ids,functor);
332}
333
334/*---------------------------------------------------------------------------*/
335/*---------------------------------------------------------------------------*/
336
337bool BasicParticleExchanger::
338_waitMessages(Integer nb_pending_particle,ItemGroup item_group,
340{
341 String func_name = "BasicParticleExchanger::waitMessages";
342 _waitMessages(item_group,new_particle_local_ids,functor);
343
344 bool do_reduce = m_current_nb_reduce>m_last_nb_reduce;
345 if (m_max_nb_message_without_reduce!=(-1))
346 do_reduce |= m_current_nb_reduce>m_max_nb_message_without_reduce;
347
348 if (do_reduce){
349 Int64 nb_to_exchange = 0;
350 IParallelMng* pm = m_parallel_mng;
351 {
352 Timer::Sentry ts(m_timer);
353 Int64 current_exchange = m_nb_particle_send+nb_pending_particle;
354 nb_to_exchange = pm->reduce(Parallel::ReduceSum,current_exchange);
355 }
356 info(4) << func_name << "TimeReduce=" << m_timer->lastActivationTime()
357 << " nbtoexchange=" << nb_to_exchange;
358 m_exchange_finished = (nb_to_exchange==0);
359 if (nb_to_exchange>0 && m_last_nb_to_exchange==nb_to_exchange && m_nb_loop>300){
360 m_print_info = true;
361 }
362 m_last_nb_to_exchange = nb_to_exchange;
363 }
364
365 ++m_current_nb_reduce;
366 debug() << func_name << " ** RETURN EXCHANGE m_exchange_finished: " << m_exchange_finished;
367 if (m_exchange_finished){
368 m_last_nb_reduce = m_current_nb_reduce - 4;
369 if (m_verbose_level>=1)
370 info() << func_name << " exchange finished "
371 << " n=" << m_current_nb_reduce
372 << " date=" << platform::getCurrentDateTime();
373 }
374 return m_exchange_finished;
375}
376
377/*---------------------------------------------------------------------------*/
378/*---------------------------------------------------------------------------*/
379
380void BasicParticleExchanger::
381_waitMessages(ItemGroup item_group,Int32Array* new_particle_local_ids,IFunctor* functor)
382{
383 if (functor){
384 {
385 Timer::Sentry ts(m_timer);
386 functor->executeFunctor();
387 }
388 m_total_time_functor += m_timer->lastActivationTime();
389 if (m_debug_exchange_items_level>=1)
390 info() << "TimeFunctor: current=" << m_timer->lastActivationTime()
391 << " total=" << m_total_time_functor;
392 }
393
394 {
395 Timer::Sentry ts(m_timer);
396 m_message_list->waitMessages(Parallel::WaitAll);
397 }
398 m_total_time_waiting += m_timer->lastActivationTime();
399 if (m_debug_exchange_items_level>=1)
400 info() << "TimeWaiting: current=" << m_timer->lastActivationTime()
401 << " total=" << m_total_time_waiting;
402
403 // Sauve les communications actuellements traitées car le traitement
404 // peut en ajouter de nouvelles
405 UniqueArray<ISerializeMessage*> current_messages(m_waiting_messages);
406 m_waiting_messages.clear();
407
408 Int64UniqueArray items_to_create_unique_id;
409 Int64UniqueArray items_to_create_cells_unique_id;
410 Int32UniqueArray items_to_create_local_id;
411 Int32UniqueArray items_to_create_cells_local_id;
412 for( ISerializeMessage* sm : current_messages ){
413 if (!sm->isSend())
414 _deserializeMessage(sm,items_to_create_unique_id,items_to_create_cells_unique_id,
415 items_to_create_local_id,items_to_create_cells_local_id,
416 item_group,new_particle_local_ids);
417 delete sm;
418 }
419 if (!m_waiting_messages.empty())
420 ARCANE_FATAL("Pending messages n={0}",m_waiting_messages.size());
421}
422
423/*---------------------------------------------------------------------------*/
424/*---------------------------------------------------------------------------*/
425
426void BasicParticleExchanger::
427_sendPendingMessages()
428{
429 IParallelMng* pm = m_parallel_mng;
430
431 if (!m_message_list.get())
432 m_message_list = pm->createSerializeMessageListRef();
433
434 {
435 Timer::Sentry ts(m_timer);
436 // Ajoute les messages en attente de traitement
437 Integer nb_message = m_pending_messages.size();
438 for( Integer i=0; i<nb_message; ++i ){
439 m_message_list->addMessage(m_pending_messages[i]);
440 m_waiting_messages.add(m_pending_messages[i]);
441 }
442 m_message_list->processPendingMessages();
443 m_pending_messages.clear();
444 }
445}
446
447/*---------------------------------------------------------------------------*/
448/*---------------------------------------------------------------------------*/
449
450void BasicParticleExchanger::
451_serializeMessage(ISerializeMessage* sm,
452 Int32ConstArrayView acc_ids,
453 Int64Array& items_to_send_uid,
454 Int64Array& items_to_send_cells_uid)
455{
456 ParticleInfoListView internal_items(m_item_family);
457
458 ISerializer* sbuf = sm->serializer();
459 sbuf->setMode(ISerializer::ModeReserve);
460
461 //for( Integer j=0; j<nb_connected_sub_domain; ++j ){
462 //ConstArrayView<Integer> acc_ids = m_ids_to_send[j];
463 Integer nb_item = acc_ids.size();
464 // Réserve pour le type de message
465 //sbuf->reserveInteger(1);
466 // Réserve pour l'id du message
467 sbuf->reserve(DT_Int64,1);
468 // Réserve pour le nombre de uniqueId()
469 sbuf->reserve(DT_Int64,1);
470 sbuf->reserveSpan(DT_Int64,nb_item);
471 // Réserve pour les uniqueId() des mailles dans lesquelles se trouvent les particules
472 //sbuf->reserve(DT_Size,1);
473 sbuf->reserveSpan(DT_Int64,nb_item);
474
475 for( VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
476 IVariable* var = *i_var;
477 var->serialize(sbuf,acc_ids);
478 }
479
480 // Sérialise les données en écriture
481 sbuf->allocateBuffer();
482
483 if (m_debug_exchange_items_level>=1)
484 info() << "BSE_SerializeMessage nb_item=" << nb_item
485 << " id=" << m_serialize_id
486 << " dest=" << sm->destination();
487
488 sbuf->setMode(ISerializer::ModePut);
489
490 sbuf->putInt64(m_serialize_id);
491 ++m_serialize_id;
492
493 sbuf->putInt64(nb_item);
494 items_to_send_uid.resize(nb_item);
495 items_to_send_cells_uid.resize(nb_item);
496 for( Integer z=0; z<nb_item; ++z ){
497 Particle item = internal_items[acc_ids[z]];
498 items_to_send_uid[z] = item.uniqueId();
499 bool has_cell = item.hasCell();
500 items_to_send_cells_uid[z] = (has_cell) ? item.cell().uniqueId() : NULL_ITEM_UNIQUE_ID;
501 if (m_debug_exchange_items_level>=2){
502 info() << "Particle BufID=" << acc_ids[z]
503 << " LID=" << item.localId()
504 << " UID=" << items_to_send_uid[z]
505 << " CellIUID=" << items_to_send_cells_uid[z]
506 << " (owner=" << item.cell().owner() << ")";
507 }
508 }
509 sbuf->putSpan(items_to_send_uid);
510 sbuf->putSpan(items_to_send_cells_uid);
511
512 for( VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
513 IVariable* var = *i_var;
514 var->serialize(sbuf,acc_ids);
515 }
516
517}
518
519/*---------------------------------------------------------------------------*/
520/*---------------------------------------------------------------------------*/
521
522void BasicParticleExchanger::
523_deserializeMessage(ISerializeMessage* message,
524 Int64Array& items_to_create_unique_id,
525 Int64Array& items_to_create_cells_unique_id,
526 Int32Array& items_to_create_local_id,
527 Int32Array& items_to_create_cells_local_id,
528 ItemGroup item_group,
529 Int32Array* new_particle_local_ids)
530{
531
532 IMesh* mesh = m_item_family->mesh();
533 ISerializer* sbuf = message->serializer();
534 IItemFamily* cell_family = mesh->cellFamily();
535
536 // Indique qu'on souhaite sérialiser les données en lecture
537 sbuf->setMode(ISerializer::ModeGet);
538 sbuf->setReadMode(ISerializer::ReadReplace);
539
540 {
541 Int64 serialize_id = sbuf->getInt64();
542 Int64 nb_item = sbuf->getInt64();
543 if (m_debug_exchange_items_level>=1)
544 info() << "BSE_DeserializeMessage id=" << serialize_id << " nb=" << nb_item
545 << " orig=" << message->destination();
546
547 items_to_create_local_id.resize(nb_item);
548 items_to_create_unique_id.resize(nb_item);
549 items_to_create_cells_unique_id.resize(nb_item);
550 items_to_create_cells_local_id.resize(nb_item);
551 sbuf->getSpan(items_to_create_unique_id);
552 sbuf->getSpan(items_to_create_cells_unique_id);
553 if (m_debug_exchange_items_level>=2){
554 //info() << "Recv from SID " << sync_infos[i].subDomain() << " N=" << nb_item;
555 for( Integer z=0; z<nb_item; ++z ){
556 info() << "Particle UID=" << items_to_create_unique_id[z]
557 << " CellIUID=" << items_to_create_cells_unique_id[z];
558 }
559 }
560
561 items_to_create_cells_local_id.resize(nb_item);
562 cell_family->itemsUniqueIdToLocalId(items_to_create_cells_local_id,items_to_create_cells_unique_id);
563
564 m_item_family->toParticleFamily()->addParticles(items_to_create_unique_id,
565 items_to_create_cells_local_id,
566 items_to_create_local_id);
567
568 // Notifie la famille qu'on a fini nos modifs.
569 // Après appel à cette méthode, les variables sont à nouveau utilisables
570 m_item_family->endUpdate();
571
572 // Converti les uniqueId() récupérée en localId() et pour les particules
573 // renseigne la maille correspondante
574 ParticleInfoListView internal_items(m_item_family);
575
576 for( Integer z=0; z<nb_item; ++z ){
577 Particle item = internal_items[items_to_create_local_id[z]];
578 //item.setCell( internal_cells[items_to_create_cells_local_id[z]] );
579 // Je suis le nouveau propriétaire (TODO: ne pas faire ici)
580 item.mutableItemBase().setOwner(m_rank,m_rank);
581 }
582 if (!item_group.null())
583 item_group.addItems(items_to_create_local_id,false);
584 if (new_particle_local_ids)
585 new_particle_local_ids->addRange(items_to_create_local_id);
586 for( VariableCollection::Enumerator i_var(m_variables_to_exchange); ++i_var; ){
587 IVariable* var = *i_var;
588 var->serialize(sbuf,items_to_create_local_id);
589 }
590 }
591}
592
593/*---------------------------------------------------------------------------*/
594/*---------------------------------------------------------------------------*/
595
596void BasicParticleExchanger::
597reset()
598{
599 if (!m_waiting_messages.empty())
600 ARCANE_FATAL("waiting parallel requests");
601 _clearMessages();
602}
603
604/*---------------------------------------------------------------------------*/
605/*---------------------------------------------------------------------------*/
606
607void BasicParticleExchanger::
608addNewParticles(Integer nb_particle)
609{
610 ARCANE_UNUSED(nb_particle);
611 throw NotImplementedException(A_FUNCINFO);
612}
613
614/*---------------------------------------------------------------------------*/
615/*---------------------------------------------------------------------------*/
616
617void BasicParticleExchanger::
618_checkInitialized()
619{
620 if (!m_item_family)
621 ARCANE_FATAL("method initialized() not called");
622 _clearMessages();
623}
624
625/*---------------------------------------------------------------------------*/
626/*---------------------------------------------------------------------------*/
627
628ARCANE_REGISTER_SERVICE_BASICPARTICLEEXCHANGER(BasicParticleExchanger,BasicParticleExchanger);
629
631 BasicParticleExchanger);
632
633/*---------------------------------------------------------------------------*/
634/*---------------------------------------------------------------------------*/
635
636} // End namespace Arcane::mesh
637
638/*---------------------------------------------------------------------------*/
639/*---------------------------------------------------------------------------*/
#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.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Tableau d'items de types quelconques.
Interface d'une famille d'entités.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual void computeMinMaxSum(char val, char &min_val, char &max_val, char &sum_val, Int32 &min_rank, Int32 &max_rank)=0
Calcule en une opération la somme, le min, le max d'une valeur.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Ref< ISerializeMessageList > createSerializeMessageListRef()=0
Créé une liste pour gérer les 'ISerializeMessage'.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual void barrier()=0
Effectue une barière.
Interface d'un échangeur de particules.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Message utilisant un SerializeBuffer.
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
Gestion d'un timer.
Definition Timer.h:62
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Exception lorsqu'une fonction n'est pas implémentée.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:513
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
Int32 Integer
Type représentant un entier.