Arcane  4.1.12.0
Developer 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
22#include "arcane/core/VariableDiff.h"
23#include "arcane/core/VariableBuildInfo.h"
24#include "arcane/core/VariableInfo.h"
25#include "arcane/core/IApplication.h"
26#include "arcane/core/IVariableMng.h"
27#include "arcane/core/IItemFamily.h"
28#include "arcane/core/IVariableSynchronizer.h"
29#include "arcane/core/IDataReader.h"
30#include "arcane/core/ItemGroup.h"
31#include "arcane/core/IDataFactoryMng.h"
32#include "arcane/core/IParallelMng.h"
33#include "arcane/core/IMesh.h"
34#include "arcane/core/VariableComparer.h"
35
36#include "arcane/core/datatype/DataTracer.h"
37#include "arcane/core/datatype/DataTypeTraits.h"
38#include "arcane/core/datatype/DataStorageBuildInfo.h"
39
40#include "arcane/core/VariableArray.h"
41#include "arcane/core/RawCopy.h"
42
43#include "arcane/core/internal/IDataInternal.h"
44#include "arcane/core/internal/IVariableMngInternal.h"
45#include "arcane/core/internal/IVariableInternal.h"
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
50namespace Arcane
51{
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56template <class DataType>
58: public VariableDiff<DataType>
59{
60 using VarDataTypeTraits = VariableDataTypeTraitsT<DataType>;
61 using DiffInfo = typename VariableDiff<DataType>::DiffInfo;
62 static constexpr bool IsNumeric = std::is_same_v<typename VarDataTypeTraits::IsNumeric, TrueType>;
63 using NormType = typename VarDataTypeTraits::NormType;
64
65 public:
66
69 const VariableComparerArgs& compare_args)
70 {
71 const bool compare_ghost = compare_args.isCompareGhost();
72 if (var->itemKind() == IK_Unknown)
73 return _checkAsArray(var, ref, current, compare_args);
74
75 ItemGroup group = var->itemGroup();
76 if (group.null())
77 return {};
78 IMesh* mesh = group.mesh();
79 if (!mesh)
80 return {};
81 ITraceMng* msg = mesh->traceMng();
82 IParallelMng* pm = mesh->parallelMng();
83
84 GroupIndexTable* group_index_table = (var->isPartial()) ? group.localIdToIndex().get() : nullptr;
85
86 int nb_diff = 0;
87 bool compare_failed = false;
88 eVariableComparerComputeDifferenceMethod diff_method = compare_args.computeDifferenceMethod();
89 // No max norm if the type is not numeric.
90 if (!IsNumeric)
92
93 Integer ref_size = ref.size();
94 NormType local_norm_max = {};
95
96 if constexpr (IsNumeric) {
97 bool is_use_local_norm = diff_method == eVariableComparerComputeDifferenceMethod::LocalNormMax;
98 if (is_use_local_norm) {
99 // Large copy-paste to calculate the global norm
100 ENUMERATE_ITEM (i, group) {
101 Item item = *i;
102 if (!item.isOwn() && !compare_ghost)
103 continue;
104 Integer index = item.localId();
105 if (group_index_table) {
106 index = (*group_index_table)[index];
107 if (index < 0)
108 continue;
109 }
110 if (index >= ref_size) {
111 continue;
112 }
113 else {
114 DataType dref = ref[index];
115 NormType norm_max = VarDataTypeTraits::normeMax(dref);
116 if (norm_max > local_norm_max) {
117 local_norm_max = norm_max;
118 }
119 }
120 }
121 }
122 }
123 // We calculate the normalized errors
124 ENUMERATE_ITEM (i, group) {
125 Item item = *i;
126 if (!item.isOwn() && !compare_ghost)
127 continue;
128 Integer index = item.localId();
129 if (group_index_table) {
130 index = (*group_index_table)[index];
131 if (index < 0)
132 continue;
133 }
134 DataType diff = DataType();
135 if (index >= ref_size) {
136 ++nb_diff;
137 compare_failed = true;
138 }
139 else {
140 DataType dref = ref[index];
141 DataType dcurrent = current[index];
142 bool is_diff = _computeDifference(dref, dcurrent, diff, local_norm_max, diff_method);
143 if (is_diff) {
144 this->m_diffs_info.add(DiffInfo(dcurrent, dref, diff, item, NULL_ITEM_ID));
145 ++nb_diff;
146 }
147 }
148 }
149 if (compare_failed) {
150 Int32 sid = pm->commRank();
151 const String& var_name = var->name();
152 msg->pinfo() << "Processor " << sid << " : "
153 << "comparison impossible because the number of the elements is different "
154 << " for the variable " << var_name << " ref_size=" << ref_size;
155 }
156 if (nb_diff != 0)
157 this->_sortAndDump(var, pm, compare_args);
158
159 return VariableComparerResults(nb_diff);
160 }
161
163 checkReplica(IVariable* var, ConstArrayView<DataType> var_value,
164 const VariableComparerArgs& compare_args)
165 {
166 IParallelMng* replica_pm = var->_internalApi()->replicaParallelMng();
167 if (!replica_pm)
168 return {};
169 // Calls the correct specialization to ensure the template type has reduction.
170 using ReduceType = typename VariableDataTypeTraitsT<DataType>::HasReduceMinMax;
171 if constexpr (std::is_same<TrueType, ReduceType>::value)
172 return _checkReplica2(replica_pm, var, var_value, compare_args);
173
174 ARCANE_UNUSED(replica_pm);
175 ARCANE_UNUSED(var);
176 ARCANE_UNUSED(var_value);
177 ARCANE_UNUSED(compare_args);
178 throw NotSupportedException(A_FUNCINFO);
179 }
180
181 private:
182
184 _checkAsArray(IVariable* var, ConstArrayView<DataType> ref, ConstArrayView<DataType> current,
185 const VariableComparerArgs& compare_args)
186 {
187 IParallelMng* pm = var->variableMng()->parallelMng();
188 ITraceMng* msg = pm->traceMng();
189
190 int nb_diff = 0;
191 bool compare_failed = false;
192 Integer ref_size = ref.size();
193 Integer current_size = current.size();
194 eVariableComparerComputeDifferenceMethod diff_method = compare_args.computeDifferenceMethod();
195 // No max norm if the type is not numeric.
196 if (!IsNumeric)
198 NormType local_norm_max = {};
199
200 if constexpr (IsNumeric) {
201 bool is_use_local_norm = compare_args.computeDifferenceMethod() == eVariableComparerComputeDifferenceMethod::LocalNormMax;
202 if (is_use_local_norm) {
203 // Large copy-paste to calculate the global norm
204 for (Integer index = 0; index < current_size; ++index) {
205 if (index >= ref_size) {
206 continue;
207 }
208 else {
209 DataType dref = ref[index];
210 typename VarDataTypeTraits::NormType norm_max = VarDataTypeTraits::normeMax(dref);
211 if (norm_max > local_norm_max) {
212 local_norm_max = norm_max;
213 }
214 }
215 }
216 }
217 }
218 // We calculate the normalized errors
219 for (Integer index = 0; index < current_size; ++index) {
220 DataType diff = DataType();
221 if (index >= ref_size) {
222 ++nb_diff;
223 compare_failed = true;
224 }
225 else {
226 DataType dref = ref[index];
227 DataType dcurrent = current[index];
228 if (_computeDifference(dref, dcurrent, diff, local_norm_max, diff_method)) {
229 this->m_diffs_info.add(DiffInfo(dcurrent, dref, diff, index, NULL_ITEM_ID));
230 ++nb_diff;
231 }
232 }
233 }
234 if (compare_failed) {
235 Int32 sid = pm->commRank();
236 const String& var_name = var->name();
237 msg->pinfo() << "Processor " << sid << " : "
238 << " comparison impossible because the number of elements is different"
239 << " for the variable " << var_name << " ref_size=" << ref_size;
240 }
241 if (nb_diff != 0)
242 this->_sortAndDump(var, pm, compare_args);
243
244 return VariableComparerResults(nb_diff);
245 }
246
248 _checkReplica2(IParallelMng* pm, IVariable* var, ConstArrayView<DataType> var_values,
249 const VariableComparerArgs& compare_args)
250 {
251 ITraceMng* msg = pm->traceMng();
252 Integer size = var_values.size();
253 // Checks that all replicas have the same number of elements for the variable.
254 Integer max_size = pm->reduce(Parallel::ReduceMax, size);
255 Integer min_size = pm->reduce(Parallel::ReduceMin, size);
256 msg->info(5) << "CheckReplica2 rep_size=" << pm->commSize() << " rank=" << pm->commRank();
257 if (max_size != min_size) {
258 const String& var_name = var->name();
259 msg->info() << "Can not compare values on replica for variable '" << var_name << "'"
260 << " because the number of elements is not the same on all the replica "
261 << " min=" << min_size << " max=" << max_size;
262 return VariableComparerResults(max_size);
263 }
264 Integer nb_diff = 0;
265 UniqueArray<DataType> min_values(var_values);
266 UniqueArray<DataType> max_values(var_values);
267 pm->reduce(Parallel::ReduceMax, max_values);
268 pm->reduce(Parallel::ReduceMin, min_values);
269
270 for (Integer index = 0; index < size; ++index) {
271 DataType diff = DataType();
272 DataType min_val = min_values[index];
273 DataType max_val = max_values[index];
274 if (VarDataTypeTraits::verifDifferent(min_val, max_val, diff, true)) {
275 this->m_diffs_info.add(DiffInfo(min_val, max_val, diff, index, NULL_ITEM_ID));
276 ++nb_diff;
277 }
278 }
279 if (nb_diff != 0)
280 this->_sortAndDump(var, pm, compare_args);
281
282 return VariableComparerResults(nb_diff);
283 }
284 bool _computeDifference(const DataType& dref, const DataType& dcurrent, DataType& diff,
285 const NormType& local_norm_max,
287 {
288 bool is_diff = false;
289 switch (diff_method) {
291 is_diff = VarDataTypeTraits::verifDifferent(dref, dcurrent, diff, true);
292 break;
294 is_diff = VarDataTypeTraits::verifDifferentNorm(dref, dcurrent, diff, local_norm_max, true);
295 break;
296 }
297 return is_diff;
298 }
299};
300
301/*---------------------------------------------------------------------------*/
302/*---------------------------------------------------------------------------*/
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
306
307template <typename T> VariableArrayT<T>::
309: Variable(vb, info)
310, m_value(nullptr)
311{
312 IDataFactoryMng* df = vb.dataFactoryMng();
313 DataStorageBuildInfo storage_build_info(vb.traceMng());
314 String storage_full_type = info.storageTypeInfo().fullName();
315 Ref<IData> data = df->createSimpleDataRef(storage_full_type, storage_build_info);
316 m_value = dynamic_cast<ValueDataType*>(data.get());
317 ARCANE_CHECK_POINTER(m_value);
318 _setData(makeRef(m_value));
319}
320
321/*---------------------------------------------------------------------------*/
322/*---------------------------------------------------------------------------*/
323
324template <typename T> VariableArrayT<T>::
326{
327}
328
329/*---------------------------------------------------------------------------*/
330/*---------------------------------------------------------------------------*/
331
332template <typename T> VariableArrayT<T>* VariableArrayT<T>::
333getReference(const VariableBuildInfo& vb, const VariableInfo& vi)
334{
335 if (vb.isNull())
336 return nullptr;
337 ThatClass* true_ptr = nullptr;
338 IVariableMng* vm = vb.variableMng();
339 IVariable* var = vm->checkVariable(vi);
340 if (var)
341 true_ptr = dynamic_cast<ThatClass*>(var);
342 else {
343 true_ptr = new ThatClass(vb, vi);
344 vm->_internalApi()->addVariable(true_ptr);
345 }
346 ARCANE_CHECK_PTR(true_ptr);
347 return true_ptr;
348}
349
350/*---------------------------------------------------------------------------*/
351/*---------------------------------------------------------------------------*/
352
353template <typename T> VariableArrayT<T>* VariableArrayT<T>::
355{
356 if (!var)
357 throw ArgumentException(A_FUNCINFO, "null variable");
358 auto* true_ptr = dynamic_cast<ThatClass*>(var);
359 if (!true_ptr)
360 ARCANE_FATAL("Can not build a reference from variable {0}", var->name());
361 return true_ptr;
362}
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
367template <typename T> void VariableArrayT<T>::
368print(std::ostream& o) const
369{
370 ConstArrayView<T> x(m_value->view());
371 Integer size = x.size();
372 o << "(dimension=" << size << ") ";
373 if (size <= 150) {
374 for (auto& i : x) {
375 o << i << '\n';
376 }
377 }
378}
379
380/*---------------------------------------------------------------------------*/
381/*---------------------------------------------------------------------------*/
382
383template <typename T> void VariableArrayT<T>::
385{
386 if (itemKind() == IK_Unknown)
387 ARCANE_THROW(NotSupportedException, "variable '{0}' is not a mesh variable", fullName());
388 IItemFamily* family = itemGroup().itemFamily();
389 if (!family)
390 ARCANE_FATAL("variable '{0}' without family", fullName());
391 if (isPartial())
392 itemGroup().synchronizer()->synchronize(this);
393 else
394 family->allItemsSynchronizer()->synchronize(this);
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
400template <typename T> void VariableArrayT<T>::
402{
403 if (itemKind() == IK_Unknown)
404 ARCANE_THROW(NotSupportedException, "variable '{0}' is not a mesh variable", fullName());
405 IItemFamily* family = itemGroup().itemFamily();
406 if (!family)
407 ARCANE_FATAL("variable '{0}' without family", fullName());
408 if (isPartial())
409 itemGroup().synchronizer()->synchronize(this, local_ids);
410 else
411 family->allItemsSynchronizer()->synchronize(this, local_ids);
412}
413
414/*---------------------------------------------------------------------------*/
415/*---------------------------------------------------------------------------*/
416
417template <typename T> Real VariableArrayT<T>::
418allocatedMemory() const
419{
420 Real v1 = (Real)(sizeof(T));
421 Real v2 = (Real)(m_value->view().size());
422 return v1 * v2;
423}
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
427
428// Uses a Helper function to specialize the call in the
429// case of the 'Byte' type because ArrayVariableDiff::checkReplica() uses
430// a Min/Max reduction, and this does not exist in MPI for the Byte type.
431namespace
432{
433 template <typename T> VariableComparerResults
434 _checkIfSameOnAllReplicaHelper(IVariable* var, ConstArrayView<T> values,
435 const VariableComparerArgs& compare_args)
436 {
438 return csa.checkReplica(var, values, compare_args);
439 }
440
441 // Specialization for the 'Byte' type which does not support reductions.
442 VariableComparerResults
443 _checkIfSameOnAllReplicaHelper(IVariable* var, ConstArrayView<Byte> values,
444 const VariableComparerArgs& compare_args)
445 {
446 Integer size = values.size();
447 UniqueArray<Integer> int_values(size);
448 for (Integer i = 0; i < size; ++i)
449 int_values[i] = values[i];
450 ArrayVariableDiff<Integer> csa;
451 return csa.checkReplica(var, int_values, compare_args);
452 }
453} // namespace
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
459_compareVariable(const VariableComparerArgs& compare_args)
460{
461 switch (compare_args.compareMode()) {
463
464 if (itemKind() == IK_Particle)
465 return {};
466 IDataReader* reader = compare_args.dataReader();
467 ARCANE_CHECK_POINTER(reader);
468
469 ArrayView<T> from_array(valueView());
470
471 Ref<IArrayDataT<T>> ref_data(m_value->cloneTrueEmptyRef());
472 reader->read(this, ref_data.get());
473
475 VariableComparerResults r = csa.check(this, ref_data->view(), from_array, compare_args);
476 return r;
477 }
479 IItemFamily* family = itemGroup().itemFamily();
480 if (!family)
481 return {};
482 ValueType& data_values = m_value->_internal()->_internalDeprecatedValue();
483 UniqueArray<T> ref_array(constValueView());
484 this->synchronize(); // works for all variables
486 ConstArrayView<T> from_array(constValueView());
487 VariableComparerResults r = csa.check(this, ref_array, from_array, compare_args);
488 data_values.copy(ref_array);
489 return r;
490 }
492 VariableComparerResults r = _checkIfSameOnAllReplicaHelper(this, constValueView(), compare_args);
493 return r;
494 }
495 }
496 ARCANE_FATAL("Invalid value for compare mode '{0}'", (int)compare_args.compareMode());
497}
498
499/*---------------------------------------------------------------------------*/
500/*---------------------------------------------------------------------------*/
501
515template <typename T> bool VariableArrayT<T>::
516initialize(const ItemGroup& group, const String& value)
517{
518 //TODO: maybe check if the variable is used?
519
520 // Tries to convert value into a value of the variable's type.
521 T v = T();
522 bool is_bad = VariableDataTypeTraitsT<T>::getValue(v, value);
523
524 if (is_bad) {
525 error() << String::format("Can not convert the string '{0}' to type '{1}'",
526 value, dataType());
527 return true;
528 }
529
530 bool is_ok = false;
531
532 ArrayView<T> values(m_value->view());
533 if (group.itemFamily() == itemFamily()) {
534 is_ok = true;
535 // VERY IMPORTANT
536 //TODO must use an indirection and a hierarchy between groups
537 // Finally, assign the value \a v to all entities in the group.
538 //ValueType& var_value = this->value();
539 ENUMERATE_ITEM (i, group) {
540 Item elem = *i;
541 values[elem.localId()] = v;
542 }
543 }
544
545 if (is_ok)
546 return false;
547
548 eItemKind group_kind = group.itemKind();
549
550 error() << "The type of elements (" << itemKindName(group_kind)
551 << ") of the group `" << group.name() << "' does not match "
552 << "the type of the variable (" << itemKindName(this->itemKind()) << ").";
553 return true;
554}
555
556/*---------------------------------------------------------------------------*/
557/*---------------------------------------------------------------------------*/
558
559template <typename T> void VariableArrayT<T>::
561{
562 ARCANE_ASSERT(source.size() == destination.size(),
563 ("Impossible to copy: source and destination of different sizes !"));
564 ArrayView<T> value = m_value->view();
565 const Integer size = source.size();
566 for (Integer i = 0; i < size; ++i)
567 value[destination[i]] = value[source[i]];
569}
570
571/*---------------------------------------------------------------------------*/
572/*---------------------------------------------------------------------------*/
573
574template <typename T> void VariableArrayT<T>::
576 Int32ConstArrayView second_source,
577 Int32ConstArrayView destination)
578{
579 ARCANE_ASSERT((first_source.size() == destination.size()) && (second_source.size() == destination.size()),
580 ("Impossible to copy: source and destination of different sizes !"));
581 ArrayView<T> value = m_value->view();
582 const Integer size = first_source.size();
583 for (Integer i = 0; i < size; ++i) {
584 value[destination[i]] = (T)((value[first_source[i]] + value[second_source[i]]) / 2);
585 }
587}
588
589/*---------------------------------------------------------------------------*/
590/*---------------------------------------------------------------------------*/
591
594 Int32ConstArrayView second_source,
595 Int32ConstArrayView destination);
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
600template <typename T> void VariableArrayT<T>::
601compact(Int32ConstArrayView new_to_old_ids)
602{
603 if (isPartial()) {
604 debug(Trace::High) << "Skip compact for partial variable " << name();
605 return;
606 }
607
608 UniqueArray<T> old_value(constValueView());
609 Integer new_size = new_to_old_ids.size();
610 m_value->resize(new_size);
611 ArrayView<T> current_value = m_value->view();
612 if (arcaneIsCheck()) {
613 for (Integer i = 0; i < new_size; ++i)
614 current_value.setAt(i, old_value.at(new_to_old_ids[i]));
615 }
616 else {
617 for (Integer i = 0; i < new_size; ++i)
618 RawCopy<T>::copy(current_value[i], old_value[new_to_old_ids[i]]); // current_value[i] = old_value[ new_to_old_ids[i] ];
619 }
621}
622
623/*---------------------------------------------------------------------------*/
624/*---------------------------------------------------------------------------*/
625
626template <typename T> void VariableArrayT<T>::
628{
630}
631
632/*---------------------------------------------------------------------------*/
633/*---------------------------------------------------------------------------*/
634
635template <typename T> void VariableArrayT<T>::
636setIsSynchronized(const ItemGroup& group)
637{
638 ARCANE_UNUSED(group);
639}
640
641/*---------------------------------------------------------------------------*/
642/*---------------------------------------------------------------------------*/
643
644template <typename T> void VariableArrayT<T>::
645_internalResize(const VariableResizeArgs& resize_args)
646{
647 Int32 new_size = resize_args.newSize();
648 Int32 nb_additional_element = resize_args.nbAdditionalCapacity();
649 bool use_no_init = resize_args.isUseNoInit();
650
651 auto* value_internal = m_value->_internal();
652
653 //const bool is_collective_allocator = value_internal->memoryAllocator().isCollectiveAllocator();
654 const bool is_collective_allocator = value_internal->_internalDeprecatedValue().allocator()->isCollective();
655 if (is_collective_allocator) {
656 value_internal->reserve(new_size + nb_additional_element);
657 }
658 else if (nb_additional_element != 0) {
659 Integer capacity = value_internal->capacity();
660 if (new_size > capacity)
661 value_internal->reserve(new_size + nb_additional_element);
662 }
664 // If the new size is greater than the old one,
665 // initialize the new elements following
666 // the desired policy
667 Integer current_size = m_value->view().size();
668 if (!isUsed()) {
669 // If the variable is no longer used, free the memory
670 // associated with it.
671 value_internal->dispose();
672 }
673 if (use_no_init)
674 value_internal->_internalDeprecatedValue().resizeNoInit(new_size);
675 else
676 value_internal->resize(new_size);
677 if (new_size > current_size) {
678 if (init_policy == DIP_InitWithDefault) {
679 ArrayView<T> values = this->valueView();
680 for (Integer i = current_size; i < new_size; ++i)
681 values[i] = T();
682 }
683 else {
684 bool use_nan = (init_policy == DIP_InitWithNan);
685 bool use_nan2 = (init_policy == DIP_InitInitialWithNanResizeWithDefault) && !_hasValidData();
686 if (use_nan || use_nan2) {
687 ArrayView<T> view = this->valueView();
688 DataTypeTraitsT<T>::fillNan(view.subView(current_size, new_size - current_size));
689 }
690 }
691 }
692
693 // Compresses the memory if requested
694 if (_wantShrink()) {
695 if (m_value->view().size() < value_internal->capacity()) {
696 value_internal->shrink();
697 }
698 }
699
700 // Checks if all modifications after the dispose have not altered the allocation state
701 // In the case of an unused variable, the maximum allowed capacity is
702 // equal to that of a platform SIMD vector.
703 // (this cannot be 0 because the Array class must allocate at least one
704 // element if a specific allocator is used, which is the case
705 // for variables.
706 Int64 capacity = value_internal->capacity();
707 if (!((isUsed() || capacity <= AlignedMemoryAllocator::simdAlignment())))
708 ARCANE_FATAL("Wrong unused data size {0}", capacity);
709}
710
711/*---------------------------------------------------------------------------*/
712/*---------------------------------------------------------------------------*/
713
714template <typename DataType> void VariableArrayT<DataType>::
715resizeWithReserve(Integer n, Integer nb_additional)
716{
717 _resize(VariableResizeArgs(n, nb_additional));
718}
719
720/*---------------------------------------------------------------------------*/
721/*---------------------------------------------------------------------------*/
722
723template <typename DataType> void VariableArrayT<DataType>::
725{
726 m_value->_internal()->shrink();
728}
729
730/*---------------------------------------------------------------------------*/
731/*---------------------------------------------------------------------------*/
732
733template <typename DataType> Integer VariableArrayT<DataType>::
734capacity()
735{
736 return m_value->_internal()->capacity();
737}
738
739/*---------------------------------------------------------------------------*/
740/*---------------------------------------------------------------------------*/
741
742template <typename DataType> void VariableArrayT<DataType>::
743fill(const DataType& value)
744{
745 m_value->view().fill(value);
746}
747
748/*---------------------------------------------------------------------------*/
749/*---------------------------------------------------------------------------*/
750
751template <typename DataType> void VariableArrayT<DataType>::
752fill(const DataType& value, const ItemGroup& group)
753{
754 ARCANE_UNUSED(group);
755 this->fill(value);
756}
757
758/*---------------------------------------------------------------------------*/
759/*---------------------------------------------------------------------------*/
760
761template <typename DataType> void
763swapValues(ThatClass& rhs)
764{
765 _checkSwapIsValid(&rhs);
766 // TODO: check if both variables must have the same number
767 // of elements, but it doesn't seem necessary a priori.
768 m_value->swapValues(rhs.m_value);
769 // References must be updated for this variable and \a rhs.
770 syncReferences();
771 rhs.syncReferences();
772}
773
774/*---------------------------------------------------------------------------*/
775/*---------------------------------------------------------------------------*/
776
777// SDP: Specialization
780 Int32ConstArrayView second_source,
781 Int32ConstArrayView destination)
782{
783 Integer dsize = destination.size();
784 bool is_ok = (first_source.size() == dsize) && (second_source.size() == dsize);
785 if (!is_ok)
786 ARCANE_FATAL("Unable to copy: source and destination of different sizes !");
787
788 ArrayView<String> value = m_value->view();
789 const Integer size = first_source.size();
790 for (Integer i = 0; i < size; ++i)
791 value[destination[i]] = value[first_source[i]];
793}
794
795/*---------------------------------------------------------------------------*/
796/*---------------------------------------------------------------------------*/
797
798template <typename DataType> auto VariableArrayT<DataType>::
799value() -> ValueType&
800{
801 return m_value->_internal()->_internalDeprecatedValue();
802}
803
804/*---------------------------------------------------------------------------*/
805/*---------------------------------------------------------------------------*/
806
807ARCANE_INTERNAL_INSTANTIATE_TEMPLATE_FOR_NUMERIC_DATATYPE(VariableArrayT);
808template class VariableArrayT<String>;
809
810/*---------------------------------------------------------------------------*/
811/*---------------------------------------------------------------------------*/
812
813} // End namespace Arcane
814
815/*---------------------------------------------------------------------------*/
816/*---------------------------------------------------------------------------*/
#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'.
Base class of a hash table between group items and their positions in the table.
Interface of the data factory manager.
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 * replicaParallelMng() const =0
Returns the IParallelMng of the mesh replica associated with the variable.
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).
Implementation of a variable on a 1D array.
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.
Template class for information about a variable type.
Base class for value comparisons between two variables.
Information characterizing a variable.
Arguments for resizing a variable.
Variable(const VariableBuildInfo &v, const VariableInfo &vi)
Creates a variable linked to the reference v.
Definition Variable.cc:344
void _setData(const Ref< IData > &data)
Positions the data.
Definition Variable.cc:918
bool isPartial() const override
Indicates if the variable is partial.
Definition Variable.cc:900
IVariableMng * variableMng() const override
Variable manager associated with the variable.
Definition Variable.cc:475
String name() const final
Variable name.
Definition Variable.cc:484
ItemGroup itemGroup() const final
Associated mesh group.
Definition Variable.cc:864
void syncReferences() override
Synchronizes references.
Definition Variable.cc:786
String fullName() const final
Full variable name (with family prefix).
Definition Variable.cc:493
eItemKind itemKind() const override
Kind of mesh entities on which the variable is based.
Definition Variable.cc:873
IItemFamily * itemFamily() const final
Associated entity family.
Definition Variable.cc:909
eDataType dataType() const override
Data type managed by the variable (Real, Integer, ...).
Definition Variable.cc:529
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:482
@ 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.