Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
AlephIndexing.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/* AlephIndexing.cc (C) 2000-2023 */
9/* */
10/*---------------------------------------------------------------------------*/
11/*---------------------------------------------------------------------------*/
12#include "AlephArcane.h"
13
14#include <map>
15#include "arcane/utils/String.h"
17#include "arcane/utils/ArcanePrecomp.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/VariableInfo.h"
21#include "arcane/core/IVariable.h"
22#include "arcane/core/IVariableMng.h"
24
25#define ALEPH_INDEX_NOT_USED (-1)
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36// ****************************************************************************
37// * AlephIndexing
38// ****************************************************************************
39AlephIndexing::
40AlephIndexing(AlephKernel* kernel)
41: TraceAccessor(kernel->parallel()->traceMng())
42, m_kernel(kernel)
43, m_sub_domain(kernel->subDomain())
44, m_current_idx(0)
45, m_known_items_own(0)
46{
47 debug() << "\33[1;33m[AlephIndexing::AlephIndexing] NEW"
48 << "\33[m";
49 m_known_items_all_address.resize(0);
50}
51
52// ****************************************************************************
53// * updateKnownItems
54// ****************************************************************************
55Int32 AlephIndexing::
56updateKnownItems(VariableItemInt32* var_idx,
57 const Item& itm)
58{
59 // In all cases, the address is this one
60 m_known_items_all_address.add(&(*var_idx)[itm]);
61 // If the targeted item is not ours, we should not count it
62 if (itm.isOwn()) {
63 // We update the memory slot, and we add it to the owned ones
64 (*var_idx)[itm] = m_current_idx;
65 m_known_items_own += 1;
66 }
67 else {
68 //debug()<< "\t\t\33[33m[AlephIndexing::updateKnownItems] " << var_idx->name() << " is NOT ours"<<"\33[m";
69 (*var_idx)[itm] = m_current_idx;
70 }
71 // Now, we can increment the row index
72 m_current_idx += 1;
73 // And we return the requested row number
74 //debug()<< "\t\t\33[33m[AlephIndexing::updateKnownItems] returning \33[1;32m"<<m_current_idx-1<<"\33[m";
75 return m_current_idx - 1;
76}
77
78// ****************************************************************************
79// * findWhichLidFromMapMap
80// ****************************************************************************
81Int32 AlephIndexing::
82findWhichLidFromMapMap(IVariable* var,
83 const Item& itm)
84{
85#ifdef ARCANE_CHECK
86 if (itm.null())
87 ARCANE_FATAL("Null item");
88#endif
89
90 VarMapIdx::const_iterator iVarMap = m_var_map_idx.find(var);
91 // If the variable is not even known yet
92 // We add a map entry (map(m_current_idx))
93 if (iVarMap == m_var_map_idx.end()) {
94 //debug()<<"\t\33[33m[findWhichLidFromMapMap] Unknown variable "<<var->name()<<"\33[m";
95 traceMng()->flush();
96 String var_idx_name(var->name());
97 var_idx_name = var_idx_name + String("_idx");
98 VariableItemInt32* var_idx =
99 new VariableItemInt32(VariableBuildInfo(var->itemFamily(),
100 var_idx_name, IVariable::PSubDomainDepend),
101 var->itemKind());
102 // We add the '_idx' variable of this variable to our map
103 m_var_map_idx.insert(std::make_pair(var, var_idx));
104 // We flush all potential indices of this variable
105 var_idx->fill(ALEPH_INDEX_NOT_USED);
106 return updateKnownItems(var_idx, itm);
107 }
108 VariableItemInt32* var_idx = iVarMap->second;
109 // If this item is not known by this variable, we add an entry
110 if ((*var_idx)[itm] == ALEPH_INDEX_NOT_USED) {
111 //debug()<<"\t\33[33m[findWhichLidFromMapMap] This item is not known by this variable, we add an entry\33[m";
112 traceMng()->flush();
113 return updateKnownItems(var_idx, itm);
114 }
115 //debug()<<"\t\33[33m[AlephIndexing::findWhichLidFromMapMap] " <<var->name()<<" "<<var->itemKind() << " hits row #\33[1;32m"<<(*var_idx)[itm]<<"\33[m";
116 traceMng()->flush();
117 return (*var_idx)[itm];
118}
119
120// ****************************************************************************
121// * get which triggers findWhichLidFromMapMap
122// ****************************************************************************
123Int32 AlephIndexing::
124get(const VariableRef& variable,
125 const ItemEnumerator& itm)
126{
127 return get(variable, *itm);
128}
129Int32 AlephIndexing::get(const VariableRef& variable,
130 const Item& itm)
131{
132 IVariable* var = variable.variable();
133 if (m_kernel->isInitialized()) {
134 auto x = m_var_map_idx.find(var);
135 if (x == m_var_map_idx.end())
136 ARCANE_FATAL("Can not find variable {0}", var->name());
137 return (*x->second)[itm] - m_kernel->topology()->part()[m_kernel->rank()];
138 }
139 // We test if we are working on a scalar variable
140 if (var->dimension() != 1)
141 throw ArgumentException(A_FUNCINFO, "cannot get non-scalar variables!");
142 // We check that the item type is well known
143 if (var->itemKind() >= IK_Unknown)
144 throw ArgumentException(A_FUNCINFO, "Unknown Item Kind!");
145 //debug()<<"\33[1;33m[AlephIndexing::get] Valid couple, now looking for known idx (uid="<<itm->uniqueId()<<")\33[m";
146 return findWhichLidFromMapMap(var, itm);
147}
148
149// ****************************************************************************
150// * buildIndexesFromAddress
151// ****************************************************************************
152void AlephIndexing::
153buildIndexesFromAddress(void)
154{
155 const Integer topology_row_offset = m_kernel->topology()->part()[m_kernel->rank()];
156 VarMapIdx::const_iterator iVarIdx = m_var_map_idx.begin();
157 debug() << "\33[1;7;33m[buildIndexesFromAddress] Re-indexing variables with offset " << topology_row_offset << "\33[m";
158 // We re-index and synchronize all variables that we have seen
159 for (; iVarIdx != m_var_map_idx.end(); ++iVarIdx) {
160 ItemGroup group = iVarIdx->first->itemGroup();
161 VariableItemInt32* var_idx = iVarIdx->second;
162 ENUMERATE_ITEM (itm, group) {
163 // If this item is not used, we skip it
164 if ((*var_idx)[itm] == ALEPH_INDEX_NOT_USED)
165 continue;
166 // Otherwise, we add the offset
167 (*var_idx)[itm] += topology_row_offset;
168 }
169 debug() << "\t\33[1;7;33m[buildIndexesFromAddress] Synchronizing idx for variable " << iVarIdx->second->name() << "\33[m";
170 iVarIdx->second->synchronize();
171 }
172}
173
174// ****************************************************************************
175// * localKnownItems
176// * Consolidation of m_known_items_own based on items
177// ****************************************************************************
178Integer AlephIndexing::
179localKnownItems(void)
180{
181 return m_known_items_own;
182}
183
184// ****************************************************************************
185// * nowYouCanBuildTheTopology
186// ****************************************************************************
187void AlephIndexing::
188nowYouCanBuildTheTopology(AlephMatrix* fromThisMatrix,
189 AlephVector* fromThisX,
190 AlephVector* fromThisB)
191{
192 // Retrieval of the item count consolidation
193 Integer lki = localKnownItems();
194 // ReduceSum over the entire topology
195 Integer gki = m_kernel->parallel()->reduce(Parallel::ReduceSum, lki);
196 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] Working with lki="
197 << lki << ", gki=" << gki << "\33[m";
198 // Initialization of the Aleph kernel based on local and global known items
199 m_kernel->initialize(gki, lki);
200 // From here, the kernel is initialized, we use m_arguments_queue directly
201 // The topology has been replaced by a new one
202 debug() << "\33[1;7;33m[AlephIndexing::nowYouCanBuildTheTopology] Kernel is now initialized, rewinding Aleph operations!\33[m";
203 // If we are in parallel, we must consolidate the indices according to the new topology
204 if (m_kernel->isParallel())
205 buildIndexesFromAddress();
206 // We can now create the triplet (matrix,lhs,rhs)
207 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] asking kernel for a Matrix\33[m";
208 AlephMatrix* firstMatrix = m_kernel->createSolverMatrix();
209 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] asking kernel for a RHS Vector\33[m";
210 AlephVector* firstRhsVector = m_kernel->createSolverVector();
211 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] asking kernel for a LHS Vector\33[m";
212 AlephVector* firstLhsVector = m_kernel->createSolverVector();
213 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstMatrix->create()\33[m";
214 firstMatrix->create();
215 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstRhsVector->create()\33[m";
216 firstRhsVector->create();
217 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstLhsVector->create()\33[m";
218 firstLhsVector->create();
219 // And we return to replay the matrix's setValues with the consolidated indices
220 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] reSetValues fromThisMatrix\33[m";
221 fromThisMatrix->reSetValuesIn(firstMatrix,
222 m_known_items_all_address);
223 // And we return to replay the matrix's addValues with the consolidated indices
224 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] reAddValues fromThisMatrix\33[m";
225 fromThisMatrix->reAddValuesIn(firstMatrix,
226 m_known_items_all_address);
227 // We re-run the assembly
228 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstMatrix->assemble()\33[m";
229 firstMatrix->assemble();
230 // And we do the same process for lhs and rhs
231 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstRhsVector reSetLocalComponents/assemble\33[m";
232 firstRhsVector->reSetLocalComponents(fromThisB);
233 firstRhsVector->assemble();
234 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstLhsVector reSetLocalComponents/assemble\33[m";
235 firstLhsVector->reSetLocalComponents(fromThisX);
236 firstLhsVector->assemble();
237 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] nothing more to do here!\33[m";
238}
239
240// ****************************************************************************
241// * ~AlephIndexing
242// ****************************************************************************
243AlephIndexing::
244~AlephIndexing()
245{
246 debug() << "\t\33[1;33m[AlephIndexing::~AlephIndexing] deleting each new'ed VarMapIdx..."
247 << "\33[m";
248 VarMapIdx::const_iterator iVarIdx = m_var_map_idx.begin();
249 for (; iVarIdx != m_var_map_idx.end(); ++iVarIdx)
250 delete iVarIdx->second;
251 debug() << "\t\33[1;33m[AlephIndexing::~AlephIndexing] done!"
252 << "\33[m";
253 traceMng()->flush();
254}
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
259} // namespace Arcane
260
261/*---------------------------------------------------------------------------*/
262/*---------------------------------------------------------------------------*/
Arcane configuration file.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Declarations of Arcane's general types.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
ItemVariableScalarRefT< Int32 > VariableItemInt32
32-bit integer type quantity
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.