HAL
python_bindings.cpp
Go to the documentation of this file.
2 
5 #include "pybind11/operators.h"
6 #include "pybind11/pybind11.h"
7 #include "pybind11/stl.h"
8 #include "pybind11/stl_bind.h"
9 
10 namespace py = pybind11;
11 
12 namespace hal
13 {
14 
15  // the name in PYBIND11_MODULE/PYBIND11_PLUGIN *MUST* match the filename of the output library (without extension),
16  // otherwise you will get "ImportError: dynamic module does not define module export function" when importing the module
17 
18 #ifdef PYBIND11_MODULE
19  PYBIND11_MODULE(boolean_influence, m)
20  {
21  m.doc() = "Set of functions to determine the influence of variables of a Boolean function on its output.";
22 #else
23  PYBIND11_PLUGIN(boolean_influence)
24  {
25  py::module m("boolean_influence", "Set of functions to determine the influence of variables of a Boolean function on its output.");
26 #endif // ifdef PYBIND11_MODULE
27 
28  py::class_<BooleanInfluencePlugin, RawPtrWrapper<BooleanInfluencePlugin>, BasePluginInterface> py_boolean_influence_plugin(m, "BooleanInfluencePlugin");
29 
30  py_boolean_influence_plugin.def_property_readonly("name", &BooleanInfluencePlugin::get_name, R"(
31  The name of the plugin.
32 
33  :type: str
34  )");
35 
36  py_boolean_influence_plugin.def("get_name", &BooleanInfluencePlugin::get_name, R"(
37  Get the name of the plugin.
38 
39  :returns: The name of the plugin.
40  :rtype: str
41  )");
42 
43  py_boolean_influence_plugin.def_property_readonly("version", &BooleanInfluencePlugin::get_version, R"(
44  The version of the plugin.
45 
46  :type: str
47  )");
48 
49  py_boolean_influence_plugin.def("get_version", &BooleanInfluencePlugin::get_version, R"(
50  Get the version of the plugin.
51 
52  :returns: The version of the plugin.
53  :rtype: str
54  )");
55 
56  py_boolean_influence_plugin.def_property_readonly("description", &BooleanInfluencePlugin::get_description, R"(
57  The description of the plugin.
58 
59  :type: str
60  )");
61 
62  py_boolean_influence_plugin.def("get_description", &BooleanInfluencePlugin::get_description, R"(
63  Get the description of the plugin.
64 
65  :returns: The description of the plugin.
66  :rtype: str
67  )");
68 
69  py_boolean_influence_plugin.def_property_readonly("dependencies", &BooleanInfluencePlugin::get_dependencies, R"(
70  A set of plugin names that this plugin depends on.
71 
72  :type: set[str]
73  )");
74 
75  py_boolean_influence_plugin.def("get_dependencies", &BooleanInfluencePlugin::get_dependencies, R"(
76  Get a set of plugin names that this plugin depends on.
77 
78  :returns: A set of plugin names that this plugin depends on.
79  :rtype: set[str]
80  )");
81 
82  m.def(
83  "get_boolean_influence",
84  [](const BooleanFunction& bf, const u32 num_evaluations = 32000) -> std::optional<std::unordered_map<std::string, double>> {
85  const auto res = boolean_influence::get_boolean_influence(bf, num_evaluations);
86  if (res.is_ok())
87  {
88  return res.get();
89  }
90  else
91  {
92  log_error("python_context", "cannot get Boolean influence of Boolean function:\n{}", res.get_error().get());
93  return std::nullopt;
94  }
95  },
96  py::arg("bf"),
97  py::arg("num_evaluations") = 32000,
98  R"(
99  Generates the Boolean influence of each input variable of a Boolean function using the internal HAL functions only
100  The function is slower, but can be better used in multithreading enviroment.
101 
102  :param hal_py.BooleanFunction bf: The Boolean function.
103  :param int num_evaluations: The amount of evaluations that are performed for each input variable.
104  :returns: A dict from the variables that appear in the function to their Boolean influence on said function on success, None otherwise.
105  :rtype: dict[str,float] or None
106  )");
107 
108  m.def(
109  "get_boolean_influence_with_hal_boolean_function_class",
110  [](const BooleanFunction& bf, const u32 num_evaluations = 32000) -> std::optional<std::unordered_map<std::string, double>> {
112  if (res.is_ok())
113  {
114  return res.get();
115  }
116  else
117  {
118  log_error("python_context", "cannot get Boolean influence of Boolean function:\n{}", res.get_error().get());
119  return std::nullopt;
120  }
121  },
122  py::arg("bf"),
123  py::arg("num_evaluations") = 32000,
124  R"(
125  The Boolean function gets translated to a z3::expr and afterwards efficient c code.
126  The program is compiled and executed many times to measure the Boolean influence of each input variable.
127 
128  :param hal_py.BooleanFunction bf: The Boolean function.
129  :param int num_evaluations: The amount of evaluations that are performed for each input variable.
130  :returns: A dict from the variables that appear in the function to their Boolean influence on said function on success, None otherwise.
131  :rtype: dict[str,float] or None
132  )");
133 
134  m.def(
135  "get_boolean_influence_with_z3_expr",
136  [](const BooleanFunction& bf, const u32 num_evaluations = 32000) -> std::optional<std::unordered_map<std::string, double>> {
137  const auto res = boolean_influence::get_boolean_influence_with_z3_expr(bf, num_evaluations);
138  if (res.is_ok())
139  {
140  return res.get();
141  }
142  else
143  {
144  log_error("python_context", "cannot get Boolean influence of Boolean function:\n{}", res.get_error().get());
145  return std::nullopt;
146  }
147  },
148  py::arg("bf"),
149  py::arg("num_evaluations") = 32000,
150  R"(
151  Generates the Boolean influence of each input variable of a Boolean function using z3 expressions and substitutions/simplifications only.
152  The function is slower, but can be better used in multithreading environment.
153 
154  :param hal_py.BooleanFunction bf: The Boolean function.
155  :param int num_evaluations: The amount of evaluations that are performed for each input variable.
156  :returns: A dict from the variables that appear in the function to their Boolean influence on said function on success, None otherwise.
157  :rtype: dict[str,float] or None
158  )");
159 
160  m.def(
161  "get_boolean_influences_of_subcircuit",
162  [](const std::vector<Gate*>& gates, const Net* start_net, const u32 num_evaluations = 32000) -> std::optional<std::map<Net*, double>> {
163  const auto res = boolean_influence::get_boolean_influences_of_subcircuit(gates, start_net, num_evaluations);
164  if (res.is_ok())
165  {
166  return res.get();
167  }
168  else
169  {
170  log_error("python_context", "cannot get Boolean influence of subcircuit function:\n{}", res.get_error().get());
171  return std::nullopt;
172  }
173  },
174  py::arg("gates"),
175  py::arg("start_net"),
176  py::arg("num_evaluations") = 32000,
177  R"(
178  Generates the function of the net using only the given gates.
179  Afterwards the generated function gets translated from a z3::expr to efficient c code, compiled, executed and evaluated.
180 
181  :param list[hal_py.Gate] gates: The gates of the subcircuit.
182  :param hal_py.Net start_net: The output net of the subcircuit at which to start the analysis.
183  :param int num_evaluations: The amount of evaluations that are performed for each input variable.
184  :returns: A dict from the nets that appear in the function of the start net to their Boolean influence on said function on success, None otherwise.
185  :rtype: dict[hal_py.Net,float] or None
186  )");
187 
188  m.def(
189  "get_boolean_influences_of_gate",
190  [](const Gate* gate, const u32 num_evaluations = 32000) -> std::optional<std::map<Net*, double>> {
191  const auto res = boolean_influence::get_boolean_influences_of_gate(gate, num_evaluations);
192  if (res.is_ok())
193  {
194  return res.get();
195  }
196  else
197  {
198  log_error("python_context", "cannot get Boolean influence of flip-flop data fan-in:\n{}", res.get_error().get());
199  return std::nullopt;
200  }
201  },
202  py::arg("gate"),
203  py::arg("num_evaluations") = 32000,
204  R"(
205  Generates the function of the dataport net of the given flip-flop.
206  Afterwards the generated function gets translated from a z3::expr to efficient c code, compiled, executed and evaluated.
207 
208  :param hal_py.Gate gate: The flip-flop which data input net is used to build the boolean function.
209  :param int num_evaluations: The amount of evaluations that are performed for each input variable.
210  :returns: A dict from the nets that appear in the function of the data net to their Boolean influence on said function on success, None otherwise.
211  :rtype: dict[hal_py.Net,float]
212  )");
213 
214  m.def(
215  "get_boolean_influence_deterministic",
216  [](const BooleanFunction& bf) -> std::optional<std::unordered_map<std::string, double>> {
218  if (res.is_ok())
219  {
220  return res.get();
221  }
222  else
223  {
224  log_error("python_context", "cannot get Boolean influence of Boolean function:\n{}", res.get_error().get());
225  return std::nullopt;
226  }
227  },
228  py::arg("bf"),
229  R"(
230  The Boolean function gets translated to a z3::expr and afterwards efficient c code.
231  The program is compiled and executed exactly once for every possible input mapping to accurately determine the boolean influence of each variable.
232 
233  :param hal_py.BooleanFunction bf: The Boolean function.
234  :returns: A dict from the variables that appear in the function to their Boolean influence on said function on success, None otherwise.
235  :rtype: dict[str,float] or None
236  )");
237 
238  m.def(
239  "get_boolean_influences_of_subcircuit_deterministic",
240  [](const std::vector<Gate*>& gates, const Net* start_net) -> std::optional<std::map<Net*, double>> {
242  if (res.is_ok())
243  {
244  return res.get();
245  }
246  else
247  {
248  log_error("python_context", "cannot get Boolean influence of subcircuit function:\n{}", res.get_error().get());
249  return std::nullopt;
250  }
251  },
252  py::arg("gates"),
253  py::arg("start_net"),
254  R"(
255  Generates the function of the net using only the given gates.
256  Afterwards the generated function gets translated from a z3::expr to efficient c code, compiled, executed and evaluated.
257 
258  :param list[hal_py.Gate] gates: The gates of the subcircuit.
259  :param hal_py.Net start_net: The output net of the subcircuit at which to start the analysis.
260  :returns: A dict from the nets that appear in the function of the start net to their Boolean influence on said function on success, None otherwise.
261  :rtype: dict[hal_py.Net,float] or None
262  )");
263 
264  m.def(
265  "get_boolean_influences_of_gate_deterministic",
266  [](const Gate* gate) -> std::optional<std::map<Net*, double>> {
268  if (res.is_ok())
269  {
270  return res.get();
271  }
272  else
273  {
274  log_error("python_context", "cannot get Boolean influence of flip-flop data fan-in:\n{}", res.get_error().get());
275  return std::nullopt;
276  }
277  },
278  py::arg("gate"),
279  R"(
280  Generates the function of the dataport net of the given flip-flop.
281  Afterwards the generated function gets translated from a z3::expr to efficient c code, compiled, executed and evaluated.
282 
283  :param hal_py.Gate gate: The flip-flop which data input net is used to build the boolean function.
284  :returns: A dict from the nets that appear in the function of the data net to their Boolean influence on said function on success, None otherwise.
285  :rtype: dict[hal_py.Net,float]
286  )");
287 
288  m.def(
289  "get_ff_dependency_matrix",
290  [](const Netlist* nl, bool with_boolean_influence) -> std::optional<std::pair<std::map<u32, Gate*>, std::vector<std::vector<double>>>> {
291  const auto res = boolean_influence::get_ff_dependency_matrix(nl, with_boolean_influence);
292  if (res.is_ok())
293  {
294  return res.get();
295  }
296  else
297  {
298  log_error("python_context", "{}", res.get_error().get());
299  return std::nullopt;
300  }
301  },
302  py::arg("netlist"),
303  py::arg("with_boolean_influence"),
304  R"(
305  Get the FF dependency matrix of a netlist, with or without boolean influences.
306 
307  :param hal_py.Netlist netlist: The netlist to extract the dependency matrix from.
308  :param bool with_boolean_influence: True -- set boolean influence, False -- sets 1.0 if connection between FFs
309  :returns: A pair consisting of std::map<u32, Gate*>, which includes the mapping from the original gate
310  :rtype: pair(dict(int, hal_py.Gate), list[list[double]])
311  )");
312  ;
313 
314 #ifndef PYBIND11_MODULE
315  return m.ptr();
316 #endif // PYBIND11_MODULE
317  }
318 } // namespace hal
std::string get_name() const override
Get the name of the plugin.
std::string get_version() const override
Get the version of the plugin.
std::string get_description() const override
Get a short description of the plugin.
std::set< std::string > get_dependencies() const override
Get the plugin dependencies.
Definition: gate.h:58
Definition: net.h:58
#define log_error(channel,...)
Definition: log.h:78
const Module * module(const Gate *g, const NodeBoxes &boxes)
Result< std::map< Net *, double > > get_boolean_influences_of_subcircuit(const std::vector< Gate * > &gates, const Net *start_net, const u32 num_evaluations=32000)
Result< std::map< Net *, double > > get_boolean_influences_of_gate(const Gate *gate, const u32 num_evaluations=32000)
Result< std::unordered_map< std::string, double > > get_boolean_influence_with_z3_expr(const BooleanFunction &bf, const u32 num_evaluations)
Result< std::map< Net *, double > > get_boolean_influences_of_subcircuit_deterministic(const std::vector< Gate * > &gates, const Net *start_net)
Result< std::unordered_map< std::string, double > > get_boolean_influence_deterministic(const BooleanFunction &bf)
Result< std::unordered_map< std::string, double > > get_boolean_influence(const BooleanFunction &bf, const u32 num_evaluations=32000)
Result< std::map< Net *, double > > get_boolean_influences_of_gate_deterministic(const Gate *gate)
Result< std::pair< std::map< u32, Gate * >, std::vector< std::vector< double > > > > get_ff_dependency_matrix(const Netlist *netlist, bool with_boolean_influence)
Result< std::unordered_map< std::string, double > > get_boolean_influence_with_hal_boolean_function_class(const BooleanFunction &bf, const u32 num_evaluations)
PYBIND11_PLUGIN(hal_py)
quint32 u32
This file contains all functions related to the HAL plugin API.