SST 15.0
Structural Simulation Toolkit
element_python.h
1// Copyright 2009-2025 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-2025, 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_MODEL_ELEMENT_PYTHON_H
13#define SST_CORE_MODEL_ELEMENT_PYTHON_H
14
15#include "sst/core/eli/elementinfo.h"
16
17#include <string>
18#include <vector>
19
20namespace SST {
21
22using genPythonModuleFunction = void* (*)(void);
23
24/** Class to represent the code that needs to be added to create the
25 * python module struture for the library.
26 */
27class SSTElementPythonModuleCode
28{
29
30private:
31 //! Pointer to parent module.
32 /** Parent module. This will be nullptr if this is the primary module (i.e. sst.*) */
33 SSTElementPythonModuleCode* parent;
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(
66 SSTElementPythonModuleCode* parent, const std::string& module_name, char* code, std::string filename) :
67 parent(parent),
68 module_name(module_name),
69 code(code),
70 filename(filename)
71 {
72 // If no filename for debug is given, just set it to the full name of the module
73 if ( filename == "" ) {
74 filename = getFullModuleName();
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 friend class SSTElementPythonModule;
93
94public:
95 //! Add a submodule to the module
96 ///
97 /// Python files will need to be turned into a char array (code parameter). One way to do
98 /// this is to use the following in your Makefile:
99 /// \verbatim %.inc: %.py
100 /// od -v -t x1 < $< | sed -e 's/^[^ ]*[ ]*//g' -e '/^\s*$$/d' -e 's/\‍([0-9a-f]*\‍)[ $$]*/0x\1,/g' > $@
101 /// \endverbatim
102 /// \param module_name simple name of the module
103 /// \param code code to be compiled
104 /// \param filename filname used when reporting errors
105 ///
106 ///
107 SSTElementPythonModuleCode* addSubModule(const std::string& module_name, char* code, const std::string& filename);
108
109 //! Add an empty submodule to the module
110 ///
111 /// \param module_name simple name of the module
112 ///
113 ///
114 SSTElementPythonModuleCode* addSubModule(const std::string& module_name);
115
116 //! Get the full name of the module
117 /**
118 * Get the full name of the module formatted as parent_full_name.module_name.
119 * \return full name of module as a string
120 */
121 std::string getFullModuleName();
122
123 virtual ~SSTElementPythonModuleCode() = default;
124};
125
126/**
127 Base class for python modules in element libraries.
128
129 Element libraries can include a class derived from this class and
130 create a python module hierarchy.
131 */
132class SSTElementPythonModule
133{
134
135protected:
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
146 SSTElementPythonModule() {}
147
148public:
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 explicit SSTElementPythonModule(const std::string& library);
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' > $@
170 /// \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 //! Create and empty top level python module (i.e. the one named sst.library)
178 ///
179 ///
181};
182
183} // namespace SST
184
185#define SST_ELI_REGISTER_PYTHON_MODULE(cls, lib, version) \
186 SST_ELI_REGISTER_DERIVED(SST::SSTElementPythonModule,cls,lib,lib,ELI_FORWARD_AS_ONE(version),"Python module " #cls)
187
188#endif // SST_CORE_MODEL_ELEMENT_PYTHON_H
Class to represent the code that needs to be added to create the python module struture for the libra...
Definition element_python.h:28
std::string getFullModuleName()
Get the full name of the module.
Definition element_python.cc:141
SSTElementPythonModuleCode * addSubModule(const std::string &module_name, char *code, const std::string &filename)
Add a submodule to the module.
Definition element_python.cc:97
SSTElementPythonModuleCode * createPrimaryModule()
Create and empty top level python module (i.e.
Definition element_python.cc:213