14#include "arcane/utils/Mutex.h"
15#include "arcane/utils/ArgumentException.h"
16#include "arcane/utils/FatalErrorException.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"
37#include "arcane/accelerator/RunCommandLoop.h"
50 MemoryAllocationOptions
54 if (mm->_internalApi()->runQueue().isAcceleratorPolicy())
55 r = eMemoryRessource::Device;
64template <
typename Traits>
67 PrivatePartType* global_var,
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());
81template <
typename Traits>
82ItemMaterialVariableBase<Traits>::
83~ItemMaterialVariableBase()
85 Integer nb_var = m_p->m_refs.size();
86 delete m_global_variable_ref;
87 for (Integer i = 1; i < nb_var; ++i) {
88 delete m_p->m_refs[i];
97template <
typename Traits> IVariable*
98ItemMaterialVariableBase<Traits>::
101 return m_global_variable;
107template <
typename Traits>
void
113 m_vars.addRange(vars);
114 Integer nb_var = m_vars.size();
115 m_device_views.resizeNoInit(nb_var);
116 m_host_views.resize(nb_var);
117 m_views_as_bytes.resize(nb_var);
121 m_p->m_refs.resize(nb_var);
122 for (
Integer i = 0; i < nb_var; ++i) {
124 m_p->m_refs[i] =
nullptr;
127 m_p->m_refs[i] = m_global_variable_ref;
132 m_p->m_refs[i] =
new VariableRefType(m_vars[i]);
139 _copyHostViewsToViews(
nullptr);
145template <
typename Traits>
void
146ItemMaterialVariableBase<Traits>::
147buildFromManager(
bool is_continue)
158 all_vars[0] = m_global_variable;
161 if (!m_global_variable->isUsed())
162 m_global_variable->setUsed(
true);
166 m_p->m_global_variable_changed_observer =
new ObserverT<ThatClass>(
this, &ThatClass::_syncFromGlobalVariable);
167 m_global_variable->onSizeChangedObservable()->attachObserver(m_p->m_global_variable_changed_observer);
169 m_p->m_modified_times.resize(nb_indexer);
170 m_p->m_modified_times.fill(0);
175 int property = m_global_variable->property();
176 for (
Integer i = 0; i < nb_indexer; ++i) {
181 all_vars[i + 1] =
nullptr;
195 VariableInfo vi = VariableRefType::_internalVariableInfo(vbi2);
196 var = PrivatePartType::getReference(vbi2, vi);
200 var->
addTag(
"Material",
"1");
201 PrivatePartType* true_ptr =
dynamic_cast<PrivatePartType*
>(var);
203 all_vars[i + 1] = true_ptr;
206 true_ptr->setUsed(
true);
211 this->_init(all_vars);
217template <
typename Traits>
void
227 const bool do_complete_sync =
true;
228 if (do_complete_sync) {
237 _copyHostViewsToViews(
nullptr);
241 ref->updateFromInternal();
248template <
typename Traits>
void
249ItemMaterialVariableBase<Traits>::
252 _syncReferences(
true);
258template <
typename Traits>
void
267 for (
Integer i = 0; i < nb_indexer; ++i) {
269 PrivatePartType* true_ptr = m_vars[i + 1];
276 _copyHostViewsToViews(
nullptr);
279 for (MeshMaterialVariableRef::Enumerator i(
this); i.hasNext(); ++i) {
280 MeshMaterialVariableRef* ref = *i;
281 ref->updateFromInternal();
288template <
typename Traits> Ref<IData>
289ItemMaterialVariableBase<Traits>::
290_internalCreateSaveDataRef(Integer nb_value)
292 Ref<IData> data = m_global_variable->data()->cloneEmptyRef();
293 auto* true_data =
dynamic_cast<ValueDataType*
>(data.get());
295 true_data->_internal()->reserve(nb_value);
302template <
typename Traits>
void
303ItemMaterialVariableBase<Traits>::
304_saveData(IMeshComponent* component, IData* data)
306 if (m_p->space() == MatVarSpace::Environment && !component->isEnvironment())
307 ARCANE_FATAL(
"Can not save data on material for environment only variable");
308 Traits::saveData(component, data, m_host_views);
314template <
typename Traits>
void
315ItemMaterialVariableBase<Traits>::
316_restoreData(IMeshComponent* component, IData* data, Integer data_index,
317 Int32ConstArrayView ids,
bool allow_null_id)
319 if (m_p->space() == MatVarSpace::Environment && !component->isEnvironment())
320 ARCANE_FATAL(
"Can not restore data on material for environment only variable");
322 auto* true_data =
dynamic_cast<ValueDataType*
>(data);
324 auto values = true_data->view();
326 PrivatePartType* global_var = this->_trueGlobalVariable();
330 UniqueContainerType tmp_values;
331 if (component->materialMng()->isDataInitialisationWithZero()) {
332 Integer max_id = m_global_variable->itemFamily()->maxLocalId();
333 Traits::resizeAndFillWithDefault(true_data, tmp_values, max_id);
336 tmp_values = global_var->constValueView();
339 for (Integer i = 0, n = ids.size(); i < n; ++i) {
340 if (ids[i] != NULL_ITEM_ID) {
341 Traits::setValue(tmp_values[ids[i]], values[data_index + i]);
346 for (Integer i = 0, n = ids.size(); i < n; ++i) {
347 Traits::setValue(tmp_values[ids[i]], values[data_index + i]);
352 ComponentCell ec = *icell;
353 setValue(ec._varIndex(), tmp_values[ec.globalCell().localId()]);
360template <
typename Traits>
bool
361ItemMaterialVariableBase<Traits>::
362_isValidAndUsedAndGlobalUsed(PrivatePartType* partial_var)
366 if (!m_global_variable->isUsed() || !partial_var->isUsed())
374template <
typename Traits>
void
375ItemMaterialVariableBase<Traits>::
376_resizeForIndexer(ResizeVariableIndexerArgs& args)
378 Int32 index = args.m_var_index;
379 RunQueue& queue = args.m_queue;
381 PrivatePartType* partial_var = m_vars[index + 1];
382 if (_isValidAndUsedAndGlobalUsed(partial_var)) {
388 IMeshMaterialMngInternal* api = m_p->materialMng()->_internalApi();
389 ConstArrayView<MeshMaterialVariableIndexer*> indexers = api->variablesIndexer();
390 Real ratio = api->additionalCapacityRatio();
391 Traits::resizeWithReserve(partial_var, indexers[index]->maxIndexInMultipleArray(), ratio);
392 this->_setView(index + 1);
394 if (args.isUseOneCommand()) {
396 auto source =
asBytes(m_host_views.view());
397 args.addOneCopyData(source, dest, 1);
400 _copyHostViewsToViews(&queue);
406template <
typename Traits>
void
407ItemMaterialVariableBase<Traits>::
408_copyHostViewsToViews(RunQueue* queue)
411 auto source =
asBytes(m_host_views);
413 Accelerator::MemoryCopyArgs copy_args(dest, source);
414 copy_args.addAsync(
true);
415 queue->copyMemory(copy_args);
418 MemoryUtils::copy(dest, source);
424template <
typename Traits>
void
425ItemMaterialVariableBase<Traits>::
426_copyBetweenPartialAndGlobal(
const CopyBetweenPartialAndGlobalArgs& args)
428 Int32 var_index = args.m_var_index + 1;
429 PrivatePartType* partial_var = m_vars[var_index];
430 if (!_isValidAndUsedAndGlobalUsed(partial_var))
432 const bool is_global_to_partial = args.m_is_global_to_partial;
433 const bool use_generic = args.m_use_generic_copy;
434 const RunQueue& queue = args.m_queue;
436 auto input = m_host_views[var_index];
437 auto output = m_host_views[0];
438 auto output_indexes = args.m_local_ids;
439 auto input_indexes = args.m_indexes_in_multiple;
441 if (is_global_to_partial) {
442 std::swap(input, output);
443 std::swap(output_indexes, input_indexes);
447 SmallSpan<const std::byte> input_bytes(Traits::toBytes(input));
448 SmallSpan<std::byte> output_bytes(Traits::toBytes(output));
449 if (args.isUseOneCommand())
450 args.addOneCopyData(input_bytes, output_bytes, data_type_size);
452 _genericCopyTo(input_bytes, input_indexes,
453 output_bytes, output_indexes, queue, data_type_size);
456 Traits::copyTo(input, input_indexes, output, output_indexes, queue);
463template <
typename Traits>
void
464ItemMaterialVariableBase<Traits>::
465_initializeNewItemsWithZero(InitializeWithZeroArgs& args)
467 const Int32 var_index = args.m_var_index + 1;
468 RunQueue& queue = args.m_queue;
469 PrivatePartType* partial_var = m_vars[var_index];
470 if (!_isValidAndUsedAndGlobalUsed(partial_var))
473 SmallSpan<const Int32> partial_indexes = args.m_indexes_in_multiple;
475 ARCANE_CHECK_ACCESSIBLE_POINTER(queue, partial_indexes.data());
477 if (args.isUseOneCommand()) {
479 auto output = m_host_views[var_index];
480 SmallSpan<std::byte> output_bytes(Traits::toBytes(output));
481 args.addOneCopyData({}, output_bytes, data_type_size);
484 ContainerSpanType partial_view = m_host_views[var_index];
485 Int32 nb_partial = partial_indexes.size();
486 DataType zero = DataType();
491 Int32 index = partial_indexes[i];
492 Traits::setValue(partial_view[index], zero);
500template <
typename Traits>
void
501ItemMaterialVariableBase<Traits>::
502fillPartialValuesWithGlobalValues()
510template <
typename Traits>
void
511ItemMaterialVariableBase<Traits>::
512fillPartialValuesWithSuperValues(
Int32 level)
515 if (level == LEVEL_MATERIAL)
517 else if (level == LEVEL_ENVIRONMENT) {
520 else if (level == LEVEL_ALLENVIRONMENT) {
531template <
typename Traits>
void
541 ComponentCell c = (*iccell).superCell();
542 setValue(iccell._varIndex(), value(c.
_varIndex()));
559template <
typename VariableTrueType> IMeshMaterialVariable*
563 typedef typename VariableTrueType::PrivatePartType PrivatePartType;
564 typedef typename VariableTrueType::VariableRefType VariableRefType;
579 if (!v.itemFamilyName().
null())
580 ARCANE_FATAL(
"Can not declare material variable for specific family");
582 if (!v.itemGroupName().
null())
583 ARCANE_FATAL(
"Can not declare partial material variable");
588 if (VariableTrueType::TraitsType::dimension() == 0)
598 VariableInfo gvar_vi = VariableRefType::_internalVariableInfo(gvar_bi);
599 IVariable* g_var = PrivatePartType::getReference(gvar_bi, gvar_vi);
601 PrivatePartType* true_ptr =
dynamic_cast<PrivatePartType*
>(g_var);
608 VariableTrueType* true_mat_var = 0;
611 true_mat_var =
dynamic_cast<VariableTrueType*
>(mat_var);
613 VariableRefType* var_ref =
new VariableRefType(gvar_bi);
615 true_mat_var =
new VariableTrueType(mvbi, true_ptr, var_ref, mvs);
619 true_mat_var->buildFromManager(
false);
622 if (mvs != true_mat_var->space())
623 ARCANE_FATAL(
"Incoherent space for variable '{0}' wanted_space={1} existing_space={2}.\n"
624 " Check all instances of the variables are of the same space\n"
625 " (i.e. all variables are MaterialVariable or EnvironmentVariable)",
626 true_mat_var->name(), (
int)mvs, (
int)true_mat_var->space());
632 ++true_mat_var->m_p->m_nb_reference;
659 return getReference(v, MatVarSpace::MaterialAndEnvironment);
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Memory and allocator management functions.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
1D loop on accelerator with additional arguments.
Exception when an argument is invalid.
Modifiable view of an array of type T.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
virtual void addTag(const String &tagname, const String &tagvalue)=0
Adds the tag tagname with the value tagvalue.
__host__ __device__ MatVarIndex _varIndex() const
Interface of a component (material or environment) of a mesh.
virtual bool hasSpace(MatVarSpace space) const =0
Indicates if the component is defined for space space.
Internal Arcane API for 'IMeshMaterialMng'.
virtual ConstArrayView< MeshMaterialVariableIndexer * > variablesIndexer()=0
List of information to index material variables.
virtual void addVariable(IMeshMaterialVariable *var)=0
Adds the variable var.
virtual Real additionalCapacityRatio() const =0
Ratio for additional capacity to allocate when resizing variables.
Interface for the material and environment manager of a mesh.
virtual MeshComponentList materialsAsComponents() const =0
List of materials viewed as components.
virtual bool isAllocateScalarEnvironmentVariableAsMaterial() const =0
Indicates if environment scalar variables are allocated on materials.
virtual Mutex * variableLock()=0
Lock used for multi-threading.
virtual MeshComponentList environmentsAsComponents() const =0
List of environments viewed as components.
virtual IMeshMaterialMngInternal * _internalApi() const =0
Internal API for Arcane.
virtual IMeshMaterialVariable * checkVariable(IVariable *global_var)=0
Material variable associated with the global variable global_var (nullptr if none).
static IMeshMaterialMng * getReference(const MeshHandleOrMesh &mesh_handle, bool create=true)
Retrieves or creates the reference associated with mesh.
Interface of a material variable on a mesh.
Base class for material variables with the characteristics specified by Traits.
ARCANE_MATERIALS_EXPORT void fillPartialValuesWithSuperValues(Int32 level) override
Fills partial values with the value of the super cell. If level equals LEVEL_MATERIAL,...
Registerer for a material variable factory..
Indexer for material variables.
bool isEnvironment() const
True if this indexer is for an environment.
Integer maxIndexInMultipleArray() const
const String & name() const
Name of the indexer.
Base class for material variable references.
Base class for material variables.
String name() const override
Name of the variable.
bool isNull() const
Indicates if the handle is null (it does not reference any existing mesh or not).
Unicode character string.
bool null() const
Returns true if the string is null.
1D data vector with value semantics (STL style).
Parameters necessary for building a variable.
Information characterizing a variable.
RunCommand makeCommand(const RunQueue &run_queue)
Creates a command associated with the queue run_queue.
Always enables tracing in Arcane parts concerning materials.
ConstArrayView< IMeshComponent * > MeshComponentList
List of multi-material components of the mesh.
MatVarSpace
Definition space for a material variable.
@ Environment
Variable having values only on environments.
@ MaterialAndEnvironment
Variable having values on environments and materials.
MemoryAllocationOptions getAllocationOptions(eMemoryResource mem_resource)
Default allocation for the resource mem_resource.
ARCANE_DATATYPE_EXPORT Integer dataTypeSize(eDataType type)
Size of data type type (which must be different from DT_String).
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
Arcane::eMemoryResource eMemoryRessource
Typedef for the historical Arcane version (with 2's').
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converts the view into an array of non-modifiable bytes.
Impl::SpanTypeFromSize< std::byte, SizeType >::SpanType asWritableBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converts the view into an array of modifiable bytes.
@ HostPinned
Allocates on the host.
std::int32_t Int32
Signed integer type of 32 bits.