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