14#include "arcane/utils/Mutex.h"
15#include "arcane/utils/ArgumentException.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/MemoryUtils.h"
19#include "arcane/core/Observer.h"
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IVariable.h"
22#include "arcane/core/IItemFamily.h"
23#include "arcane/core/VariableInfo.h"
24#include "arcane/core/internal/IDataInternal.h"
25#include "arcane/core/materials/MaterialVariableBuildInfo.h"
26#include "arcane/core/materials/IMeshMaterialMng.h"
27#include "arcane/core/materials/IMeshMaterialVariableFactoryMng.h"
28#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
30#include "arcane/materials/MeshMaterialVariableRef.h"
31#include "arcane/materials/internal/ComponentItemListBuilder.h"
32#include "arcane/materials/internal/MeshMaterialVariablePrivate.h"
33#include "arcane/materials/internal/MeshMaterialVariableIndexer.h"
35#include "arcane/accelerator/core/RunQueue.h"
36#include "arcane/accelerator/core/Memory.h"
50MemoryAllocationOptions
51_getViewAllocator(IMeshMaterialMng* mm)
54 if (mm->_internalApi()->runQueue().isAcceleratorPolicy())
56 return MemoryUtils::getAllocationOptions(r);
64template<
typename Traits>
65ItemMaterialVariableBase<Traits>::
66ItemMaterialVariableBase(
const MaterialVariableBuildInfo& v,
67 PrivatePartType* global_var,
69: MeshMaterialVariable(v,mvs)
70, m_global_variable(global_var)
71, m_global_variable_ref(global_var_ref)
72, m_device_views(_getViewAllocator(m_p->materialMng()))
75 m_device_views.setDebugName(String(
"ItemMaterialVariableViews") + v.name());
82template<
typename Traits>
83ItemMaterialVariableBase<Traits>::
84~ItemMaterialVariableBase()
86 Integer nb_var = m_p->m_refs.size();
87 delete m_global_variable_ref;
88 for( Integer i=1; i<nb_var; ++i ){
89 delete m_p->m_refs[i];
98template<
typename Traits> IVariable*
102 return m_global_variable;
108template<
typename Traits>
void
114 m_vars.addRange(vars);
115 Integer nb_var = m_vars.size();
116 m_device_views.resizeNoInit(nb_var);
117 m_host_views.resize(nb_var);
118 m_views_as_bytes.resize(nb_var);
122 m_p->m_refs.resize(nb_var);
123 for( Integer i=0; i<nb_var; ++i ){
125 m_p->m_refs[i] =
nullptr;
128 m_p->m_refs[i] = m_global_variable_ref;
133 m_p->m_refs[i] =
new VariableRefType(m_vars[i]);
140 _copyHostViewsToViews(
nullptr);
146template<
typename Traits>
void
147ItemMaterialVariableBase<Traits>::
148buildFromManager(
bool is_continue)
150 IMeshMaterialMng* mat_mng = m_p->materialMng();
154 IMeshMaterialMngInternal* mm_api = mat_mng->_internalApi();
155 const Real reserve_ratio = mm_api->additionalCapacityRatio();
156 ConstArrayView<MeshMaterialVariableIndexer*> indexers = mm_api->variablesIndexer();
157 Integer nb_indexer = indexers.size();
158 UniqueArray<PrivatePartType*> all_vars(nb_indexer+1);
159 all_vars[0] = m_global_variable;
160 IMesh* mesh = m_global_variable->mesh();
162 if (!m_global_variable->isUsed())
163 m_global_variable->setUsed(
true);
167 m_p->m_global_variable_changed_observer =
new ObserverT<ThatClass>(
this,&ThatClass::_syncFromGlobalVariable);
168 m_global_variable->onSizeChangedObservable()->attachObserver(m_p->m_global_variable_changed_observer);
170 m_p->m_modified_times.resize(nb_indexer);
171 m_p->m_modified_times.fill(0);
173 bool is_env_only = m_p->space()==MatVarSpace::Environment;
176 int property = m_global_variable->property();
177 for( Integer i=0; i<nb_indexer; ++i ){
178 MeshMaterialVariableIndexer* indexer = indexers[i];
181 if (is_env_only && !indexer->isEnvironment()){
182 all_vars[i+1] =
nullptr;
189 String var_name = String(
"Mat")+indexer->name()+
"_"+this->name();
193 IVariable* var =
nullptr;
195 VariableBuildInfo vbi2(mesh,var_name,property);
196 VariableInfo vi = VariableRefType::_internalVariableInfo(vbi2);
197 var = PrivatePartType::getReference(vbi2,vi);
201 var->addTag(
"Material",
"1");
202 PrivatePartType* true_ptr =
dynamic_cast<PrivatePartType*
>(var);
204 all_vars[i+1] = true_ptr;
207 true_ptr->setUsed(
true);
209 Traits::resizeWithReserve(true_ptr, indexer->maxIndexInMultipleArray(), reserve_ratio);
212 this->_init(all_vars);
218template<
typename Traits>
void
219ItemMaterialVariableBase<Traits>::
220_syncFromGlobalVariable()
228 const bool do_complete_sync =
true;
229 if (do_complete_sync){
238 _copyHostViewsToViews(
nullptr);
240 for( MeshMaterialVariableRef::Enumerator i(
this); i.hasNext(); ++i ){
241 MeshMaterialVariableRef* ref = *i;
242 ref->updateFromInternal();
249template<
typename Traits>
void
253 _syncReferences(
true);
259template <
typename Traits>
void
264 IMeshMaterialMngInternal* api = m_p->materialMng()->_internalApi();
266 Real ratio = api->additionalCapacityRatio();
267 Integer nb_indexer = indexers.
size();
268 for (Integer i = 0; i < nb_indexer; ++i) {
269 MeshMaterialVariableIndexer* indexer = indexers[i];
270 PrivatePartType* true_ptr = m_vars[i + 1];
272 Traits::resizeWithReserve(true_ptr, indexer->maxIndexInMultipleArray(), ratio);
277 _copyHostViewsToViews(
nullptr);
280 for( MeshMaterialVariableRef::Enumerator i(
this); i.hasNext(); ++i ){
281 MeshMaterialVariableRef* ref = *i;
282 ref->updateFromInternal();
289template<
typename Traits> Ref<IData>
290ItemMaterialVariableBase<Traits>::
291_internalCreateSaveDataRef(Integer nb_value)
293 Ref<IData> data = m_global_variable->data()->cloneEmptyRef();
294 auto* true_data =
dynamic_cast<ValueDataType*
>(data.get());
296 true_data->_internal()->reserve(nb_value);
303template<
typename Traits>
void
304ItemMaterialVariableBase<Traits>::
305_saveData(IMeshComponent* component,IData* data)
307 if (m_p->space()==MatVarSpace::Environment && !component->isEnvironment())
308 ARCANE_FATAL(
"Can not save data on material for environment only variable");
309 Traits::saveData(component,data,m_host_views);
315template<
typename Traits>
void
320 if (m_p->space()==MatVarSpace::Environment && !component->
isEnvironment())
321 ARCANE_FATAL(
"Can not restore data on material for environment only variable");
323 auto* true_data =
dynamic_cast<ValueDataType*
>(data);
325 auto values = true_data->view();
327 PrivatePartType* global_var = this->_trueGlobalVariable();
331 UniqueContainerType tmp_values;
333 Integer max_id = m_global_variable->itemFamily()->maxLocalId();
334 Traits::resizeAndFillWithDefault(true_data,tmp_values,max_id);
337 tmp_values = global_var->constValueView();
340 for( Integer i=0, n=ids.size(); i<n; ++i ){
341 if (ids[i]!=NULL_ITEM_ID){
342 Traits::setValue(tmp_values[ids[i]],values[data_index+i]);
347 for( Integer i=0, n=ids.size(); i<n; ++i ){
348 Traits::setValue(tmp_values[ids[i]] , values[data_index+i] );
353 ComponentCell ec = *icell;
354 setValue(ec._varIndex(),tmp_values[ec.globalCell().localId()]);
361template<
typename Traits>
bool
362ItemMaterialVariableBase<Traits>::
363_isValidAndUsedAndGlobalUsed(PrivatePartType* partial_var)
367 if (!m_global_variable->isUsed() || !partial_var->isUsed())
375template <
typename Traits>
void
376ItemMaterialVariableBase<Traits>::
377_resizeForIndexer(ResizeVariableIndexerArgs& args)
379 Int32 index = args.m_var_index;
380 RunQueue& queue = args.m_queue;
382 PrivatePartType* partial_var = m_vars[index + 1];
383 if (_isValidAndUsedAndGlobalUsed(partial_var)) {
389 IMeshMaterialMngInternal* api = m_p->materialMng()->_internalApi();
390 ConstArrayView<MeshMaterialVariableIndexer*> indexers = api->variablesIndexer();
391 Real ratio = api->additionalCapacityRatio();
392 Traits::resizeWithReserve(partial_var, indexers[index]->maxIndexInMultipleArray(), ratio);
393 this->_setView(index + 1);
395 if (args.isUseOneCommand()) {
397 auto source =
asBytes(m_host_views.view());
398 args.addOneCopyData(source,dest,1);
401 _copyHostViewsToViews(&queue);
407template <
typename Traits>
void
408ItemMaterialVariableBase<Traits>::
409_copyHostViewsToViews(RunQueue* queue)
412 auto source =
asBytes(m_host_views);
414 Accelerator::MemoryCopyArgs copy_args(dest,source);
415 copy_args.addAsync(
true);
416 queue->copyMemory(copy_args);
419 MemoryUtils::copy(dest,source);
425template <
typename Traits>
void
426ItemMaterialVariableBase<Traits>::
427_copyBetweenPartialAndGlobal(
const CopyBetweenPartialAndGlobalArgs& args)
429 Int32 var_index = args.m_var_index + 1;
430 PrivatePartType* partial_var = m_vars[var_index];
431 if (!_isValidAndUsedAndGlobalUsed(partial_var))
433 const bool is_global_to_partial = args.m_is_global_to_partial;
434 const bool use_generic = args.m_use_generic_copy;
435 const RunQueue& queue = args.m_queue;
437 auto input = m_host_views[var_index];
438 auto output = m_host_views[0];
439 auto output_indexes = args.m_local_ids;
440 auto input_indexes = args.m_indexes_in_multiple;
442 if (is_global_to_partial) {
443 std::swap(input, output);
444 std::swap(output_indexes, input_indexes);
448 SmallSpan<const std::byte> input_bytes(Traits::toBytes(input));
449 SmallSpan<std::byte> output_bytes(Traits::toBytes(output));
450 if (args.isUseOneCommand())
451 args.addOneCopyData(input_bytes, output_bytes, data_type_size);
453 _genericCopyTo(input_bytes, input_indexes,
454 output_bytes, output_indexes, queue, data_type_size);
457 Traits::copyTo(input, input_indexes, output, output_indexes, queue);
464template <
typename Traits>
void
465ItemMaterialVariableBase<Traits>::
466_initializeNewItemsWithZero(InitializeWithZeroArgs& args)
468 const Int32 var_index = args.m_var_index + 1;
469 RunQueue& queue = args.m_queue;
470 PrivatePartType* partial_var = m_vars[var_index];
471 if (!_isValidAndUsedAndGlobalUsed(partial_var))
474 SmallSpan<const Int32> partial_indexes = args.m_indexes_in_multiple;
479 if (args.isUseOneCommand()){
481 auto output = m_host_views[var_index];
482 SmallSpan<std::byte> output_bytes(Traits::toBytes(output));
483 args.addOneCopyData({}, output_bytes, data_type_size);
486 ContainerSpanType partial_view = m_host_views[var_index];
487 Int32 nb_partial = partial_indexes.size();
488 DataType zero = DataType();
493 Int32 index = partial_indexes[i];
494 Traits::setValue(partial_view[index], zero);
502template<
typename Traits>
void
506 fillPartialValuesWithSuperValues(LEVEL_ALLENVIRONMENT);
512template<
typename Traits>
void
517 if (level==LEVEL_MATERIAL)
519 else if (level==LEVEL_ENVIRONMENT){
522 else if (level==LEVEL_ALLENVIRONMENT){
533template<
typename Traits>
void
544 setValue(iccell._varIndex(),value(c._varIndex()));
560template<
typename VariableTrueType> IMeshMaterialVariable*
564 typedef typename VariableTrueType::PrivatePartType PrivatePartType;
565 typedef typename VariableTrueType::VariableRefType VariableRefType;
575 mat_mng = IMeshMaterialMng::getReference(mesh_handle,
true);
580 if (!v.itemFamilyName().
null())
581 ARCANE_FATAL(
"Can not declare material variable for specific family");
583 if (!v.itemGroupName().
null())
584 ARCANE_FATAL(
"Can not declare partial material variable");
589 if (VariableTrueType::TraitsType::dimension()==0)
591 mvs = MatVarSpace::MaterialAndEnvironment;
599 VariableInfo gvar_vi = VariableRefType::_internalVariableInfo(gvar_bi);
600 IVariable* g_var = PrivatePartType::getReference(gvar_bi,gvar_vi);
602 PrivatePartType* true_ptr =
dynamic_cast<PrivatePartType*
>(g_var);
609 VariableTrueType* true_mat_var = 0;
612 true_mat_var =
dynamic_cast<VariableTrueType*
>(mat_var);
614 VariableRefType* var_ref =
new VariableRefType(gvar_bi);
616 true_mat_var =
new VariableTrueType(mvbi,true_ptr,var_ref,mvs);
619 if (!mat_mng->
_internalApi()->variablesIndexer().empty())
620 true_mat_var->buildFromManager(
false);
623 if (mvs!=true_mat_var->space())
624 ARCANE_FATAL(
"Incoherent space for variable '{0}' wanted_space={1} existing_space={2}.\n"
625 " Check all instances of the variables are of the same space\n"
626 " (i.e. all variables are MaterialVariable or EnvironmentVariable)",
627 true_mat_var->name(),(
int)mvs,(
int)true_mat_var->space());
633 ++true_mat_var->m_p->m_nb_reference;
643m_auto_registerer1(_autoCreate1,TrueType::BuilderType::_buildVarTypeInfo(MatVarSpace::Environment));
647m_auto_registerer2(_autoCreate2,TrueType::BuilderType::_buildVarTypeInfo(MatVarSpace::MaterialAndEnvironment));
653 return getReference(v,MatVarSpace::Environment);
660 return getReference(v,MatVarSpace::MaterialAndEnvironment);
#define ARCANE_CHECK_ACCESSIBLE_POINTER(queue_or_runner_or_policy, ptr)
Macro qui vérifie en mode check si ptr est accessible pour une RunQueue ou un Runner.
#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.
Types et macros pour gérer les boucles sur les accélérateurs.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle sur accélérateur avec arguments supplémentaires pour les réductions.
Représente un composant d'une maille multi-matériau.
Interface d'un composant (matériau ou milieu) d'un maillage.
virtual bool isEnvironment() const =0
Vrai si le composant est un milieu.
virtual bool hasSpace(MatVarSpace space) const =0
Indique si le composant est défini pour l'espace space.
virtual IMeshMaterialMng * materialMng()=0
Gestionnaire associé.
Interface du gestionnaire des matériaux et des milieux d'un maillage.
virtual MeshComponentList materialsAsComponents() const =0
Liste des matériaux vus comme composants.
virtual bool isAllocateScalarEnvironmentVariableAsMaterial() const =0
Indique si les variables scalaires milieux sont allouées sur les matériaux.
virtual Mutex * variableLock()=0
Verrou utilisé pour le multi-threading.
virtual bool isDataInitialisationWithZero() const =0
Indique comment initialiser les nouvelles valeurs dans les mailles matériaux et milieux.
virtual MeshComponentList environmentsAsComponents() const =0
Liste des milieux vus comme composants.
virtual IMeshMaterialMngInternal * _internalApi() const =0
API interne à Arcane.
virtual IMeshMaterialVariable * checkVariable(IVariable *global_var)=0
Variable aux matériaux associé à la variable global global_var (nullptr si aucune)
Interface d'une variable matériau d'un maillage.
bool isNull() const
Indique si le handle est nul (il ne référence aucun maillage existant ou non)
Paramètres nécessaires à la construction d'une variable.
Infos caractérisant une variable.
Exception lorsqu'un argument est invalide.
Vue modifiable d'un tableau d'un type T.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
bool null() const
Retourne true si la chaîne est nulle.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
Active toujours les traces dans les parties Arcane concernant les matériaux.
MatVarSpace
Espace de définition d'une variable matériau.
eMemoryRessource
Liste des ressources mémoire disponibles.
@ HostPinned
Alloue sur l'hôte.
@ Device
Alloue sur le device.
ARCANE_DATATYPE_EXPORT Integer dataTypeSize(eDataType type)
Taille du type de donnée type (qui doit être différent de DT_String)
double Real
Type représentant un réel.
Int32 Integer
Type représentant un entier.
detail::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets non modifiables.
detail::SpanTypeFromSize< std::byte, SizeType >::SpanType asWritableBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets modifiables.