OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
PythonExpr.h
Go to the documentation of this file.
1//
2// Struct PythonExpression
3// Execute a python script using all given arguments (except for the first
4// being the script name) and return the value of the "result" variable in
5// the python script.
6// Expression arguments can be accessed in the Python script using the vector
7// variable "arguments", like i.e. in file "test.py":
8// \verbatim
9// result = 2.0 * arguments[0]
10// \endverbatim
11// to double the value passed as second argument to the Python expression.
12// For example the expression
13// \verbatim
14// EXPR="python("test.py", 15.0)";
15// \endverbatim
16// evaluates to a value of 30.0 (test.py contains the line shown above).
17//
18// Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
19// All rights reserved
20//
21// Implemented as part of the PhD thesis
22// "Toward massively parallel multi-objective optimization with application to
23// particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
24//
25// This file is part of OPAL.
26//
27// OPAL is free software: you can redistribute it and/or modify
28// it under the terms of the GNU General Public License as published by
29// the Free Software Foundation, either version 3 of the License, or
30// (at your option) any later version.
31//
32// You should have received a copy of the GNU General Public License
33// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
34//
35#ifndef __PYTHON_EXPR_H__
36#define __PYTHON_EXPR_H__
37
38#include "boost/tuple/tuple.hpp"
39#include "boost/variant/get.hpp"
40#include "boost/variant/variant.hpp"
41
42#include <boost/python.hpp>
43#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
44
45#include "Util/Types.h"
49
50using namespace boost::python;
51
53
55 std::string script = boost::get<std::string>(args[0]);
56 std::vector<double> pargs;
57 for(size_t i = 1; i < args.size(); i++) {
58 pargs.push_back(boost::get<double>(args[i]));
59 }
60
61 try {
62 Py_Initialize();
63 object main_module = import("__main__");
64 object main_namespace = main_module.attr("__dict__");
65
66 boost::python::class_<std::vector<double> >("PyVec")
67 .def(boost::python::vector_indexing_suite<std::vector<double> >());
68 main_namespace["arguments"] = pargs;
69
70 object ignored = exec_file(script.c_str(), main_namespace);
71 double res = extract<double>(main_namespace["result"]);
72
73 Py_Finalize();
74 return boost::make_tuple(res, true);
75
76 } catch (error_already_set) {
77 PyErr_Print();
78 return boost::make_tuple(0.0, false);
79 }
80 }
81};
82
83
84#endif
boost::tuple< double, bool > Result_t
Definition: Expression.h:66
std::vector< argument_t > arguments_t
Definition: function.hpp:19
Expressions::Result_t operator()(client::function::arguments_t args)
Definition: PythonExpr.h:54