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/MemoryRessource.h"
20#include "arcane/utils/FatalErrorException.h"
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/IVariableSynchronizer.h"
24#include "arcane/core/internal/IParallelMngInternal.h"
25#include "arcane/core/materials/IMeshMaterialMng.h"
26#include "arcane/core/materials/internal/IMeshMaterialVariableInternal.h"
27#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
29#include "arcane/materials/MeshMaterialVariable.h"
30#include "arcane/materials/IMeshMaterialSynchronizeBuffer.h"
31#include "arcane/materials/IMeshMaterialVariableSynchronizer.h"
33#include "arcane/accelerator/core/RunQueue.h"
52 Ref<IMeshMaterialSynchronizeBuffer> buf_list;
54 bool use_generic_version =
false;
55 Int32 sync_version = 0;
57 Int64 message_total_size = 0;
70 : m_material_mng(material_mng)
75 m_use_generic_version = (v.value() == 0);
83 Int64 m_total_size = 0;
84 bool m_use_generic_version =
true;
88 bool m_is_in_sync =
false;
94MeshMaterialVariableSynchronizerList::
96: m_p(new
Impl(material_mng))
103MeshMaterialVariableSynchronizerList::
104~MeshMaterialVariableSynchronizerList()
115 return m_p->m_total_size;
128 bool is_blocking = (v == 8);
130 _beginSynchronize(is_blocking);
131 _endSynchronize(is_blocking);
142 ARCANE_FATAL(
"beginSynchronize() is only valid for synchronize version 7 (v={0})", v);
143 _beginSynchronize(
false);
152 _endSynchronize(
false);
158void MeshMaterialVariableSynchronizerList::
159_beginSynchronize(
bool is_blocking)
161 if (m_p->m_is_in_sync)
163 m_p->m_is_in_sync =
true;
165 m_p->m_total_size = 0;
169 m_p->m_mat_env_sync_info = SyncInfo();
170 m_p->m_env_only_sync_info = SyncInfo();
173 SyncInfo& sync_info = m_p->m_mat_env_sync_info;
174 _fillSyncInfo(sync_info);
175 sync_info.mat_synchronizer = mm->
_internalApi()->allCellsMatEnvSynchronizer();
176 sync_info.variables = m_p->m_mat_env_vars;
178 if (!sync_info.variables.empty()) {
179 _beginSynchronizeMultiple(sync_info);
181 _endSynchronizeMultiple2(sync_info);
185 SyncInfo& sync_info = m_p->m_env_only_sync_info;
186 _fillSyncInfo(sync_info);
187 sync_info.mat_synchronizer = mm->
_internalApi()->allCellsEnvOnlySynchronizer();
188 sync_info.variables = m_p->m_env_only_vars;
190 if (!sync_info.variables.empty()) {
191 _beginSynchronizeMultiple(sync_info);
193 _endSynchronizeMultiple2(sync_info);
201void MeshMaterialVariableSynchronizerList::
202_endSynchronize(
bool is_blocking)
204 if (!m_p->m_is_in_sync)
205 ARCANE_FATAL(
"beginSynchronize() has to be called before endSynchronize()");
208 SyncInfo& sync_info = m_p->m_mat_env_sync_info;
209 if (!sync_info.variables.empty() && !is_blocking)
210 _endSynchronizeMultiple2(sync_info);
211 m_p->m_total_size += sync_info.message_total_size;
214 SyncInfo& sync_info = m_p->m_env_only_sync_info;
215 if (!sync_info.variables.empty() && !is_blocking)
216 _endSynchronizeMultiple2(sync_info);
217 m_p->m_total_size += sync_info.message_total_size;
220 m_p->m_is_in_sync =
false;
231 m_p->m_mat_env_vars.add(var);
233 m_p->m_env_only_vars.add(var);
236 var->
name(), (
int)mvs);
242void MeshMaterialVariableSynchronizerList::
243_fillSyncInfo(SyncInfo& sync_info)
245 sync_info.use_generic_version = m_p->m_use_generic_version;
252void MeshMaterialVariableSynchronizerList::
253_beginSynchronizeMultiple(SyncInfo& sync_info)
257 const Int32 sync_version = sync_info.sync_version;
259 if (sync_version == 8) {
263 else if (sync_version == 7) {
265 sync_info.buf_list = impl::makeOneBufferMeshMaterialSynchronizeBufferRef(mem);
269 sync_info.buf_list = impl::makeMultiBufferMeshMaterialSynchronizeBufferRef(mem);
271 if (sync_version < 8) {
273 Integer nb_rank = ranks.size();
274 sync_info.buf_list->setNbRank(nb_rank);
277 _beginSynchronizeMultiple2(sync_info);
283void MeshMaterialVariableSynchronizerList::
284_beginSynchronizeMultiple2(SyncInfo& sync_info)
286 ConstArrayView<MeshMaterialVariable*> vars = sync_info.variables;
287 IMeshMaterialSynchronizeBuffer* buf_list = sync_info.buf_list.get();
288 IMeshMaterialVariableSynchronizer* mmvs = sync_info.mat_synchronizer;
304 if (!pm->isParallel())
306 const bool use_new_version = sync_info.use_generic_version;
307 RunQueue* queue = pm->_internalApi()->defaultQueue();
309 mmvs->checkRecompute();
311 ITraceMng* tm = pm->traceMng();
313 tm->info(4) <<
"MAT_SYNCHRONIZE version=" << sync_info.sync_version <<
" multiple n="
314 << nb_var <<
" is_generic?=" << use_new_version;
316 sync_info.data_sizes.resize(nb_var);
318 for (Integer i = 0; i < nb_var; ++i) {
319 sync_info.data_sizes[i] = vars[i]->dataTypeSize();
320 all_datatype_size += sync_info.data_sizes[i];
321 tm->info(4) <<
"MAT_SYNCHRONIZE name=" << vars[i]->name()
322 <<
" size=" << sync_info.data_sizes[i];
326 Int32 nb_rank = ranks.
size();
329 for (Integer i = 0; i < nb_rank; ++i) {
330 ConstArrayView<MatVarIndex> ghost_matcells(mmvs->ghostItems(i));
331 Integer total_ghost = ghost_matcells.size();
332 buf_list->setReceiveBufferSize(i, total_ghost * all_datatype_size);
333 ConstArrayView<MatVarIndex> shared_matcells(mmvs->sharedItems(i));
334 Integer total_shared = shared_matcells.size();
335 buf_list->setSendBufferSize(i, total_shared * all_datatype_size);
337 buf_list->allocate();
340 for (Integer i = 0; i < nb_rank; ++i) {
341 Int32 rank = ranks[i];
343 sync_info.requests.add(
mpReceive(mpm, buf_list->receiveBuffer(i), msg_info));
347 for (Integer i = 0; i < nb_rank; ++i) {
348 ConstArrayView<MatVarIndex> shared_matcells(mmvs->sharedItems(i));
349 Integer total_shared = shared_matcells.size();
352 for (Integer z = 0; z < nb_var; ++z) {
353 Integer my_data_size = sync_info.data_sizes[z];
354 auto sub_view = values.subView(offset, total_shared * my_data_size);
355 if (use_new_version) {
356 auto* ptr =
reinterpret_cast<std::byte*
>(sub_view.data());
357 vars[z]->_internalApi()->copyToBuffer(shared_matcells, { ptr, sub_view.size() }, queue);
360 vars[z]->copyToBuffer(shared_matcells, sub_view);
361 offset += total_shared * my_data_size;
370 for (Integer i = 0; i < nb_rank; ++i) {
371 Int32 rank = ranks[i];
373 sync_info.requests.add(
mpSend(mpm, buf_list->sendBuffer(i), msg_info));
380void MeshMaterialVariableSynchronizerList::
381_endSynchronizeMultiple2(SyncInfo& sync_info)
383 ConstArrayView<MeshMaterialVariable*> vars = sync_info.variables;
384 IMeshMaterialVariableSynchronizer* mmvs = sync_info.mat_synchronizer;
385 IVariableSynchronizer* var_syncer = mmvs->variableSynchronizer();
386 IParallelMng* pm = var_syncer->parallelMng();
388 if (!pm->isParallel())
390 const bool use_new_version = sync_info.use_generic_version;
391 RunQueue* queue = pm->_internalApi()->defaultQueue();
392 IMeshMaterialSynchronizeBuffer* buf_list = sync_info.buf_list.get();
395 Int32 nb_rank = ranks.
size();
398 pm->waitAllRequests(sync_info.requests);
401 for (Integer i = 0; i < nb_rank; ++i) {
402 ConstArrayView<MatVarIndex> ghost_matcells(mmvs->ghostItems(i));
403 Integer total_ghost = ghost_matcells.size();
407 for (Integer z = 0; z < nb_var; ++z) {
408 Integer my_data_size = sync_info.data_sizes[z];
409 auto sub_view = values.subView(offset, total_ghost * my_data_size);
410 if (use_new_version) {
411 auto* ptr =
reinterpret_cast<const std::byte*
>(sub_view.data());
412 vars[z]->_internalApi()->copyFromBuffer(ghost_matcells, { ptr, sub_view.size() }, queue);
415 vars[z]->copyFromBuffer(ghost_matcells, sub_view);
416 offset += total_ghost * my_data_size;
419 sync_info.message_total_size += buf_list->totalSize();
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Liste des fonctions d'échange de message.
virtual IMessagePassingMng * messagePassingMng() const =0
Gestionnaire de message de Arccore associé
virtual Int32ConstArrayView communicatingRanks()=0
Rangs des sous-domaines avec lesquels on communique.
virtual IParallelMng * parallelMng()=0
Gestionnaire parallèle associé
Interface du gestionnaire des matériaux et des milieux d'un maillage.
virtual Integer synchronizeVariableVersion() const =0
Version de l'implémentation pour la synchronisation des variables matériaux.
virtual IMeshMaterialMngInternal * _internalApi() const =0
API interne à Arcane.
virtual IVariableSynchronizer * variableSynchronizer()=0
Synchroniseur des variables classiques associé.
virtual eMemoryRessource bufferMemoryRessource() const =0
Ressource mémoire à utiliser pour les buffers de communication.
virtual Ref< IMeshMaterialSynchronizeBuffer > commonBuffer()=0
Buffer commun pour les messages.
Int64 totalMessageSize() const
Après appel à apply(), contient la taille des messages envoyés.
void beginSynchronize()
Commence une synchronisation non bloquante.
void apply()
Effectue la synchronisation.
void add(MeshMaterialVariable *var)
Ajoute la variable var à la liste des variables à synchroniser.
void endSynchronize()
Bloque tant que la synchronisation en cours n'est pas terminé.
String name() const override
Nom de la variable.
MatVarSpace space() const override
Espace de définition de la variable (matériau+milieu ou milieu uniquement)
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Informations pour envoyer/recevoir un message point à point.
Vecteur 1D de données avec sémantique par valeur (style STL).
Active toujours les traces dans les parties Arcane concernant les matériaux.
MatVarSpace
Espace de définition d'une variable matériau.
@ Environment
Variable ayant des valeurs uniquement sur les milieux.
@ MaterialAndEnvironment
Variable ayant des valeurs sur les milieux et matériaux.
eMemoryRessource
Liste des ressources mémoire disponibles.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
Espace de nommage contenant les types et déclarations qui gèrent le mécanisme de parallélisme par éch...
Request mpSend(IMessagePassingMng *pm, const ISerializer *values, const PointToPointMessageInfo &message)
Message d'envoi utilisant un ISerializer.
Request mpReceive(IMessagePassingMng *pm, ISerializer *values, const PointToPointMessageInfo &message)
Message de réception utilisant un ISerializer.
Int32 Integer
Type représentant un entier.