Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MeshComponentPartData.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/* MeshComponentPartData.cc (C) 2000-2024 */
9/* */
10/* Data of a part (pure or partial) of a constituent. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/FatalErrorException.h"
15#include "arcane/utils/ValueChecker.h"
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/ArraySimdPadder.h"
18#include "arcane/utils/IFunctor.h"
19
20#include "arcane/core/IItemFamily.h"
21
22#include "arcane/core/materials/IMeshComponent.h"
23#include "arcane/core/materials/ComponentItemInternal.h"
24#include "arcane/core/materials/ComponentPartItemVectorView.h"
25#include "arcane/core/materials/internal/IMeshComponentInternal.h"
26
27#include "arcane/materials/internal/MeshComponentPartData.h"
28
29#include "arcane/accelerator/Filter.h"
30#include "arcane/accelerator/RunCommandLoop.h"
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane::Materials
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
41MeshComponentPartData::
42MeshComponentPartData(IMeshComponent* component, const String& debug_name)
43: TraceAccessor(component->traceMng())
44, m_component(component)
45, m_impure_var_idx(component->_internalApi()->variableIndexerIndex() + 1)
46{
47 // Utilise l'allocateur des données pour permettre d'accéder à ces valeurs
48 // sur les accélérateurs
49 IMemoryAllocator* allocator = platform::getDefaultDataAllocator();
50 for (Integer i = 0; i < 2; ++i) {
51 m_value_indexes[i] = UniqueArray<Int32>(allocator);
52 m_items_internal_indexes[i] = UniqueArray<Int32>(allocator);
53 }
54 if (!debug_name.empty()) {
55 String base_name = String("MeshComponentPartData") + debug_name;
56 for (Integer i = 0; i < 2; ++i) {
57 m_value_indexes[i].setDebugName(base_name + "ValueIndexes" + String::fromNumber(i));
58 m_items_internal_indexes[i].setDebugName(base_name + "ValueIndexes" + String::fromNumber(i));
59 }
60 }
61}
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69/*!
70 * \brief Notification of changes to m_values_indexes.
71 *
72 * Applies padding for vectorization on valueIndex() if necessary.
73 * \a queue may be null.
74 */
75void MeshComponentPartData::
76_notifyValueIndexesChanged(RunQueue* queue)
77{
78 FixedArray<Span<Int32>, 2> indexes;
79 indexes[0] = m_value_indexes[0].span();
80 indexes[1] = m_value_indexes[1].span();
81
82 bool is_need_padding = false;
83 for (Int32 i = 0; i < 2; ++i)
84 is_need_padding |= ArraySimdPadder::isNeedPadding(Span<const Int32>(indexes[i]));
85
86 if (!is_need_padding)
87 return;
88
89 if (queue) {
90 auto command = makeCommand(queue);
91 command << RUNCOMMAND_LOOP1(iter, 2)
92 {
93 auto [i] = iter();
94 ArraySimdPadder::applySimdPaddingView(indexes[i]);
95 };
96 }
97 else {
98 ArraySimdPadder::applySimdPaddingView(indexes[0]);
99 ArraySimdPadder::applySimdPaddingView(indexes[1]);
100 }
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106void MeshComponentPartData::
107_setFromMatVarIndexes(ConstArrayView<MatVarIndex> matvar_indexes, RunQueue& queue)
108{
109 Int32 nb_index = matvar_indexes.size();
110
111 Int32Array& pure_indexes = m_value_indexes[(Int32)eMatPart::Pure];
112 Int32Array& impure_indexes = m_value_indexes[(Int32)eMatPart::Impure];
113
114 Int32Array& pure_internal_indexes = m_items_internal_indexes[(Int32)eMatPart::Pure];
115 Int32Array& impure_internal_indexes = m_items_internal_indexes[(Int32)eMatPart::Impure];
116
117 pure_indexes.resize(nb_index);
118 pure_internal_indexes.resize(nb_index);
119
120 // TODO: Perform a first pass to calculate the number of pure values
121 // and thus allocate directly to the correct size.
122 info(4) << "BEGIN_BUILD_PART_DATA_FOR_COMPONENT c=" << m_component->name();
123 Accelerator::GenericFilterer filterer(queue);
124
125 Int32 nb_impure = 0;
126 {
127 SmallSpan<Int32> pure_indexes_view(pure_indexes.view());
128 SmallSpan<Int32> pure_internal_indexes_view(pure_internal_indexes.view());
129
130 auto is_pure_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i) -> bool {
131 return matvar_indexes[i].arrayIndex() == 0;
132 };
133 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i, Int32 output_index) {
134 pure_indexes_view[output_index] = matvar_indexes[i].valueIndex();
135 pure_internal_indexes_view[output_index] = i;
136 };
137 filterer.applyWithIndex(nb_index, is_pure_lambda, setter_lambda, A_FUNCINFO);
138 Int32 nb_out = filterer.nbOutputElement();
139 pure_indexes.resize(nb_out);
140 pure_internal_indexes.resize(nb_out);
141 nb_impure = nb_index - nb_out;
142 }
143
144 impure_indexes.resize(nb_impure);
145 impure_internal_indexes.resize(nb_impure);
146
147 {
148 SmallSpan<Int32> impure_indexes_view(impure_indexes.view());
149 SmallSpan<Int32> impure_internal_indexes_view(impure_internal_indexes.view());
150 auto is_impure_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i) -> bool {
151 return matvar_indexes[i].arrayIndex() != 0;
152 };
153 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i, Int32 output_index) {
154 impure_indexes_view[output_index] = matvar_indexes[i].valueIndex();
155 impure_internal_indexes_view[output_index] = i;
156 };
157 filterer.applyWithIndex(nb_index, is_impure_lambda, setter_lambda, A_FUNCINFO);
158 filterer.nbOutputElement();
159 }
160
161 info(4) << "BUILD_PART_DATA_FOR_COMPONENT c=" << m_component->name()
162 << " nb_pure=" << pure_indexes.size()
163 << " nb_impure=" << impure_indexes.size();
164
165 _notifyValueIndexesChanged(&queue);
166}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
171void MeshComponentPartData::
172_setFromMatVarIndexes(ConstArrayView<MatVarIndex> globals,
173 ConstArrayView<MatVarIndex> multiples)
174{
175 Integer nb_global = globals.size();
176 Integer nb_multiple = multiples.size();
177
178 {
179 const auto mat_part = static_cast<Int32>(eMatPart::Pure);
180 Int32Array& idx = m_value_indexes[mat_part];
181 idx.resize(nb_global);
182 for (Integer i = 0; i < nb_global; ++i)
183 idx[i] = globals[i].valueIndex();
184 }
185
186 {
187 const auto mat_part = static_cast<Int32>(eMatPart::Impure);
188 Int32Array& idx = m_value_indexes[mat_part];
189 idx.resize(nb_multiple);
190 for (Integer i = 0; i < nb_multiple; ++i)
191 idx[i] = multiples[i].valueIndex();
192 }
193
194 _notifyValueIndexesChanged(nullptr);
195}
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
200void MeshComponentPartData::
201_setConstituentListView(const ConstituentItemLocalIdListView& v)
202{
203 m_constituent_list_view = v;
204}
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
209void MeshComponentPartData::
210checkValid()
211{
212 info(4) << "CHECK_VALID_COMPONENT_PART_DATA c=" << m_component->name();
213 _checkNeedRecompute();
214 ValueChecker vc(A_FUNCINFO);
215 Integer nb_error = 0;
216 for (Integer i = 0; i < 2; ++i) {
217 Int32 var_idx = (i == 0) ? 0 : m_impure_var_idx;
218 Int32ConstArrayView indexes = m_value_indexes[i];
219 Int32ConstArrayView item_indexes = m_items_internal_indexes[i];
220 Integer nb_item = indexes.size();
221 vc.areEqual(nb_item, item_indexes.size(), "Indexes size");
222 for (Integer k = 0; k < nb_item; ++k) {
223 MatVarIndex mvi(var_idx, indexes[k]);
224 MatVarIndex component_mvi = m_constituent_list_view._matVarIndex(item_indexes[k]);
225 if (mvi != component_mvi) {
226 info() << "Bad MatVarIndex i=" << i << " k=" << k
227 << " mvi=" << mvi << " component_mvi=" << component_mvi;
228 ++nb_error;
229 }
230 }
231 }
232 if (nb_error != 0)
233 ARCANE_FATAL("Bad component part data nb_error={0}", nb_error);
234}
235
236/*---------------------------------------------------------------------------*/
237/*---------------------------------------------------------------------------*/
238
239void MeshComponentPartData::
240_checkNeedRecompute()
241{
242 if (!m_is_need_recompute)
243 return;
244 if (!m_compute_functor)
245 ARCANE_FATAL("No compute functor");
246 m_compute_functor->executeFunctor();
247 m_is_need_recompute = false;
248}
249
250/*---------------------------------------------------------------------------*/
251/*---------------------------------------------------------------------------*/
252
253ComponentPartItemVectorView MeshComponentPartData::
254partView(eMatPart part)
255{
256 _checkNeedRecompute();
257 const auto mat_part = static_cast<Int32>(part);
258 Int32ConstArrayView value_indexes = m_value_indexes[mat_part];
259 Int32ConstArrayView item_indexes = m_items_internal_indexes[mat_part];
260 Int32 var_idx = (part == eMatPart::Pure) ? 0 : impureVarIdx();
261 return { m_component, var_idx, value_indexes,
262 item_indexes, m_constituent_list_view, part };
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
268ComponentPurePartItemVectorView MeshComponentPartData::
269pureView()
270{
271 _checkNeedRecompute();
272 const auto mat_part = static_cast<Int32>(eMatPart::Pure);
273 Int32ConstArrayView value_indexes = m_value_indexes[mat_part];
274 Int32ConstArrayView item_indexes = m_items_internal_indexes[mat_part];
275 return { m_component, value_indexes,
276 item_indexes, m_constituent_list_view };
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
282ComponentImpurePartItemVectorView MeshComponentPartData::
283impureView()
284{
285 _checkNeedRecompute();
286 const auto mat_part = static_cast<Int32>(eMatPart::Impure);
287 Int32ConstArrayView value_indexes = m_value_indexes[mat_part];
288 Int32ConstArrayView item_indexes = m_items_internal_indexes[mat_part];
289 const Int32 var_idx = impureVarIdx();
290 return { m_component, var_idx, value_indexes,
291 item_indexes, m_constituent_list_view };
292}
293
294/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297} // End namespace Arcane::Materials
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
1D loop on accelerator with additional arguments.
void resize(Int64 s)
Changes the number of elements in the array to s.
Interface of a component (material or environment) of a mesh.
RunCommand makeCommand(const RunQueue &run_queue)
Creates a command associated with the queue run_queue.
Always enables tracing in Arcane parts concerning materials.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.
Definition UtilsTypes.h:127