SST  11.1.0
StructuralSimulationToolkit
configGraph.h
1 // -*- c++ -*-
2 
3 // Copyright 2009-2021 NTESS. Under the terms
4 // of Contract DE-NA0003525 with NTESS, the U.S.
5 // Government retains certain rights in this software.
6 //
7 // Copyright (c) 2009-2021, NTESS
8 // All rights reserved.
9 //
10 // This file is part of the SST software package. For license
11 // information, see the LICENSE file in the top level directory of the
12 // distribution.
13 
14 #ifndef SST_CORE_CONFIGGRAPH_H
15 #define SST_CORE_CONFIGGRAPH_H
16 
17 #include "sst/core/params.h"
18 #include "sst/core/rankInfo.h"
19 #include "sst/core/serialization/serializable.h"
20 #include "sst/core/sparseVectorMap.h"
21 #include "sst/core/sst_types.h"
22 #include "sst/core/statapi/statbase.h"
23 #include "sst/core/statapi/statoutput.h"
24 #include "sst/core/unitAlgebra.h"
25 
26 #include <climits>
27 #include <map>
28 #include <set>
29 #include <vector>
30 
31 using namespace SST::Statistics;
32 
33 namespace SST {
34 
35 class Simulation_impl;
36 
37 class Config;
38 class TimeLord;
39 class ConfigGraph;
40 
41 typedef SparseVectorMap<ComponentId_t> ComponentIdMap_t;
42 typedef std::vector<LinkId_t> LinkIdMap_t;
43 
44 /** Represents the configuration of a generic Link */
46 {
47 public:
48  LinkId_t id; /*!< ID of this link */
49  std::string name; /*!< Name of this link */
50  ComponentId_t component[2]; /*!< IDs of the connected components */
51  std::string port[2]; /*!< Names of the connected ports */
52  SimTime_t latency[2]; /*!< Latency from each side */
53  std::string latency_str[2]; /*!< Temp string holding latency */
54  int current_ref; /*!< Number of components currently referring to this Link */
55  bool no_cut; /*!< If set to true, partitioner will not make a cut through this Link */
56 
57  // inline const std::string& key() const { return name; }
58  inline LinkId_t key() const { return id; }
59 
60  /** Return the minimum latency of this link (from both sides) */
61  SimTime_t getMinLatency() const
62  {
63  if ( latency[0] < latency[1] ) return latency[0];
64  return latency[1];
65  }
66 
67  /** Print the Link information */
68  void print(std::ostream& os) const
69  {
70  os << "Link " << name << " (id = " << id << ")" << std::endl;
71  os << " component[0] = " << component[0] << std::endl;
72  os << " port[0] = " << port[0] << std::endl;
73  os << " latency[0] = " << latency[0] << std::endl;
74  os << " component[1] = " << component[1] << std::endl;
75  os << " port[1] = " << port[1] << std::endl;
76  os << " latency[1] = " << latency[1] << std::endl;
77  }
78 
79  /* Do not use. For serialization only */
80  ConfigLink() {}
81 
82  void serialize_order(SST::Core::Serialization::serializer& ser) override
83  {
84  ser& id;
85  ser& name;
86  ser& component[0];
87  ser& component[1];
88  ser& port[0];
89  ser& port[1];
90  ser& latency[0];
91  ser& latency[1];
92  ser& current_ref;
93  }
94 
95  ImplementSerializable(SST::ConfigLink)
96 
97 private:
98  friend class ConfigGraph;
99  ConfigLink(LinkId_t id) : id(id), no_cut(false)
100  {
101  current_ref = 0;
102 
103  // Initialize the component data items
104  component[0] = ULONG_MAX;
105  component[1] = ULONG_MAX;
106  }
107 
108  ConfigLink(LinkId_t id, const std::string& n) : id(id), no_cut(false)
109  {
110  current_ref = 0;
111  name = n;
112 
113  // Initialize the component data items
114  component[0] = ULONG_MAX;
115  component[1] = ULONG_MAX;
116  }
117 
118  void updateLatencies(TimeLord*);
119 };
120 
122 {
123 public:
124  StatisticId_t id; /*!< Unique ID of this statistic */
125  Params params;
126  bool shared;
127  std::string name;
128 
129  ConfigStatistic(StatisticId_t _id, bool _shared = false, std::string _name = "") :
130  id(_id),
131  shared(_shared),
132  name(_name)
133  {}
134 
135  ConfigStatistic() : id(stat_null_id) {}
136 
137  inline const StatisticId_t& getId() const { return id; }
138 
139  void addParameter(const std::string& key, const std::string& value, bool overwrite);
140 
141  void serialize_order(SST::Core::Serialization::serializer& ser) override
142  {
143  ser& id;
144  ser& shared;
145  ser& name;
146  ser& params;
147  }
148 
149  ImplementSerializable(ConfigStatistic)
150 
151  static constexpr StatisticId_t stat_null_id = std::numeric_limits<StatisticId_t>::max();
152 };
153 
154 class ConfigStatGroup : public SST::Core::Serialization::serializable
155 {
156 public:
157  std::string name;
158  std::map<std::string, Params> statMap;
159  std::vector<ComponentId_t> components;
160  size_t outputID;
161  UnitAlgebra outputFrequency;
162 
163  ConfigStatGroup(const std::string& name) : name(name), outputID(0) {}
164  ConfigStatGroup() {} /* Do not use */
165 
166  bool addComponent(ComponentId_t id);
167  bool addStatistic(const std::string& name, Params& p);
168  bool setOutput(size_t id);
169  bool setFrequency(const std::string& freq);
170 
171  /**
172  * Checks to make sure that all components in the group support all
173  * of the statistics as configured in the group.
174  * @return pair of: bool for OK, string for error message (if any)
175  */
176  std::pair<bool, std::string> verifyStatsAndComponents(const ConfigGraph* graph);
177 
178  void serialize_order(SST::Core::Serialization::serializer& ser) override
179  {
180  ser& name;
181  ser& statMap;
182  ser& components;
183  ser& outputID;
184  ser& outputFrequency;
185  }
186 
187  ImplementSerializable(SST::ConfigStatGroup)
188 };
189 
191 {
192 public:
193  std::string type;
194  Params params;
195 
196  ConfigStatOutput(const std::string& type) : type(type) {}
197  ConfigStatOutput() {}
198 
199  void addParameter(const std::string& key, const std::string& val) { params.insert(key, val); }
200 
201  void serialize_order(SST::Core::Serialization::serializer& ser) override
202  {
203  ser& type;
204  ser& params;
205  }
206 
207  ImplementSerializable(SST::ConfigStatOutput)
208 };
209 
211 
212 /** Represents the configuration of a generic component */
214 {
215  friend class ComponentInfo;
216 
217 public:
218  ComponentId_t id; /*!< Unique ID of this component */
219  ConfigGraph* graph; /*!< Graph that this component belongs to */
220  std::string name; /*!< Name of this component, or slot name for subcomp */
221  int slot_num; /*!< Slot number. Only valid for subcomponents */
222  std::string type; /*!< Type of this component */
223  float weight; /*!< Partitioning weight for this component */
224  RankInfo rank; /*!< Parallel Rank for this component */
225  std::vector<LinkId_t> links; /*!< List of links connected */
226  Params params; /*!< Set of Parameters */
227  uint8_t statLoadLevel; /*!< Statistic load level for this component */
228  // std::vector<ConfigStatistic> enabledStatistics; /*!< List of subcomponents */
229 
230  std::map<std::string, StatisticId_t> enabledStatNames;
231  bool enabledAllStats;
232  ConfigStatistic allStatConfig;
233 
234  std::vector<ConfigComponent*> subComponents; /*!< List of subcomponents */
235  std::vector<double> coords;
236  uint16_t nextSubID; /*!< Next subID to use for children, if component, if subcomponent, subid of parent */
237  bool visited; /*! Used when traversing graph to indicate component was visited already */
238  uint16_t nextStatID; /*!< Next statID to use for children */
239 
240  static constexpr ComponentId_t null_id = std::numeric_limits<ComponentId_t>::max();
241 
242  inline const ComponentId_t& key() const { return id; }
243 
244  /** Print Component information */
245  void print(std::ostream& os) const;
246 
247  ConfigComponent* cloneWithoutLinks() const;
248  ConfigComponent* cloneWithoutLinksOrParams() const;
249 
250  ~ConfigComponent() {}
251  ConfigComponent() :
252  id(null_id),
253  statLoadLevel(STATISTICLOADLEVELUNINITIALIZED),
254  enabledAllStats(false),
255  nextSubID(1),
256  visited(false)
257  {}
258 
259  ComponentId_t getNextSubComponentID();
260  StatisticId_t getNextStatisticID();
261 
262  ConfigComponent* getParent() const;
263  std::string getFullName() const;
264 
265  void setRank(RankInfo r);
266  void setWeight(double w);
267  void setCoordinates(const std::vector<double>& c);
268  void addParameter(const std::string& key, const std::string& value, bool overwrite);
269  ConfigComponent* addSubComponent(ComponentId_t, const std::string& name, const std::string& type, int slot);
270  ConfigComponent* findSubComponent(ComponentId_t);
271  const ConfigComponent* findSubComponent(ComponentId_t) const;
272  ConfigComponent* findSubComponentByName(const std::string& name);
273  ConfigStatistic* findStatistic(const std::string& name) const;
274  ConfigStatistic* insertStatistic(StatisticId_t id);
275  ConfigStatistic* findStatistic(StatisticId_t) const;
276  ConfigStatistic*
277  enableStatistic(const std::string& statisticName, const SST::Params& params, bool recursively = false);
278  ConfigStatistic* createStatistic();
279  bool reuseStatistic(const std::string& statisticName, StatisticId_t sid);
280  void addStatisticParameter(
281  const std::string& statisticName, const std::string& param, const std::string& value, bool recursively = false);
282  void setStatisticParameters(const std::string& statisticName, const Params& params, bool recursively = false);
283  void setStatisticLoadLevel(uint8_t level, bool recursively = false);
284 
285  void addGlobalParamSet(const std::string& set) { params.addGlobalParamSet(set); }
286 
287  std::vector<LinkId_t> allLinks() const;
288 
289  void serialize_order(SST::Core::Serialization::serializer& ser) override
290  {
291  ser& id;
292  ser& name;
293  ser& slot_num;
294  ser& type;
295  ser& weight;
296  ser& rank.rank;
297  ser& rank.thread;
298  ser& links;
299  ser& params;
300  ser& enabledStatNames;
301  ser& enabledAllStats;
302  ser& statistics;
303  ser& enabledAllStats;
304  ser& statLoadLevel;
305  ser& subComponents;
306  ser& coords;
307  ser& nextSubID;
308  ser& nextStatID;
309  }
310 
311  ImplementSerializable(SST::ConfigComponent)
312 
313 private:
314  std::map<StatisticId_t, ConfigStatistic> statistics;
315 
316  friend class ConfigGraph;
317  /** Checks to make sure port names are valid and that a port isn't used twice
318  */
319  void checkPorts() const;
320 
321  /** Create a new Component */
322  ConfigComponent(
323  ComponentId_t id, ConfigGraph* graph, const std::string& name, const std::string& type, float weight,
324  RankInfo rank) :
325  id(id),
326  graph(graph),
327  name(name),
328  type(type),
329  weight(weight),
330  rank(rank),
331  statLoadLevel(STATISTICLOADLEVELUNINITIALIZED),
332  enabledAllStats(false),
333  nextSubID(1),
334  nextStatID(1)
335  {
336  coords.resize(3, 0.0);
337  }
338 
339  ConfigComponent(
340  ComponentId_t id, ConfigGraph* graph, uint16_t parent_subid, const std::string& name, int slot_num,
341  const std::string& type, float weight, RankInfo rank) :
342  id(id),
343  graph(graph),
344  name(name),
345  slot_num(slot_num),
346  type(type),
347  weight(weight),
348  rank(rank),
349  statLoadLevel(STATISTICLOADLEVELUNINITIALIZED),
350  enabledAllStats(false),
351  nextSubID(parent_subid),
352  nextStatID(parent_subid)
353  {
354  coords.resize(3, 0.0);
355  }
356 };
357 
358 /** Map names to Links */
359 // typedef std::map<std::string,ConfigLink> ConfigLinkMap_t;
360 // typedef SparseVectorMap<std::string,ConfigLink> ConfigLinkMap_t;
361 /** Map IDs to Components */
362 typedef SparseVectorMap<ComponentId_t, ConfigComponent*> ConfigComponentMap_t;
363 /** Map names to Components */
364 typedef std::map<std::string, ComponentId_t> ConfigComponentNameMap_t;
365 /** Map names to Parameter Sets: XML only */
366 typedef std::map<std::string, Params*> ParamsMap_t;
367 /** Map names to variable values: XML only */
368 typedef std::map<std::string, std::string> VariableMap_t;
369 
370 class PartitionGraph;
371 
372 /** A Configuration Graph
373  * A graph representing Components and Links
374  */
375 class ConfigGraph : public SST::Core::Serialization::serializable
376 {
377 public:
378  /** Print the configuration graph */
379  void print(std::ostream& os) const
380  {
381  os << "Printing graph" << std::endl;
382  for ( ConfigComponentMap_t::const_iterator i = comps.begin(); i != comps.end(); ++i ) {
383  (*i)->print(os);
384  }
385  }
386 
387  ConfigGraph() : output(Output::getDefaultObject()), nextComponentId(0)
388  {
389  links.clear();
390  comps.clear();
391  // Init the statistic output settings
392  statLoadLevel = STATISTICSDEFAULTLOADLEVEL;
393  statOutputs.emplace_back(STATISTICSDEFAULTOUTPUTNAME);
394  }
395 
396  size_t getNumComponents() { return comps.data.size(); }
397 
398  /** Helper function to set all the ranks to the same value */
399  void setComponentRanks(RankInfo rank);
400  /** Checks to see if rank contains at least one component */
401  bool containsComponentInRank(RankInfo rank);
402  /** Verify that all components have valid Ranks assigned */
403  bool checkRanks(RankInfo ranks);
404 
405  // API for programmatic initialization
406  /** Create a new component with weight and rank */
407  ComponentId_t addComponent(const std::string& name, const std::string& type, float weight, RankInfo rank);
408  /** Create a new component */
409  ComponentId_t addComponent(const std::string& name, const std::string& type);
410 
411  /** Add a parameter to a global param set */
412  void addGlobalParam(const std::string& global_set, const std::string& key, const std::string& value);
413 
414  /** Set the statistic output module */
415  void setStatisticOutput(const std::string& name);
416 
417  /** Add parameter to the statistic output module */
418  void addStatisticOutputParameter(const std::string& param, const std::string& value);
419 
420  /** Set a set of parameter to the statistic output module */
421  void setStatisticOutputParams(const Params& p);
422 
423  /** Set the statistic system load level */
424  void setStatisticLoadLevel(uint8_t loadLevel);
425 
426  std::vector<ConfigStatOutput>& getStatOutputs() { return statOutputs; }
427 
428  const ConfigStatOutput& getStatOutput(size_t index = 0) const { return statOutputs[index]; }
429 
430  long getStatLoadLevel() const { return statLoadLevel; }
431 
432  /** Add a Link to a Component on a given Port */
433  void addLink(
434  ComponentId_t comp_id, const std::string& link_name, const std::string& port, const std::string& latency_str,
435  bool no_cut = false);
436 
437  /** Set a Link to be no-cut */
438  void setLinkNoCut(const std::string& link_name);
439 
440  /** Perform any post-creation cleanup processes */
441  void postCreationCleanup();
442 
443  /** Check the graph for Structural errors */
444  bool checkForStructuralErrors();
445 
446  // Temporary until we have a better API
447  /** Return the map of components */
449 
450  const std::map<std::string, ConfigStatGroup>& getStatGroups() const { return statGroups; }
451  ConfigStatGroup* getStatGroup(const std::string& name)
452  {
453  auto found = statGroups.find(name);
454  if ( found == statGroups.end() ) {
455  bool ok;
456  std::tie(found, ok) = statGroups.emplace(name, name);
457  }
458  return &(found->second);
459  }
460 
461  bool containsComponent(ComponentId_t id) const;
462  ConfigComponent* findComponent(ComponentId_t);
463  ConfigComponent* findComponentByName(const std::string& name);
464  const ConfigComponent* findComponent(ComponentId_t) const;
465 
466  bool containsStatistic(StatisticId_t id) const;
467  ConfigStatistic* findStatistic(StatisticId_t) const;
468 
469  /** Return the map of links */
470  ConfigLinkMap_t& getLinkMap() { return links; }
471 
472  ConfigGraph* getSubGraph(uint32_t start_rank, uint32_t end_rank);
473  ConfigGraph* getSubGraph(const std::set<uint32_t>& rank_set);
474 
475  PartitionGraph* getPartitionGraph();
476  PartitionGraph* getCollapsedPartitionGraph();
477  void annotateRanks(PartitionGraph* graph);
478  void getConnectedNoCutComps(ComponentId_t start, std::set<ComponentId_t>& group);
479 
480  void serialize_order(SST::Core::Serialization::serializer& ser) override
481  {
482  ser& links;
483  ser& comps;
484  ser& statOutputs;
485  ser& statLoadLevel;
486  ser& statGroups;
487  }
488 
489 private:
490  friend class Simulation_impl;
491  friend class SSTSDLModelDefinition;
492 
493  Output& output;
494 
495  ComponentId_t nextComponentId;
496 
497  ConfigLinkMap_t links; // SparseVectorMap
498  ConfigComponentMap_t comps; // SparseVectorMap
499  ConfigComponentNameMap_t compsByName; // std::map
500  std::map<std::string, ConfigStatGroup> statGroups;
501 
502  std::map<std::string, LinkId_t> link_names;
503 
504  std::vector<ConfigStatOutput> statOutputs; // [0] is default
505  uint8_t statLoadLevel;
506 
507  ImplementSerializable(SST::ConfigGraph)
508 };
509 
511 {
512 public:
513  ComponentId_t id;
514  float weight;
515  RankInfo rank;
516  LinkIdMap_t links;
517 
518  ComponentIdMap_t group;
519 
521  {
522  id = cc->id;
523  weight = cc->weight;
524  rank = cc->rank;
525  }
526 
527  PartitionComponent(LinkId_t id) : id(id), weight(0), rank(RankInfo(RankInfo::UNASSIGNED, 0)) {}
528 
529  // PartitionComponent(ComponentId_t id, ConfigGraph* graph, const ComponentIdMap_t& group);
530  void print(std::ostream& os, const PartitionGraph* graph) const;
531 
532  inline ComponentId_t key() const { return id; }
533 };
534 
536 {
537 public:
538  LinkId_t id;
539  ComponentId_t component[2];
540  SimTime_t latency[2];
541  bool no_cut;
542 
543  PartitionLink(const ConfigLink& cl)
544  {
545  id = cl.id;
546  component[0] = cl.component[0];
547  component[1] = cl.component[1];
548  latency[0] = cl.latency[0];
549  latency[1] = cl.latency[1];
550  no_cut = cl.no_cut;
551  }
552 
553  inline LinkId_t key() const { return id; }
554 
555  /** Return the minimum latency of this link (from both sides) */
556  SimTime_t getMinLatency() const
557  {
558  if ( latency[0] < latency[1] ) return latency[0];
559  return latency[1];
560  }
561 
562  /** Print the Link information */
563  void print(std::ostream& os) const
564  {
565  os << " Link " << id << std::endl;
566  os << " component[0] = " << component[0] << std::endl;
567  os << " latency[0] = " << latency[0] << std::endl;
568  os << " component[1] = " << component[1] << std::endl;
569  os << " latency[1] = " << latency[1] << std::endl;
570  }
571 };
572 
573 typedef SparseVectorMap<ComponentId_t, PartitionComponent*> PartitionComponentMap_t;
574 typedef SparseVectorMap<LinkId_t, PartitionLink> PartitionLinkMap_t;
575 
577 {
578 private:
580  PartitionLinkMap_t links;
581 
582 public:
583  /** Print the configuration graph */
584  void print(std::ostream& os) const
585  {
586  os << "Printing graph" << std::endl;
587  for ( PartitionComponentMap_t::const_iterator i = comps.begin(); i != comps.end(); ++i ) {
588  (*i)->print(os, this);
589  }
590  }
591 
592  PartitionComponentMap_t& getComponentMap() { return comps; }
593  PartitionLinkMap_t& getLinkMap() { return links; }
594 
595  const PartitionLink& getLink(LinkId_t id) const { return links[id]; }
596 
597  size_t getNumComponents() { return comps.size(); }
598 };
599 
600 } // namespace SST
601 
602 #endif // SST_CORE_CONFIGGRAPH_H
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file...
Definition: output.h:51
int slot_num
Definition: configGraph.h:221
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:34
float weight
Definition: configGraph.h:223
StatisticId_t id
Definition: configGraph.h:124
ConfigComponentMap_t & getComponentMap()
Return the map of components.
Definition: configGraph.h:448
Represents the configuration of a generic component.
Definition: configGraph.h:213
Definition: configGraph.h:576
std::string type
Definition: configGraph.h:222
A Configuration Graph A graph representing Components and Links.
Definition: configGraph.h:375
void print(std::ostream &os) const
Print the configuration graph.
Definition: configGraph.h:584
Definition: configGraph.h:121
Definition: configGraph.h:510
RankInfo rank
Definition: configGraph.h:224
uint16_t nextSubID
Definition: configGraph.h:236
uint8_t statLoadLevel
Definition: configGraph.h:227
Definition: serializable.h:118
size_t size()
Returns the number of items in the SparseVectorMap.
Definition: sparseVectorMap.h:266
ConfigLinkMap_t & getLinkMap()
Return the map of links.
Definition: configGraph.h:470
ComponentId_t id
Definition: configGraph.h:218
Definition: rankInfo.h:21
Params params
Definition: configGraph.h:226
void print(std::ostream &os) const
Print the configuration graph.
Definition: configGraph.h:379
uint16_t nextStatID
Definition: configGraph.h:238
std::vector< LinkId_t > links
Definition: configGraph.h:225
Parameter store.
Definition: params.h:43
Definition: configGraph.h:190
std::string name
Definition: configGraph.h:220
std::vector< ConfigComponent * > subComponents
Definition: configGraph.h:234
Definition: configGraph.h:154
Definition: componentInfo.h:39
ConfigGraph * graph
Definition: configGraph.h:219
Performs Unit math in full precision.
Definition: unitAlgebra.h:106