Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
LimaCutInfosReader.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/* LimaCutInfosReader.cc (C) 2000-2018 */
9/* */
10/* Lecteur des informations de découpages avec les fichiers Lima. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/ScopedPtr.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/FatalErrorException.h"
19
20#include "arcane/ItemGroup.h"
21#include "arcane/Item.h"
22#include "arcane/IXmlDocumentHolder.h"
23#include "arcane/XmlNode.h"
24#include "arcane/XmlNodeList.h"
25#include "arcane/IParallelMng.h"
26#include "arcane/IIOMng.h"
27#include "arcane/Timer.h"
28#include "arcane/IMesh.h"
29
30#include "arcane/cea/LimaCutInfosReader.h"
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35ARCANE_BEGIN_NAMESPACE
36
37//Juste pour faire le .lib sous Windows.
38class ARCANE_EXPORT LimaTest
39{
40};
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45LimaCutInfosReader::
46LimaCutInfosReader(IParallelMng* parallel_mng)
47: TraceAccessor(parallel_mng->traceMng())
48, m_parallel_mng(parallel_mng)
49{
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54/*!
55 * \brief Lecture des correspondances.
56 *
57 * Les correspondances sont stockées en mémoire à l'adresse \a buf sous la
58 * forme d'une suite d'entier au format ascii séparés par des espaces.
59 * Par exemple: "125 132 256".
60 */
61static Integer
62_readList(Int64ArrayView& int_list,const char* buf)
63{
64 std::istringstream istr(buf);
65 Integer index = 0;
66 while (!istr.eof()){
67 Int64 v = 0;
68 istr >> v;
69 if (istr.eof())
70 break;
71 int_list[index] = v;
72 ++index;
73 }
74 return index;
75}
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79/*!
80 * \brief Construit les structures internes du maillage.
81 */
84 const String& dir_name)
85{
86 _readUniqueIndex(nodes_id,cells_id,dir_name);
87}
88
89/*---------------------------------------------------------------------------*/
90/*---------------------------------------------------------------------------*/
91/*!
92 * \brief Récupération des indices uniques des entités.
93 *
94 * Récupère pour chaque entité son numéro unique pour tout domaine.
95 * Les valeurs sont stockées dans \a nodes_id pour les noeuds et
96 * \a cells_id pour les mailles. Ces deux tableaux doivent déjà avoir été
97 * alloués à la bonne taille.
98
99 * Le fonctionnement est le suivant:
100 * \arg le processeur 0 lit le fichier de correspondance et récupère les
101 * informations qui le concerne.
102 * \arg pour chaque autre processeur, le processeur 0 récupère le nombre
103 * de noeuds et mailles à lire, lit les valeurs dans le fichier de
104 * correspondance et les transfert au processeur.
105 */
106void LimaCutInfosReader::
107_readUniqueIndex(Int64ArrayView nodes_id,Int64ArrayView cells_id,
108 const String& dir_name)
109{
110 Timer time_to_read(m_parallel_mng->timerMng(),"ReadCorrespondance",Timer::TimerReal);
111 IParallelMng* pm = m_parallel_mng;
112
113 // Si le cas est parallèle, lecture du fichier de correspondance.
114 bool is_parallel = pm->isParallel();
115 Int32 comm_rank = pm->commRank();
116 Int32 nb_rank = pm->commSize();
117 // Si on est dans le cas où Arcane est retranché à un coeur
118 if ((!is_parallel) || (is_parallel && nb_rank==1)){
119 for( Integer i=0, n=nodes_id.size(); i<n; ++i )
120 nodes_id[i] = i;
121 for( Integer i=0, n=cells_id.size(); i<n; ++i )
122 cells_id[i] = i;
123 return;
124 }
125
126 ScopedPtrT<IXmlDocumentHolder> doc_holder;
127 StringBuilder correspondance_filename;
128 if (!dir_name.empty()){
129 correspondance_filename += dir_name;
130 correspondance_filename += "/";
131 }
132 correspondance_filename += "Correspondances";
133
134 if (comm_rank==0){
135 {
136 Timer::Sentry sentry(&time_to_read);
137 IXmlDocumentHolder* doc = pm->ioMng()->parseXmlFile(correspondance_filename);
138 doc_holder = doc;
139 }
140 if (!doc_holder.get())
141 ARCANE_FATAL("Invalid correspondance file '{0}'",correspondance_filename);
142
143 info() << "Time to read (unit: second) 'Correspondances' file: "
144 << time_to_read.lastActivationTime();
145
146 XmlNode root_element = doc_holder->documentNode().documentElement();
147
148 // D'abord, le sous-domaine lit ses valeurs.
149 _readUniqueIndexFromXml(nodes_id,cells_id,root_element,0);
150
151 {
152 Timer::Sentry sentry(&time_to_read);
153 // Ensuite boucle, sur les autres sous-domaine.
154 Int64UniqueArray other_nodes_id;
155 Int64UniqueArray other_cells_id;
156 UniqueArray<Integer> other_sizes(2);
157 for( Int32 i=1; i<nb_rank; ++i ){
158 pm->recv(other_sizes,i);
159 other_nodes_id.resize(other_sizes[0]);
160 other_cells_id.resize(other_sizes[1]);
161 _readUniqueIndexFromXml(other_nodes_id,other_cells_id,root_element,i);
162 pm->send(other_nodes_id,i);
163 pm->send(other_cells_id,i);
164 }
165 }
166 info() << "Time to transfert values: "
167 << time_to_read.lastActivationTime();
168 }
169 else{
170 // Réceptionne les valeurs envoyées par le sous-domaine 0
171 Integer mes[2];
172 IntegerArrayView mesh_element_size(2,mes);
173 mesh_element_size[0] = nodes_id.size();
174 mesh_element_size[1] = cells_id.size();
175 pm->send(mesh_element_size,0);
176 pm->recv(nodes_id,0);
177 pm->recv(cells_id,0);
178 }
179 // Vérifie que tous les messages sont envoyés et recus avant de détruire
180 // le document XML.
181 pm->barrier();
182}
183
184/*---------------------------------------------------------------------------*/
185/*---------------------------------------------------------------------------*/
186/*!
187 * \brief Lecture des indices uniques à partir d'un fichier de correspondance
188 * XML.
189 * \param nodes_id indices des noeuds
190 * \param cells_id indices des mailles
191 * \param root_element élément racine de l'arbre XML.
192 * \param comm_rank numéro du sous-domaine à lire.
193 */
194void LimaCutInfosReader::
195_readUniqueIndexFromXml(Int64ArrayView nodes_id,Int64ArrayView cells_id,
196 XmlNode root_element,Int32 comm_rank)
197{
198 XmlNode cpu_elem;
199 XmlNodeList cpu_list = root_element.children(String("cpu"));
200
201 String ustr_buf(String::fromNumber(comm_rank));
202
203 String us_id("id");
204 for( Integer i=0, s=cpu_list.size(); i<s; ++i ){
205 String id_str = cpu_list[i].attrValue(us_id);
206 if (id_str.null())
207 continue;
208 if (id_str==ustr_buf){
209 cpu_elem = cpu_list[i];
210 break;
211 }
212 }
213 if (cpu_elem.null())
214 ARCANE_FATAL("No element <cpu[@id=\"{0}\"]>",comm_rank);
215 XmlNode node_elem = cpu_elem.child("noeuds");
216 if (node_elem.null())
217 ARCANE_FATAL("No element <noeuds>");
218 XmlNode cell_elem = cpu_elem.child("mailles");
219 if (cell_elem.null())
220 ARCANE_FATAL("No element <mailles>");
221
222 // Tableau de correspodance des noeuds
223 {
224 String ustr_value = node_elem.value();
225 Integer nb_read = _readList(nodes_id,ustr_value.localstr());
226 Integer expected_size = nodes_id.size();
227 if (nb_read!=expected_size)
228 ARCANE_FATAL("Bad number of nodes rank={0} nb_read={1} expected={2}",
229 comm_rank,nb_read,expected_size);
230 }
231
232 // Tableau de correspodance des mailles
233 {
234 String ustr_value = cell_elem.value();
235 Integer nb_read = _readList(cells_id,ustr_value.localstr());
236 Integer expected_size = cells_id.size();
237 if (nb_read!=expected_size)
238 ARCANE_FATAL("Bad number of cells rank={0} nb_read={1} expected={2}",
239 comm_rank,nb_read,expected_size);
240 }
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
246ARCANE_END_NAMESPACE
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
virtual IXmlDocumentHolder * parseXmlFile(const String &filename, const String &schemaname=String())=0
Lit et analyse le fichier XML filename.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual IIOMng * ioMng() const =0
Gestionnaire des entrées/sorties.
virtual ITimerMng * timerMng() const =0
Gestionnaire de timers.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
virtual void barrier()=0
Effectue une barière.
void readItemsUniqueId(Int64ArrayView nodes_id, Int64ArrayView cells_id, const String &dir_name)
Construit les structures internes du maillage.
Gestion d'un timer.
Definition Timer.h:62
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Chaîne de caractères unicode.
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
Definition String.cc:315
TraceMessage info() const
Flot pour un message d'information.
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:513
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:615
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:609
Int32 Integer
Type représentant un entier.