Bridge++  Ver. 1.3.x
parameterManager_XML.cpp
Go to the documentation of this file.
1 
14 #include "parameterManager_XML.h"
15 
16 #include "communicator.h"
17 #include "evalexpr.h"
18 
19 #include <fstream>
20 #include <sstream>
21 #include <map>
22 
23 #include "tinyxml2.h"
24 using namespace tinyxml2;
25 
26 using std::string;
27 using Bridge::vout;
28 
29 const std::string ParameterManager_XML::class_name = "ParameterManager_XML";
30 
31 namespace {
32  template<typename T>
33  std::string to_str(const std::vector<T>& v)
34  {
35  std::ostringstream ss;
36 
37  ss << "[ ";
38  for (size_t i = 0, n = v.size(); i < n; ++i) {
39  if (i != 0) ss << ", ";
40  ss << v[i];
41  }
42  ss << " ]";
43 
44  return ss.str();
45  }
46 }
47 
48 //====================================================================
49 void ParameterManager_XML::read_params(const std::string& params_file, Parameters *params)
50 {
51  const int io_node = 0; // node id for file i/o.
52 
53  int filesize = 0;
54  char *buf = 0;
55 
56  if (Communicator::nodeid() == io_node) {
57  // load and distribute
58  std::ifstream fin(params_file.c_str());
59  if (!fin) {
60  vout.crucial(m_vl, "%s: unable to read parameter file: %s.\n", class_name.c_str(), params_file.c_str());
61 
63  }
64 
65  fin.seekg(0, std::ios::end);
66  filesize = fin.tellg();
67  fin.seekg(0, std::ios::beg);
68 
69  int padding = 8 - (filesize % 8);
70 
71  vout.paranoiac(m_vl, "%s::%s: filesize = %d, padding = %d\n", class_name.c_str(), __func__, filesize, padding);
72 
73  filesize += padding;
74 
75  Communicator::broadcast(1, &filesize, io_node);
76 
77  buf = new char [filesize];
78  memset(buf, 0, filesize);
79 
80  fin.read(buf, filesize - padding);
81 
82  Communicator::Base::broadcast(filesize, buf, io_node);
83  } else {
84  // receive from io_node
85 
86  Communicator::broadcast(1, &filesize, io_node);
87 
88  buf = new char [filesize];
89  memset(buf, 0, filesize);
90 
91  Communicator::Base::broadcast(filesize, buf, io_node);
92  }
93 
94  process_params(buf, params);
95 
96  delete [] buf;
97 }
98 
99 
100 //====================================================================
101 void ParameterManager_XML::process_params(const char *buf, Parameters *params_top)
102 {
103  XMLDocument doc;
104 
105  XMLError err = doc.Parse(buf);
106 
107  if (err != XML_NO_ERROR) {
108  vout.crucial(m_vl, "%s: parse failed: %s\n", class_name.c_str(), doc.ErrorName());
109 
110  const char *err_str1 = doc.GetErrorStr1();
111  if (err_str1) {
112  vout.crucial(m_vl, " %s\n", err_str1);
113  }
114  const char *err_str2 = doc.GetErrorStr2();
115  if (err_str2) {
116  vout.crucial(m_vl, " %s\n", err_str2);
117  }
118 
119  exit(EXIT_FAILURE);
120  }
121 
122  XMLElement *root = doc.FirstChildElement("Parameters");
123  if (!root) {
124  vout.crucial(m_vl, "%s: tag \"Parameters\" not found.\n", class_name.c_str());
125  exit(EXIT_FAILURE);
126  }
127 
128  traverse(root, params_top);
129 }
130 
131 
132 //====================================================================
134 {
135  if (!elem || !params) return;
136 
137  for (const XMLElement *e = elem->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) {
138  traverse_item(e, params);
139  }
140 }
141 
142 
143 //====================================================================
145 {
146  if (!elem || !params) return;
147 
148  std::string tag(elem->Name());
149 
150  vout.paranoiac(m_vl, "%s::%s: tag = \"%s\"\n", class_name.c_str(), __func__, tag.c_str());
151 
152  if (params->find_Parameters(tag)) {
153  vout.paranoiac(m_vl, "%s::%s: matched entry for parameters.\n", class_name.c_str(), __func__);
154 
155  return traverse(elem, params->get_Parameters(tag));
156  }
157 
158  if (params->find_int(tag)) {
159  int val = atoi(elem->GetText());
160 
161  vout.paranoiac(m_vl, "%s::%s: matched entry for int. val = %d\n", class_name.c_str(), __func__, val);
162 
163  return params->set_int(tag, val);
164  }
165 
166  if (params->find_double(tag)) {
167  double val = EvalExpr(elem->GetText()).parse();
168 
169  vout.paranoiac(m_vl, "%s::%s: matched entry for double. expr = %s, val = %20.16e\n", class_name.c_str(), __func__, elem->GetText(), val);
170 
171  return params->set_double(tag, val);
172  }
173 
174  if (params->find_string(tag)) {
175  vout.paranoiac(m_vl, "%s::%s: matched entry for string. val = %s\n", class_name.c_str(), __func__, elem->GetText());
176 
177  return params->set_string(tag, elem->GetText());
178  }
179 
180  if (params->find_int_vector(tag)) {
181  std::vector<int> val = convert_to_int_vector(elem);
182 
183  vout.paranoiac(m_vl, "%s::%s: matched entry for int vector. val = %s\n", class_name.c_str(), __func__, to_str(val).c_str());
184 
185  return params->set_int_vector(tag, val);
186  }
187 
188  if (params->find_double_vector(tag)) {
189  std::vector<double> val = convert_to_double_vector(elem);
190 
191  vout.paranoiac(m_vl, "%s::%s: matched entry for double vector. val = %s\n", class_name.c_str(), __func__, to_str(val).c_str());
192 
193  return params->set_double_vector(tag, val);
194  }
195 
196  if (tag == "verbose_level") {
198 
199  vout.paranoiac(m_vl, "%s::%s: matched entry for verbose_level. val = %d\n", class_name.c_str(), __func__, vl);
200 
201  return params->set_VerboseLevel(vl);
202  }
203 
204  // unknown entry. skip
205  vout.paranoiac(m_vl, "%s::%s: no match. skipped.\n", class_name.c_str(), __func__);
206 }
207 
208 
209 //====================================================================
211 {
212  if (!elem) return std::vector<int>();
213 
214  const XMLElement *ee = elem->FirstChildElement();
215  if (!ee) return std::vector<int>();
216 
217  std::map<int, int> array;
218  int max_index = 0;
219 
220  if (strcmp(ee->Name(), "value") == 0) {
221  vout.paranoiac(m_vl, "%s::%s: plain array.\n", class_name.c_str(), __func__);
222 
223  int count = 0;
224 
225  for (const XMLElement *e = elem->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) {
226  int id = 0;
227  if (e->QueryIntAttribute("id", &id) == XML_SUCCESS) {
228  --id; /* id starts from 1 */
229  } else {
230  vout.general(m_vl, "%s::%s: array index not found.\n", class_name.c_str(), __func__);
231  id = count;
232  }
233 
234  if (id < 0) {
235  vout.crucial(m_vl, "%s::%s: inappropriate array index %d.\n", class_name.c_str(), __func__, id);
236  exit(EXIT_FAILURE);
237  }
238 
239  if (id > max_index) {
240  max_index = id;
241  }
242 
243  int val = atoi(e->GetText());
244 
245  vout.paranoiac(m_vl, "%s::%s: id = %d, value = %d\n", class_name.c_str(), __func__, id, val);
246 
247  array[id] = val;
248  ++count;
249  }
250  } else {
251  vout.paranoiac(m_vl, "%s::%s: directional array.\n", class_name.c_str(), __func__);
252 
253  for (const XMLElement *e = elem->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) {
254  int id = 0;
255 
256  std::string tag = std::string(e->Name());
257 
258  if (tag == "x") {
259  id = 0;
260  } else if (tag == "y") {
261  id = 1;
262  } else if (tag == "z") {
263  id = 2;
264  } else if (tag == "t") {
265  id = 3;
266  } else {
267  vout.crucial("%s::%s: unknown array index \"%s\".\n", class_name.c_str(), __func__, tag.c_str());
268  exit(EXIT_FAILURE);
269  }
270 
271  if (id > max_index) {
272  max_index = id;
273  }
274 
275  int val = atoi(e->GetText());
276 
277  vout.paranoiac(m_vl, "%s::%s: id = %s (%d), value = %d\n", class_name.c_str(), __func__, tag.c_str(), id, val);
278 
279  array[id] = val;
280  }
281  }
282 
283  vout.paranoiac(m_vl, "%s::%s: max_index = %d\n", class_name.c_str(), __func__, max_index);
284 
285  std::vector<int> v(max_index + 1);
286 
287  for (std::map<int, int>::const_iterator p = array.begin(); p != array.end(); ++p) {
288  v[p->first] = p->second;
289  }
290 
291  return v;
292 }
293 
294 
295 //====================================================================
297 {
298  if (!elem) return std::vector<double>();
299 
300  const XMLElement *ee = elem->FirstChildElement();
301  if (!ee) return std::vector<double>();
302 
303  std::map<int, double> array;
304  int max_index = 0;
305 
306  if (strcmp(ee->Name(), "value") == 0) {
307  vout.paranoiac(m_vl, "%s::%s: plain array.\n", class_name.c_str(), __func__);
308 
309  int count = 0;
310 
311  for (const XMLElement *e = elem->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) {
312  int id = 0;
313  if (e->QueryIntAttribute("id", &id) == XML_SUCCESS) {
314  --id; /* id starts from 1 */
315  } else {
316  vout.general(m_vl, "%s::%s: array index not found.\n", class_name.c_str(), __func__);
317  id = count;
318  }
319 
320  if (id < 0) {
321  vout.crucial(m_vl, "%s::%s: inappropriate array index %d.\n", class_name.c_str(), __func__, id);
322  exit(EXIT_FAILURE);
323  }
324 
325  if (id > max_index) {
326  max_index = id;
327  }
328 
329  double val = EvalExpr(e->GetText()).parse();
330 
331  vout.paranoiac(m_vl, "%s::%s: id = %d, expr = %s, value = %20.16e\n", class_name.c_str(), __func__, id, e->GetText(), val);
332 
333  array[id] = val;
334  ++count;
335  }
336  } else {
337  vout.paranoiac(m_vl, "%s::%s: directional array.\n", class_name.c_str(), __func__);
338 
339  for (const XMLElement *e = elem->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) {
340  int id = 0;
341 
342  std::string tag = std::string(e->Name());
343 
344  if (tag == "x") {
345  id = 0;
346  } else if (tag == "y") {
347  id = 1;
348  } else if (tag == "z") {
349  id = 2;
350  } else if (tag == "t") {
351  id = 3;
352  } else {
353  vout.crucial("%s::%s: unknown array index \"%s\".\n", class_name.c_str(), __func__, tag.c_str());
354  exit(EXIT_FAILURE);
355  }
356 
357  if (id > max_index) {
358  max_index = id;
359  }
360 
361  double val = EvalExpr(e->GetText()).parse();
362 
363  vout.paranoiac(m_vl, "%s::%s: id = %s (%d), expr = %s, value = %20.16e\n", class_name.c_str(), __func__, tag.c_str(), id, e->GetText(), val);
364 
365  array[id] = val;
366  }
367  }
368 
369  vout.paranoiac(m_vl, "%s::%s: max_index = %d\n", class_name.c_str(), __func__, max_index);
370 
371  std::vector<double> v(max_index + 1);
372 
373  for (std::map<int, double>::const_iterator p = array.begin(); p != array.end(); ++p) {
374  v[p->first] = p->second;
375  }
376 
377  return v;
378 }
379 
380 
381 //====================================================================
382 //============================================================END=====
bool find_int(const string &) const
Definition: parameters.cpp:220
void read_params(const std::string &params_file, Parameters *params)
read parameters from file.
BridgeIO vout
Definition: bridgeIO.cpp:278
static void abort()
terminate communicator
XMLError Parse(const char *xml, size_t nBytes=(size_t)(-1))
Definition: tinyxml2.cpp:1861
void general(const char *format,...)
Definition: bridgeIO.cpp:65
void set_int(const string &key, const int value)
Definition: parameters.cpp:262
void set_double_vector(const string &key, const std::vector< double > &value)
Definition: parameters.cpp:289
bool find_double(const string &) const
Definition: parameters.cpp:227
bool find_Parameters(const string &) const
Definition: parameters.cpp:255
static int broadcast(size_t size, void *data, int sender)
Class for parameters.
Definition: parameters.h:38
void set_VerboseLevel(Bridge::VerboseLevel value)
Definition: parameters.cpp:316
const char * GetErrorStr2() const
Return a possibly helpful secondary diagnostic location or string.
Definition: tinyxml2.h:1719
Parameters * get_Parameters(const string &key) const
Definition: parameters.cpp:102
void process_params(const char *buf, Parameters *params)
read parameters from input file stream.
void set_string(const string &key, const string &value)
Definition: parameters.cpp:298
bool find_string(const string &) const
Definition: parameters.cpp:248
const XMLElement * FirstChildElement(const char *value=0) const
Definition: tinyxml2.cpp:770
const char * GetText() const
Definition: tinyxml2.cpp:1300
EvalExpr class for algebraic expression in parameter strings.
Definition: evalexpr.h:39
bool find_double_vector(const string &) const
Definition: parameters.cpp:241
std::vector< int > convert_to_int_vector(const tinyxml2::XMLElement *elem)
convert from string to int vector.
void paranoiac(const char *format,...)
Definition: bridgeIO.cpp:99
void traverse(const tinyxml2::XMLElement *elem, Parameters *params)
static const std::string class_name
void crucial(const char *format,...)
Definition: bridgeIO.cpp:48
const char * GetErrorStr1() const
Return a possibly helpful diagnostic location or string.
Definition: tinyxml2.h:1715
void set_double(const string &key, const double value)
Definition: parameters.cpp:271
Bridge::VerboseLevel vl
Definition: checker.cpp:18
const XMLElement * NextSiblingElement(const char *value=0) const
Get the next (right) sibling element of this node, with an optionally supplied name.
Definition: tinyxml2.cpp:798
VerboseLevel
Definition: bridgeIO.h:39
static int broadcast(int count, double *data, int sender)
broadcast array of double from sender.
void traverse_item(const tinyxml2::XMLElement *elem, Parameters *params)
static int nodeid()
alternative name for self().
Definition: communicator.h:92
std::vector< double > convert_to_double_vector(const tinyxml2::XMLElement *elem)
convert from string to double vector.
void set_int_vector(const string &key, const std::vector< int > &value)
Definition: parameters.cpp:280
bool find_int_vector(const string &) const
Definition: parameters.cpp:234
const char * ErrorName() const
Definition: tinyxml2.cpp:1909
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:28
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1181