13#include "arcane/mesh/NonBlockingParticleExchanger.h"
15#include "arcane/utils/List.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/IFunctor.h"
18#include "arcane/utils/PlatformUtils.h"
20#include "arcane/core/ItemGroup.h"
21#include "arcane/core/ItemVector.h"
22#include "arcane/core/IItemFamily.h"
23#include "arcane/core/IParticleFamily.h"
24#include "arcane/core/IParallelMng.h"
25#include "arcane/core/IVariableMng.h"
26#include "arcane/core/IVariable.h"
27#include "arcane/core/IMesh.h"
28#include "arcane/core/Item.h"
29#include "arcane/core/Timer.h"
30#include "arcane/core/ISerializeMessageList.h"
31#include "arcane/core/CommonVariables.h"
32#include "arcane/core/FactoryService.h"
33#include "arcane/core/internal/SerializeMessage.h"
46NonBlockingParticleExchanger::
47NonBlockingParticleExchanger(
const ServiceBuildInfo& sbi)
49, m_item_family(nullptr)
50, m_parallel_mng(sbi.mesh()->parallelMng())
51, m_rank(m_parallel_mng->commRank())
52, m_timer(new Timer(m_parallel_mng->timerMng(),
"NonBlockingParticleExchanger", Timer::TimerReal))
53, m_total_time_functor(0.)
54, m_total_time_waiting(0.)
55, m_nb_total_particle_finish_exchange(0)
56, m_nb_total_particle(0)
57, m_nb_original_blocking_size(0)
58, m_nb_blocking_size(m_nb_original_blocking_size)
59, m_exchange_finished(true)
61, m_need_general_receive(false)
62, m_end_message_sended(false)
63, m_can_process_messages(true)
64, m_can_process_non_blocking(false)
65, m_want_process_non_blocking(false)
66, m_want_fast_send_particles(true)
67, m_nb_receive_message(0)
68, m_nb_particle_finished_exchange(0)
74#if ARCANE_DEBUG_EXCHANGE_ITEMS
82NonBlockingParticleExchanger::
83~NonBlockingParticleExchanger()
86 if (!m_pending_messages.empty() || !m_waiting_messages.empty()) {
87 String s = String::format(
"pending or waiting messages: nb_pending={0} nb_waiting=",
88 m_pending_messages.size(), m_waiting_messages.size());
92 if (!m_waiting_local_ids.empty()) {
93 warning() << String::format(
"pending particles: nb_pending=", m_waiting_local_ids.size());
102void NonBlockingParticleExchanger::
105 m_item_family = item_family;
111void NonBlockingParticleExchanger::
114 for (
Integer i = 0, is = m_accumulate_infos.size(); i < is; ++i) {
115 delete m_accumulate_infos[i];
116 m_accumulate_infos[i] = 0;
118 m_accumulate_infos.clear();
124void NonBlockingParticleExchanger::
125beginNewExchange(
Integer i_nb_particle)
130 m_end_message_sended =
false;
131 m_exchange_finished =
false;
133 m_nb_receive_message = 0;
134 m_nb_particle_finished_exchange = 0;
137 Int64 nb_particle = i_nb_particle;
139 info() <<
"BEGIN TRACKING TOTAL FLYING = " << m_nb_total_particle
140 <<
" (local=" << nb_particle <<
") "
143 m_nb_total_particle_finish_exchange = 0;
145 m_need_general_receive =
true;
158bool NonBlockingParticleExchanger::
159exchangeItems(
Integer nb_particle_finish_exchange,
165 m_nb_particle_finished_exchange += nb_particle_finish_exchange;
166 return _exchangeItems(local_ids, sub_domains_to_send, item_group, 0, functor);
172bool NonBlockingParticleExchanger::
173exchangeItems(
Integer nb_particle_finish_exchange,
180 m_nb_particle_finished_exchange += nb_particle_finish_exchange;
181 return _exchangeItems(local_ids, sub_domains_to_send,
ItemGroup(), new_particle_local_ids, functor);
187void NonBlockingParticleExchanger::
188sendItems(
Integer nb_particle_finish_exchange,
192 m_nb_particle_finished_exchange += nb_particle_finish_exchange;
193 _checkSendItems(local_ids, sub_domains_to_send);
194 _sendPendingMessages();
200bool NonBlockingParticleExchanger::
203 return _waitMessages(nb_pending_particle,
ItemGroup(), new_particle_local_ids, functor);
209void NonBlockingParticleExchanger::
214 Integer nb_waiting_local_ids = m_waiting_local_ids.size();
215 Integer nb_waiting_sub_domains_to_send = m_waiting_sub_domains_to_send.size();
216 if ((nb_particle + nb_waiting_local_ids) >= m_nb_blocking_size) {
217 _generateSendItemsMessages(local_ids, sub_domains_to_send);
221 m_waiting_local_ids.resize(nb_waiting_local_ids + nb_particle);
222 m_waiting_sub_domains_to_send.resize(nb_waiting_sub_domains_to_send + nb_particle);
223 for (
Integer i = 0; i < nb_particle; ++i) {
224 m_waiting_local_ids[nb_waiting_local_ids + i] = local_ids[i];
225 m_waiting_sub_domains_to_send[nb_waiting_sub_domains_to_send + i] = sub_domains_to_send[i];
233bool NonBlockingParticleExchanger::
234_exchangeItems(Int32ConstArrayView local_ids,
235 Int32ConstArrayView sub_domains_to_send, ItemGroup item_group,
236 Int32Array* new_particle_local_ids,
239 if (m_want_fast_send_particles) {
240 if (local_ids.empty())
241 _processFinishTrackingMessage();
243 else if (!m_want_process_non_blocking)
244 _processFinishTrackingMessage();
245 if (m_exchange_finished) {
246 _sendFinishExchangeParticle();
247 m_need_general_receive =
false;
249 _checkNeedReceiveMessage();
251 _checkSendItems(local_ids, sub_domains_to_send);
253 return _waitMessages(0, item_group, new_particle_local_ids, functor);
259bool NonBlockingParticleExchanger::
260_waitMessages(Integer nb_pending_particle, ItemGroup item_group,
261 Int32Array* new_particle_local_ids, IFunctor* functor)
263 ARCANE_UNUSED(nb_pending_particle);
265 if (!item_group.null())
268 m_can_process_messages =
true;
269 m_can_process_non_blocking = m_want_process_non_blocking;
270 while (m_can_process_messages && !m_exchange_finished) {
271 m_can_process_messages =
false;
272 _processMessages(item_group, new_particle_local_ids,
false, functor);
275 if (m_exchange_finished) {
276 info(5) <<
" ** EXCHANGE finished: ";
278 _processMessages(item_group, new_particle_local_ids,
true, 0);
279 info(5) <<
" ** EXCHANGE finished END: ";
282 info(5) <<
" ** RETURN EXCHANGE m_exchange_finished: " << m_exchange_finished;
283 return m_exchange_finished;
289void NonBlockingParticleExchanger::
290_checkNeedReceiveMessage()
292 if (m_need_general_receive) {
293 auto sm =
new SerializeMessage(m_rank, A_NULL_RANK, ISerializeMessage::MT_Recv);
294 m_pending_messages.add(sm);
295 m_need_general_receive =
false;
302void NonBlockingParticleExchanger::
303_generateSendItemsMessages(Int32ConstArrayView local_ids,
304 Int32ConstArrayView sub_domains_to_send)
306 Timer::Phase tphase(m_parallel_mng->timeStats(), TP_Communication);
308 IMesh* mesh = m_item_family->mesh();
311 mesh->cellFamily()->getCommunicatingSubDomains(communicating_sub_domains);
313 Integer nb_connected_sub_domain = communicating_sub_domains.size();
315 UniqueArray<SharedArray<Int32>> ids_to_send(nb_connected_sub_domain);
318 m_accumulate_infos.clear();
319 m_accumulate_infos.resize(nb_connected_sub_domain);
320 for (Integer i = 0; i < nb_connected_sub_domain; ++i)
321 m_accumulate_infos[i] =
new SerializeMessage(m_rank, communicating_sub_domains[i],
322 ISerializeMessage::MT_Send);
324 _addItemsToSend(local_ids, sub_domains_to_send, communicating_sub_domains, ids_to_send);
325 _addItemsToSend(m_waiting_local_ids, m_waiting_sub_domains_to_send,
326 communicating_sub_domains, ids_to_send);
329 info() <<
"-- Subdomain " << m_rank <<
". NB to send: " << local_ids.size()
330 <<
" NB connected subdomains: " << nb_connected_sub_domain;
332 info() <<
"NB connected subdomain for " << m_rank <<
" : " << m_accumulate_infos.size();
333 for (Integer i = 0, n = m_accumulate_infos.size(); i < n; ++i) {
334 info() <<
"------------- Send: rank=" << m_accumulate_infos[i]->destRank()
335 <<
" n=" << ids_to_send[i].size();
342 for (Integer j = 0; j < nb_connected_sub_domain; ++j) {
343 ISerializeMessage* sm = m_accumulate_infos[j];
346 if (!ids_to_send[j].empty())
347 _serializeMessage(sm, ids_to_send[j], items_to_send_uid,
348 items_to_send_cells_uid);
354 m_accumulate_infos.
clear();
357 info(5) <<
"NonBlockingParticleExchanger:: sendItems " <<
"local_ids " << local_ids.size();
358 info(5) <<
"NonBlockingParticleExchanger:: sendItems " <<
"m_waiting_local_ids " << m_waiting_local_ids.size();
360 m_item_family->toParticleFamily()->removeParticles(local_ids);
361 m_item_family->toParticleFamily()->removeParticles(m_waiting_local_ids);
362 m_item_family->endUpdate();
363 m_waiting_local_ids.clear();
364 m_waiting_sub_domains_to_send.clear();
370void NonBlockingParticleExchanger::
371_addItemsToSend(Int32ConstArrayView local_ids,
372 Int32ConstArrayView sub_domains_to_send,
373 Int32ConstArrayView communicating_sub_domains,
374 UniqueArray<SharedArray<Int32>>& ids_to_send)
376 String func_name(
"NonBlockingParticleExchanger::_addItemsToSend()");
377 Integer nb_connected_sub_domain = ids_to_send.size();
380 Integer id_size = local_ids.size();
381 for (Integer i = 0; i < id_size; ++i) {
382 Int32 item_local_id = local_ids[i];
383 Integer sd_to_send = sub_domains_to_send[i];
385 if (sd_to_send == m_rank)
387 fatal() << func_name <<
"The entity with local id " << item_local_id
388 <<
" should not be sent to its own subdomain";
393 Integer sd_index = nb_connected_sub_domain;
394 for (Integer i_sd = 0; i_sd < nb_connected_sub_domain; ++i_sd)
395 if (sd_to_send == communicating_sub_domains[i_sd]) {
400 if (sd_index == nb_connected_sub_domain)
401 fatal() << func_name <<
"Internal: bad subdomain index";
403 ids_to_send[sd_index].add(item_local_id);
410void NonBlockingParticleExchanger::
411_processMessages(ItemGroup item_group, Int32Array* new_particle_local_ids,
412 bool wait_all, IFunctor* functor)
414 _sendPendingMessages();
418 Timer::Sentry ts(m_timer);
419 functor->executeFunctor();
421 m_total_time_functor += m_timer->lastActivationTime();
422 info(5) <<
"TimeFunctor: current=" << m_timer->lastActivationTime()
423 <<
" total=" << m_total_time_functor;
426 Integer nb_message_finished = 0;
428 Timer::Sentry ts(m_timer);
430 nb_message_finished = m_message_list->waitMessages(Parallel::WaitAll);
432 if (m_can_process_non_blocking)
433 nb_message_finished = m_message_list->waitMessages(Parallel::WaitSomeNonBlocking);
435 nb_message_finished = m_message_list->waitMessages(Parallel::WaitSome);
437 if (nb_message_finished == 0) {
438 m_can_process_non_blocking =
false;
439 m_can_process_messages =
true;
440 _processFinishTrackingMessage();
445 m_total_time_waiting += m_timer->lastActivationTime();
446 info(5) <<
"TimeWaiting: current=" << m_timer->lastActivationTime()
447 <<
" total=" << m_total_time_waiting;
450 UniqueArray<ISerializeMessage*> current_messages(m_waiting_messages);
451 m_waiting_messages.clear();
455 for (Integer i = 0, is = current_messages.size(); i < is; ++i) {
456 ISerializeMessage* sm = current_messages[i];
457 if (sm->finished()) {
459 _deserializeMessage(sm, items_to_create_id, items_to_create_cells_id, item_group, new_particle_local_ids);
460 ++m_nb_receive_message;
465 m_waiting_messages.add(sm);
472void NonBlockingParticleExchanger::
473_sendPendingMessages()
475 IParallelMng* pm = m_parallel_mng;
477 _checkNeedReceiveMessage();
479 if (!m_message_list.get())
480 m_message_list = pm->createSerializeMessageListRef();
483 Timer::Sentry ts(m_timer);
485 Integer nb_message = m_pending_messages.size();
486 for (Integer i = 0; i < nb_message; ++i) {
487 m_message_list->addMessage(m_pending_messages[i]);
488 m_waiting_messages.add(m_pending_messages[i]);
490 m_message_list->processPendingMessages();
491 m_pending_messages.clear();
493 info(5) <<
"TimeSendMessages=" << m_timer->lastActivationTime()
494 <<
" buffersize=" << m_waiting_local_ids.size();
500void NonBlockingParticleExchanger::
501_serializeMessage(ISerializeMessage* sm,
502 Int32ConstArrayView acc_ids,
503 Int64Array& items_to_send_uid,
504 Int64Array& items_to_send_cells_uid)
506 ParticleInfoListView internal_items(m_item_family);
508 ISerializer* sbuf = sm->serializer();
509 sbuf->setMode(ISerializer::ModeReserve);
513 Integer nb_item = acc_ids.size();
515 sbuf->reserveInteger(1);
516 if (m_want_fast_send_particles) {
518 sbuf->reserveInt64(1);
521 sbuf->reserveInt32(1);
523 sbuf->reserveInt64(1);
525 sbuf->reserveSpan(eBasicDataType::Int64, nb_item);
527 sbuf->reserveSpan(eBasicDataType::Int64, nb_item);
529 for (VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var;) {
530 IVariable* var = *i_var;
531 var->serialize(sbuf, acc_ids);
535 sbuf->allocateBuffer();
536 sbuf->setMode(ISerializer::ModePut);
538 sbuf->putInteger(MESSAGE_EXCHANGE);
539 if (m_want_fast_send_particles) {
540 sbuf->putInt64(m_nb_particle_finished_exchange);
541 m_nb_particle_finished_exchange = 0;
543 sbuf->putInt32(m_rank);
544 sbuf->putInt64(nb_item);
545 items_to_send_uid.resize(nb_item);
546 items_to_send_cells_uid.resize(nb_item);
548 for (Integer z = 0; z < nb_item; ++z) {
549 Particle item = internal_items[acc_ids[z]];
550 items_to_send_uid[z] = item.uniqueId();
551 bool has_cell = item.hasCell();
552 items_to_send_cells_uid[z] = (has_cell) ? item.cell().uniqueId() : NULL_ITEM_UNIQUE_ID;
553#ifdef ARCANE_DEBUG_EXCHANGE_ITEMS
555 info() <<
"Particle BufID=" << acc_ids[z]
556 <<
" LID=" << item.localId()
557 <<
" UID=" << items_to_send_uid[z]
558 <<
" CellIUID=" << items_to_send_cells_uid[z]
559 <<
" (owner=" << item.cell().owner() <<
")";
563 sbuf->putSpan(items_to_send_uid);
564 sbuf->putSpan(items_to_send_cells_uid);
566 for (VariableList::Enumerator i_var(m_variables_to_exchange); ++i_var;) {
567 IVariable* var = *i_var;
568 var->serialize(sbuf, acc_ids);
571 m_pending_messages.add(sm);
577void NonBlockingParticleExchanger::
578_deserializeMessage(ISerializeMessage* message,
579 Int64Array& items_to_create_unique_id,
580 Int64Array& items_to_create_cells_id,
581 ItemGroup item_group,
582 Int32Array* new_particle_local_ids)
585 IMesh* mesh = m_item_family->mesh();
586 ISerializer* sbuf = message->serializer();
589 sbuf->setMode(ISerializer::ModeGet);
590 sbuf->setReadMode(ISerializer::ReadReplace);
594 Integer message_type = sbuf->getInteger();
595 info(4) <<
"Deserialise message_type=" << (int)message_type;
596 switch (message_type) {
597 case MESSAGE_EXCHANGE: {
598 m_need_general_receive =
true;
599 if (m_want_fast_send_particles) {
600 Int64 nb_finished = sbuf->getInt64();
601 m_nb_particle_finished_exchange += nb_finished;
603 Int32 orig_rank = sbuf->getInt32();
604 Int64 nb_item = sbuf->getInt64();
606 info() <<
"------------- Receive: rank=" << orig_rank <<
" particle nb=" << nb_item
607 <<
" (orig_rank=" << message->destination() <<
")";
611 items_to_create_local_id.resize(nb_item);
612 items_to_create_unique_id.resize(nb_item);
613 items_to_create_cells_id.resize(nb_item);
614 sbuf->getSpan(items_to_create_unique_id);
615 sbuf->getSpan(items_to_create_cells_id);
616#ifdef ARCANE_DEBUG_EXCHANGE_ITEMS
619 for( Integer z=0; z<nb_item; ++z ){
620 info() <<
"Particle UID=" << items_to_create_unique_id[z]
621 <<
" CellIUID=" << items_to_create_cells_id[z];
625 cells_lid.resize(nb_item);
626 mesh->cellFamily()->itemsUniqueIdToLocalId(cells_lid, items_to_create_cells_id);
628 items_to_create_local_id.resize(nb_item);
629 ParticleVectorView particles_view = m_item_family->toParticleFamily()->addParticles(items_to_create_unique_id,
631 items_to_create_local_id);
632 info(5) <<
"Nb create=" << particles_view.
size();
636 m_item_family->endUpdate();
640 ParticleInfoListView internal_items(m_item_family);
644 for (Integer z = 0; z < nb_item; ++z) {
645 Particle item = internal_items[items_to_create_local_id[z]];
648 item.mutableItemBase().setOwner(m_rank, m_rank);
650 if (!item_group.null())
651 item_group.addItems(items_to_create_local_id,
false);
652 if (new_particle_local_ids)
653 new_particle_local_ids->addRange(items_to_create_local_id);
655 for (VariableCollection::Enumerator i_var(m_variables_to_exchange); ++i_var;) {
656 IVariable* var = *i_var;
657 var->serialize(sbuf, items_to_create_local_id);
660 case MESSAGE_NB_FINISH_EXCHANGE: {
661 m_need_general_receive =
true;
664 m_can_process_messages =
true;
665 Int64 nb_particle = sbuf->getInt64();
666 Int32 orig_rank = sbuf->getInt32();
668 info() <<
"MESSAGE_NB_FINISH_EXCHANGE nb=" << nb_particle <<
" (from rank=" << orig_rank <<
")";
669 _addFinishExchangeParticle(nb_particle);
671 case MESSAGE_FINISH_EXCHANGE_STATUS: {
672 m_nb_total_particle_finish_exchange = sbuf->getInt64();
673 m_exchange_finished = (m_nb_total_particle_finish_exchange == m_nb_total_particle);
675 info() <<
"** RECEIVING FINISH EXCHANGE " << m_exchange_finished
676 <<
" finish=" << m_nb_total_particle_finish_exchange
677 <<
" total=" << m_nb_total_particle;
682 case MESSAGE_CHANGE_BLOCKING: {
683 m_need_general_receive =
true;
685 Integer nb_blocking_size = sbuf->getInteger();
688 if (nb_blocking_size < m_nb_blocking_size)
689 m_nb_blocking_size = nb_blocking_size;
690 info(4) <<
"** RECEIVING CHANGE BLOCKING"
691 <<
" new_blocking_size=" << m_nb_blocking_size;
693 if (m_waiting_local_ids.size() > 0)
702void NonBlockingParticleExchanger::
705 if (!m_waiting_messages.empty())
713void NonBlockingParticleExchanger::
714_processFinishTrackingMessage()
723 if (m_rank == m_master_proc) {
724 _addFinishExchangeParticle(m_nb_particle_finished_exchange);
728 if (m_nb_particle_finished_exchange != 0) {
729 info(4) <<
"Send to master proc (" << m_master_proc <<
") nb_finish=" << m_nb_particle_finished_exchange;
730 SerializeMessage* sm =
new SerializeMessage(m_rank, m_master_proc, ISerializeMessage::MT_Send);
731 ISerializer* sbuf = sm->serializer();
732 sbuf->setMode(ISerializer::ModeReserve);
733 sbuf->reserveInteger(1);
734 sbuf->reserveInt64(1);
735 sbuf->reserveInt32(1);
736 sbuf->allocateBuffer();
737 sbuf->setMode(ISerializer::ModePut);
738 sbuf->putInteger(MESSAGE_NB_FINISH_EXCHANGE);
739 sbuf->putInt64(m_nb_particle_finished_exchange);
740 sbuf->putInt32(m_rank);
741 m_pending_messages.add(sm);
744 m_nb_particle_finished_exchange = 0;
750void NonBlockingParticleExchanger::
751_sendFinishExchangeParticle()
753 Int32 nb_rank = m_parallel_mng->commSize();
754 if (m_rank != m_master_proc || m_end_message_sended)
756 m_end_message_sended =
true;
757 info(4) <<
" ** ** SEND FINISH EXCHANGE PARTICLE2";
758 for (Integer i = 0; i < nb_rank; ++i) {
759 if (i == m_master_proc)
761 SerializeMessage* sm =
new SerializeMessage(m_rank, i, ISerializeMessage::MT_Send);
762 ISerializer* sbuf = sm->serializer();
763 sbuf->setMode(ISerializer::ModeReserve);
764 sbuf->reserveInteger(1);
765 sbuf->reserveInt64(1);
766 sbuf->allocateBuffer();
767 sbuf->setMode(ISerializer::ModePut);
768 sbuf->putInteger(MESSAGE_FINISH_EXCHANGE_STATUS);
769 sbuf->putInt64(m_nb_total_particle_finish_exchange);
770 m_pending_messages.add(sm);
777void NonBlockingParticleExchanger::
778_addFinishExchangeParticle(Int64 nb_particle_finish_exchange)
780 m_nb_total_particle_finish_exchange += nb_particle_finish_exchange;
781 Int32 nb_rank = m_parallel_mng->commSize();
782 Int64 nb_rank_as_int64 = nb_rank;
784 info(4) <<
"** RECEIVING FINISH EXCHANGE n=" << nb_particle_finish_exchange
785 <<
" totalfinish=" << m_nb_total_particle_finish_exchange
786 <<
" total=" << m_nb_total_particle;
788 Int64 remaining_particle = m_nb_total_particle - m_nb_total_particle_finish_exchange;
789 if (remaining_particle == 0) {
790 m_exchange_finished =
true;
791 m_need_general_receive =
false;
792 info() <<
"** ** FINISH TRACKING NB_RECV=" << m_nb_receive_message
793 <<
" (Date=" << platform::getCurrentDateTime() <<
")";
794 _sendFinishExchangeParticle();
796 else if (remaining_particle < (m_nb_blocking_size * nb_rank_as_int64)) {
799 m_nb_blocking_size = 0;
800 warning() <<
"** ** CHANGE BLOCKING NEW_SIZE " << m_nb_blocking_size
801 <<
" REMAING_PARTICLE " << remaining_particle
802 <<
" (Date=" << platform::getCurrentDateTime() <<
")";
805 if (m_waiting_local_ids.size() > 0)
807 for (Int32 i = 0; i < nb_rank; ++i) {
808 if (i == m_master_proc)
810 SerializeMessage* sm =
new SerializeMessage(m_rank, i, ISerializeMessage::MT_Send);
811 ISerializer* sbuf = sm->serializer();
812 sbuf->setMode(ISerializer::ModeReserve);
813 sbuf->reserveInteger(1);
814 sbuf->reserveInteger(1);
815 sbuf->allocateBuffer();
816 sbuf->setMode(ISerializer::ModePut);
817 sbuf->putInteger(MESSAGE_CHANGE_BLOCKING);
818 sbuf->putInteger(m_nb_blocking_size);
819 m_pending_messages.add(sm);
827void NonBlockingParticleExchanger::
839 NonBlockingParticleExchanger);
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCANE_REGISTER_CASE_OPTIONS_NOAXL_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
void clear()
Removes the elements from the array.
constexpr Integer size() const noexcept
Number of elements in the array.
Interface of an entity family.
Interface of the parallelism manager for a subdomain.
virtual char reduce(eReduceType rt, char v)=0
Performs a reduction of type rt on the real v and returns the value.
Int32 size() const
Number of elements in the vector.
TraceMessage info() const
Flow for an information message.
VariableList m_variables_to_exchange
List of variables to exchange.
Integer m_nb_blocking_size
Number of remaining particles before switching to blocking mode.
ItemVectorViewT< Particle > ParticleVectorView
View over a vector of particles.
@ ReduceSum
Sum of values.
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.