SST  6.1.0
StructuralSimulationToolkit
introspectedComponent.h
1 // Copyright 2009-2016 Sandia Corporation. Under the terms
2 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2016, Sandia Corporation
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_INTROSPECTED_COMPONENT_H
13 #define SST_CORE_INTROSPECTED_COMPONENT_H
14 #include <sst/core/sst_types.h>
15 
16 #include <cmath>
17 //#include <deque>
18 #include <iostream>
19 #include <list>
20 #include <map>
21 
22 #if defined(__x86_64__) && defined(__APPLE__) && !defined(__USE_ISOC99)
23 // Boost interval sometimes doesn't detect the correct method for
24 // manipulating FP rounting on MacOS
25 #define __USE_ISOC99 1
26 #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
27 #pragma GCC diagnostic push
28 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
29 #endif
30 #include <boost/numeric/interval.hpp>
31 #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
32 #pragma GCC diagnostic pop
33 #endif
34 #undef __USE_ISOC99
35 #else
36 
37 #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
38 #pragma GCC diagnostic push
39 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
40 #endif
41 #include <boost/numeric/interval.hpp>
42 #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
43 #pragma GCC diagnostic pop
44 #endif
45 
46 #endif
47 #include <boost/io/ios_state.hpp>
48 #include <boost/any.hpp>
49 
50 #include <sst/core/component.h>
51 //#include <sst/core/linkMap.h>
52 #include <sst/core/timeConverter.h>
53 
54 namespace io_interval { // from boost interval io example (io_wide)
55 template<class T, class Policies, class CharType, class CharTraits>
56 std::basic_ostream<CharType, CharTraits>
57 &operator<<(std::basic_ostream<CharType, CharTraits> &stream,
58  const boost::numeric::interval<T, Policies> &value)
59 {
60  if (empty(value)) {
61  return stream << "nothing";
62  } else if (singleton(value)) {
63  boost::io::ios_precision_saver state(stream, std::numeric_limits<T>::digits10);
64  return stream << lower(value);
65  } else if (zero_in(value)) {
66  return stream << "0~";
67  } else {
68  std::streamsize p = stream.precision();
69  p = (p > 15) ? 15 : p - 1;
70  double eps = 1.0; for(; p > 0; --p) { eps /= 10; }
71  T eps2 = static_cast<T>(eps / 2) * norm(value);
72  boost::numeric::interval<T, Policies> r = widen(value, eps2);
73  //return stream << '[' << lower(r) << ',' << upper(r) << ']';
74  return stream << median(r) << " ± " << width(r)/2;
75  }
76 }
77 }
78 
79 using boost::any_cast;
80 
81 namespace SST {
82 
83 class Introspector;
84 
85 typedef boost::numeric::interval<double> I;
86 
87 typedef struct {
88  I il1, il2, dl1, dl2, itlb, dtlb;
89  I clock, bpred, rf, io, logic;
90  I alu, fpu, mult, ib, issueQ, decoder, bypass, exeu;
91  I pipeline, lsq, rat, rob, btb, L2, mc;
92  I router, loadQ, renameU, schedulerU, L3, L1dir, L2dir;
93 } itemized_t;
94 
95 typedef struct
96 {
97  //I internalPower;
98  //I switchingPower;
99  I TDP; //thermal dynamic power
100  I runtimeDynamicPower;
101  I leakagePower; //=threshold leakage + gate leakage
102  I peak;
103  I currentPower; //=leakage + rumtimeDynamic
104  I averagePower;
105  I totalEnergy;
106  itemized_t itemizedRuntimeDynamicPower;
107  itemized_t itemizedLeakagePower;
108  itemized_t itemizedCurrentPower;
109  itemized_t itemizedTDP;
110  itemized_t itemizedPeak;
111  itemized_t itemizedTotalPower; //total energy
112  Time_t currentSimTime;
114 
115 
116 typedef std::map<ComponentId_t, Pdissipation_t> PowerDatabase;
117 
118 /**
119  * Main component object for the simulation.
120  * All models inherit from this.
121  */
123 public:
124 
125 
126  /** Constructor. Generally only called by the factory class.
127  @param id Unique component ID
128  @param sim Pointer to the global simulation object */
129  IntrospectedComponent( ComponentId_t id );
130  virtual ~IntrospectedComponent() {}
131 
132  /** List of id of introspectors that monitor this component. */
133  std::list<Introspector*> MyIntroList;
134 
135  // Power
136  /** Central power/energy database that stores power dissipation data
137  (including current power, total energy, peak power, etc) of the components
138  on the same rank.*/
139  static PowerDatabase PDB;
140  /** Register/update power dissipation data in the central power database
141  @param pusage Structure that contains power dissipation data of a component */
142  void regPowerStats(Pdissipation_t pusage);
143  /** Read power dissipation data of this component from database
144  @param c Pointer to the component that one whats to query power
145  from the central power database */
146  std::pair<bool, Pdissipation_t> readPowerStats(Component* c);
147 
148 
149  //Introspection
150  // Functor classes for monitor handling
151  ////template <typename returnT>
152  class MonitorBase {
153  public:
154  ////virtual returnT operator()() = 0;
155  virtual boost::any operator()() = 0;
156  virtual ~MonitorBase() {}
157  };
158 
159 
160  template <typename classT, typename returnT, typename argT = void>
161  class MonitorFunction : public MonitorBase{
162  private:
163  typedef returnT (classT::*PtrMember)(argT);
164  classT* object;
165  const PtrMember member;
166  argT data;
167 
168  public:
169  MonitorFunction( classT* const object, PtrMember member, argT data ) :
170  object(object),
171  member(member),
172  data(data)
173  {}
174 
175  /*returnT operator()() {
176  return (const_cast<classT*>(object)->*member)(data);
177  }*/
178  boost::any operator()() {
179  return static_cast<boost::any>( (const_cast<classT*>(object)->*member)(data) );
180  }
181  };
182 
183  template <typename classT, typename returnT>
184  class MonitorFunction<classT, returnT, void> : public MonitorBase{
185  private:
186  typedef returnT (classT::*PtrMember)();
187  const PtrMember member;
188  classT* object;
189 
190  public:
191  MonitorFunction( classT* const object, PtrMember member ) :
192  member(member),
193  object(object)
194  {}
195 
196  /*returnT operator()() {
197  return (const_cast<classT*>(object)->*member)();
198  }*/
199  boost::any operator()() {
200  return static_cast<boost::any>( (const_cast<classT*>(object)->*member)() );
201  }
202  };
203 
204  template <typename ptrT, typename idxT = void>
205  class MonitorPointer : public MonitorBase{
206  private:
207  ptrT *data;
208  idxT index;
209 
210  public:
211  MonitorPointer( ptrT* const data, idxT index ) :
212  data(data),
213  index(index)
214  {}
215 
216  boost::any operator()() {
217  return static_cast<boost::any>( *data[index] );
218  }
219  };
220 
221  template <typename ptrT>
222  class MonitorPointer<ptrT, void> : public MonitorBase{
223  private:
224  ptrT* data;
225 
226  public:
227  MonitorPointer( ptrT* const data ) :
228  data(data)
229  {}
230  boost::any operator()() {
231  //return static_cast<boost::any>( const_cast<ptrT*>(data) );
232  return static_cast<boost::any>( *data );
233  }
234  };
235 
236  /** Add the pointer to a introspector to an internal list, MyIntroList.
237  Indicates the introspector monitors the component.
238  @param name Name of the introspector that monitors the component*/
239  void registerIntrospector(std::string name);
240  /** Add the data to the map of monitors to specify which data to be monitored
241  . The map, monitorMap, stores both the name and the handler of the data.
242  @param dataName Description of the data
243  @param handler Pointer to IntrospectedComponent::MonitorBase which is to be invoked
244  in Introspector::getData()*/
245  void registerMonitor(std::string dataName, IntrospectedComponent::MonitorBase* handler);
246  /** Find monitor indicated by "dataname" from the map. This is called in Introspector::getData()
247  @param dataname name of the data*/
248  std::pair<bool, IntrospectedComponent::MonitorBase*> getMonitor(std::string dataname);
249  /** 'Component-push' mechanism. Component asks its introspector(s) to pull data in.*/
250  void triggerUpdate();
251 
252  /** Get the period set by defaultTimeBase, which is usually set by Component::registerClock().
253  This can be used by clever components to ensure they only compute statistics data when needed.
254  Returns the time between two handler function calls. (For introspectors, this means time
255  between introspections.) */
256  SimTime_t getFreq() {return defaultTimeBase->getFactor();}
257 
258 
259  /** Check if current is the time for the component to push/report data (e.g. power)
260  by querying its introspector.
261  @param current Current cycle from component's view
262  @param type Name of the introspector that component queries about push frequency*/
263  bool isTimeToPush(Cycle_t current, const char *name);
264  /** Return the value of the integer data indicated by "dataID" and "index" (if the data structure is a table).
265  Each component type needs to implement its own getIntData. The function is usually called by introspector pull
266  mechanism.
267  @param dataID ID of the integer data
268  @param index of the table (if the data structure is a table); default is set to 0 */
269  //virtual uint64_t getIntData(int dataID, int index=0){ return 0;}
270  /** Return the value of the double data indicated by "dataID" and "index" (if the data structure is a table).
271  Each component type needs to implement its own getDoubleData. The function is usually called by introspector pull
272  mechanism.
273  @param dataID ID of the integer data
274  @param index of the table (if the data structure is a table); default is set to 0 */
275  //virtual double getDoubleData(int dataID, int index=0){ return 0;}
276 
277 
278 
279  typedef std::map<std::string, IntrospectedComponent::MonitorBase*> MonitorMap_t;
280 
281 protected:
282  /** Database of monitors (arbitrary data that a
283  compopent wishes to be monitored) available through
284  introspectedComponent::MonitorBase* getMonitor() */
285  MonitorMap_t monitorMap;
286 
287 
288 protected:
289  IntrospectedComponent(); // For serialization only
290 
291 private:
292 };
293 
294 } //namespace SST
295 
296 #endif // SST_CORE_INTROSPECTED_COMPONENT_H
Definition: introspectedComponent.h:205
bool isTimeToPush(Cycle_t current, const char *name)
Check if current is the time for the component to push/report data (e.g.
Definition: introspectedComponent.cc:177
SimTime_t getFactor()
Return the factor used for conversions with Core Time.
Definition: timeConverter.h:50
std::pair< bool, IntrospectedComponent::MonitorBase * > getMonitor(std::string dataname)
Find monitor indicated by "dataname" from the map.
Definition: introspectedComponent.cc:142
static PowerDatabase PDB
Central power/energy database that stores power dissipation data (including current power...
Definition: introspectedComponent.h:139
void registerMonitor(std::string dataName, IntrospectedComponent::MonitorBase *handler)
Add the data to the map of monitors to specify which data to be monitored
Definition: introspectedComponent.cc:126
void triggerUpdate()
'Component-push' mechanism.
Definition: introspectedComponent.cc:159
Main component object for the simulation.
Definition: component.h:56
void regPowerStats(Pdissipation_t pusage)
Register/update power dissipation data in the central power database.
Definition: introspectedComponent.cc:43
Definition: introspectedComponent.h:54
Definition: action.cc:17
TimeConverter * defaultTimeBase
Timebase used if no other timebase is specified for calls like Component::getCurrentSimTime().
Definition: component.h:357
std::map< std::string, IntrospectedComponent::MonitorBase * > MonitorMap_t
Return the value of the integer data indicated by "dataID" and "index" (if the data structure is a ta...
Definition: introspectedComponent.h:279
std::list< Introspector * > MyIntroList
List of id of introspectors that monitor this component.
Definition: introspectedComponent.h:133
std::pair< bool, Pdissipation_t > readPowerStats(Component *c)
Read power dissipation data of this component from database.
Definition: introspectedComponent.cc:71
Definition: introspectedComponent.h:152
Main component object for the simulation.
Definition: introspectedComponent.h:122
void registerIntrospector(std::string name)
Add the pointer to a introspector to an internal list, MyIntroList.
Definition: introspectedComponent.cc:104
Definition: introspectedComponent.h:161
Definition: introspectedComponent.h:87
SimTime_t getFreq()
Get the period set by defaultTimeBase, which is usually set by Component::registerClock().
Definition: introspectedComponent.h:256
Definition: introspectedComponent.h:95
MonitorMap_t monitorMap
Database of monitors (arbitrary data that a compopent wishes to be monitored) available through intro...
Definition: introspectedComponent.h:285