Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
AllCellToAllEnvCellConverter.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/* AllCellToAllEnvCellConverter.cc (C) 2000-2024 */
9/* */
10/* Conversion of 'Cell' to 'AllEnvCell'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/AllCellToAllEnvCellConverter.h"
15
16#include "arcane/utils/NumArray.h"
17
18#include "arcane/core/IItemFamily.h"
20#include "arcane/core/ItemGroup.h"
21#include "arcane/core/materials/internal/IMeshMaterialMngInternal.h"
22
23#include "arcane/materials/internal/AllCellToAllEnvCellContainer.h"
24
25#include "arcane/accelerator/Reduce.h"
27#include "arcane/accelerator/NumArrayViews.h"
28
29#include <algorithm>
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::Materials
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
41{
42 public:
43
44 explicit Impl(IMeshMaterialMng* mm)
45 : m_material_mng(mm)
46 {
47 m_mem_pool.setDebugName("AllCellToAllEnvCellMemPool");
48 m_envcell_container.setDebugName("AllCellToAllEnvCellCells");
49 }
50
51 public:
52
54 void initialize();
55 void bruteForceUpdate();
56 void reset();
57 AllCellToAllEnvCell view() const { return m_all_cell_to_all_env_cell; }
58
59 public:
60
61 static void updateValues(IMeshMaterialMng* material_mng,
63 Span<Span<ComponentItemLocalId>> allcell_allenvcell,
64 Int32 max_nb_env);
65
66 private:
67
68 IMeshMaterialMng* m_material_mng = nullptr;
69 Int32 m_size = 0;
70 NumArray<Span<ComponentItemLocalId>, MDDim1> m_envcell_container;
72 Int32 m_current_max_nb_env = 0;
73 AllCellToAllEnvCell m_all_cell_to_all_env_cell;
74};
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79Int32 AllCellToAllEnvCellContainer::Impl::
80computeMaxNbEnvPerCell()
81{
82 IMeshMaterialMng* material_mng = m_material_mng;
83 CellToAllEnvCellConverter allenvcell_converter(material_mng);
84 RunQueue& queue = material_mng->_internalApi()->runQueue();
86 auto local_ids = material_mng->mesh()->allCells().internal()->itemsLocalId();
87 Int32 nb_item = local_ids.size();
88 auto select_func = [=] ARCCORE_HOST_DEVICE(Int32 i) -> Int32 {
89 CellLocalId lid(local_ids[i]);
90 AllEnvCell all_env_cell = allenvcell_converter[lid];
91 return all_env_cell.nbEnvironment();
92 };
93 reducer.applyMaxWithIndex(nb_item, select_func);
94 Int32 max_nb_env = reducer.reducedValue();
95 return max_nb_env;
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101void AllCellToAllEnvCellContainer::Impl::
102updateValues(IMeshMaterialMng* material_mng,
104 Span<Span<ComponentItemLocalId>> allcell_allenvcell,
105 Int32 max_nb_env)
106{
107 // update values
108 CellToAllEnvCellConverter all_env_cell_converter(material_mng);
109 RunQueue& queue = material_mng->_internalApi()->runQueue();
110 auto command = makeCommand(queue);
111 command << RUNCOMMAND_ENUMERATE (CellLocalId, cid, material_mng->mesh()->allCells())
112 {
113 AllEnvCell all_env_cell = all_env_cell_converter[cid];
114 Integer offset = cid * max_nb_env;
115 Int32 nb_env = all_env_cell.nbEnvironment();
116 // Initialize the indices of my cell's 'mem_pools' to zero.
117 for (Int32 x = 0; x < max_nb_env; ++x)
118 mem_pool[offset + x] = ComponentItemLocalId();
119 if (nb_env != 0) {
120 Integer i = 0;
121 for (EnvCell ev : all_env_cell.subEnvItems()) {
122 mem_pool[offset + i] = ComponentItemLocalId(ev._varIndex());
123 ++i;
124 }
125 allcell_allenvcell[cid] = Span<ComponentItemLocalId>(mem_pool.ptrAt(offset), nb_env);
126 }
127 else {
128 allcell_allenvcell[cid] = {};
129 }
130 };
131}
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135
136void AllCellToAllEnvCellContainer::Impl::
137initialize()
138{
139 IMeshMaterialMng* mm = m_material_mng;
140 RunQueue queue = mm->_internalApi()->runQueue();
141 m_size = mm->mesh()->cellFamily()->maxLocalId() + 1;
142
143 m_envcell_container.resize(m_size);
144 m_all_cell_to_all_env_cell.m_allcell_allenvcell_ptr = m_envcell_container.to1DSpan();
145
146 // We force the initial value on all elements because in the ENUMERATE_CELL below
147 // m_size (which equals maxLocalId()+1) might be different from allCells().size()
148 m_envcell_container.fill(Span<ComponentItemLocalId>(), &queue);
149
150 m_current_max_nb_env = computeMaxNbEnvPerCell();
151 // TODO: check for overflow
152 Int32 pool_size = m_current_max_nb_env * m_size;
153 m_mem_pool.resize(pool_size);
154 m_mem_pool.fill(ComponentItemLocalId(), &queue);
155
156 Span<ComponentItemLocalId> mem_pool_view(m_mem_pool.to1DSpan());
157 CellToAllEnvCellConverter all_env_cell_converter(mm);
158 auto command = makeCommand(queue);
159 auto mem_pool = viewOut(command, m_mem_pool);
160 auto allcell_allenvcell = viewOut(command, m_envcell_container);
161 const Int32 max_nb_env = m_current_max_nb_env;
162 command << RUNCOMMAND_ENUMERATE (CellLocalId, cid, mm->mesh()->allCells())
163 {
164 AllEnvCell all_env_cell = all_env_cell_converter[CellLocalId(cid)];
165 Integer nb_env(all_env_cell.nbEnvironment());
166 if (nb_env != 0) {
167 Integer i = 0;
168 Integer offset(cid * max_nb_env);
169 ENUMERATE_CELL_ENVCELL (ienvcell, all_env_cell) {
170 EnvCell ev = *ienvcell;
171 mem_pool[offset + i] = ComponentItemLocalId(ev._varIndex());
172 ++i;
173 }
174 allcell_allenvcell[cid] = Span<ComponentItemLocalId>(mem_pool_view.ptrAt(offset), nb_env);
175 }
176 };
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
182void AllCellToAllEnvCellContainer::Impl::
183bruteForceUpdate()
184{
185 // If the IDs have changed, we must redo everything
186 if (m_size != m_material_mng->mesh()->allCells().itemFamily()->maxLocalId() + 1) {
187 initialize();
188 return;
189 }
190
191 Int32 current_max_nb_env(computeMaxNbEnvPerCell());
192 // If the IDs have not changed, we check if the maximum number of environments per cell has changed at this moment
193 // If it has changed, recreate the mem pool; otherwise, just update the values
194 if (current_max_nb_env != m_current_max_nb_env) {
195 // Don't forget to update the new value!
196 m_current_max_nb_env = current_max_nb_env;
197 // we recreate the pool
198 Int32 pool_size = CheckedConvert::multiply(m_current_max_nb_env, m_size);
199 m_mem_pool.resize(pool_size);
200 }
201 // Update values
202 updateValues(m_material_mng, m_mem_pool.to1DSpan(), m_all_cell_to_all_env_cell.m_allcell_allenvcell_ptr, m_current_max_nb_env);
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208void AllCellToAllEnvCellContainer::Impl::
209reset()
210{
211 m_envcell_container.resize(0);
212 m_all_cell_to_all_env_cell.m_allcell_allenvcell_ptr = {};
213 m_mem_pool.resize(0);
214 m_material_mng = nullptr;
215 m_size = 0;
216 m_current_max_nb_env = 0;
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225AllCellToAllEnvCellContainer::
226AllCellToAllEnvCellContainer(IMeshMaterialMng* mm)
227: m_p(new Impl(mm))
228{
229}
230
231/*---------------------------------------------------------------------------*/
232/*---------------------------------------------------------------------------*/
233
234AllCellToAllEnvCellContainer::
235~AllCellToAllEnvCellContainer()
236{
237 delete m_p;
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243void AllCellToAllEnvCellContainer::
244reset()
245{
246 m_p->reset();
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
254{
255 return m_p->computeMaxNbEnvPerCell();
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
263{
264 m_p->initialize();
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
272{
273 m_p->bruteForceUpdate();
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
279AllCellToAllEnvCell AllCellToAllEnvCellContainer::
280view() const
281{
282 return m_p->view();
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291CellToAllEnvCellAccessor::
292CellToAllEnvCellAccessor(const IMeshMaterialMng* mm)
293{
295 if (c)
296 m_cell_allenvcell = c->view();
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
302} // End namespace Arcane::Materials
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
Types and macros for iterating over mesh entities.
Types and macros to manage enumerations of entities on accelerators.
#define RUNCOMMAND_ENUMERATE(ItemTypeName, iter_name, item_group,...)
Macro to iterate over an accelerator on a group of entities.
virtual CellGroup allCells()=0
Group of all cells.
Int32ConstArrayView itemsLocalId() const
List of local IDs of the entities in this group.
ItemGroupImpl * internal() const
Returns the group implementation.
Definition ItemGroup.h:125
Connectivity table of 'Cell' to its 'AllEnvCell' intended for use on accelerator.
Int32 computeMaxNbEnvPerCell() const
Method to provide the maximum number of environments present on a cell at time t.
void initialize()
Alternative creation function. It is necessary to wait until the data related to the materials is fin...
Connectivity table from 'Cell' to its 'AllEnvCell' intended for use on accelerator.
Arcane cell with material and environment information.
__host__ __device__ CellEnvCellEnumerator subEnvItems() const
Enumerator over the environment cells of this cell.
__host__ __device__ Int32 nbEnvironment() const
Number of environments present in the cell.
Arcane cell of an environment.
virtual RunQueue & runQueue() const =0
Default run queue.
virtual AllCellToAllEnvCellContainer * getAllCellToAllEnvCellContainer() const =0
Returns the "connectivity" table CellLocalId -> AllEnvCell intended to be used in a RUNCOMMAND_ENUMER...
Interface for the material and environment manager of a mesh.
virtual IMesh * mesh()=0
Associated mesh.
virtual IMeshMaterialMngInternal * _internalApi() const =0
Internal API for Arcane.
Multi-dimensional arrays for numerical types accessible on accelerators.
constexpr __host__ __device__ pointer ptrAt(SizeType index) const
Address of the index-th element.
Definition Span.h:362
View of an array of elements of type T.
Definition Span.h:635
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro to iterate over all EnvCell cells of a cell.
RunCommand makeCommand(const RunQueue &run_queue)
Creates a command associated with the queue run_queue.
Always enables tracing in Arcane parts concerning materials.
MatItemVariableScalarOutViewT< Cell, DataType > viewOut(CellMaterialVariableScalarRef< DataType > &var)
Write view.
Int32 Integer
Type representing an integer.
ExtentsV< Int32, DynExtent > MDDim1
Constant for a rank 1 dynamic array.
std::int32_t Int32
Signed integer type of 32 bits.