SST  11.0.0
StructuralSimulationToolkit
element_python.h
1 // Copyright 2009-2021 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-2021, 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 nullptr 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, 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, const std::string& filename);
109 
110  //! Add an empty submodule to the module
111  ///
112  /// \param module_name simple name of the module
113  ///
114  ///
115  SSTElementPythonModuleCode* addSubModule(const std::string& module_name);
116 
117  //! Get the full name of the module
118  /**
119  * Get the full name of the module formatted as parent_full_name.module_name.
120  * \return full name of module as a string
121  */
122  std::string getFullModuleName();
123 
124 };
125 
126 
127 /**
128  Base class for python modules in element libraries.
129 
130  Element libraries can include a class derived from this class and
131  create a python module hierarchy.
132  */
134 
135 protected:
136  std::string library;
137  std::string pylibrary;
138  std::string sstlibrary;
139  char* primary_module;
140 
141  std::vector<std::pair<std::string,char*> > sub_modules;
142 
143  SSTElementPythonModuleCode* primary_code_module;
144 
145  // Only needed for supporting the old ELI
147 
148 public:
149  SST_ELI_DECLARE_BASE(SSTElementPythonModule)
150  SST_ELI_DECLARE_DEFAULT_INFO_EXTERN()
151  SST_ELI_DECLARE_CTOR_EXTERN(const std::string&)
152 
153  virtual ~SSTElementPythonModule() {}
154 
155  //! Constructor for SSTElementPythonModule. Must be called by derived class
156  /**
157  * \param library name of the element library the module is part
158  * of. Primary module name will be sst.library and submodules
159  * under this can also be created.
160  */
161  SSTElementPythonModule(const std::string& library);
162 
163 
164  virtual void* load();
165 
166  //! Create the top level python module (i.e. the one named sst.library)
167  /// Python files will need to be turned into a char array (code parameter). One way to do
168  /// this is to use the following in your Makefile:
169  /// \verbatim %.inc: %.py
170  /// od -v -t x1 < $< | sed -e 's/^[^ ]*[ ]*//g' -e '/^\s*$$/d' -e 's/\([0-9a-f]*\)[ $$]*/0x\1,/g' > $@ \endverbatim
171  /// \param code code to be compiled
172  /// \param filename filname used when reporting errors
173  ///
174  ///
175  SSTElementPythonModuleCode* createPrimaryModule(char* code, const std::string& filename);
176 
177 
178  //! Create and empty top level python module (i.e. the one named sst.library)
179  ///
180  ///
182 
183 };
184 
185 
186 } //end SST
187 
188 #define SST_ELI_REGISTER_PYTHON_MODULE(cls,lib,version) \
189  SST_ELI_REGISTER_DERIVED(SST::SSTElementPythonModule,cls,lib,lib,ELI_FORWARD_AS_ONE(version),"Python module " #cls)
190 
191 #endif // SST_CORE_MODEL_ELEMENT_PYTHON_H
std::string getFullModuleName()
Get the full name of the module.
Definition: element_python.cc:141
SSTElementPythonModuleCode * createPrimaryModule()
Create and empty top level python module (i.e.
Definition: element_python.cc:205
SSTElementPythonModuleCode * addSubModule(const std::string &module_name, char *code, const std::string &filename)
Add a submodule to the module.
Definition: element_python.cc:102
Class to represent the code that needs to be added to create the python module struture for the libra...
Definition: element_python.h:28
Base class for python modules in element libraries.
Definition: element_python.h:133