Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MultiReduce.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/* MultiReduce.cc (C) 2000-2013 */
9/* */
10/* Gestion de réductions multiples. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15#include "arcane/utils/TraceAccessor.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/TraceInfo.h"
18#include "arcane/utils/String.h"
19#include "arcane/utils/PlatformUtils.h"
20
21#include "arcane/IParallelMng.h"
22
23#include "arcane/parallel/IMultiReduce.h"
24
25#include <map>
26#include <algorithm>
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31ARCANE_BEGIN_NAMESPACE
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36class PostProcessingMng;
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40/*!
41 */
43: public TraceAccessor
44, public IMultiReduce
45{
46 public:
47
50
51 public:
52
53 virtual void execute();
54 virtual bool isStrict() const { return m_is_strict; }
55 virtual void setStrict(bool is_strict) { m_is_strict = is_strict; }
56
57 public:
58
60 {
61 ReduceSumOfRealHelperMap::const_iterator i = m_sum_helpers.find(name);
63 if (i==m_sum_helpers.end()){
64 v = new ReduceSumOfRealHelper(m_is_strict);
65 m_sum_helpers.insert(std::make_pair(name,v));
66 }
67 else
68 v = i->second;
69 return v;
70 }
71
72 private:
73
74 typedef std::map<String,ReduceSumOfRealHelper*> ReduceSumOfRealHelperMap;
75
76 IParallelMng* m_parallel_mng;
77 bool m_is_strict;
78 ReduceSumOfRealHelperMap m_sum_helpers;
79
80 private:
81
82 void _execStrict(ReduceSumOfRealHelper* v);
83};
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88IMultiReduce* IMultiReduce::
89create(IParallelMng* pm)
90{
91 return new MultiReduce(pm);
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100MultiReduce::
101MultiReduce(IParallelMng* pm)
102: TraceAccessor(pm->traceMng())
103, m_parallel_mng(pm)
104, m_is_strict(false)
105{
106 if (!platform::getEnvironmentVariable("ARCANE_STRICT_REDUCE").null())
107 m_is_strict = true;
108}
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
113MultiReduce::
114~MultiReduce()
115{
116 ReduceSumOfRealHelperMap::const_iterator i = m_sum_helpers.begin();
117 for( ; i!=m_sum_helpers.end(); ++i )
118 delete i->second;
119 m_sum_helpers.clear();
120}
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
126execute()
127{
128 if (m_is_strict){
129 ReduceSumOfRealHelperMap::const_iterator i = m_sum_helpers.begin();
130 for( ; i!=m_sum_helpers.end(); ++i )
131 _execStrict(i->second);
132 return;
133 }
134
135 // Si on ne souhaite pas de réduction stricte, on stocke dans un
136 // tableau l'ensemble des sommes à réduire et on effectue
137 // une seule réduction sur ce tableau.
138
139 Integer nb_val = arcaneCheckArraySize(m_sum_helpers.size());
140 RealUniqueArray values(nb_val);
141
142 // Copie dans \a values les sommes à réduire
143 {
144 Integer index = 0;
145 ReduceSumOfRealHelperMap::const_iterator i = m_sum_helpers.begin();
146 for( ; i!=m_sum_helpers.end(); ++i ){
147 // Dans ce cas non strict, une seule valeur le tableau.
148 values[index] = i->second->values()[0];
149 ++index;
150 }
151 }
152
153 // Effectue la réduction
154 m_parallel_mng->reduce(Parallel::ReduceSum,values);
155
156 {
157 Integer index = 0;
158 ReduceSumOfRealHelperMap::const_iterator i = m_sum_helpers.begin();
159 for( ; i!=m_sum_helpers.end(); ++i ){
160 // Dans ce cas non strict, une seule valeur le tableau.
161 i->second->setReducedValue(values[index]);
162 ++index;
163 }
164 }
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
170void MultiReduce::
171_execStrict(ReduceSumOfRealHelper* v)
172{
173 // On souhaite une réduction stricte qui donne toujours les même résultats.
174 // Pour cela, un proc (le 0) récupère toutes les valeurs accumulées.
175 // Elles sont ensuite triées et accumulées puis renvoyées à tous le monde.
176 RealUniqueArray all_values;
177 m_parallel_mng->gatherVariable(v->values(),all_values,0);
178 //info() << "NB_VAL=" << all_values.size();
179 std::sort(std::begin(all_values),std::end(all_values));
180 Real sum = 0.0;
181 for( Integer i=0, n=all_values.size(); i<n; ++i )
182 sum += all_values[i];
183 // TODO: il est possible de faire un seul broadcast une fois les réductions
184 // de tous les \a v effectuées
185 m_parallel_mng->broadcast(RealArrayView(1,&sum),0);
186 v->setReducedValue(sum);
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
192ARCANE_END_NAMESPACE
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
Gestion de réductions multiples.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual void gatherVariable(ConstArrayView< char > send_buf, Array< char > &recv_buf, Int32 rank)=0
Effectue un regroupement sur tous les processeurs.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual bool isStrict() const
Indique si on utilise le mode strict.
virtual ReduceSumOfRealHelper * getSumOfReal(const String &name)
Retourne le gestionnaire de nom name. S'il n'existe pas de gestionnaire de nom name il est créé....
virtual void setStrict(bool is_strict)
Positionne le mode strict.
virtual void execute()
Exécute les réductions.
Classe gérant une réduction d'une somme de valeur.
RealConstArrayView values() const
Liste des valeurs accumulées.
void setReducedValue(Real v)
Positionne la valeur réduite.
Integer size() const
Nombre d'éléments du vecteur.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
ArrayView< Real > RealArrayView
Equivalent C d'un tableau à une dimension de réels.
Definition UtilsTypes.h:617