SST  9.0.0
StructuralSimulationToolkit
element_python.h
1 // Copyright 2009-2019 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-2019, 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 SST_CORE_MODEL_ELEMENT_PYTHON_H
14 #define SST_CORE_MODEL_ELEMENT_PYTHON_H
15 
16 #include <vector>
17 #include <string>
18 #include <sst/core/eli/elementinfo.h>
19 
20 namespace SST {
21 
22 typedef void* (*genPythonModuleFunction)(void);
23 
24 
25 /** Class to represent the code that needs to be added to create the
26  * python module struture for the library.
27  */
29 
30 private:
31  //! Pointer to parent module.
32  /** Parent module. This will be NULL if this is the primary module (i.e. sst.*) */
34 
35  //! Simple name of the module.
36  /** Simple name of the module. Full name will be parant_full_name.module_name */
37  std::string module_name;
38 
39  //! Code to be compiled
40  ///
41  /// The code to be added under the specified module name. Python
42  /// files will need to be turned into a char array. One way to do
43  /// this is to use the following in your Makefile:
44  /// %.inc: %.py
45  /// od -v -t x1 < $< | sed -e 's/^[^ ]*[ ]*//g' -e '/^\s*$$/d' -e 's/\([0-9a-f]*\)[ $$]*/0x\1,/g' > $@
46  ///
47  // (Used different comment style because command above would have ended a c-style comment block)
48  char* code;
49 
50  //! Filename used when reporting errors
51  /** Filename that will be used in any error messages generated
52  * when loading the python module into the interpreter.
53  */
54  std::string filename;
55 
56  //! Private constructor. Called by friend class SSTElementPythonModule.
57  /**
58  * Private constructor. Called by friend class SSTElementPythonModule.
59  * \param parent pointer to parent module
60  * \param module_name simple name of the module
61  * \param code code to be compiled
62  * \param filename filname used when reporting errors
63  * \sa parent, module_name, code, filename
64  */
65  SSTElementPythonModuleCode(SSTElementPythonModuleCode* parent, const std::string& module_name, char* code = NULL, std::string filename = "") :
66  parent(parent),
67  module_name(module_name),
68  code(code),
69  filename(filename)
70  {
71  // If no filename for debug is given, just set it to the full name of the module
72  if ( filename == "" ) {
73  filename = getFullModuleName();
74  }
75  }
76 
77 
78  //! load the code as a module into the interpreter
79  /**
80  * Load the code as a module into the interpreter.
81  * Both return type and pyobj are actually PyObject*, but passing
82  * as a void* to avoid including python header files in base SST
83  * header files.
84  * \param parent_module parent module (passed as PyObject*)to load this module under
85  * \return pointer (as PyObject*) to the created module
86  */
87  virtual void* load(void* parent_module);
88 
89  //! Vector of sub_modules
90  std::vector<SSTElementPythonModuleCode*> sub_modules;
91 
92 
93  friend class SSTElementPythonModule;
94 
95 public:
96 
97  //! Add a submodule to the module
98  ///
99  /// Python files will need to be turned into a char array (code parameter). One way to do
100  /// this is to use the following in your Makefile:
101  /// \verbatim %.inc: %.py
102  /// od -v -t x1 < $< | sed -e 's/^[^ ]*[ ]*//g' -e '/^\s*$$/d' -e 's/\([0-9a-f]*\)[ $$]*/0x\1,/g' > $@ \endverbatim
103  /// \param module_name simple name of the module
104  /// \param code code to be compiled
105  /// \param filename filname used when reporting errors
106  ///
107  ///
108  SSTElementPythonModuleCode* addSubModule(const std::string& module_name, char* code = NULL, std::string filename = "");
109 
110  //! Get the full name of the module
111  /**
112  * Get the full name of the module formatted as parent_full_name.module_name.
113  * \return full name of module as a string
114  */
115  std::string getFullModuleName();
116 
117 };
118 
119 
120 /**
121  Base class for python modules in element libraries.
122 
123  Element libraries can include a class derived from this class and
124  create a python module hierarchy.
125  */
127 
128 protected:
129  std::string library;
130  std::string pylibrary;
131  std::string sstlibrary;
132  char* primary_module;
133 
134  std::vector<std::pair<std::string,char*> > sub_modules;
135 
136  SSTElementPythonModuleCode* primary_code_module;
137 
138  // Only needed for supporting the old ELI
140 
141 public:
142  SST_ELI_DECLARE_BASE(SSTElementPythonModule)
143  SST_ELI_DECLARE_DEFAULT_INFO_EXTERN()
144  SST_ELI_DECLARE_CTOR_EXTERN(const std::string&)
145 
146  virtual ~SSTElementPythonModule() {}
147 
148  //! Constructor for SSTElementPythonModule. Must be called by derived class
149  /**
150  * \param library name of the element library the module is part
151  * of. Primary module name will be sst.library and submodules
152  * under this can also be created.
153  */
154  SSTElementPythonModule(std::string library);
155 
156 
157  __attribute__ ((deprecated("Support for addPrimaryModule will be removed in version 9.0. Please use createPrimaryModule().")))
158  void addPrimaryModule(char* file);
159 
160  __attribute__ ((deprecated("Support for addPrimaryModule will be removed in version 9.0. Please use createPrimaryModule() to get an SSTElementPythonModuleCode object then use it's addSubModule() method.")))
161  void addSubModule(std::string name, char* file);
162 
163  virtual void* load();
164 
165  //! Create the top level python module (i.e. the one named sst.library)
166  /// Python files will need to be turned into a char array (code parameter). One way to do
167  /// this is to use the following in your Makefile:
168  /// \verbatim %.inc: %.py
169  /// od -v -t x1 < $< | sed -e 's/^[^ ]*[ ]*//g' -e '/^\s*$$/d' -e 's/\([0-9a-f]*\)[ $$]*/0x\1,/g' > $@ \endverbatim
170  /// \param code code to be compiled
171  /// \param filename filname used when reporting errors
172  ///
173  ///
174  SSTElementPythonModuleCode* createPrimaryModule(char* code = NULL, std::string filename = "");
175 
176 };
177 
178 // Class to use to support old ELI
180 private:
181  genPythonModuleFunction func;
182 
183 public:
184  SSTElementPythonModuleOldELI(const std::string& lib, genPythonModuleFunction func) :
186  func(func)
187  {
188  }
189 
190  void* load() override {
191  return (*func)();
192  }
193 };
194 
195 namespace ELI {
196 template <class T> struct Allocator<SSTElementPythonModule,T> :
197  public CachedAllocator<SSTElementPythonModule,T>
198 {
199 };
200 
201 template <>
203  public Builder<SSTElementPythonModule,const std::string&>
204 {
205  SSTElementPythonModule* create(const std::string& lib) override {
206  return new SSTElementPythonModuleOldELI(lib, func_);
207  }
208 
209  DerivedBuilder(genPythonModuleFunction func) :
210  func_(func)
211  {}
212 
213  genPythonModuleFunction func_;
214 };
215 
216 } //end ELI
217 } //end SST
218 
219 #define SST_ELI_REGISTER_PYTHON_MODULE(cls,lib,version) \
220  SST_ELI_REGISTER_DERIVED(SST::SSTElementPythonModule,cls,lib,lib,ELI_FORWARD_AS_ONE(version),"Python module " #cls)
221 
222 #endif // SST_CORE_MODEL_ELEMENT_PYTHON_H
std::string getFullModuleName()
Get the full name of the module.
Definition: element_python.cc:119
Definition: element_python.h:179
Definition: elementbuilder.h:143
Definition: elementbuilder.h:118
Class to represent the code that needs to be added to create the python module struture for the libra...
Definition: element_python.h:28
Definition: elementbuilder.h:12
SSTElementPythonModuleCode * createPrimaryModule(char *code=NULL, std::string filename="")
Create the top level python module (i.e.
Definition: element_python.cc:188
Base class for python modules in element libraries.
Definition: element_python.h:126
SSTElementPythonModuleCode * addSubModule(const std::string &module_name, char *code=NULL, std::string filename="")
Add a submodule to the module.
Definition: element_python.cc:87
Definition: elementbuilder.h:127