Arcane  4.2.1.0
User documentation
Loading...
Searching...
No Matches
VariableArray.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* VariableArray.cc (C) 2000-2026 */
9/* */
10/* 1D array variable. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/NotSupportedException.h"
15#include "arcane/utils/ArgumentException.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/TraceInfo.h"
18#include "arcane/utils/Ref.h"
19#include "arcane/utils/MemoryAccessInfo.h"
20#include "arcane/utils/MemoryAllocator.h"
21#include "arccore/common/AlignedMemoryAllocator.h"
22
23#include "arcane/core/VariableDiff.h"
24#include "arcane/core/VariableBuildInfo.h"
25#include "arcane/core/VariableInfo.h"
26#include "arcane/core/IApplication.h"
27#include "arcane/core/IVariableMng.h"
28#include "arcane/core/IItemFamily.h"
29#include "arcane/core/IVariableSynchronizer.h"
30#include "arcane/core/IDataReader.h"
31#include "arcane/core/ItemGroup.h"
32#include "arcane/core/IDataFactoryMng.h"
33#include "arcane/core/IParallelMng.h"
34#include "arcane/core/IMesh.h"
35#include "arcane/core/VariableComparer.h"
36
37#include "arcane/core/datatype/DataTracer.h"
38#include "arcane/core/datatype/DataTypeTraits.h"
39#include "arcane/core/datatype/DataStorageBuildInfo.h"
40
41#include "arcane/core/VariableArray.h"
42#include "arcane/core/RawCopy.h"
43
44#include "arcane/core/internal/IDataInternal.h"
45#include "arcane/core/internal/IVariableMngInternal.h"
46#include "arcane/core/internal/IVariableInternal.h"
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51namespace Arcane
52{
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57template <class DataType>
59: public VariableDiff<DataType>
60{
61 using VarDataTypeTraits = VariableDataTypeTraitsT<DataType>;
62 using DiffInfo = typename VariableDiff<DataType>::DiffInfo;
63 static constexpr bool IsNumeric = std::is_same_v<typename VarDataTypeTraits::IsNumeric, TrueType>;
64 using NormType = typename VarDataTypeTraits::NormType;
65
66 public:
67
70 const VariableComparerArgs& compare_args)
71 {
72 const bool compare_ghost = compare_args.isCompareGhost();
73 if (var->itemKind() == IK_Unknown)
74 return _checkAsArray(var, ref, current, compare_args);
75
76 ItemGroup group = var->itemGroup();
77 if (group.null())
78 return {};
79 IMesh* mesh = group.mesh();
80 if (!mesh)
81 return {};
82 ITraceMng* msg = mesh->traceMng();
83 IParallelMng* pm = mesh->parallelMng();
84
85 GroupIndexTable* group_index_table = (var->isPartial()) ? group.localIdToIndex().get() : nullptr;
86
87 int nb_diff = 0;
88 bool compare_failed = false;
89 eVariableComparerComputeDifferenceMethod diff_method = compare_args.computeDifferenceMethod();
90 // No max norm if the type is not numeric.
91 if (!IsNumeric)
93
94 Integer ref_size = ref.size();
95 NormType local_norm_max = {};
96
97 if constexpr (IsNumeric) {
98 bool is_use_local_norm = diff_method == eVariableComparerComputeDifferenceMethod::LocalNormMax;
99 if (is_use_local_norm) {
100 // Large copy-paste to calculate the global norm
101 ENUMERATE_ITEM (i, group) {
102 Item item = *i;
103 if (!item.isOwn() && !compare_ghost)
104 continue;
105 Integer index = item.localId();
106 if (group_index_table) {
107 index = (*group_index_table)[index];
108 if (index < 0)
109 continue;
110 }
111 if (index >= ref_size) {
112 continue;
113 }
114 else {
115 DataType dref = ref[index];
116 NormType norm_max = VarDataTypeTraits::normeMax(dref);
117 if (norm_max > local_norm_max) {
118 local_norm_max = norm_max;
119 }
120 }
121 }
122 }
123 }
124 // We calculate the normalized errors
125 ENUMERATE_ITEM (i, group) {
126 Item item = *i;
127 if (!item.isOwn() && !compare_ghost)
128 continue;
129 Integer index = item.localId();
130 if (group_index_table) {
131 index = (*group_index_table)[index];
132 if (index < 0)
133 continue;
134 }
135 DataType diff = DataType();
136 if (index >= ref_size) {
137 ++nb_diff;
138 compare_failed = true;
139 }
140 else {
141 DataType dref = ref[index];
142 DataType dcurrent = current[index];
143 bool is_diff = _computeDifference(dref, dcurrent, diff, local_norm_max, diff_method);
144 if (is_diff) {
145 this->m_diffs_info.add(DiffInfo(dcurrent, dref, diff, item, NULL_ITEM_ID));
146 ++nb_diff;
147 }
148 }
149 }
150 if (compare_failed) {
151 Int32 sid = pm->commRank();
152 const String& var_name = var->name();
153 msg->pinfo() << "Processor " << sid << " : "
154 << "comparison impossible because the number of the elements is different "
155 << " for the variable " << var_name << " ref_size=" << ref_size;
156 }
157 if (nb_diff != 0)
158 this->_sortAndDump(var, pm, compare_args);
159
160 return VariableComparerResults(nb_diff);
161 }
162
164 checkReplica(IVariable* var, ConstArrayView<DataType> var_value,
165 const VariableComparerArgs& compare_args)
166 {
167 IParallelMng* replica_pm = var->_internalApi()->replicaParallelMng();
168 if (!replica_pm)
169 return {};
170 // Calls the correct specialization to ensure the template type has reduction.
171 using ReduceType = typename VariableDataTypeTraitsT<DataType>::HasReduceMinMax;
172 if constexpr (std::is_same<TrueType, ReduceType>::value)
173 return _checkReplica2(replica_pm, var, var_value, compare_args);
174
175 ARCANE_UNUSED(replica_pm);
176 ARCANE_UNUSED(var);
177 ARCANE_UNUSED(var_value);
178 ARCANE_UNUSED(compare_args);
179 throw NotSupportedException(A_FUNCINFO);
180 }
181
182 private:
183
185 _checkAsArray(IVariable* var, ConstArrayView<DataType> ref, ConstArrayView<DataType> current,
186 const VariableComparerArgs& compare_args)
187 {
188 IParallelMng* pm = var->variableMng()->parallelMng();
189 ITraceMng* msg = pm->traceMng();
190
191 int nb_diff = 0;
192 bool compare_failed = false;
193 Integer ref_size = ref.size();
194 Integer current_size = current.size();
195 eVariableComparerComputeDifferenceMethod diff_method = compare_args.computeDifferenceMethod();
196 // No max norm if the type is not numeric.
197 if (!IsNumeric)
199 NormType local_norm_max = {};
200
201 if constexpr (IsNumeric) {
202 bool is_use_local_norm = compare_args.computeDifferenceMethod() == eVariableComparerComputeDifferenceMethod::LocalNormMax;
203 if (is_use_local_norm) {
204 // Large copy-paste to calculate the global norm
205 for (Integer index = 0; index < current_size; ++index) {
206 if (index >= ref_size) {
207 continue;
208 }
209 else {
210 DataType dref = ref[index];
211 typename VarDataTypeTraits::NormType norm_max = VarDataTypeTraits::normeMax(dref);
212 if (norm_max > local_norm_max) {
213 local_norm_max = norm_max;
214 }
215 }
216 }
217 }
218 }
219 // We calculate the normalized errors
220 for (Integer index = 0; index < current_size; ++index) {
221 DataType diff = DataType();
222 if (index >= ref_size) {
223 ++nb_diff;
224 compare_failed = true;
225 }
226 else {
227 DataType dref = ref[index];
228 DataType dcurrent = current[index];
229 if (_computeDifference(dref, dcurrent, diff, local_norm_max, diff_method)) {
230 this->m_diffs_info.add(DiffInfo(dcurrent, dref, diff, index, NULL_ITEM_ID));
231 ++nb_diff;
232 }
233 }
234 }
235 if (compare_failed) {
236 Int32 sid = pm->commRank();
237 const String& var_name = var->name();
238 msg->pinfo() << "Processor " << sid << " : "
239 << " comparison impossible because the number of elements is different"
240 << " for the variable " << var_name << " ref_size=" << ref_size;
241 }
242 if (nb_diff != 0)
243 this->_sortAndDump(var, pm, compare_args);
244
245 return VariableComparerResults(nb_diff);
246 }
247
249 _checkReplica2(IParallelMng* pm, IVariable* var, ConstArrayView<DataType> var_values,
250 const VariableComparerArgs& compare_args)
251 {
252 ITraceMng* msg = pm->traceMng();
253 Integer size = var_values.size();
254 // Checks that all replicas have the same number of elements for the variable.
255 Integer max_size = pm->reduce(Parallel::ReduceMax, size);
256 Integer min_size = pm->reduce(Parallel::ReduceMin, size);
257 msg->info(5) << "CheckReplica2 rep_size=" << pm->commSize() << " rank=" << pm->commRank();
258 if (max_size != min_size) {
259 const String& var_name = var->name();
260 msg->info() << "Can not compare values on replica for variable '" << var_name << "'"
261 << " because the number of elements is not the same on all the replica "
262 << " min=" << min_size << " max=" << max_size;
263 return VariableComparerResults(max_size);
264 }
265 Integer nb_diff = 0;
266 UniqueArray<DataType> min_values(var_values);
267 UniqueArray<DataType> max_values(var_values);
268 pm->reduce(Parallel::ReduceMax, max_values);
269 pm->reduce(Parallel::ReduceMin, min_values);
270
271 for (Integer index = 0; index < size; ++index) {
272 DataType diff = DataType();
273 DataType min_val = min_values[index];
274 DataType max_val = max_values[index];
275 if (VarDataTypeTraits::verifDifferent(min_val, max_val, diff, true)) {
276 this->m_diffs_info.add(DiffInfo(min_val, max_val, diff, index, NULL_ITEM_ID));
277 ++nb_diff;
278 }
279 }
280 if (nb_diff != 0)
281 this->_sortAndDump(var, pm, compare_args);
282
283 return VariableComparerResults(nb_diff);
284 }
285 bool _computeDifference(const DataType& dref, const DataType& dcurrent, DataType& diff,
286 const NormType& local_norm_max,
288 {
289 bool is_diff = false;
290 switch (diff_method) {
292 is_diff = VarDataTypeTraits::verifDifferent(dref, dcurrent, diff, true);
293 break;
295 is_diff = VarDataTypeTraits::verifDifferentNorm(dref, dcurrent, diff, local_norm_max, true);
296 break;
297 }
298 return is_diff;
299 }
300};
301
302/*---------------------------------------------------------------------------*/
303/*---------------------------------------------------------------------------*/
304
305/*---------------------------------------------------------------------------*/
306/*---------------------------------------------------------------------------*/
307
308template <typename T> VariableArrayT<T>::
310: Variable(vb, info)
311, m_value(nullptr)
312{
313 IDataFactoryMng* df = vb.dataFactoryMng();
314 DataStorageBuildInfo storage_build_info(vb.traceMng());
315 String storage_full_type = info.storageTypeInfo().fullName();
316 Ref<IData> data = df->createSimpleDataRef(storage_full_type, storage_build_info);
317 m_value = dynamic_cast<ValueDataType*>(data.get());
318 ARCANE_CHECK_POINTER(m_value);
319 _setData(makeRef(m_value));
320}
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
325template <typename T> VariableArrayT<T>::
327{
328}
329
330/*---------------------------------------------------------------------------*/
331/*---------------------------------------------------------------------------*/
332
333template <typename T> VariableArrayT<T>* VariableArrayT<T>::
334getReference(const VariableBuildInfo& vb, const VariableInfo& vi)
335{
336 if (vb.isNull())
337 return nullptr;
338 ThatClass* true_ptr = nullptr;
339 IVariableMng* vm = vb.variableMng();
340 IVariable* var = vm->checkVariable(vi);
341 if (var)
342 true_ptr = dynamic_cast<ThatClass*>(var);
343 else {
344 true_ptr = new ThatClass(vb, vi);
345 vm->_internalApi()->addVariable(true_ptr);
346 }
347 ARCANE_CHECK_PTR(true_ptr);
348 return true_ptr;
349}
350
351/*---------------------------------------------------------------------------*/
352/*---------------------------------------------------------------------------*/
353
354template <typename T> VariableArrayT<T>* VariableArrayT<T>::
356{
357 if (!var)
358 throw ArgumentException(A_FUNCINFO, "null variable");
359 auto* true_ptr = dynamic_cast<ThatClass*>(var);
360 if (!true_ptr)
361 ARCANE_FATAL("Can not build a reference from variable {0}", var->name());
362 return true_ptr;
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
368template <typename T> void VariableArrayT<T>::
369print(std::ostream& o) const
370{
371 ConstArrayView<T> x(m_value->view());
372 Integer size = x.size();
373 o << "(dimension=" << size << ") ";
374 if (size <= 150) {
375 for (auto& i : x) {
376 o << i << '\n';
377 }
378 }
379}
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
384template <typename T> void VariableArrayT<T>::
386{
387 if (itemKind() == IK_Unknown)
388 ARCANE_THROW(NotSupportedException, "variable '{0}' is not a mesh variable", fullName());
389 IItemFamily* family = itemGroup().itemFamily();
390 if (!family)
391 ARCANE_FATAL("variable '{0}' without family", fullName());
392 if (isPartial())
393 itemGroup().synchronizer()->synchronize(this);
394 else
395 family->allItemsSynchronizer()->synchronize(this);
396}
397
398/*---------------------------------------------------------------------------*/
399/*---------------------------------------------------------------------------*/
400
401template <typename T> void VariableArrayT<T>::
403{
404 if (itemKind() == IK_Unknown)
405 ARCANE_THROW(NotSupportedException, "variable '{0}' is not a mesh variable", fullName());
406 IItemFamily* family = itemGroup().itemFamily();
407 if (!family)
408 ARCANE_FATAL("variable '{0}' without family", fullName());
409 if (isPartial())
410 itemGroup().synchronizer()->synchronize(this, local_ids);
411 else
412 family->allItemsSynchronizer()->synchronize(this, local_ids);
413}
414
415/*---------------------------------------------------------------------------*/
416/*---------------------------------------------------------------------------*/
417
418template <typename T> Real VariableArrayT<T>::
419allocatedMemory() const
420{
421 Real v1 = (Real)(sizeof(T));
422 Real v2 = (Real)(m_value->view().size());
423 return v1 * v2;
424}
425
426/*---------------------------------------------------------------------------*/
427/*---------------------------------------------------------------------------*/
428
429// Uses a Helper function to specialize the call in the
430// case of the 'Byte' type because ArrayVariableDiff::checkReplica() uses
431// a Min/Max reduction, and this does not exist in MPI for the Byte type.
432namespace
433{
434 template <typename T> VariableComparerResults
435 _checkIfSameOnAllReplicaHelper(IVariable* var, ConstArrayView<T> values,
436 const VariableComparerArgs& compare_args)
437 {
439 return csa.checkReplica(var, values, compare_args);
440 }
441
442 // Specialization for the 'Byte' type which does not support reductions.
443 VariableComparerResults
444 _checkIfSameOnAllReplicaHelper(IVariable* var, ConstArrayView<Byte> values,
445 const VariableComparerArgs& compare_args)
446 {
447 Integer size = values.size();
448 UniqueArray<Integer> int_values(size);
449 for (Integer i = 0; i < size; ++i)
450 int_values[i] = values[i];
451 ArrayVariableDiff<Integer> csa;
452 return csa.checkReplica(var, int_values, compare_args);
453 }
454} // namespace
455
456/*---------------------------------------------------------------------------*/
457/*---------------------------------------------------------------------------*/
458
460_compareVariable(const VariableComparerArgs& compare_args)
461{
462 switch (compare_args.compareMode()) {
464
465 if (itemKind() == IK_Particle)
466 return {};
467 IDataReader* reader = compare_args.dataReader();
468 ARCANE_CHECK_POINTER(reader);
469
470 ArrayView<T> from_array(valueView());
471
472 Ref<IArrayDataT<T>> ref_data(m_value->cloneTrueEmptyRef());
473 reader->read(this, ref_data.get());
474
476 VariableComparerResults r = csa.check(this, ref_data->view(), from_array, compare_args);
477 return r;
478 }
480 IItemFamily* family = itemGroup().itemFamily();
481 if (!family)
482 return {};
483 ValueType& data_values = m_value->_internal()->_internalDeprecatedValue();
484 UniqueArray<T> ref_array(constValueView());
485 this->synchronize(); // works for all variables
487 ConstArrayView<T> from_array(constValueView());
488 VariableComparerResults r = csa.check(this, ref_array, from_array, compare_args);
489 data_values.copy(ref_array);
490 return r;
491 }
493 VariableComparerResults r = _checkIfSameOnAllReplicaHelper(this, constValueView(), compare_args);
494 return r;
495 }
496 }
497 ARCANE_FATAL("Invalid value for compare mode '{0}'", (int)compare_args.compareMode());
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
503/*!
504 * \brief Initializes the variable.
505 *
506 Initializes the variable with the value \a value on the group \a group.
507
508 Since the value is passed as a character string, it verifies that
509 the conversion to the variable's type is possible. It also verifies
510 that the group \a group is of type #GroupType. If either of these two points
511 is not met, the initialization fails.
512
513 \retval true in case of error,
514 \retval false in case of success.
515*/
516template <typename T> bool VariableArrayT<T>::
517initialize(const ItemGroup& group, const String& value)
518{
519 //TODO: maybe check if the variable is used?
520
521 // Tries to convert value into a value of the variable's type.
522 T v = T();
523 bool is_bad = VariableDataTypeTraitsT<T>::getValue(v, value);
524
525 if (is_bad) {
526 error() << String::format("Can not convert the string '{0}' to type '{1}'",
527 value, dataType());
528 return true;
529 }
530
531 bool is_ok = false;
532
533 ArrayView<T> values(m_value->view());
534 if (group.itemFamily() == itemFamily()) {
535 is_ok = true;
536 // VERY IMPORTANT
537 //TODO must use an indirection and a hierarchy between groups
538 // Finally, assign the value \a v to all entities in the group.
539 //ValueType& var_value = this->value();
540 ENUMERATE_ITEM (i, group) {
541 Item elem = *i;
542 values[elem.localId()] = v;
543 }
544 }
545
546 if (is_ok)
547 return false;
548
549 eItemKind group_kind = group.itemKind();
550
551 error() << "The type of elements (" << itemKindName(group_kind)
552 << ") of the group `" << group.name() << "' does not match "
553 << "the type of the variable (" << itemKindName(this->itemKind()) << ").";
554 return true;
555}
556
557/*---------------------------------------------------------------------------*/
558/*---------------------------------------------------------------------------*/
559
560template <typename T> void VariableArrayT<T>::
562{
563 ARCANE_ASSERT(source.size() == destination.size(),
564 ("Impossible to copy: source and destination of different sizes !"));
565 ArrayView<T> value = m_value->view();
566 const Integer size = source.size();
567 for (Integer i = 0; i < size; ++i)
568 value[destination[i]] = value[source[i]];
570}
571
572/*---------------------------------------------------------------------------*/
573/*---------------------------------------------------------------------------*/
574
575template <typename T> void VariableArrayT<T>::
577 Int32ConstArrayView second_source,
578 Int32ConstArrayView destination)
579{
580 ARCANE_ASSERT((first_source.size() == destination.size()) && (second_source.size() == destination.size()),
581 ("Impossible to copy: source and destination of different sizes !"));
582 ArrayView<T> value = m_value->view();
583 const Integer size = first_source.size();
584 for (Integer i = 0; i < size; ++i) {
585 value[destination[i]] = (T)((value[first_source[i]] + value[second_source[i]]) / 2);
586 }
588}
589
590/*---------------------------------------------------------------------------*/
591/*---------------------------------------------------------------------------*/
592
595 Int32ConstArrayView second_source,
596 Int32ConstArrayView destination);
597
598/*---------------------------------------------------------------------------*/
599/*---------------------------------------------------------------------------*/
600
601template <typename T> void VariableArrayT<T>::
602compact(Int32ConstArrayView new_to_old_ids)
603{
604 if (isPartial()) {
605 debug(Trace::High) << "Skip compact for partial variable " << name();
606 return;
607 }
608
609 UniqueArray<T> old_value(constValueView());
610 Integer new_size = new_to_old_ids.size();
611 m_value->resize(new_size);
612 ArrayView<T> current_value = m_value->view();
613 if (arcaneIsCheck()) {
614 for (Integer i = 0; i < new_size; ++i)
615 current_value.setAt(i, old_value.at(new_to_old_ids[i]));
616 }
617 else {
618 for (Integer i = 0; i < new_size; ++i)
619 RawCopy<T>::copy(current_value[i], old_value[new_to_old_ids[i]]); // current_value[i] = old_value[ new_to_old_ids[i] ];
620 }
622}
623
624/*---------------------------------------------------------------------------*/
625/*---------------------------------------------------------------------------*/
626
627template <typename T> void VariableArrayT<T>::
629{
631}
632
633/*---------------------------------------------------------------------------*/
634/*---------------------------------------------------------------------------*/
635
636template <typename T> void VariableArrayT<T>::
637setIsSynchronized(const ItemGroup& group)
638{
639 ARCANE_UNUSED(group);
640}
641
642/*---------------------------------------------------------------------------*/
643/*---------------------------------------------------------------------------*/
644
645template <typename T> void VariableArrayT<T>::
646_internalResize(const VariableResizeArgs& resize_args)
647{
648 Int32 new_size = resize_args.newSize();
649 Int32 nb_additional_element = resize_args.nbAdditionalCapacity();
650 bool use_no_init = resize_args.isUseNoInit();
651
652 auto* value_internal = m_value->_internal();
653
654 //const bool is_collective_allocator = value_internal->memoryAllocator().isCollectiveAllocator();
655 const bool is_collective_allocator = value_internal->_internalDeprecatedValue().allocator()->isCollective();
656 if (is_collective_allocator) {
657 value_internal->reserve(new_size + nb_additional_element);
658 }
659 else if (nb_additional_element != 0) {
660 Integer capacity = value_internal->capacity();
661 if (new_size > capacity)
662 value_internal->reserve(new_size + nb_additional_element);
663 }
665 // If the new size is greater than the old one,
666 // initialize the new elements following
667 // the desired policy
668 Integer current_size = m_value->view().size();
669 if (!isUsed()) {
670 // If the variable is no longer used, free the memory
671 // associated with it.
672 value_internal->dispose();
673 }
674 if (use_no_init)
675 value_internal->_internalDeprecatedValue().resizeNoInit(new_size);
676 else
677 value_internal->resize(new_size);
678 if (new_size > current_size) {
679 if (init_policy == DIP_InitWithDefault) {
680 ArrayView<T> values = this->valueView();
681 for (Integer i = current_size; i < new_size; ++i)
682 values[i] = T();
683 }
684 else {
685 bool use_nan = (init_policy == DIP_InitWithNan);
686 bool use_nan2 = (init_policy == DIP_InitInitialWithNanResizeWithDefault) && !_hasValidData();
687 if (use_nan || use_nan2) {
688 ArrayView<T> view = this->valueView();
689 DataTypeTraitsT<T>::fillNan(view.subView(current_size, new_size - current_size));
690 }
691 }
692 }
693
694 // Compresses the memory if requested
695 if (_wantShrink()) {
696 if (m_value->view().size() < value_internal->capacity()) {
697 value_internal->shrink();
698 }
699 }
700
701 // Checks if all modifications after the dispose have not altered the allocation state
702 // In the case of an unused variable, the maximum allowed capacity is
703 // equal to that of a platform SIMD vector.
704 // (this cannot be 0 because the Array class must allocate at least one
705 // element if a specific allocator is used, which is the case
706 // for variables.
707 Int64 capacity = value_internal->capacity();
708 if (!((isUsed() || capacity <= AlignedMemoryAllocator::simdAlignment())))
709 ARCANE_FATAL("Wrong unused data size {0}", capacity);
710}
711
712/*---------------------------------------------------------------------------*/
713/*---------------------------------------------------------------------------*/
714
715template <typename DataType> void VariableArrayT<DataType>::
716resizeWithReserve(Integer n, Integer nb_additional)
717{
718 _resize(VariableResizeArgs(n, nb_additional));
719}
720
721/*---------------------------------------------------------------------------*/
722/*---------------------------------------------------------------------------*/
723
724template <typename DataType> void VariableArrayT<DataType>::
726{
727 m_value->_internal()->shrink();
729}
730
731/*---------------------------------------------------------------------------*/
732/*---------------------------------------------------------------------------*/
733
734template <typename DataType> Integer VariableArrayT<DataType>::
735capacity()
736{
737 return m_value->_internal()->capacity();
738}
739
740/*---------------------------------------------------------------------------*/
741/*---------------------------------------------------------------------------*/
742
743template <typename DataType> void VariableArrayT<DataType>::
744fill(const DataType& value)
745{
746 m_value->view().fill(value);
747}
748
749/*---------------------------------------------------------------------------*/
750/*---------------------------------------------------------------------------*/
751
752template <typename DataType> void VariableArrayT<DataType>::
753fill(const DataType& value, const ItemGroup& group)
754{
755 ARCANE_UNUSED(group);
756 this->fill(value);
757}
758
759/*---------------------------------------------------------------------------*/
760/*---------------------------------------------------------------------------*/
761
762template <typename DataType> void
764swapValues(ThatClass& rhs)
765{
766 _checkSwapIsValid(&rhs);
767 // TODO: check if both variables must have the same number
768 // of elements, but it doesn't seem necessary a priori.
769 m_value->swapValues(rhs.m_value);
770 // References must be updated for this variable and \a rhs.
771 syncReferences();
772 rhs.syncReferences();
773}
774
775/*---------------------------------------------------------------------------*/
776/*---------------------------------------------------------------------------*/
777
778// SDP: Specialization
781 Int32ConstArrayView second_source,
782 Int32ConstArrayView destination)
783{
784 Integer dsize = destination.size();
785 bool is_ok = (first_source.size() == dsize) && (second_source.size() == dsize);
786 if (!is_ok)
787 ARCANE_FATAL("Unable to copy: source and destination of different sizes !");
788
789 ArrayView<String> value = m_value->view();
790 const Integer size = first_source.size();
791 for (Integer i = 0; i < size; ++i)
792 value[destination[i]] = value[first_source[i]];
794}
795
796/*---------------------------------------------------------------------------*/
797/*---------------------------------------------------------------------------*/
798
799template <typename DataType> auto VariableArrayT<DataType>::
800value() -> ValueType&
801{
802 return m_value->_internal()->_internalDeprecatedValue();
803}
804
805/*---------------------------------------------------------------------------*/
806/*---------------------------------------------------------------------------*/
807
808ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE(VariableArrayT);
809template class VariableArrayT<String>;
810
811/*---------------------------------------------------------------------------*/
812/*---------------------------------------------------------------------------*/
813
814} // End namespace Arcane
815
816/*---------------------------------------------------------------------------*/
817/*---------------------------------------------------------------------------*/
#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_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
static constexpr Integer simdAlignment()
Alignment for structures using vectorization.
Modifiable view of an array of type T.
T & at(Int64 i)
Element at index i. Always checks for overflows.
void copy(Span< const T > rhs)
Copies the values from rhs into the instance.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Information to construct an instance of 'IData'.
Interface for reading variable data.
Definition IDataReader.h:35
virtual void read(IVariable *var, IData *data)=0
Reads the data data of the variable var.
Interface of an entity family.
Definition IItemFamily.h:83
virtual IVariableSynchronizer * allItemsSynchronizer()=0
Synchronizer on all entities of the family.
Interface of the parallelism manager for a subdomain.
virtual ITraceMng * traceMng() const =0
Trace manager.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual char reduce(eReduceType rt, char v)=0
Performs a reduction of type rt on the real v and returns the value.
virtual TraceMessage pinfo()=0
Stream for a parallel information message.
virtual TraceMessage info()=0
Stream for an information message.
virtual IParallelMng * parallelMng() const =0
Associated parallelism manager.
virtual IVariable * checkVariable(const VariableInfo &infos)=0
Checks a variable.
virtual void synchronize(IVariable *var)=0
Synchronizes the variable var in blocking mode.
Interface of a variable.
Definition IVariable.h:40
virtual eItemKind itemKind() const =0
Kind of mesh entities on which the variable is based.
virtual bool isPartial() const =0
Indicates if the variable is partial.
virtual ItemGroup itemGroup() const =0
Associated mesh group.
virtual String name() const =0
Variable name.
virtual IVariableInternal * _internalApi()=0
Internal Arcane API.
virtual IVariableMng * variableMng() const =0
Variable manager associated with the variable.
Mesh entity group.
Definition ItemGroup.h:51
const String & name() const
Group name.
Definition ItemGroup.h:81
SharedPtrT< GroupIndexTable > localIdToIndex() const
Table of local ids to a position for all entities in the group.
Definition ItemGroup.h:312
IItemFamily * itemFamily() const
Entity family to which this group belongs (0 for the null group).
Definition ItemGroup.h:128
eItemKind itemKind() const
Group kind. This is the kind of its elements.
Definition ItemGroup.h:114
bool null() const
true means the group is the null group
Definition ItemGroup.h:75
IMesh * mesh() const
Mesh to which this group belongs (0 for the null group).
Definition ItemGroup.h:131
Base class for a mesh element.
Definition Item.h:84
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
constexpr bool isOwn() const
true if the entity belongs to the subdomain
Definition Item.h:267
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
TraceMessage error() const
Flow for an error message.
1D data vector with value semantics (STL style).
VariableArrayT(const VariableBuildInfo &v, const VariableInfo &vi)
Construit une variable basée sur la référence v.
void copyItemsMeanValues(Int32ConstArrayView first_source, Int32ConstArrayView second_source, Int32ConstArrayView destination) override
Copies the mean values of entities numbered first_source and second_source into entities numbered des...
void shrinkMemory() override
Frees any additional memory allocated for the data.
void compact(Int32ConstArrayView old_to_new_ids) override
Compresses the variable's values.
bool initialize(const ItemGroup &group, const String &value) override
Initializes the variable.
void copyItemsValues(Int32ConstArrayView source, Int32ConstArrayView destination) override
Copies the values of entities numbered source into entities numbered destination.
IData * data() override
Data associated with the variable.
VariableComparerResults _compareVariable(const VariableComparerArgs &compare_args) final
Comparison of values between variables.
void print(std::ostream &o) const override
Prints the variable's values to the stream o.
void setIsSynchronized() override
Indicates that the variable is synchronized.
Real allocatedMemory() const override
Memory size (in Bytes) used by the variable.
void synchronize() override
Synchronizes the variable.
Parameters necessary for building a variable.
Arguments for VariableComparer methods.
Results of a comparison operation.
Information characterizing a variable.
Variable(const VariableBuildInfo &v, const VariableInfo &vi)
Creates a variable linked to the reference v.
Definition Variable.cc:345
void _setData(const Ref< IData > &data)
Positions the data.
Definition Variable.cc:919
bool isPartial() const override
Indicates if the variable is partial.
Definition Variable.cc:901
IVariableMng * variableMng() const override
Variable manager associated with the variable.
Definition Variable.cc:476
String name() const final
Variable name.
Definition Variable.cc:485
ItemGroup itemGroup() const final
Associated mesh group.
Definition Variable.cc:865
void syncReferences() override
Synchronizes references.
Definition Variable.cc:787
String fullName() const final
Full variable name (with family prefix).
Definition Variable.cc:494
eItemKind itemKind() const override
Kind of mesh entities on which the variable is based.
Definition Variable.cc:874
IItemFamily * itemFamily() const final
Associated entity family.
Definition Variable.cc:910
eDataType dataType() const override
Data type managed by the variable (Real, Integer, ...).
Definition Variable.cc:530
void fill(MutableMemoryView destination, ConstMemoryView source, const RunQueue *run_queue=nullptr)
Fills a memory region with a value.
@ ReduceMin
Minimum of values.
@ ReduceMax
Maximum of values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
bool arcaneIsCheck()
True if running in check mode.
Definition Misc.cc:66
eDataInitialisationPolicy
Possible data initialization policy.
Definition DataTypes.h:135
@ DIP_InitInitialWithNanResizeWithDefault
Initialization with NaN upon creation and default constructor thereafter.
Definition DataTypes.h:175
@ DIP_InitWithNan
Initialization with NaN (Not a Number).
Definition DataTypes.h:153
@ DIP_InitWithDefault
Initialization with the default constructor.
Definition DataTypes.h:144
std::int64_t Int64
Signed integer type of 64 bits.
eVariableComparerComputeDifferenceMethod
Method used to calculate the difference between two values v1 and v2.
eDataInitialisationPolicy getGlobalDataInitialisationPolicy()
Gets the initialization policy for variables.
Definition DataTypes.cc:164
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:476
@ SameOnAllReplica
Checks that the variable values are the same on all replicas.
@ Same
Compares with a reference.
@ Sync
Checks that the variable is synchronized.
eItemKind
Mesh entity type.
@ IK_Particle
Particle mesh entity.
@ IK_Unknown
Unknown or uninitialized mesh entity.
const char * itemKindName(eItemKind kind)
Entity kind name.
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.