Xyce  6.1
N_DEV_Print.C
Go to the documentation of this file.
1 //-------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2015 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_Print.C,v $
27 //
28 // Purpose :
29 //
30 //
31 //
32 // Special Notes :
33 //
34 //
35 // Creator : David Baur
36 //
37 // Creation Date :
38 //
39 // Revision Information:
40 // ---------------------
41 //
42 // Revision Number: $Revision: 1.14.2.1 $
43 //
44 // Revision Date : $Date: 2015/04/02 18:20:09 $
45 //
46 // Current Owner : $Author: tvrusso $
47 //-------------------------------------------------------------------------
48 
49 #include <Xyce_config.h>
50 
51 #include <map>
52 #include <utility>
53 #include <vector>
54 #include <iostream>
55 
56 #include <N_DEV_Algorithm.h>
57 #include <N_DEV_CompositeParam.h>
58 #include <N_DEV_Const.h>
59 #include <N_DEV_Device.h>
60 #include <N_DEV_DeviceInstance.h>
61 #include <N_DEV_DeviceMaster.h>
62 #include <N_DEV_DeviceModel.h>
63 #include <N_DEV_Dump.h>
64 #include <N_UTL_IndentStreamBuf.h>
65 #include <N_DEV_LaTexDoc.h>
66 #include <N_DEV_Print.h>
67 
68 namespace Xyce {
69 namespace Device {
70 
71 namespace {
72 
73 struct DeviceInstanceCmp : public std::binary_function<DeviceInstance, DeviceInstance, bool>
74 {
75  bool operator()(const DeviceInstance &entity_0, const DeviceInstance &entity_1) const
76  {
77  return less_nocase(entity_0.getName().getEncodedName(), entity_1.getName().getEncodedName());
78  }
79  bool operator()(const DeviceInstance *entity_0, const DeviceInstance *entity_1) const
80  {
81  return less_nocase(entity_0->getName().getEncodedName(), entity_1->getName().getEncodedName());
82  }
83 };
84 
85 }
86 //-----------------------------------------------------------------------------
87 // Function : printOutModels
88 // Purpose : debugging tool
89 // Special Notes :
90 // Scope : public
91 // Creator : Eric Keiter, SNL, factory_block, Parallel Computational Sciences
92 // Creation Date : 2/03/06
93 //-----------------------------------------------------------------------------
94 std::ostream &print(std::ostream &os, const Device &device)
95 {
96  std::vector<DeviceModel *> models;
97  getDeviceModels(device, std::back_inserter(models));
98 
99  os << std::endl
100  << std::endl << section_divider << std::endl
101  << "Number of " << device.getName() << " models: " << models.size() << std::endl;
102 
103  int i = 0;
104  for (std::vector<DeviceModel *>::const_iterator it = models.begin(); it != models.end(); ++it, ++i)
105  {
106  os << i << ": name = " << (*it)->getName() << " type = " << (*it)->getType() << " level = " << (*it)->getLevel() << std::endl;
107 
108  (*it)->printOutInstances(os);
109  }
110  os << section_divider << std::endl;
111 
112  return os;
113 }
114 
115 typedef std::map<std::string, std::pair<DeviceModel *, std::vector<DeviceInstance *> > > UglyMap;
116 
118 {
119  UglyDeviceModelOp(const Device &device, UglyMap &model_map)
120  : device_(device),
121  modelMap_(model_map),
122  deviceCount_(0)
123  {}
124 
125  virtual bool operator()(DeviceModel *model) {
126  std::pair<UglyMap::iterator, bool> result = modelMap_.insert(UglyMap::value_type(model->getName(), std::make_pair(model, std::vector<DeviceInstance *>())));
127 
128  if (result.second) {
129  getDeviceInstances(*model, std::back_inserter((*result.first).second.second));
130  if ((*result.first).second.second.empty())
131  modelMap_.erase(result.first);
132  else {
133  deviceCount_ += (*result.first).second.second.size();
134  std::sort((*result.first).second.second.begin(), (*result.first).second.second.end(), DeviceInstanceCmp());
135  }
136  }
137  return true;
138  }
139 
140  const Device & device_;
141  UglyMap & modelMap_;
143 };
144 
145 
146 
147 //-----------------------------------------------------------------------------
148 // Function : DeviceMaster:printDotOpOutput
149 // Purpose :
150 // Special Notes :
151 // Scope : public
152 // Creator : Eric Keiter, SNL, factory_block, Parallel Computational Sciences
153 // Creation Date : 5/4/12
154 //-----------------------------------------------------------------------------
155 std::ostream &printDotOpOutput (std::ostream &os, const Device &device)
156 {
157  static const int stdWidth = 15;
158 
159 // Output models
160  UglyMap model_map;
161 
162  UglyDeviceModelOp op(device, model_map);
163  device.forEachModel(op);
164 
165  os << std::endl
166  << "Number of " << device.getName() << " models: " << model_map.size() << std::endl
167  << std::setw(stdWidth) << "name ";
168 
169  if (!model_map.empty())
170  {
171  int column_count = 1;
172  for (UglyMap::const_iterator it_model = model_map.begin(); it_model != model_map.end(); ++it_model, ++column_count)
173  {
174  if (column_count%8 == 0)
175  os << std::endl;
176  os << std::setw(stdWidth) << (*it_model).first ;
177  }
178  os << std::endl;
179 
180  os << std::setw(stdWidth) << "type ";
181  column_count = 1;
182  for (UglyMap::const_iterator it_model = model_map.begin(); it_model != model_map.end(); ++it_model, ++column_count)
183  {
184  if (column_count%8 == 0)
185  os << std::endl;
186  os << std::setw(stdWidth) << (*it_model).second.first->getType() ;
187  }
188  os << std::endl;
189 
190  os << std::setw(stdWidth) << "level ";
191  column_count = 1;
192  for (UglyMap::const_iterator it_model = model_map.begin(); it_model != model_map.end(); ++it_model, ++column_count)
193  {
194  if (column_count%8 == 0)
195  os << std::endl;
196  os << std::setw(stdWidth) << (*it_model).second.first->getLevel() ;
197  }
198  os << std::endl;
199 
200  const ParameterMap &parMap = (*model_map.begin()).second.first->getParameterMap();
201 
202  column_count = 1;
203  for (ParameterMap::const_iterator it_parameter = parMap.begin(); it_parameter != parMap.end(); ++it_parameter)
204  {
205  for (UglyMap::const_iterator it_model = model_map.begin(); it_model != model_map.end(); ++it_model, ++column_count)
206  {
207  if (it_model == model_map.begin())
208  {
209  if (column_count%8 == 0)
210  os << std::endl;
211  os << std::setw(stdWidth) << (*it_parameter).first;
212  }
213 
214  os << std::setw(stdWidth);
215  printParameter(os, *(*it_model).second.first, (*it_parameter).first, *(*it_parameter).second);
216  }
217  os << std::endl;
218  }
219  os << std::endl;
220 
221 // Output instances
222  os << "Number of " << device.getName() << " instances: " << op.deviceCount_ << std::endl
223  << std::setw(stdWidth) << "name ";
224 
225  column_count = 1;
226  for (UglyMap::const_iterator it_model = model_map.begin(); it_model != model_map.end(); ++it_model)
227  {
228  const std::vector<DeviceInstance *> &instance_list = (*it_model).second.second;
229 
230  for (std::vector<DeviceInstance *>::const_iterator it_instance = instance_list.begin(); it_instance != instance_list.end(); ++it_instance, ++column_count)
231  {
232  if (column_count%8 == 0)
233  os << std::endl;
234  os << std::setw(stdWidth) << (*it_instance)->getName();
235  }
236  }
237  os << std::endl
238  << std::setw(stdWidth) << "model ";
239 
240 
241  const DeviceInstance &first_instance = *(*model_map.begin()).second.second.front();
242 
243  column_count = 1;
244  for (UglyMap::const_iterator it_model = model_map.begin(); it_model != model_map.end(); ++it_model)
245  {
246  const DeviceModel &model = *(*it_model).second.first;
247  const std::vector<DeviceInstance *> &instance_list = (*it_model).second.second;
248 
249  if ( !instance_list.empty () ) {
250  for (std::vector<DeviceInstance *>::const_iterator it_instance = instance_list.begin(); it_instance != instance_list.end(); ++it_instance, ++column_count)
251  {
252  if (column_count%8 == 0)
253  os << std::endl;
254  os << std::setw(stdWidth) << model.getName();
255  }
256  }
257  }
258 
259  os << std::endl;
260 
261  // output instance parameters:
262  const ParameterMap &parameter_map = first_instance.getParameterMap();
263  for (ParameterMap::const_iterator it_parameter = parameter_map.begin() ; it_parameter != parameter_map.end(); ++it_parameter)
264  {
265  os << std::setw(stdWidth) << it_parameter->first;
266 
267  column_count = 1;
268  for (UglyMap::const_iterator it_model = model_map.begin(); it_model != model_map.end(); ++it_model)
269  {
270  const DeviceModel &model = *(*it_model).second.first;
271  const std::vector<DeviceInstance *> &instance_list = (*it_model).second.second;
272 
273  if ( !instance_list.empty () ) {
274  for (std::vector<DeviceInstance *>::const_iterator it_instance = instance_list.begin(); it_instance != instance_list.end(); ++it_instance, ++column_count)
275  {
276  if (column_count%8 == 0)
277  os << std::endl;
278  os << std::setw(stdWidth);
279  printParameter(os, *(*it_instance), (*it_parameter).first, *(*it_parameter).second);
280  }
281  }
282  }
283  os << std::endl;
284  }
285  os << std::endl;
286  }
287 
288  return os;
289 }
290 
291 
292 //-----------------------------------------------------------------------------
293 // Function : printParameter
294 //
295 // Purpose : This function finds a parameter in the par table, and then
296 // formats its value in a string.
297 //
298 // Special Notes :
299 // Scope : public
300 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
301 // Creation Date : 5/4/12
302 //-----------------------------------------------------------------------------
303 std::ostream &printParameter(std::ostream &os, const ParameterBase &entity, const std::string &name, const Descriptor &param)
304 {
305  if (param.isType<double>())
306  {
307  if (isTempParam(name))
308  {
309  os << param.value<double>(entity) - CONSTCtoK;
310  }
311  else
312  {
313  os << param.value<double>(entity);
314  }
315  }
316  else if (param.isType<bool>())
317  {
318  os << param.value<bool>(entity);
319  }
320  else if (param.isType<int>())
321  {
322  os << param.value<int>(entity);
323  }
324  else if (param.isType<long>())
325  {
326  os << param.value<long>(entity);
327  }
328  else if (param.isType<std::string>())
329  {
330  os << param.value<std::string>(entity);
331  }
332  else if (param.isType<std::vector<std::string> >())
333  {
334  os << "string[]";
335  // const std::vector<std::string> &string_vector = param.value<std::vector<std::string> >(entity);
336  // os << " string[" << string_vector.size() << "]" << std::endl;
337  // {
338  // for (std::vector<std::string>::const_iterator it = string_vector.begin(), end = string_vector.end(); it != end; ++it)
339  // {
340  // os << " " << *it;
341  // }
342  // }
343  }
344  else if (param.isType<std::vector<int> >())
345  {
346  os << "int[]";
347  // const std::vector<int> &int_vector = param.value<std::vector<int> >(entity);
348  // os << " int[" << int_vector.size() << "]" << std::endl;
349  // {
350  // for (std::vector<int>::const_iterator it = int_vector.begin(), end = int_vector.end(); it != end; ++it)
351  // {
352  // os << " " << *it;
353  // }
354  // }
355  }
356  else if (param.isType<std::vector<double> >())
357  {
358  os << "double[]";
359  // const std::vector<double> &double_vector = param.value<std::vector<double> >(entity);
360  // os << " double[" << double_vector.size() << "]" << std::endl;
361  // {
362  // for (std::vector<double>::const_iterator it = double_vector.begin(), end = double_vector.end(); it != end; ++it)
363  // {
364  // os << " " << *it;
365  // }
366  // }
367  }
368  else if (param.hasCompositeData())
369  {
370 
371  os << "composite";
372  // if (param.isType<CompositeMap>()) {
373  // const CompositeMap &composite_map = param.value<CompositeMap>(entity);
374  // for (CompositeMap::const_iterator it = composite_map.begin(), end = composite_map.end(); it != end; ++it)
375  // {
376  // os << "[" << (*it).first << "] ";
377  // printCompositeParameters(os, *(*it).second);
378  // }
379  // }
380  // else if (param.isType<CompositeVector>()) {
381  // const CompositeVector &composite_vector = param.value<CompositeVector>(entity);
382  // for (CompositeVector::const_iterator it = composite_vector.begin(), end = composite_vector.end(); it != end; ++it)
383  // {
384  // os << "[" << std::distance(composite_vector.begin(), it) << "] ";
385  // printCompositeParameters(os, *(*it));
386  // }
387  // }
388  }
389 
390  return os;
391 }
392 
393 std::ostream &printCompositeParameters(std::ostream &os, const CompositeParam &composite)
394 {
395  const ParameterMap &parameter_map = composite.getParameterMap();
396  for (ParameterMap::const_iterator it = composite.getParameterMap().begin(), end = composite.getParameterMap().end(); it != end ;++it)
397  {
398  printParameter(os, composite, (*it).first, *(*it).second);
399  os << " ";
400  }
401 
402  return os;
403 }
404 
405 
406 //-----------------------------------------------------------------------------
407 // Function : handleParameterOutputs_
408 //
409 // Purpose : Handles command line arguments like -doc, to output model
410 // parameters either to stdout or to files, depending on which
411 // option is chosen.
412 //
413 // Special Notes : erkeite: This function is called from parseCommandLine. I
414 // moved this code out of that function because that function had
415 // gotten too long and confusing.
416 //
417 // Scope : Public
418 // Creator : Eric Keiter
419 // Creation Date : 10/31/07
420 //-----------------------------------------------------------------------------
421 void
423  OutputMode::Mode format,
424  std::string option_device_name,
425  int option_device_level,
426  bool print_model,
427  bool print_instance)
428 {
429  typedef std::map<std::pair<std::string, int>, Device *> DeviceMap;
430 
431  if (format == OutputMode::PARAM) {
432  typedef std::map<NameLevelKey, Configuration *, NameLevelKeyLess> OrderedConfigurationMap;
433  const OrderedConfigurationMap configuration_map(Configuration::getConfigurationMap().begin(), Configuration::getConfigurationMap().end());
434  for (OrderedConfigurationMap::const_iterator it = configuration_map.begin(), end = configuration_map.end(); it != end; ++it)
435  {
436  Xyce::dout() << (*it).first << Xyce::Util::push << std::endl
437  << *(*it).second << Xyce::Util::pop << std::endl;
438  }
439  }
440  else {
442  for (Configuration::ConfigurationMap::const_iterator it = configuration_map.begin(), end = configuration_map.end(); it != end; ++it)
443  {
444  const NameLevelKey &device_key = (*it).first;
445 
446  std::string device_name = (*it).first.first;
447  const int device_level = (*it).first.second;
448 
449  device_name[0] = toupper(device_name[0]);
450 
451  if ((option_device_name.empty() || Xyce::equal_nocase(option_device_name, device_name)) && (option_device_level == -1 || option_device_level == device_level)) {
452  Configuration &configuration = *(*it).second;
453 
454  std::string device_description = configuration.getName();
455  ParametricData<void> &instance_parameters = configuration.getInstanceParameters();
456  ParametricData<void> &model_parameters = configuration.getModelParameters();
457 
458  if (configuration.getName() == "Behavioral Digital")
459  device_name = "Digital";
460 
461  if (print_instance && !instance_parameters.getMap().empty()) {
462  std::ostringstream path;
463  path << device_name << "_" << device_level << "_Device_Instance" << "_Params.tex";
464 
465  std::ofstream os(path.str().c_str(), std::ios_base::out);
466  os << "% This table was generated by Xyce:" << std::endl
467  << "% Xyce " << (format == OutputMode::DOC_CAT ? "-doc_cat " : "-doc ")
468  << device_name << " " << device_level << std::endl
469  << "%" << std::endl;
470 
471  laTexDevice(os, device_name, device_level, 0, device_description, instance_parameters, format);
472  }
473 
474  if (print_model && !model_parameters.getMap().empty()) {
475  std::ostringstream path;
476  path << device_name << "_" << device_level << "_Device_Model" << "_Params.tex";
477 
478  std::ofstream os(path.str().c_str(), std::ios_base::out);
479 
480  os << "% This table was generated by Xyce:" << std::endl
481  << "% Xyce " << (format == OutputMode::DOC_CAT ? "-doc_cat " : "-doc ")
482  << device_name << " " << device_level << std::endl
483  << "%" << std::endl;
484 
485  laTexDevice(os, device_name, device_level, 1, device_description, model_parameters, format);
486  }
487  }
488  }
489  }
490 }
491 
492 } // namespace Device
493 } // namespace Xyce
494 
ParametricData< void > & getModelParameters() const
Returns the model parameter descriptions.
std::ostream & printDotOpOutput(std::ostream &os, const Device &device)
Definition: N_DEV_Print.C:155
#define CONSTCtoK
Definition: N_DEV_Const.h:52
UglyDeviceModelOp(const Device &device, UglyMap &model_map)
Definition: N_DEV_Print.C:119
Pure virtual class to augment a linear system.
void getDeviceInstances(const D &d, Out it)
Calls forEachInstance() on d which iterates through all the instances copies them to the output itera...
unordered_map< std::string, Descriptor *, HashNoCase, EqualNoCase > ParameterMap
Definition: N_DEV_fwd.h:159
Base class for all parameters.
Definition: N_DEV_Pars.h:169
bool isTempParam(const std::string &name)
Returns true if the name is TNOM or TEMP.
Definition: N_DEV_Pars.h:1705
void getDeviceModels(const D &d, Out it)
Calls forEachModel() on d which iterates through all the models copies them to the output iterator...
void handleParameterOutputs(OutputMode::Mode format, std::string option_device_name, int option_device_level, bool print_model, bool print_instance)
Definition: N_DEV_Print.C:422
const ParameterMap & getParameterMap() const
const std::string & getName() const
const T & value(const ParameterBase &entity) const
Returns the value of the parameter for the entity.
Definition: N_DEV_Pars.h:871
ParametricData< void > & getInstanceParameters() const
Returns the instance parameter descriptions.
Class ParametricData manages the configuration information and the parameter binding map...
Definition: N_DEV_Pars.h:1303
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
Class Descriptor describes the parameters stored in the ParametricData parameter map.
Definition: N_DEV_Pars.h:546
Class Configuration contains device configuration data.
bool hasCompositeData() const
Definition: N_DEV_Pars.h:605
std::ostream & print(std::ostream &os, const Device &device)
Definition: N_DEV_Print.C:94
static const ConfigurationMap & getConfigurationMap()
Returns the configuration map of the system.
unordered_map< NameLevelKey, Configuration * > ConfigurationMap
virtual bool operator()(DeviceModel *model)
Definition: N_DEV_Print.C:125
bool isType() const
Tests entry data type.
Definition: N_DEV_Pars.h:597
const std::string & getName() const
Returns the device name.
std::ostream & printCompositeParameters(std::ostream &os, const CompositeParam &composite)
Definition: N_DEV_Print.C:393
ParameterMap & getMap()
Gets the parameter binding map map.
Definition: N_DEV_Pars.h:1341
std::ostream & printParameter(std::ostream &os, const ParameterBase &entity, const std::string &name, const Descriptor &param)
Definition: N_DEV_Print.C:303
std::map< std::string, std::pair< DeviceModel *, std::vector< DeviceInstance * > > > UglyMap
Definition: N_DEV_Print.C:115
CompositeParam is the base class for classes that wish to only manage the processing of parameter dat...
const ParameterMap & getParameterMap() const
getParameterMap returns the parameter map which describes the parameters.
std::ostream & laTexDevice(std::ostream &os, const std::string &name, const int level, const int type, const std::string &device_description, const ParametricData< void > &parameters, const OutputMode::Mode format)