SST  8.0.0
StructuralSimulationToolkit
componentregisterstat_impl.h
1 // Copyright 2009-2018 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2018, NTESS
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 
13 #ifndef _H_SST_CORE_COMP_REG_STAT__
14 #define _H_SST_CORE_COMP_REG_STAT__
15 
16 // THIS IS THE IMPLEMENTATION OF Component::registerStatistic(...) code.
17 // It is placed in this implementation file to provide a clean interface for
18 // the class Component.
19 
20 //template <typename T>
21 //Statistic<T>* registerStatisticCore(std::string statName, std::string statSubId = 0)
22 //{
23  std::string fullStatName;
24  bool statGood = true;
25  bool nameFound = false;
26  StatisticBase::StatMode_t statCollectionMode = StatisticBase::STAT_MODE_COUNT;
27  Output & out = getSimulation()->getSimulationOutput();
28  StatisticProcessingEngine *engine = StatisticProcessingEngine::getInstance();
29  UnitAlgebra collectionRate;
30  Params statParams;
31  std::string statRateParam;
32  std::string statTypeParam;
33  Statistic<T>* statistic = NULL;
34 
35 
36  // Build a name to report errors against
37  fullStatName = StatisticBase::buildStatisticFullName(getName().c_str(), statName, statSubId);
38 
39  // Make sure that the wireup has not been completed
40  if (true == getSimulation()->isWireUpFinished()) {
41  // We cannot register statistics AFTER the wireup (after all components have been created)
42  out.fatal(CALL_INFO, 1, "ERROR: Statistic %s - Cannot be registered after the Components have been wired up. Statistics must be registered on Component creation.; exiting...\n", fullStatName.c_str());
43  }
44 
45  /* Create the statistic in the "owning" component. That should just be us,
46  * in the case of 'modern' subcomponents. For legacy subcomponents, that will
47  * be the owning component. We've got the ID of that component in 'my_info->getID()'
48  */
49  BaseComponent *owner = this->getStatisticOwner();
50 
51  // // Verify here that name of the stat is one of the registered
52  // // names of the component's ElementInfoStatistic.
53  // if (false == doesComponentInfoStatisticExist(statName)) {
54  // fprintf(stderr, "Error: Statistic %s name %s is not found in ElementInfoStatistic, exiting...\n", fullStatName.c_str(), statName.c_str());
55  // exit(1);
56  // }
57 
58  // Check each entry in the StatEnableList (from the ConfigGraph via the
59  // Python File) to see if this Statistic is enabled, then check any of
60  // its critical parameters
61  for ( auto & si : *my_info->getStatEnableList() ) {
62  // First check to see if the any entry in the StatEnableList matches
63  // the Statistic Name or the STATALLFLAG. If so, then this Statistic
64  // will be enabled. Then check any critical parameters
65  if ((std::string(STATALLFLAG) == si.name) || (statName == si.name)) {
66  // Identify what keys are Allowed in the parameters
67  Params::KeySet_t allowedKeySet;
68  allowedKeySet.insert("type");
69  allowedKeySet.insert("rate");
70  allowedKeySet.insert("startat");
71  allowedKeySet.insert("stopat");
72  allowedKeySet.insert("resetOnRead");
73  si.params.pushAllowedKeys(allowedKeySet);
74 
75  // We found an acceptable name... Now check its critical Parameters
76  // Note: If parameter not found, defaults will be provided
77  statTypeParam = si.params.find<std::string>("type", "sst.AccumulatorStatistic");
78  statRateParam = si.params.find<std::string>("rate", "0ns");
79 
80  collectionRate = UnitAlgebra(statRateParam);
81  statParams = si.params;
82  nameFound = true;
83  break;
84  }
85  }
86 
87  // Did we find a matching enable name?
88  if (false == nameFound) {
89  statGood = false;
90  out.verbose(CALL_INFO, 1, 0, " Warning: Statistic %s is not enabled in python script, statistic will not be enabled...\n", fullStatName.c_str());
91  }
92 
93  if (true == statGood) {
94  // Check that the Collection Rate is a valid unit type that we can use
95  if ((true == collectionRate.hasUnits("s")) ||
96  (true == collectionRate.hasUnits("hz")) ) {
97  // Rate is Periodic Based
98  statCollectionMode = StatisticBase::STAT_MODE_PERIODIC;
99  } else if (true == collectionRate.hasUnits("event")) {
100  // Rate is Count Based
101  statCollectionMode = StatisticBase::STAT_MODE_COUNT;
102  } else if (0 == collectionRate.getValue()) {
103  // Collection rate is zero and has no units, so make up a periodic flavor
104  collectionRate = UnitAlgebra("0ns");
105  statCollectionMode = StatisticBase::STAT_MODE_PERIODIC;
106  } else {
107  // collectionRate is a unit type we dont recognize
108  out.fatal(CALL_INFO, 1, "ERROR: Statistic %s - Collection Rate = %s not valid; exiting...\n", fullStatName.c_str(), collectionRate.toString().c_str());
109  }
110  }
111 
112  if (true == statGood) {
113  // Instantiate the Statistic here defined by the type here
114  statistic = engine->createStatistic<T>(owner, statTypeParam, statName, statSubId, statParams);
115  if (NULL == statistic) {
116  out.fatal(CALL_INFO, 1, "ERROR: Unable to instantiate Statistic %s; exiting...\n", fullStatName.c_str());
117  }
118 
119  // Check that the statistic supports this collection rate
120  if (false == statistic->isStatModeSupported(statCollectionMode)) {
121  if (StatisticBase::STAT_MODE_PERIODIC == statCollectionMode) {
122  out.verbose(CALL_INFO, 1, 0, " Warning: Statistic %s Does not support Periodic Based Collections; Collection Rate = %s\n", fullStatName.c_str(), collectionRate.toString().c_str());
123  } else {
124  out.verbose(CALL_INFO, 1, 0, " Warning: Statistic %s Does not support Event Based Collections; Collection Rate = %s\n", fullStatName.c_str(), collectionRate.toString().c_str());
125  }
126  statGood = false;
127  }
128 
129  // Tell the Statistic what collection mode it is in
130  statistic->setRegisteredCollectionMode(statCollectionMode);
131  }
132 
133  // If Stat is good, Add it to the Statistic Processing Engine
134  if (true == statGood) {
135  statGood = engine->registerStatisticWithEngine<T>(statistic);
136  }
137 
138  if (false == statGood ) {
139  // Delete the original statistic (if created), and return a NULL statistic instead
140  if (NULL != statistic) {
141  delete statistic;
142  }
143 
144  // Instantiate the Statistic here defined by the type here
145  statTypeParam = "sst.NullStatistic";
146  statistic = engine->createStatistic<T>(owner, statTypeParam, statName, statSubId, statParams);
147  if (NULL == statistic) {
148  statGood = false;
149  out.fatal(CALL_INFO, 1, "ERROR: Unable to instantiate Null Statistic %s; exiting...\n", fullStatName.c_str());
150  }
151  engine->registerStatisticWithEngine<T>(statistic);
152  }
153 
154  // Register the new Statistic with the Statistic Engine
155  return statistic;
156 //}
157 
158 #endif //_H_SST_CORE_COMP_REG_STAT__