SST  8.0.0
StructuralSimulationToolkit
factory.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 #ifndef _SST_CORE_FACTORY_H
13 #define _SST_CORE_FACTORY_H
14 
15 #include <sst/core/sst_types.h>
16 
17 #include <stdio.h>
18 #include <mutex>
19 
20 #include <sst/core/params.h>
21 #include <sst/core/elemLoader.h>
22 #include <sst/core/element.h>
23 #include <sst/core/elementinfo.h>
24 #include <sst/core/model/element_python.h>
25 #include <sst/core/statapi/statfieldinfo.h>
26 
27 /* Forward declare for Friendship */
28 extern int main(int argc, char **argv);
29 
30 namespace SST {
31 namespace Statistics {
32 class StatisticOutput;
33 class StatisticBase;
34 }
35 
36 class Module;
37 class Component;
38 class BaseComponent;
39 class SubComponent;
40 
41 /**
42  * Class for instantiating Components, Links and the like out
43  * of element libraries.
44  */
45 class Factory {
46 public:
47 
48  static Factory* getFactory() { return instance; }
49 
50  /** Get a list of allowed ports for a given component type.
51  * @param type - Name of component in lib.name format
52  * @return True if this is a valid portname
53  */
54  bool isPortNameValid(const std::string &type, const std::string port_name);
55 
56 
57  /** Attempt to create a new Component instantiation
58  * @param id - The unique ID of the component instantiation
59  * @param componentname - The fully qualified elementlibname.componentname type of component
60  * @param params - The params to pass to the component's constructor
61  * @return Newly created component
62  */
63  Component* CreateComponent(ComponentId_t id, std::string &componentname,
64  Params& params);
65 
66  /** Ensure that an element library containing the required event is loaded
67  * @param eventname - The fully qualified elementlibname.eventname type
68  */
69  void RequireEvent(std::string eventname);
70 
71  /** Instantiate a new Module
72  * @param type - Fully qualified elementlibname.modulename type
73  * @param params - Parameters to pass to the Module's constructor
74  */
75  Module* CreateModule(std::string type, Params& params);
76 
77  /** Instantiate a new Module
78  * @param type - Fully qualified elementlibname.modulename type
79  * @param comp - Component instance to pass to the Module's constructor
80  * @param params - Parameters to pass to the Module's constructor
81  */
82  Module* CreateModuleWithComponent(std::string type, Component* comp, Params& params);
83 
84  /** Instantiate a new Module from within the SST core
85  * @param type - Name of the module to load (just modulename, not element.modulename)
86  * @param params - Parameters to pass to the module at constructor time
87  */
88  Module* CreateCoreModule(std::string type, Params& params);
89 
90  /** Instantiate a new Module from within the SST core
91  * @param type - Name of the module to load (just modulename, not element.modulename)
92  * @param params - Parameters to pass to the module at constructor time
93  */
94  Module* CreateCoreModuleWithComponent(std::string type, Component* comp, Params& params);
95 
96  /** Instantiate a new Module
97  * @param type - Fully qualified elementlibname.modulename type
98  * @param comp - Component instance to pass to the SubComponent's constructor
99  * @param params - Parameters to pass to the SubComponent's constructor
100  */
101  SubComponent* CreateSubComponent(std::string type, Component* comp, Params& params);
102 
103  /** Return partitioner function
104  * @param name - Fully qualified elementlibname.partitioner type name
105  */
106  Partition::SSTPartitioner* CreatePartitioner(std::string name, RankInfo total_ranks, RankInfo my_rank, int verbosity);
107 
108  /** Return generator function
109  * @param name - Fully qualified elementlibname.generator type name
110  */
111  generateFunction GetGenerator(std::string name);
112 
113 
114  /** Instantiate a new Statistic
115  * @param comp - Owning component
116  * @param type - Fully qualified elementlibname.statisticname type
117  * @param statName - Name of the statistic
118  * @param statSubId - Name of the sub statistic
119  * @param params - Parameters to pass to the Statistics's constructor
120  * @param fieldType - Type of data stored in statistic
121  */
122  Statistics::StatisticBase* CreateStatistic(BaseComponent* comp, const std::string &type,
123  const std::string &statName, const std::string &statSubId,
125 
126 
127  /** Return Python Module creation function
128  * @param name - Fully qualified elementlibname.pythonModName type name
129  */
130  // genPythonModuleFunction getPythonModule(std::string name);
131  SSTElementPythonModule* getPythonModule(std::string name);
132  /** Checks to see if library exists and can be loaded */
133  bool hasLibrary(std::string elemlib);
134  void requireLibrary(std::string &elemlib);
135 
136  void getLoadedLibraryNames(std::set<std::string>& lib_names);
137  void loadUnloadedLibraries(const std::set<std::string>& lib_names);
138 
139  /** Attempt to create a new Statistic Output instantiation
140  * @param statOutputType - The name of the Statistic Output to create (Module Name)
141  * @param statOutputParams - The params to pass to the statistic output's constructor
142  * @return Newly created Statistic Output
143  */
144  Statistics::StatisticOutput* CreateStatisticOutput(const std::string& statOutputType, const Params& statOutputParams);
145 
146  /** Determine if a SubComponentSlot is defined in a components ElementInfoStatistic
147  * @param type - The name of the component/subcomponent
148  * @param slotName - The name of the SubComponentSlot
149  * @return True if the SubComponentSlot is defined in the component's ELI
150  */
151  bool DoesSubComponentSlotExist(const std::string& type, const std::string& slotName);
152 
153  /** Determine if a statistic is defined in a components ElementInfoStatistic
154  * @param type - The name of the component
155  * @param statisticName - The name of the statistic
156  * @return True if the statistic is defined in the component's ElementInfoStatistic
157  */
158  bool DoesComponentInfoStatisticNameExist(const std::string& type, const std::string& statisticName);
159 
160  /** Determine if a statistic is defined in a subcomponents ElementInfoStatistic
161  * @param type - The name of the subcomponent
162  * @param statisticName - The name of the statistic
163  * @return True if the statistic is defined in the component's ElementInfoStatistic
164  */
165  bool DoesSubComponentInfoStatisticNameExist(const std::string& type, const std::string& statisticName);
166 
167  /** Get the enable level of a statistic defined in the component's ElementInfoStatistic
168  * @param componentname - The name of the component
169  * @param statisticName - The name of the statistic
170  * @return The Enable Level of the statistic from the ElementInfoStatistic
171  */
172  uint8_t GetComponentInfoStatisticEnableLevel(const std::string& type, const std::string& statisticName);
173 
174  /** Get the units of a statistic defined in the component's ElementInfoStatistic
175  * @param componentname - The name of the component
176  * @param statisticName - The name of the statistic
177  * @return The units string of the statistic from the ElementInfoStatistic
178  */
179  std::string GetComponentInfoStatisticUnits(const std::string& type, const std::string& statisticName);
180 
181 private:
182  Module* LoadCoreModule_StatisticOutputs(std::string& type, Params& params);
183 
184  friend int ::main(int argc, char **argv);
185 
186 
187  typedef std::map<std::string, const ElementLibraryInfo*> eli_map_t;
188 
189  // Need to keep generator info for now
190  typedef std::map<std::string, const ElementInfoGenerator*> eig_map_t;
191 
192  Factory(std::string searchPaths);
193  ~Factory();
194 
195  Factory(); // Don't Implement
196  Factory(Factory const&); // Don't Implement
197  void operator=(Factory const&); // Don't Implement
198 
199  static Factory *instance;
200 
201  // find library information for name
202  const ElementLibraryInfo* findLibrary(std::string name, bool showErrors=true);
203  // handle low-level loading of name
204  const ElementLibraryInfo* loadLibrary(std::string name, bool showErrors=true);
205 
206  eli_map_t loaded_libraries;
207  eig_map_t found_generators;
208 
209  std::string searchPaths;
210 
211  ElemLoader *loader;
212  std::string loadingComponentType;
213 
214  std::pair<std::string, std::string> parseLoadName(const std::string& wholename);
215 
216  std::recursive_mutex factoryMutex;
217 
218 
219 protected:
220  Output &out;
221 };
222 
223 
224 
225 /*******************************************************
226  Classes to provide backward compatibility with the
227  old ELI
228 *******************************************************/
229 
230 /**************************************************************************
231  Class to support Components
232 **************************************************************************/
234 
235 private:
236  std::string library;
237  std::string name;
238  std::string description;
239 
240  std::vector<ElementInfoParam> valid_params;
241  std::vector<ElementInfoStatistic> valid_stats;
242  std::vector<ElementInfoPort2> valid_ports;
243  std::vector<ElementInfoSubComponentSlot> subcomp_slots;
244 
245  uint32_t category;
246 
247  componentAllocate alloc;
248 
249 public:
250 
251  ComponentDocOldELI(const std::string& library, const ElementInfoComponent* component) :
253  library(library),
254  name(component->name),
255  description(component->description),
256  category(component->category),
257  alloc(component->alloc)
258 
259  {
260  const ElementInfoParam *p = component->params;
261  while ( NULL != p && NULL != p->name ) {
262  valid_params.emplace_back(*p);
263  p++;
264  }
265 
266  const ElementInfoPort *po = component->ports;
267  while ( NULL != po && NULL != po->name ) {
268  valid_ports.emplace_back(po);
269  po++;
270  }
271 
272  const ElementInfoStatistic *s = component->stats;
273  while ( NULL != s && NULL != s->name ) {
274  valid_stats.emplace_back(*s);
275  s++;
276  }
277 
278  const ElementInfoSubComponentSlot *ss = component->subComponents;
279  while ( NULL != ss && NULL != ss->name ) {
280  subcomp_slots.emplace_back(*ss);
281  ss++;
282  }
283 
284  initialize_allowedKeys();
285  initialize_portnames();
286  initialize_statnames();
287  }
288 
289  Component* create(ComponentId_t id, Params& params) {
290  return (*alloc)(id,params);
291  }
292 
293  const std::string getLibrary() { return library; }
294  const std::string getName() { return name; }
295  const std::string getDescription() { return description; }
296  const std::vector<ElementInfoParam>& getValidParams() { return valid_params; }
297  const std::vector<ElementInfoStatistic>& getValidStats() { return valid_stats; }
298  const std::vector<ElementInfoPort2>& getValidPorts() { return valid_ports; }
299  const std::vector<ElementInfoSubComponentSlot>& getSubComponentSlots() { return subcomp_slots; }
300 
301  uint32_t getCategory() { return category; }
302  const std::vector<int>& getELICompiledVersion() { static std::vector<int> vec = {-1, -1, -1};
303  return vec; }
304  const std::vector<int>& getVersion() { static std::vector<int> vec = {-1, -1, -1};
305  return vec; }
306  const std::string getCompileFile() { return "UNKNOWN"; }
307  const std::string getCompileDate() { return "UNKNOWN"; }
308 };
309 
310 
311 /**************************************************************************
312  Class to support SubComponents
313 **************************************************************************/
314 
316 private:
317 
318  std::string library;
319  std::string name;
320  std::string description;
321 
322  std::vector<ElementInfoParam> valid_params;
323  std::vector<ElementInfoStatistic> valid_stats;
324  std::vector<ElementInfoPort2> valid_ports;
325  std::vector<ElementInfoSubComponentSlot> subcomp_slots;
326 
327  std::string interface;
328  subcomponentAllocate alloc;
329 
330 public:
331 
332  SubComponentDocOldELI(const std::string& library, const ElementInfoSubComponent* component) :
334  library(library),
335  name(component->name),
336  description(component->description),
337  interface(component->provides),
338  alloc(component->alloc)
339 
340  {
341 
342  const ElementInfoParam *p = component->params;
343  while ( NULL != p && NULL != p->name ) {
344  valid_params.emplace_back(*p);
345  p++;
346  }
347 
348  const ElementInfoPort *po = component->ports;
349  while ( NULL != po && NULL != po->name ) {
350  valid_ports.emplace_back(po);
351  po++;
352  }
353 
354  const ElementInfoStatistic *s = component->stats;
355  while ( NULL != s && NULL != s->name ) {
356  valid_stats.emplace_back(*s);
357  s++;
358  }
359 
360  const ElementInfoSubComponentSlot *ss = component->subComponents;
361  while ( NULL != ss && NULL != ss->name ) {
362  subcomp_slots.emplace_back(*ss);
363  ss++;
364  }
365 
366 
367  initialize_allowedKeys();
368  initialize_portnames();
369  initialize_statnames();
370  }
371 
372  SubComponent* create(Component* comp, Params& params) {
373  return (*alloc)(comp,params);
374  }
375 
376  const std::string getLibrary() { return library; }
377  const std::string getName() { return name; }
378  const std::string getDescription() { return description; }
379  const std::vector<ElementInfoParam>& getValidParams() { return valid_params; }
380  const std::vector<ElementInfoStatistic>& getValidStats() { return valid_stats; }
381  const std::vector<ElementInfoPort2>& getValidPorts() { return valid_ports; }
382  const std::vector<ElementInfoSubComponentSlot>& getSubComponentSlots() { return subcomp_slots; }
383  const std::string getInterface() { return interface; }
384 
385  const std::vector<int>& getELICompiledVersion() { static std::vector<int> vec = {-1, -1, -1};
386  return vec; }
387  const std::vector<int>& getVersion() { static std::vector<int> vec = {-1, -1, -1};
388  return vec; }
389  const std::string getCompileFile() { return "UNKNOWN"; }
390  const std::string getCompileDate() { return "UNKNOWN"; }
391 
392 };
393 
394 
395 /**************************************************************************
396  Class to support Modules
397 **************************************************************************/
398 
400 private:
401 
402  std::string library;
403  std::string name;
404  std::string description;
405 
406  std::vector<ElementInfoParam> valid_params;
407 
408  std::string interface;
409 
410  moduleAllocate alloc;
411  moduleAllocateWithComponent allocWithComponent;
412 
413 public:
414 
415  ModuleDocOldELI(const std::string& library, const ElementInfoModule* module) :
417  library(library),
418  name(module->name),
419  description(module->description),
420  alloc(module->alloc),
421  allocWithComponent(module->alloc_with_comp)
422  {
423 
424  const ElementInfoParam *p = module->params;
425  while ( NULL != p && NULL != p->name ) {
426  valid_params.emplace_back(*p);
427  p++;
428  }
429 
430  initialize_allowedKeys();
431  }
432 
433  Module* create(Component* comp, Params& params) {
434  return (*allocWithComponent)(comp,params);
435  }
436 
437  Module* create(Params& params) {
438  return (*alloc)(params);
439  }
440 
441  const std::string getLibrary() { return library; }
442  const std::string getName() { return name; }
443  const std::string getDescription() { return description; }
444  const std::vector<ElementInfoParam>& getValidParams() { return valid_params; }
445  const std::string getInterface() { return interface; }
446 
447  const std::vector<int>& getELICompiledVersion() { static std::vector<int> vec = {-1, -1, -1};
448  return vec; }
449  const std::vector<int>& getVersion() { static std::vector<int> vec = {-1, -1, -1};
450  return vec; }
451  const std::string getCompileFile() { return "UNKNOWN"; }
452  const std::string getCompileDate() { return "UNKNOWN"; }
453 
454 };
455 
456 
457 /**************************************************************************
458  Classes to support partitioners
459 **************************************************************************/
460 
462 private:
463 
464  std::string library;
465  std::string name;
466  std::string description;
467 
468  partitionFunction alloc;
469 
470 public:
471 
472  PartitionerDocOldELI(const std::string& library, const ElementInfoPartitioner* part) :
474  library(library),
475  name(part->name),
476  description(part->description),
477  alloc(part->func)
478  {
479  }
480 
481  Partition::SSTPartitioner* create(RankInfo total_ranks, RankInfo my_rank, int verbosity) override {
482  return (*alloc)(total_ranks,my_rank,verbosity);
483  }
484 
485  const std::string getLibrary() override { return library; }
486  const std::string getName() override { return name; }
487  const std::string getDescription() override { return description; }
488 
489  const std::vector<int>& getELICompiledVersion() override { static std::vector<int> vec = {-1, -1, -1};
490  return vec; }
491  const std::vector<int>& getVersion() override { static std::vector<int> vec = {-1, -1, -1};
492  return vec; }
493  const std::string getCompileFile() override { return "UNKNOWN"; }
494  const std::string getCompileDate() override { return "UNKNOWN"; }
495 };
496 
497 /**************************************************************************
498  Class to support element python modules
499 **************************************************************************/
501 private:
502 
503  // Only need to create one of these
504  static SSTElementPythonModuleOldELI* instance;
505 
506  std::string library;
507  genPythonModuleFunction alloc;
508 
509 public:
510 
511  PythonModuleDocOldELI(const std::string& library, const genPythonModuleFunction func) :
513  library(library),
514  alloc(func)
515  {
516  }
517 
518  SSTElementPythonModule* create() override {
519  // return new T(getLibrary());
520  if( instance == NULL ) instance = new SSTElementPythonModuleOldELI(alloc);
521  return instance;
522  }
523 
524  const std::string getLibrary() override { return library; }
525 
526  const std::vector<int>& getELICompiledVersion() override { static std::vector<int> vec = {-1, -1, -1};
527  return vec; }
528  const std::vector<int>& getVersion() override { static std::vector<int> vec = {-1, -1, -1};
529  return vec; }
530  const std::string getCompileFile() override { return "UNKNOWN"; }
531  const std::string getCompileDate() override { return "UNKNOWN"; }
532 };
533 
534 
535 } // namespace SST
536 
537 #endif // SST_CORE_FACTORY_H
Definition: factory.h:233
const ElementInfoStatistic * stats
Definition: element.h:98
Output object provides consistent method for outputting data to stdout, stderr and/or sst debug file...
Definition: output.h:54
Statistics::StatisticBase * CreateStatistic(BaseComponent *comp, const std::string &type, const std::string &statName, const std::string &statSubId, Params &params, Statistics::StatisticFieldInfo::fieldType_t fieldType)
Instantiate a new Statistic.
Definition: factory.cc:232
Definition: factory.h:315
Module * CreateCoreModuleWithComponent(std::string type, Component *comp, Params &params)
Instantiate a new Module from within the SST core.
Definition: factory.cc:540
Component * CreateComponent(ComponentId_t id, std::string &componentname, Params &params)
Attempt to create a new Component instantiation.
Definition: factory.cc:155
generateFunction GetGenerator(std::string name)
Return generator function.
Definition: factory.cc:657
void RequireEvent(std::string eventname)
Ensure that an element library containing the required event is loaded.
Definition: factory.cc:611
Definition: element_python.h:51
Describes a Component and its associated information.
Definition: element.h:49
componentAllocate alloc
Definition: element.h:53
Describes a Partitioner.
Definition: element.h:106
const char * description
Definition: element.h:51
bool isPortNameValid(const std::string &type, const std::string port_name)
Get a list of allowed ports for a given component type.
Definition: factory.cc:112
Definition: elibase.h:89
Forms the base class for statistics output generation within the SST core.
Definition: statoutput.h:47
uint32_t category
Definition: element.h:56
const char * name
Definition: element.h:50
Describes all the parts of the Element Library.
Definition: element.h:127
Main component object for the simulation.
Definition: component.h:32
bool hasLibrary(std::string elemlib)
Checks to see if library exists and can be loaded.
Definition: factory.cc:702
Definition: elementinfo.h:120
moduleAllocate alloc
Definition: element.h:86
Statistics::StatisticOutput * CreateStatisticOutput(const std::string &statOutputType, const Params &statOutputParams)
Attempt to create a new Statistic Output instantiation.
Definition: factory.cc:190
Forms the base class for statistics gathering within SST.
Definition: statbase.h:61
bool DoesComponentInfoStatisticNameExist(const std::string &type, const std::string &statisticName)
Determine if a statistic is defined in a components ElementInfoStatistic.
Definition: factory.cc:302
Definition: factory.h:461
std::string GetComponentInfoStatisticUnits(const std::string &type, const std::string &statisticName)
Get the units of a statistic defined in the component&#39;s ElementInfoStatistic.
Definition: factory.cc:411
const ElementInfoStatistic * stats
Definition: element.h:57
Definition: elementinfo.h:97
Describes Statistics used by a Component.
Definition: elibase.h:31
Module is a tag class used with the loadModule function.
Definition: module.h:20
Module * CreateCoreModule(std::string type, Params &params)
Instantiate a new Module from within the SST core.
Definition: factory.cc:534
Module * CreateModuleWithComponent(std::string type, Component *comp, Params &params)
Instantiate a new Module.
Definition: factory.cc:547
Class to load Element Libraries.
Definition: elemLoader.h:24
Definition: elementinfo.h:140
uint8_t GetComponentInfoStatisticEnableLevel(const std::string &type, const std::string &statisticName)
Get the enable level of a statistic defined in the component&#39;s ElementInfoStatistic.
Definition: factory.cc:375
Partition::SSTPartitioner * CreatePartitioner(std::string name, RankInfo total_ranks, RankInfo my_rank, int verbosity)
Return partitioner function.
Definition: factory.cc:633
const char * description
Definition: element.h:108
const char * name
Definition: elibase.h:41
Definition: elementinfo.h:133
Definition: factory.h:500
Definition: rankInfo.h:21
const char * name
Definition: elibase.h:32
Main component object for the simulation.
Definition: baseComponent.h:104
const ElementInfoParam * params
Definition: element.h:97
Describes Parameters to a Component.
Definition: elibase.h:40
partitionFunction func
Definition: element.h:110
const char * description
Definition: element.h:84
Definition: elementinfo.h:109
subcomponentAllocate alloc
Definition: element.h:96
moduleAllocateWithComponent alloc_with_comp
Definition: element.h:87
Base class for Partitioning graphs.
Definition: sstpart.h:31
const char * name
Definition: element.h:83
const char * provides
Definition: element.h:99
Describes a Module.
Definition: element.h:82
const ElementInfoPort * ports
Definition: element.h:55
Parameter store.
Definition: params.h:45
const ElementInfoPort * ports
Definition: element.h:100
SSTElementPythonModule * getPythonModule(std::string name)
Return Python Module creation function.
Definition: factory.cc:682
const char * name
Definition: elibase.h:49
const char * description
Definition: element.h:94
Class for instantiating Components, Links and the like out of element libraries.
Definition: factory.h:45
Base class for python modules in element libraries.
Definition: element_python.h:26
const ElementInfoParam * params
Definition: element.h:88
bool DoesSubComponentInfoStatisticNameExist(const std::string &type, const std::string &statisticName)
Determine if a statistic is defined in a subcomponents ElementInfoStatistic.
Definition: factory.cc:339
const ElementInfoParam * params
Definition: element.h:54
SubComponent * CreateSubComponent(std::string type, Component *comp, Params &params)
Instantiate a new Module.
Definition: factory.cc:582
const char * name
Definition: element.h:107
Describes Ports that the Component can use.
Definition: elibase.h:48
const char * name
Definition: element.h:93
Definition: element.h:92
SubComponent is a class loadable through the factory which allows dynamic functionality to be added t...
Definition: subcomponent.h:29
Definition: factory.h:399
fieldType_t
Supported Field Types.
Definition: statfieldinfo.h:36
bool DoesSubComponentSlotExist(const std::string &type, const std::string &slotName)
Determine if a SubComponentSlot is defined in a components ElementInfoStatistic.
Definition: factory.cc:269
Module * CreateModule(std::string type, Params &params)
Instantiate a new Module.
Definition: factory.cc:446