14#include "arcane/materials/MeshMaterialVariableSynchronizerList.h"
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/NotSupportedException.h"
18#include "arcane/utils/ValueConvert.h"
19#include "arcane/utils/FatalErrorException.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/IVariableSynchronizer.h"
23#include "arcane/core/internal/IParallelMngInternal.h"
24#include "arcane/core/materials/IMeshMaterialMng.h"
25#include "arcane/core/materials/internal/IMeshMaterialVariableInternal.h"
26#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
28#include "arcane/materials/MeshMaterialVariable.h"
29#include "arcane/materials/IMeshMaterialSynchronizeBuffer.h"
30#include "arcane/materials/IMeshMaterialVariableSynchronizer.h"
32#include "arcane/accelerator/core/RunQueue.h"
41namespace MP = Arccore::MessagePassing;
53 bool use_generic_version =
false;
54 Int32 sync_version = 0;
56 Int64 message_total_size = 0;
58 MP::MessageTag message_tag;
69 : m_material_mng(material_mng)
74 m_use_generic_version = (v.value() == 0);
82 Int64 m_total_size = 0;
83 bool m_use_generic_version =
true;
87 bool m_is_in_sync =
false;
93MeshMaterialVariableSynchronizerList::
95: m_p(new
Impl(material_mng))
102MeshMaterialVariableSynchronizerList::
103~MeshMaterialVariableSynchronizerList()
114 return m_p->m_total_size;
125 Int32 v = m_p->m_material_mng->synchronizeVariableVersion();
126 bool is_blocking = (v == 8);
128 _beginSynchronize(is_blocking);
129 _endSynchronize(is_blocking);
138 Int32 v = m_p->m_material_mng->synchronizeVariableVersion();
140 ARCANE_FATAL(
"beginSynchronize() is only valid for synchronize version 7 (v={0})", v);
141 _beginSynchronize(
false);
150 _endSynchronize(
false);
156void MeshMaterialVariableSynchronizerList::
157_beginSynchronize(
bool is_blocking)
159 if (m_p->m_is_in_sync)
161 m_p->m_is_in_sync =
true;
163 m_p->m_total_size = 0;
167 m_p->m_mat_env_sync_info = SyncInfo();
168 m_p->m_env_only_sync_info = SyncInfo();
171 SyncInfo& sync_info = m_p->m_mat_env_sync_info;
172 _fillSyncInfo(sync_info);
174 sync_info.variables = m_p->m_mat_env_vars;
175 sync_info.message_tag = MP::MessageTag(569);
176 if (!sync_info.variables.empty()) {
177 _beginSynchronizeMultiple(sync_info);
179 _endSynchronizeMultiple2(sync_info);
183 SyncInfo& sync_info = m_p->m_env_only_sync_info;
184 _fillSyncInfo(sync_info);
186 sync_info.variables = m_p->m_env_only_vars;
187 sync_info.message_tag = MP::MessageTag(585);
188 if (!sync_info.variables.empty()) {
189 _beginSynchronizeMultiple(sync_info);
191 _endSynchronizeMultiple2(sync_info);
199void MeshMaterialVariableSynchronizerList::
200_endSynchronize(
bool is_blocking)
202 if (!m_p->m_is_in_sync)
203 ARCANE_FATAL(
"beginSynchronize() has to be called before endSynchronize()");
206 SyncInfo& sync_info = m_p->m_mat_env_sync_info;
207 if (!sync_info.variables.empty() && !is_blocking)
208 _endSynchronizeMultiple2(sync_info);
209 m_p->m_total_size += sync_info.message_total_size;
212 SyncInfo& sync_info = m_p->m_env_only_sync_info;
213 if (!sync_info.variables.empty() && !is_blocking)
214 _endSynchronizeMultiple2(sync_info);
215 m_p->m_total_size += sync_info.message_total_size;
218 m_p->m_is_in_sync =
false;
229 m_p->m_mat_env_vars.add(var);
231 m_p->m_env_only_vars.add(var);
234 var->
name(), (
int)mvs);
240void MeshMaterialVariableSynchronizerList::
241_fillSyncInfo(SyncInfo& sync_info)
243 sync_info.use_generic_version = m_p->m_use_generic_version;
250void MeshMaterialVariableSynchronizerList::
251_beginSynchronizeMultiple(SyncInfo& sync_info)
255 const Int32 sync_version = sync_info.sync_version;
257 if (sync_version == 8) {
261 else if (sync_version == 7) {
263 sync_info.buf_list = impl::makeOneBufferMeshMaterialSynchronizeBufferRef(mem);
267 sync_info.buf_list = impl::makeMultiBufferMeshMaterialSynchronizeBufferRef(mem);
269 if (sync_version < 8) {
272 sync_info.buf_list->setNbRank(nb_rank);
275 _beginSynchronizeMultiple2(sync_info);
281void MeshMaterialVariableSynchronizerList::
282_beginSynchronizeMultiple2(
SyncInfo& sync_info)
284 ConstArrayView<MeshMaterialVariable*> vars = sync_info.variables;
285 IMeshMaterialSynchronizeBuffer* buf_list = sync_info.buf_list.get();
286 IMeshMaterialVariableSynchronizer* mmvs = sync_info.mat_synchronizer;
300 if (!pm->isParallel())
302 const bool use_new_version = sync_info.use_generic_version;
303 RunQueue queue = pm->_internalApi()->queue();
305 mmvs->checkRecompute();
307 ITraceMng* tm = pm->traceMng();
309 tm->info(4) <<
"MAT_SYNCHRONIZE version=" << sync_info.sync_version <<
" multiple n="
310 << nb_var <<
" is_generic?=" << use_new_version;
312 sync_info.data_sizes.resize(nb_var);
314 for (
Integer i = 0; i < nb_var; ++i) {
315 sync_info.data_sizes[i] = vars[i]->dataTypeSize();
316 all_datatype_size += sync_info.data_sizes[i];
317 tm->info(4) <<
"MAT_SYNCHRONIZE name=" << vars[i]->name()
318 <<
" size=" << sync_info.data_sizes[i];
325 for (
Integer i = 0; i < nb_rank; ++i) {
326 ConstArrayView<MatVarIndex> ghost_matcells(mmvs->ghostItems(i));
327 Integer total_ghost = ghost_matcells.size();
328 buf_list->setReceiveBufferSize(i, total_ghost * all_datatype_size);
329 ConstArrayView<MatVarIndex> shared_matcells(mmvs->sharedItems(i));
330 Integer total_shared = shared_matcells.size();
331 buf_list->setSendBufferSize(i, total_shared * all_datatype_size);
333 buf_list->allocate();
336 for (
Integer i = 0; i < nb_rank; ++i) {
337 Int32 rank = ranks[i];
338 MP::PointToPointMessageInfo msg_info(MP::MessageRank(rank), sync_info.message_tag, MP::eBlockingType::NonBlocking);
339 sync_info.requests.add(
mpReceive(mpm, buf_list->receiveBuffer(i), msg_info));
343 for (
Integer i = 0; i < nb_rank; ++i) {
344 ConstArrayView<MatVarIndex> shared_matcells(mmvs->sharedItems(i));
345 Integer total_shared = shared_matcells.size();
348 for (
Integer z = 0; z < nb_var; ++z) {
349 Integer my_data_size = sync_info.data_sizes[z];
350 auto sub_view = values.subView(offset, total_shared * my_data_size);
351 if (use_new_version) {
352 auto* ptr =
reinterpret_cast<std::byte*
>(sub_view.data());
353 vars[z]->_internalApi()->copyToBuffer(shared_matcells, { ptr, sub_view.size() }, &queue);
356 vars[z]->copyToBuffer(shared_matcells, sub_view);
357 offset += total_shared * my_data_size;
365 for (
Integer i = 0; i < nb_rank; ++i) {
366 Int32 rank = ranks[i];
367 MP::PointToPointMessageInfo msg_info(MP::MessageRank(rank), sync_info.message_tag, MP::eBlockingType::NonBlocking);
368 sync_info.requests.add(
mpSend(mpm, buf_list->sendBuffer(i), msg_info));
375void MeshMaterialVariableSynchronizerList::
376_endSynchronizeMultiple2(
SyncInfo& sync_info)
378 ConstArrayView<MeshMaterialVariable*> vars = sync_info.variables;
379 IMeshMaterialVariableSynchronizer* mmvs = sync_info.mat_synchronizer;
380 IVariableSynchronizer* var_syncer = mmvs->variableSynchronizer();
381 IParallelMng* pm = var_syncer->parallelMng();
383 if (!pm->isParallel())
385 const bool use_new_version = sync_info.use_generic_version;
386 RunQueue queue = pm->_internalApi()->queue();
387 IMeshMaterialSynchronizeBuffer* buf_list = sync_info.buf_list.get();
393 pm->waitAllRequests(sync_info.requests);
396 for (
Integer i = 0; i < nb_rank; ++i) {
397 ConstArrayView<MatVarIndex> ghost_matcells(mmvs->ghostItems(i));
398 Integer total_ghost = ghost_matcells.size();
402 for (
Integer z = 0; z < nb_var; ++z) {
403 Integer my_data_size = sync_info.data_sizes[z];
404 auto sub_view = values.subView(offset, total_ghost * my_data_size);
405 if (use_new_version) {
406 auto* ptr =
reinterpret_cast<const std::byte*
>(sub_view.data());
407 vars[z]->_internalApi()->copyFromBuffer(ghost_matcells, { ptr, sub_view.size() }, &queue);
410 vars[z]->copyFromBuffer(ghost_matcells, sub_view);
411 offset += total_ghost * my_data_size;
414 sync_info.message_total_size += buf_list->totalSize();
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Brief list of message exchange functions.
constexpr Integer size() const noexcept
Number of elements in the array.
Template class for converting a type.
virtual IMessagePassingMng * messagePassingMng() const =0
Associated Arccore message passing manager.
virtual Int32ConstArrayView communicatingRanks()=0
Ranks of subdomains with which communication occurs.
virtual IParallelMng * parallelMng()=0
Associated parallel manager.
virtual IMeshMaterialVariableSynchronizer * allCellsEnvOnlySynchronizer()=0
Synchronizer for medium-only variables across all cells.
virtual IMeshMaterialVariableSynchronizer * allCellsMatEnvSynchronizer()=0
Synchronizer for material and medium variables across all cells.
Interface for the material and environment manager of a mesh.
virtual Integer synchronizeVariableVersion() const =0
Version of the implementation for synchronizing material variables.
virtual IMeshMaterialMngInternal * _internalApi() const =0
Internal API for Arcane.
Interface of the material variable synchronizer.
virtual IVariableSynchronizer * variableSynchronizer()=0
Associated classical variable synchronizer.
virtual eMemoryRessource bufferMemoryRessource() const =0
Memory resource to use for communication buffers.
virtual Ref< IMeshMaterialSynchronizeBuffer > commonBuffer()=0
Common buffer for messages.
Int64 totalMessageSize() const
After calling apply(), contains the size of the messages sent.
void beginSynchronize()
Starts a non-blocking synchronization.
void apply()
Performs the synchronization.
void add(MeshMaterialVariable *var)
Adds the variable var to the list of variables to synchronize.
void endSynchronize()
Blocks until the ongoing synchronization is finished.
Base class for material variables.
String name() const override
Name of the variable.
MatVarSpace space() const override
Variable definition space (material+environment or environment only).
Exception when an operation is not supported.
Reference to an instance.
1D data vector with value semantics (STL style).
Always enables tracing in Arcane parts concerning materials.
MatVarSpace
Definition space for a material variable.
@ Environment
Variable having values only on environments.
@ MaterialAndEnvironment
Variable having values on environments and materials.
Request mpReceive(IMessagePassingMng *pm, ISerializer *values, const PointToPointMessageInfo &message)
Receive message using an ISerializer.
Request mpSend(IMessagePassingMng *pm, const ISerializer *values, const PointToPointMessageInfo &message)
Send message using an ISerializer.
ArrayView< Byte > ByteArrayView
C equivalent of a 1D array of characters.
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.
Arcane::eMemoryResource eMemoryRessource
Typedef for the historical Arcane version (with 2's').
ConstArrayView< Byte > ByteConstArrayView
C equivalent of a 1D array of characters.
std::int32_t Int32
Signed integer type of 32 bits.
Namespace containing the types and declarations that manage the message-passing parallelism mechanism...