Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AlephIndexing.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/IMesh.h"
16#include "arcane/VariableInfo.h"
17#include "arcane/ArcaneTypes.h"
18#include "arcane/utils/String.h"
19#include <arcane/IVariable.h>
20#include <arcane/IVariableMng.h>
22#include <arcane/utils/ArcanePrecomp.h>
23
24#define ALEPH_INDEX_NOT_USED (-1)
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35// ****************************************************************************
36// * AlephIndexing
37// ****************************************************************************
38AlephIndexing::
39AlephIndexing(AlephKernel* kernel)
40: TraceAccessor(kernel->parallel()->traceMng())
41, m_kernel(kernel)
42, m_sub_domain(kernel->subDomain())
43, m_current_idx(0)
44, m_known_items_own(0)
45{
46 debug() << "\33[1;33m[AlephIndexing::AlephIndexing] NEW"
47 << "\33[m";
48 m_known_items_all_address.resize(0);
49}
50
51// ****************************************************************************
52// * updateKnownItems
53// ****************************************************************************
54Int32 AlephIndexing::
55updateKnownItems(VariableItemInt32* var_idx,
56 const Item& itm)
57{
58 // Dans tous les cas l'adresse est celle-ci
59 m_known_items_all_address.add(&(*var_idx)[itm]);
60 // Si l'item ciblé n'est pas à nous, on ne doit pas le compter
61 if (itm.isOwn()) {
62 // On met à jour la case mémoire, et on le rajoute aux owned
63 (*var_idx)[itm] = m_current_idx;
64 m_known_items_own += 1;
65 }
66 else {
67 //debug()<< "\t\t\33[33m[AlephIndexing::updateKnownItems] " << var_idx->name() << " is NOT ours"<<"\33[m";
68 (*var_idx)[itm] = m_current_idx;
69 }
70 // Maintenant, on peut incrémenter l'index de ligne
71 m_current_idx += 1;
72 // Et on retourne le numéro demandé de la ligne
73 //debug()<< "\t\t\33[33m[AlephIndexing::updateKnownItems] returning \33[1;32m"<<m_current_idx-1<<"\33[m";
74 return m_current_idx - 1;
75}
76
77// ****************************************************************************
78// * findWhichLidFromMapMap
79// ****************************************************************************
80Int32 AlephIndexing::
81findWhichLidFromMapMap(IVariable* var,
82 const Item& itm)
83{
84#ifdef ARCANE_CHECK
85 if (itm.null())
86 ARCANE_FATAL("Null item");
87#endif
88
89 VarMapIdx::const_iterator iVarMap = m_var_map_idx.find(var);
90 // Si la variable n'est même pas encore connue
91 // On rajoute une entrée map(map(m_current_idx))
92 if (iVarMap == m_var_map_idx.end()) {
93 //debug()<<"\t\33[33m[findWhichLidFromMapMap] Unknown variable "<<var->name()<<"\33[m";
94 traceMng()->flush();
95 String var_idx_name(var->name());
96 var_idx_name = var_idx_name + String("_idx");
97 VariableItemInt32* var_idx =
98 new VariableItemInt32(VariableBuildInfo(var->itemFamily(),
99 var_idx_name,IVariable::PSubDomainDepend),
100 var->itemKind());
101 // On rajoute à notre map la variable '_idx' de cette variable
102 m_var_map_idx.insert(std::make_pair(var, var_idx));
103 // On flush tous les indices potentiels de cette variable
104 var_idx->fill(ALEPH_INDEX_NOT_USED);
105 return updateKnownItems(var_idx, itm);
106 }
107 VariableItemInt32* var_idx = iVarMap->second;
108 // Si cet item n'est pas connu de cette variable, on rajoute une entrée
109 if ((*var_idx)[itm] == ALEPH_INDEX_NOT_USED) {
110 //debug()<<"\t\33[33m[findWhichLidFromMapMap] Cet item n'est pas connu de cette variable, on rajoute une entrée\33[m";
111 traceMng()->flush();
112 return updateKnownItems(var_idx, itm);
113 }
114 //debug()<<"\t\33[33m[AlephIndexing::findWhichLidFromMapMap] " <<var->name()<<" "<<var->itemKind() << " hits row #\33[1;32m"<<(*var_idx)[itm]<<"\33[m";
115 traceMng()->flush();
116 return (*var_idx)[itm];
117}
118
119// ****************************************************************************
120// * get qui trig findWhichLidFromMapMap
121// ****************************************************************************
122Int32 AlephIndexing::
123get(const VariableRef& variable,
124 const ItemEnumerator& itm)
125{
126 return get(variable, *itm);
127}
128Int32 AlephIndexing::get(const VariableRef& variable,
129 const Item& itm)
130{
131 IVariable* var = variable.variable();
132 if (m_kernel->isInitialized()){
133 auto x = m_var_map_idx.find(var);
134 if (x==m_var_map_idx.end())
135 ARCANE_FATAL("Can not find variable {0}",var->name());
136 return (*x->second)[itm] - m_kernel->topology()->part()[m_kernel->rank()];
137 }
138 // On teste de bien travailler sur une variables scalaire
139 if (var->dimension() != 1)
140 throw ArgumentException(A_FUNCINFO, "cannot get non-scalar variables!");
141 // On vérifie que le type d'item est bien connu
142 if (var->itemKind() >= IK_Unknown)
143 throw ArgumentException(A_FUNCINFO, "Unknown Item Kind!");
144 //debug()<<"\33[1;33m[AlephIndexing::get] Valid couple, now looking for known idx (uid="<<itm->uniqueId()<<")\33[m";
145 return findWhichLidFromMapMap(var, itm);
146}
147
148// ****************************************************************************
149// * buildIndexesFromAddress
150// ****************************************************************************
151void AlephIndexing::
152buildIndexesFromAddress(void)
153{
154 const Integer topology_row_offset = m_kernel->topology()->part()[m_kernel->rank()];
155 VarMapIdx::const_iterator iVarIdx = m_var_map_idx.begin();
156 debug() << "\33[1;7;33m[buildIndexesFromAddress] Re-inexing variables with offset " << topology_row_offset << "\33[m";
157 // On ré-indice et synchronise toutes les variables qu'on a pu voir passer
158 for (; iVarIdx != m_var_map_idx.end(); ++iVarIdx) {
159 ItemGroup group = iVarIdx->first->itemGroup();
160 VariableItemInt32* var_idx = iVarIdx->second;
161 ENUMERATE_ITEM (itm, group) {
162 // Si cet item n'est pas utilisé, on s'en occupe pas
163 if ((*var_idx)[itm] == ALEPH_INDEX_NOT_USED)
164 continue;
165 // Sinon on rajoute l'offset
166 (*var_idx)[itm] += topology_row_offset;
167 }
168 debug() << "\t\33[1;7;33m[buildIndexesFromAddress] Synchronizing idx for variable " << iVarIdx->second->name() << "\33[m";
169 iVarIdx->second->synchronize();
170 }
171}
172
173// ****************************************************************************
174// * localKnownItems
175// * Consolidation en nombre des m_known_items_own fonction des items
176// ****************************************************************************
177Integer AlephIndexing::
178localKnownItems(void)
179{
180 return m_known_items_own;
181}
182
183// ****************************************************************************
184// * nowYouCanBuildTheTopology
185// ****************************************************************************
186void AlephIndexing::
187nowYouCanBuildTheTopology(AlephMatrix* fromThisMatrix,
188 AlephVector* fromThisX,
189 AlephVector* fromThisB)
190{
191 // Récupération de la consolidation en nombre des items
192 Integer lki = localKnownItems();
193 // ReduceSum sur l'ensemble de la topologie
194 Integer gki = m_kernel->parallel()->reduce(Parallel::ReduceSum, lki);
195 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] Working with lki="
196 << lki << ", gki=" << gki << "\33[m";
197 // Initialisation du kernel d'Aleph en fonction les locals et globals known items
198 m_kernel->initialize(gki, lki);
199 // A partir d'ici, le kernel est initialisé, on utilise directement les m_arguments_queue
200 // LA topologie a été remplacée par une nouvelle
201 debug() << "\33[1;7;33m[AlephIndexing::nowYouCanBuildTheTopology] Kernel is now initialized, rewinding Aleph operations!\33[m";
202 // Si on est en parallèle, il faut consolider les indices suivant la nouvelle topologie
203 if (m_kernel->isParallel())
204 buildIndexesFromAddress();
205 // On peut maintenant créer le triplet (matrice,lhs,rhs)
206 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] asking kernel for a Matrix\33[m";
207 AlephMatrix* firstMatrix = m_kernel->createSolverMatrix();
208 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] asking kernel for a RHS Vector\33[m";
209 AlephVector* firstRhsVector = m_kernel->createSolverVector();
210 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] asking kernel for a LHS Vector\33[m";
211 AlephVector* firstLhsVector = m_kernel->createSolverVector();
212 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstMatrix->create()\33[m";
213 firstMatrix->create();
214 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstRhsVector->create()\33[m";
215 firstRhsVector->create();
216 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstLhsVector->create()\33[m";
217 firstLhsVector->create();
218 // Et on revient pour rejouer les setValues de la matrice avec les indices consolidés
219 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] reSetValues fromThisMatrix\33[m";
220 fromThisMatrix->reSetValuesIn(firstMatrix,
221 m_known_items_all_address);
222 // Et on revient pour rejouer les addValues de la matrice avec les indices consolidés
223 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] reAddValues fromThisMatrix\33[m";
224 fromThisMatrix->reAddValuesIn(firstMatrix,
225 m_known_items_all_address);
226 // On reprovoque l'assemblage
227 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstMatrix->assemble()\33[m";
228 firstMatrix->assemble();
229 // Et on fait le même processus pour les lhs et rhs
230 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstRhsVector reSetLocalComponents/assemble\33[m";
231 firstRhsVector->reSetLocalComponents(fromThisB);
232 firstRhsVector->assemble();
233 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] firstLhsVector reSetLocalComponents/assemble\33[m";
234 firstLhsVector->reSetLocalComponents(fromThisX);
235 firstLhsVector->assemble();
236 debug() << "\33[1;33m[AlephIndexing::nowYouCanBuildTheTopology] nothing more to do here!\33[m";
237}
238
239// ****************************************************************************
240// * ~AlephIndexing
241// ****************************************************************************
242AlephIndexing::
243~AlephIndexing()
244{
245 debug() << "\t\33[1;33m[AlephIndexing::~AlephIndexing] deleting each new'ed VarMapIdx..."
246 << "\33[m";
247 VarMapIdx::const_iterator iVarIdx = m_var_map_idx.begin();
248 for (; iVarIdx != m_var_map_idx.end(); ++iVarIdx)
249 delete iVarIdx->second;
250 debug() << "\t\33[1;33m[AlephIndexing::~AlephIndexing] done!"
251 << "\33[m";
252 traceMng()->flush();
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
Fichier de configuration d'Arcane.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
String name() const
Nom de la variable.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.