Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
VariableUtilities.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/* VariableUtilities.cc (C) 2000-2015 */
9/* */
10/* Utility functions for variables. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Array.h"
15#include "arcane/utils/Iostream.h"
16#include "arcane/utils/String.h"
17
18#include "arcane/impl/VariableUtilities.h"
19
20#include "arcane/core/IVariable.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/IVariableMng.h"
23#include "arcane/core/VariableDependInfo.h"
24#include "arcane/core/VariableCollection.h"
25#include "arcane/core/SerializeBuffer.h"
26
27#include <map>
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38VariableUtilities::
39VariableUtilities(IVariableMng* vm)
40: TraceAccessor(vm->traceMng())
41, m_variable_mng(vm)
42{
43}
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
48VariableUtilities::
49~VariableUtilities()
50{
51}
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
59void VariableUtilities::
60dumpAllVariableDependencies(std::ostream& ostr, bool is_recursive)
61{
62 VariableCollection used_variables = m_variable_mng->usedVariables();
63 for (VariableCollection::Enumerator ivar(used_variables); ++ivar;) {
64 IVariable* var = *ivar;
65 dumpDependencies(var, ostr, is_recursive);
66 }
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72void VariableUtilities::
73dumpDependencies(IVariable* var, std::ostream& ostr, bool is_recursive)
74{
75 // Set of variables already processed to prevent infinite recursion
76 _dumpDependencies(var, ostr, is_recursive);
77}
78
79/*---------------------------------------------------------------------------*/
80/*---------------------------------------------------------------------------*/
81
82void VariableUtilities::
83_dumpDependencies(IVariable* var, std::ostream& ostr, bool is_recursive)
84{
85 std::set<IVariable*> done_vars;
86 done_vars.insert(var);
87
89 var->dependInfos(depends);
90 Integer nb_depend = depends.size();
91 if (nb_depend == 0)
92 return;
93
94 ostr << var->fullName()
95 << " time=" << var->modifiedTime()
96 << " nb_depend=" << nb_depend
97 << '\n';
98
99 if (nb_depend != 0) {
100 ostr << "{\n";
101 for (Integer i = 0; i < nb_depend; ++i) {
102 _dumpDependencies(depends[i], ostr, is_recursive, done_vars, 2);
103 }
104 ostr << "}\n";
105 }
106}
107
108/*---------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------*/
110
111void VariableUtilities::
112_dumpDependencies(VariableDependInfo& vdi, std::ostream& ostr, bool is_recursive,
113 std::set<IVariable*>& done_vars, Integer indent_level)
114{
115 IVariable* var = vdi.variable();
116 bool no_cycle = done_vars.find(var) == done_vars.end();
117 bool do_depend = no_cycle;
118 if (!is_recursive)
119 do_depend = false;
120 done_vars.insert(var);
121
122 std::string indent_str;
123 for (Integer i = 0; i < indent_level; ++i)
124 indent_str.push_back(' ');
125
126 UniqueArray<VariableDependInfo> depends;
127 var->dependInfos(depends);
128 Integer nb_depend = depends.size();
129
130 ostr << indent_str
131 << var->fullName()
132 << " time=" << var->modifiedTime()
133 << " nb_depend=" << nb_depend
134 << " trace_info=" << vdi.traceInfo();
135 if (!no_cycle)
136 ostr << " (cycle)";
137 ostr << '\n';
138
139 if (do_depend && nb_depend != 0) {
140 ostr << indent_str << "{\n";
141 for (Integer i = 0; i < nb_depend; ++i) {
142 _dumpDependencies(depends[i], ostr, true, done_vars, indent_level + 2);
143 }
144 ostr << indent_str << "}\n";
145 }
146}
147
148/*---------------------------------------------------------------------------*/
149/*---------------------------------------------------------------------------*/
150
161VariableCollection VariableUtilities::
162filterCommonVariables(IParallelMng* pm, const VariableCollection input_variables,
163 bool dump_not_common)
164{
165 UniqueArray<IVariable*> vars_to_check;
166 for (VariableCollection::Enumerator i(input_variables); ++i;)
167 vars_to_check.add(*i);
168
169 Integer nb_var = vars_to_check.size();
170 info(4) << "CHECK: nb_variable_to_compare=" << nb_var;
171
172 // Create a buffer to serialize the names of the variables we have
173 SerializeBuffer send_buf;
174 send_buf.setMode(ISerializer::ModeReserve);
175 send_buf.reserveInteger(1);
176 for (Integer i = 0; i < nb_var; ++i) {
177 send_buf.reserve(vars_to_check[i]->fullName());
178 }
179
180 send_buf.allocateBuffer();
182 send_buf.putInteger(nb_var);
183 for (Integer i = 0; i < nb_var; ++i) {
184 send_buf.put(vars_to_check[i]->fullName());
185 }
186
187 // Retrieve info from other PEs.
188 SerializeBuffer recv_buf;
189 pm->allGather(&send_buf, &recv_buf);
190
191 std::map<String, Int32> var_occurences;
192
193 Int32 nb_rank = pm->commSize();
195 for (Integer i = 0; i < nb_rank; ++i) {
196 Integer nb_var_rank = recv_buf.getInteger();
197 info(5) << "String recv_nb_var_rank rank=" << i << " n=" << nb_var_rank;
198 for (Integer z = 0; z < nb_var_rank; ++z) {
199 String x;
200 recv_buf.get(x);
201 std::map<String, Int32>::iterator vo = var_occurences.find(x);
202 if (vo == var_occurences.end())
203 var_occurences.insert(std::make_pair(x, 1));
204 else
205 vo->second = vo->second + 1;
206 //info() << "String rank=" << i << " z=" << z << " name=" << x;
207 }
208 }
209
210 // Iterate through the list of variables and store in \a common_vars
211 // those that are available on all ranks of \a pm
212 std::map<String, IVariable*> common_vars;
213 {
214 std::map<String, Int32>::const_iterator end_var = var_occurences.end();
215 for (Integer i = 0; i < nb_var; ++i) {
216 IVariable* var = vars_to_check[i];
217 std::map<String, Int32>::const_iterator i_var = var_occurences.find(var->fullName());
218 if (i_var == end_var)
219 // Should not happen
220 continue;
221 if (i_var->second != nb_rank) {
222 if (dump_not_common)
223 info() << "ERROR: can not compare variable '" << var->fullName()
224 << "' because it is not defined on all replica nb_define=" << i_var->second;
225 continue;
226 }
227 common_vars.insert(std::make_pair(var->fullName(), var));
228 }
229 }
230
231 // Create the final list by iterating over the map \a common_vars
232 // and storing the values in \a sorted_common_vars. Since the map
233 // is sorted alphabetically, \a sorted_common_vars will also be;
234 VariableList sorted_common_vars;
235 {
236 std::map<String, IVariable*>::const_iterator end_var = common_vars.end();
237 std::map<String, IVariable*>::const_iterator i_var = common_vars.begin();
238 for (; i_var != end_var; ++i_var) {
239 sorted_common_vars.add(i_var->second);
240 }
241 }
242
243 return sorted_common_vars;
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249} // namespace Arcane
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
Integer size() const
Number of elements in the vector.
void add(ConstReferenceType val)
Adds element val to the end of the array.
void put(Span< const Real > values) override
Add the array values.
void reserve(eBasicDataType dt, Int64 n) override
Reserves memory for n objects of type dt.
void allocateBuffer() override
Allocates the serializer memory.
Integer getInteger() override
Retrieve a size.
void get(ArrayView< Real > values) override
Retrieve the array values.
void setMode(eMode new_mode) override
Sets the current mode.
void putInteger(Integer value) override
Add the integer value.
Interface of the parallelism manager for a subdomain.
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Performs an all-gather operation across all processors. This is a collective operation....
Variable manager interface.
Interface of a variable.
Definition IVariable.h:40
virtual String fullName() const =0
Full variable name (with family prefix).
virtual Int64 modifiedTime()=0
Time when the variable was updated.
virtual void dependInfos(Array< VariableDependInfo > &infos)=0
Dependency information.
Implementation of a buffer for serialization.
TraceMessage info() const
Flow for an information message.
1D data vector with value semantics (STL style).
virtual void dumpDependencies(IVariable *var, std::ostream &ostr, bool is_recursive)
Displays dependency information for a variable.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
std::int32_t Int32
Signed integer type of 32 bits.