Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MeshComponentPartData.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* Données d'une partie (pure ou partielle) d'un constituant. */
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"
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 * \brief Notification de changement des m_values_indexes.
70 *
71 * Applique le padding pour la vectorisation sur les valueIndex() si nécessaire.
72 * \a queue peut-être nul.
73 */
74void MeshComponentPartData::
75_notifyValueIndexesChanged(RunQueue* queue)
76{
77 FixedArray<Span<Int32>, 2> indexes;
78 indexes[0] = m_value_indexes[0].span();
79 indexes[1] = m_value_indexes[1].span();
80
81 bool is_need_padding = false;
82 for (Int32 i = 0; i < 2; ++i)
83 is_need_padding |= ArraySimdPadder::isNeedPadding(Span<const Int32>(indexes[i]));
84
85 if (!is_need_padding)
86 return;
87
88 if (queue) {
89 auto command = makeCommand(queue);
90 command << RUNCOMMAND_LOOP1(iter, 2)
91 {
92 auto [i] = iter();
93 ArraySimdPadder::applySimdPaddingView(indexes[i]);
94 };
95 }
96 else {
97 ArraySimdPadder::applySimdPaddingView(indexes[0]);
98 ArraySimdPadder::applySimdPaddingView(indexes[1]);
99 }
100}
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
105void MeshComponentPartData::
106_setFromMatVarIndexes(ConstArrayView<MatVarIndex> matvar_indexes, RunQueue& queue)
107{
108 Int32 nb_index = matvar_indexes.size();
109
110 Int32Array& pure_indexes = m_value_indexes[(Int32)eMatPart::Pure];
111 Int32Array& impure_indexes = m_value_indexes[(Int32)eMatPart::Impure];
112
113 Int32Array& pure_internal_indexes = m_items_internal_indexes[(Int32)eMatPart::Pure];
114 Int32Array& impure_internal_indexes = m_items_internal_indexes[(Int32)eMatPart::Impure];
115
116 pure_indexes.resize(nb_index);
117 pure_internal_indexes.resize(nb_index);
118
119 // TODO: Faire une première passe pour calculer le nombre de valeurs pures
120 // et ainsi allouer directement à la bonne taille.
121 info(4) << "BEGIN_BUILD_PART_DATA_FOR_COMPONENT c=" << m_component->name();
122 Accelerator::GenericFilterer filterer(queue);
123
124 Int32 nb_impure = 0;
125 {
126 SmallSpan<Int32> pure_indexes_view(pure_indexes.view());
127 SmallSpan<Int32> pure_internal_indexes_view(pure_internal_indexes.view());
128
129 auto is_pure_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i) -> bool {
130 return matvar_indexes[i].arrayIndex() == 0;
131 };
132 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i, Int32 output_index) {
133 pure_indexes_view[output_index] = matvar_indexes[i].valueIndex();
134 pure_internal_indexes_view[output_index] = i;
135 };
136 filterer.applyWithIndex(nb_index, is_pure_lambda, setter_lambda, A_FUNCINFO);
137 Int32 nb_out = filterer.nbOutputElement();
138 pure_indexes.resize(nb_out);
139 pure_internal_indexes.resize(nb_out);
140 nb_impure = nb_index - nb_out;
141 }
142
143 impure_indexes.resize(nb_impure);
144 impure_internal_indexes.resize(nb_impure);
145
146 {
147 SmallSpan<Int32> impure_indexes_view(impure_indexes.view());
148 SmallSpan<Int32> impure_internal_indexes_view(impure_internal_indexes.view());
149 auto is_impure_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i) -> bool {
150 return matvar_indexes[i].arrayIndex() != 0;
151 };
152 auto setter_lambda = [=] ARCCORE_HOST_DEVICE(Int32 i, Int32 output_index) {
153 impure_indexes_view[output_index] = matvar_indexes[i].valueIndex();
154 impure_internal_indexes_view[output_index] = i;
155 };
156 filterer.applyWithIndex(nb_index, is_impure_lambda, setter_lambda, A_FUNCINFO);
157 filterer.nbOutputElement();
158 }
159
160 info(4) << "BUILD_PART_DATA_FOR_COMPONENT c=" << m_component->name()
161 << " nb_pure=" << pure_indexes.size()
162 << " nb_impure=" << impure_indexes.size();
163
164 _notifyValueIndexesChanged(&queue);
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170void MeshComponentPartData::
171_setFromMatVarIndexes(ConstArrayView<MatVarIndex> globals,
172 ConstArrayView<MatVarIndex> multiples)
173{
174 Integer nb_global = globals.size();
175 Integer nb_multiple = multiples.size();
176
177 {
178 const auto mat_part = static_cast<Int32>(eMatPart::Pure);
179 Int32Array& idx = m_value_indexes[mat_part];
180 idx.resize(nb_global);
181 for (Integer i = 0; i < nb_global; ++i)
182 idx[i] = globals[i].valueIndex();
183 }
184
185 {
186 const auto mat_part = static_cast<Int32>(eMatPart::Impure);
187 Int32Array& idx = m_value_indexes[mat_part];
188 idx.resize(nb_multiple);
189 for (Integer i = 0; i < nb_multiple; ++i)
190 idx[i] = multiples[i].valueIndex();
191 }
192
193 _notifyValueIndexesChanged(nullptr);
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
199void MeshComponentPartData::
200_setConstituentListView(const ConstituentItemLocalIdListView& v)
201{
202 m_constituent_list_view = v;
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208void MeshComponentPartData::
209checkValid()
210{
211 info(4) << "CHECK_VALID_COMPONENT_PART_DATA c=" << m_component->name();
212 _checkNeedRecompute();
213 ValueChecker vc(A_FUNCINFO);
214 Integer nb_error = 0;
215 for (Integer i = 0; i < 2; ++i) {
216 Int32 var_idx = (i == 0) ? 0 : m_impure_var_idx;
217 Int32ConstArrayView indexes = m_value_indexes[i];
218 Int32ConstArrayView item_indexes = m_items_internal_indexes[i];
219 Integer nb_item = indexes.size();
220 vc.areEqual(nb_item, item_indexes.size(), "Indexes size");
221 for (Integer k = 0; k < nb_item; ++k) {
222 MatVarIndex mvi(var_idx, indexes[k]);
223 MatVarIndex component_mvi = m_constituent_list_view._matVarIndex(item_indexes[k]);
224 if (mvi != component_mvi) {
225 info() << "Bad MatVarIndex i=" << i << " k=" << k
226 << " mvi=" << mvi << " component_mvi=" << component_mvi;
227 ++nb_error;
228 }
229 }
230 }
231 if (nb_error != 0)
232 ARCANE_FATAL("Bad component part data nb_error={0}", nb_error);
233}
234
235/*---------------------------------------------------------------------------*/
236/*---------------------------------------------------------------------------*/
237
238void MeshComponentPartData::
239_checkNeedRecompute()
240{
241 if (!m_is_need_recompute)
242 return;
243 if (!m_compute_functor)
244 ARCANE_FATAL("No compute functor");
245 m_compute_functor->executeFunctor();
246 m_is_need_recompute = false;
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
252ComponentPartItemVectorView MeshComponentPartData::
253partView(eMatPart part)
254{
255 _checkNeedRecompute();
256 const auto mat_part = static_cast<Int32>(part);
257 Int32ConstArrayView value_indexes = m_value_indexes[mat_part];
258 Int32ConstArrayView item_indexes = m_items_internal_indexes[mat_part];
259 Int32 var_idx = (part == eMatPart::Pure) ? 0 : impureVarIdx();
260 return { m_component, var_idx, value_indexes,
261 item_indexes, m_constituent_list_view, part };
262}
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
267ComponentPurePartItemVectorView MeshComponentPartData::
268pureView()
269{
270 _checkNeedRecompute();
271 const auto mat_part = static_cast<Int32>(eMatPart::Pure);
272 Int32ConstArrayView value_indexes = m_value_indexes[mat_part];
273 Int32ConstArrayView item_indexes = m_items_internal_indexes[mat_part];
274 return { m_component, value_indexes,
275 item_indexes, m_constituent_list_view };
276}
277
278/*---------------------------------------------------------------------------*/
279/*---------------------------------------------------------------------------*/
280
281ComponentImpurePartItemVectorView MeshComponentPartData::
282impureView()
283{
284 _checkNeedRecompute();
285 const auto mat_part = static_cast<Int32>(eMatPart::Impure);
286 Int32ConstArrayView value_indexes = m_value_indexes[mat_part];
287 Int32ConstArrayView item_indexes = m_items_internal_indexes[mat_part];
288 const Int32 var_idx = impureVarIdx();
289 return { m_component, var_idx, value_indexes,
290 item_indexes, m_constituent_list_view };
291}
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
296} // End namespace Arcane::Materials
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour gérer les boucles sur les accélérateurs.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle sur accélérateur avec arguments supplémentaires pour les réductions.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
Active toujours les traces dans les parties Arcane concernant les matériaux.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:327
Int32 Integer
Type représentant un entier.