ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
ETISSPython.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// This file is part of ETISS. It is licensed under the BSD 3-Clause License; you may not use this file except in
4// compliance with the License. You should have received a copy of the license along with this project. If not, see the
5// LICENSE file.
6
7#include "etiss/config.h"
8
9#if ETISS_USE_PYTHON
10#include <Python.h> // include before anyting else
11#endif
12
13#include "etiss/ETISS.h"
14
15#if ETISS_USE_PYTHON
17// move to ETISS.h ? ETISSPython.h?
18
19template <typename T>
20PyObject *convert(const T &t)
21{
22 PyErr_SetString(PyExc_NotImplementedError, "failed to convert C++ object to PyObject");
23 return nullptr;
24}
25template <>
26PyObject *convert<std::string>(const std::string &s);
27template <>
28PyObject *convert<etiss::int32>(const etiss::int32 &s);
29
30template <typename T>
31T convert(PyObject *, bool &ok)
32{
33 ok = false;
34 return T();
35}
36
37template <typename T1, typename T2, typename T3>
38PyObject *convert(const std::tuple<T1, T2, T3> &a234)
39{
40 PyObject *list = PyList_New(0);
41 PyObject *o = convert(std::get<0>(a234));
42 if (o == 0)
43 {
44 Py_DecRef(list);
45 return 0;
46 }
47 PyList_Append(list, o);
48 Py_DecRef(o);
49 o = convert(std::get<1>(a234));
50 if (o == 0)
51 {
52 Py_DecRef(list);
53 return 0;
54 }
55 PyList_Append(list, o);
56 Py_DecRef(o);
57 o = convert(std::get<2>(a234));
58 if (o == 0)
59 {
60 Py_DecRef(list);
61 return 0;
62 }
63 PyList_Append(list, o);
64 Py_DecRef(o);
65 return list;
66}
67
68template <typename T>
69PyObject *convert(const std::set<T> &set)
70{
71 PyObject *list = PyList_New(0);
72 for (auto iter = set.begin(); iter != set.end(); iter++)
73 {
74 PyObject *e = convert(*iter);
75 if (e == 0)
76 {
77 Py_DecRef(list);
78 return 0;
79 }
80 else
81 {
82 if (PyList_Append(list, convert(*iter)) != 0)
83 {
84 Py_DecRef(e);
85 Py_DecRef(list);
86 return 0;
87 }
88 Py_DecRef(e);
89 }
90 }
91 return list;
92}
93template <typename T>
94PyObject *convert(const std::list<T> &set)
95{
96 PyObject *list = PyList_New(0);
97 for (auto iter = set.begin(); iter != set.end(); iter++)
98 {
99 PyObject *e = convert(*iter);
100 if (e == 0)
101 {
102 Py_DecRef(list);
103 return 0;
104 }
105 else
106 {
107 if (PyList_Append(list, convert(*iter)) != 0)
108 {
109 Py_DecRef(e);
110 Py_DecRef(list);
111 return 0;
112 }
113 Py_DecRef(e);
114 }
115 }
116 return list;
117}
118template <typename K, typename V>
119PyObject *convert(const std::map<K, V> &set)
120{
121 PyObject *dict = PyDict_New();
122 for (auto iter = set.begin(); iter != set.end(); iter++)
123 {
124 PyObject *k = convert(iter->first);
125 if (k == 0)
126 {
127 Py_DecRef(dict);
128 return 0;
129 }
130 else
131 {
132 PyObject *v = convert(iter->second);
133 if (v == 0)
134 {
135 Py_DecRef(k);
136 Py_DecRef(dict);
137 return 0;
138 }
139 else
140 {
141 if (PyDict_SetItem(dict, k, v) != 0)
142 {
143 Py_DecRef(k);
144 Py_DecRef(v);
145 Py_DecRef(dict);
146 return 0;
147 }
148 Py_DecRef(k);
149 Py_DecRef(v);
150 }
151 }
152 }
153 return dict;
154}
155
157
159// PYTHON
160
162// conversion
163
164template <>
165PyObject *convert<std::string>(const std::string &s)
166{
167 return PyString_FromString(s.c_str());
168}
169template <>
170PyObject *convert<etiss::int32>(const etiss::int32 &s)
171{
172 return PyInt_FromSsize_t(s);
173}
174
175template <>
176std::string convert<std::string>(PyObject *o, bool &ok)
177{
178 char *str = PyString_AsString(o);
179 if (str != nullptr)
180 {
181 return std::string(str);
182 }
183 else
184 {
185 ok = false;
186 return "";
187 }
188}
189
190// /conversion
192
194// helper functions
195template <std::set<std::string> (*list)()>
196static PyObject *pyetiss_listX(PyObject *self, PyObject *args)
197{
198 return convert(list());
199}
200template <std::list<std::string> (*list)()>
201static PyObject *pyetiss_listX(PyObject *self, PyObject *args)
202{
203 return convert(list());
204}
205
206static PyObject *pyetiss_loadLibrary(PyObject *self, PyObject *args)
207{
208 const char *name;
209 const char *path;
210
211 if (!PyArg_ParseTuple(args, "ss", &name, &path))
212 {
213 Py_IncRef(Py_False);
214 return Py_False;
215 }
216
217 if (etiss::loadLibrary(std::string(name), std::string(path)))
218 {
219 Py_IncRef(Py_True);
220 return Py_True;
221 }
222 else
223 {
224 Py_IncRef(Py_False);
225 return Py_False;
226 }
227}
228
229static PyObject *pyetiss_cfg_get(PyObject *self, PyObject *args)
230{
231 const char *name;
232 const char *def;
233
234 if (!PyArg_ParseTuple(args, "ss", &name, &def))
235 return nullptr;
236 return convert(etiss::cfg().get<std::string>(std::string(name), std::string(def)));
237}
238static PyObject *pyetiss_cfg_set(PyObject *self, PyObject *args)
239{
240 const char *name;
241 const char *def;
242
243 if (!PyArg_ParseTuple(args, "ss", &name, &def))
244 return nullptr;
245 return convert(etiss::cfg().get<std::string>(std::string(name), std::string(def)));
246}
247static PyObject *pyetiss_cfg_all(PyObject *self, PyObject *args)
248{
249 return convert(etiss::cfg().config());
250}
251static PyObject *pyetiss_cfg_help(PyObject *self, PyObject *args)
252{
253 return convert(etiss::cfg().getAnnounced());
254}
255
256static PyObject *pyetiss_returnCodes(PyObject *self, PyObject *args)
257{
258 std::map<etiss::int32, const char *> m = etiss::RETURNCODE::getErrorMessages();
259 std::map<etiss::int32, std::string> ret;
260 for (auto iter = m.begin(); iter != m.end(); iter++)
261 {
262 ret[iter->first] = std::string(etiss::RETURNCODE::getErrorNames()[iter->first]) + ": " + iter->second;
263 }
264 return convert(ret);
265}
266
267// /helper functions
269
270// function register table
271static PyMethodDef ETISSMethods[] = {
272
273 { "listCPUArchs", pyetiss_listX<etiss::listCPUArchs>, METH_VARARGS, "List available cpu architectures." },
274 { "listJITs", pyetiss_listX<etiss::listJITs>, METH_VARARGS, "List compilers." },
275 { "listPlugins", pyetiss_listX<etiss::listPlugins>, METH_VARARGS, "List plugins." },
276 { "listCPUs", pyetiss_listX<etiss::CPUCore::list>, METH_VARARGS, "List plugins." },
277 { "listLibraries", pyetiss_listX<etiss::listLibraries>, METH_VARARGS, "List loaded libraries." },
278 { "loadLibrary", pyetiss_loadLibrary, METH_VARARGS, "Try to open a shared library." },
279 { "cfgGet", pyetiss_cfg_get, METH_VARARGS, "Get the string value of an option" },
280 { "cfgSet", pyetiss_cfg_set, METH_VARARGS, "Set the string value of an option" },
281 { "cfg", pyetiss_cfg_all, METH_VARARGS, "Get all options in a list" },
282 { "cfgHelp", pyetiss_cfg_help, METH_VARARGS, "Get all announced option info in a dictionary" },
283 { "RETURNCODES", pyetiss_returnCodes, METH_VARARGS, "Get global return codes" },
284 { NULL, NULL, 0, NULL } /* Sentinel */
285};
286
287// /function register table
289
290// initialization
291
292extern "C"
293{
297 void initETISS()
298 {
299 static bool done = false;
300 if (done)
301 return;
302 done = true;
303 Py_InitModule3("etiss", ETISSMethods, "ETISS python bindings");
304 }
305}
306
307// /PYTHON
309
310PyThreadState *etiss_main_pyThreadState = 0;
311
312namespace etiss
313{
314namespace py
315{
316
317bool supported()
318{
319 return true;
320}
321
322void run(std::function<void(void)> func)
323{
324 PyGILState_STATE gstate = PyGILState_Ensure();
325 func();
326 PyGILState_Release(gstate);
327}
328
329void runEXT(std::function<void(void)> func)
330{
331 Py_BEGIN_ALLOW_THREADS func();
332 Py_END_ALLOW_THREADS
333}
334
335void runString(const char *s)
336{
337 run([&s]() { PyRun_SimpleString(s); });
338}
339
340void console()
341{
342 initETISS();
343 runString("print('ETISS functions are provided the the module \\'etiss\\'.')");
344 runString("import code;\ncode.interact(\"ETISS Python Console\")");
345}
346
347void init()
348{
349
350 if (etiss::cfg().get<bool>("pyinitialize", true))
351 {
352 Py_Initialize();
353 if (etiss::cfg().get<bool>("pyinittheads", true))
354 {
355 if (PyEval_ThreadsInitialized() == 0)
356 {
357 PyEval_InitThreads(); // init gil
358 PyEval_ReleaseLock(); // release gil
359 etiss::log(etiss::VERBOSE, "PyEval_InitThreads() called.");
360 }
361 }
362 etiss::log(etiss::VERBOSE, "Py_Initialize() called.");
363 }
364
365 run(
366 []()
367 {
368 PyEval_AcquireLock(); // lock gil
370 PyRun_SimpleString("print('ETISS: INFO: ETISS has been build with python support.')\n");
371 // Py_InitModule3("etiss", ETISSMethods,"ETISS python bindings");
372 PyEval_ReleaseLock(); // release gil
373 });
374}
375
376void shutdown()
377{
378 if (etiss::cfg().get<bool>("pyfinalize", true))
379 {
380 Py_Finalize();
381 etiss::log(etiss::VERBOSE, "Py_Finalize() called");
382 }
383}
384
385std::string evalForString(const char *stmt, bool *ok = nullptr)
386{
387 if (ok != 0)
388 *ok = false;
389 PyObject *result = 0;
390 run(
391 [stmt, &result]()
392 {
393 PyObject *main = PyImport_AddModule("__main__");
394 if (main == 0)
395 {
396 return;
397 }
398 PyObject *globalDictionary = PyModule_GetDict(main);
399 if (globalDictionary == 0)
400 {
401 return;
402 }
403 PyObject *localDictionary = PyDict_New();
404 if (localDictionary == 0)
405 {
406 return;
407 }
408 result = PyRun_String(stmt, Py_file_input, globalDictionary, localDictionary);
409 });
410 if (result == 0)
411 return "";
412 bool lok = false;
413 std::string ret = convert<std::string>(result, ok ? *ok : lok);
414 Py_DecRef(result);
415 return ret;
416}
417
418} // namespace py
419} // namespace etiss
420
421#else
422// ETISS_USE_PYTHON == 0
423
424namespace etiss
425{
426namespace py
427{
428
429void init() {}
430
431void shutdown() {}
432
433void console() {}
434
436{
437 return false;
438}
439
440void runString(std::string s) {}
441
442void run(std::function<void(void)> func) {}
443
444std::string evalForString(const char *stmt, bool *ok = nullptr)
445{
446 if (ok)
447 *ok = false;
448 return "";
449}
450
451} // namespace py
452} // namespace etiss
453
454#endif
Header file of the ETISS library.
__device__ __2f16 float bool s
do v
Definition arm_acle.h:76
contains defines to configure ETISS.
bool loadLibrary(std::string path, std::string name)
Load a library.
Definition ETISS.cpp:270
int main(int argc, const char *argv[])
Definition main.cpp:15
void console()
bool supported()
std::string evalForString(const char *stmt, bool *ok=nullptr)
void runString(std::string s)
void run(std::function< void(void)> func)
void shutdown()
void runEXT(std::function< void(void)> func)
forwards: include/jit/*
Definition Benchmark.h:17
@ INFO
Definition Misc.h:87
@ VERBOSE
Definition Misc.h:88
Configuration & cfg()
Definition Misc.cpp:548
Verbosity & verbosity()
Get log level reference.
Definition Misc.cpp:84
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:94
#define NULL