HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
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  Compute the Boolean influence of each input variable of a Boolean function.
100  The influence is approximated by evaluating the function on randomly sampled input assignments.
101 
102  :param hal_py.BooleanFunction bf: The Boolean function.
103  :param int num_evaluations: The number of evaluations that are performed for each input variable.
104  :returns: A dict from each variable of the function to its Boolean influence 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  Compute the Boolean influence of each input variable of a Boolean function using only HAL-internal functionality.
126  The influence is approximated by evaluating the function on randomly sampled input assignments.
127  This variant is slower than ``get_boolean_influence``, but it is better suited for use in a multi-threaded environment.
128 
129  :param hal_py.BooleanFunction bf: The Boolean function.
130  :param int num_evaluations: The number of evaluations that are performed for each input variable.
131  :returns: A dict from each variable of the function to its Boolean influence on success, ``None`` otherwise.
132  :rtype: dict[str,float] or None
133  )");
134 
135  m.def(
136  "get_boolean_influence_with_z3_expr",
137  [](const BooleanFunction& bf, const u32 num_evaluations = 32000) -> std::optional<std::unordered_map<std::string, double>> {
138  const auto res = boolean_influence::get_boolean_influence_with_z3_expr(bf, num_evaluations);
139  if (res.is_ok())
140  {
141  return res.get();
142  }
143  else
144  {
145  log_error("python_context", "cannot get Boolean influence of Boolean function:\n{}", res.get_error().get());
146  return std::nullopt;
147  }
148  },
149  py::arg("bf"),
150  py::arg("num_evaluations") = 32000,
151  R"(
152  Compute the Boolean influence of each input variable of a Boolean function using only z3 substitution and simplification.
153  The influence is approximated by evaluating the function on randomly sampled input assignments.
154  This variant is slower than ``get_boolean_influence``, but it is better suited for use in a multi-threaded environment.
155 
156  :param hal_py.BooleanFunction bf: The Boolean function.
157  :param int num_evaluations: The number of evaluations that are performed for each input variable.
158  :returns: A dict from each variable of the function to its Boolean influence on success, ``None`` otherwise.
159  :rtype: dict[str,float] or None
160  )");
161 
162  m.def(
163  "get_boolean_influences_of_subcircuit",
164  [](const std::vector<Gate*>& gates, const Net* start_net, const u32 num_evaluations = 32000) -> std::optional<std::map<Net*, double>> {
165  const auto res = boolean_influence::get_boolean_influences_of_subcircuit(gates, start_net, num_evaluations);
166  if (res.is_ok())
167  {
168  return res.get();
169  }
170  else
171  {
172  log_error("python_context", "cannot get Boolean influence of subcircuit function:\n{}", res.get_error().get());
173  return std::nullopt;
174  }
175  },
176  py::arg("gates"),
177  py::arg("start_net"),
178  py::arg("num_evaluations") = 32000,
179  R"(
180  Compute the Boolean influence of each input net of a subcircuit on one of its output nets.
181  The Boolean function of the start net is built from the given gates, translated into C code, and then compiled and executed for speed.
182  The influence is approximated by evaluating that function on randomly sampled input assignments.
183 
184  :param list[hal_py.Gate] gates: The gates of the subcircuit.
185  :param hal_py.Net start_net: The output net of the subcircuit at which to start the analysis.
186  :param int num_evaluations: The number of evaluations that are performed for each input variable.
187  :returns: A dict from each input net of the subcircuit to its Boolean influence on the start net on success, ``None`` otherwise.
188  :rtype: dict[hal_py.Net,float] or None
189  )");
190 
191  m.def(
192  "get_boolean_influences_of_gate",
193  [](const Gate* gate, const u32 num_evaluations = 32000) -> std::optional<std::map<Net*, double>> {
194  const auto res = boolean_influence::get_boolean_influences_of_gate(gate, num_evaluations);
195  if (res.is_ok())
196  {
197  return res.get();
198  }
199  else
200  {
201  log_error("python_context", "cannot get Boolean influence of flip-flop data fan-in:\n{}", res.get_error().get());
202  return std::nullopt;
203  }
204  },
205  py::arg("gate"),
206  py::arg("num_evaluations") = 32000,
207  R"(
208  Compute the Boolean influence of each net that drives the data input of the given flip-flop.
209  The Boolean function of the data input net is built, translated into C code, and then compiled and executed for speed.
210  The influence is approximated by evaluating that function on randomly sampled input assignments.
211 
212  :param hal_py.Gate gate: The flip-flop whose data input net is used to build the Boolean function.
213  :param int num_evaluations: The number of evaluations that are performed for each input variable.
214  :returns: A dict from each net of the function to its Boolean influence on the data input net on success, ``None`` otherwise.
215  :rtype: dict[hal_py.Net,float]
216  )");
217 
218  m.def(
219  "get_boolean_influence_deterministic",
220  [](const BooleanFunction& bf) -> std::optional<std::unordered_map<std::string, double>> {
222  if (res.is_ok())
223  {
224  return res.get();
225  }
226  else
227  {
228  log_error("python_context", "cannot get Boolean influence of Boolean function:\n{}", res.get_error().get());
229  return std::nullopt;
230  }
231  },
232  py::arg("bf"),
233  R"(
234  Compute the exact Boolean influence of each input variable of a Boolean function.
235  In contrast to ``get_boolean_influence``, the function is evaluated on every possible input assignment instead of a random sample.
236  This is only feasible for functions of at most 16 variables.
237 
238  :param hal_py.BooleanFunction bf: The Boolean function.
239  :returns: A dict from each variable of the function to its Boolean influence on success, ``None`` otherwise.
240  :rtype: dict[str,float] or None
241  )");
242 
243  m.def(
244  "get_boolean_influences_of_subcircuit_deterministic",
245  [](const std::vector<Gate*>& gates, const Net* start_net) -> std::optional<std::map<Net*, double>> {
247  if (res.is_ok())
248  {
249  return res.get();
250  }
251  else
252  {
253  log_error("python_context", "cannot get Boolean influence of subcircuit function:\n{}", res.get_error().get());
254  return std::nullopt;
255  }
256  },
257  py::arg("gates"),
258  py::arg("start_net"),
259  R"(
260  Compute the exact Boolean influence of each input net of a subcircuit on one of its output nets.
261  In contrast to ``get_boolean_influences_of_subcircuit``, the function is evaluated on every possible input assignment instead of a random sample.
262  This is only feasible for subcircuits with at most 16 input nets.
263 
264  :param list[hal_py.Gate] gates: The gates of the subcircuit.
265  :param hal_py.Net start_net: The output net of the subcircuit at which to start the analysis.
266  :returns: A dict from each input net of the subcircuit to its Boolean influence on the start net on success, ``None`` otherwise.
267  :rtype: dict[hal_py.Net,float] or None
268  )");
269 
270  m.def(
271  "get_boolean_influences_of_gate_deterministic",
272  [](const Gate* gate) -> std::optional<std::map<Net*, double>> {
274  if (res.is_ok())
275  {
276  return res.get();
277  }
278  else
279  {
280  log_error("python_context", "cannot get Boolean influence of flip-flop data fan-in:\n{}", res.get_error().get());
281  return std::nullopt;
282  }
283  },
284  py::arg("gate"),
285  R"(
286  Compute the exact Boolean influence of each net that drives the data input of the given flip-flop.
287  In contrast to ``get_boolean_influences_of_gate``, the function is evaluated on every possible input assignment instead of a random sample.
288  This is only feasible for data input functions of at most 16 nets.
289 
290  :param hal_py.Gate gate: The flip-flop whose data input net is used to build the Boolean function.
291  :returns: A dict from each net of the function to its Boolean influence on the data input net on success, ``None`` otherwise.
292  :rtype: dict[hal_py.Net,float]
293  )");
294 
295  m.def(
296  "get_ff_dependency_matrix",
297  [](const Netlist* nl, bool with_boolean_influence) -> std::optional<std::pair<std::map<u32, Gate*>, std::vector<std::vector<double>>>> {
298  const auto res = boolean_influence::get_ff_dependency_matrix(nl, with_boolean_influence);
299  if (res.is_ok())
300  {
301  return res.get();
302  }
303  else
304  {
305  log_error("python_context", "{}", res.get_error().get());
306  return std::nullopt;
307  }
308  },
309  py::arg("netlist"),
310  py::arg("with_boolean_influence"),
311  R"(
312  Get the flip-flop dependency matrix of a netlist, i.e., a matrix that holds an entry for every pair of flip-flops that are connected through combinational logic.
313 
314  :param hal_py.Netlist netlist: The netlist to extract the dependency matrix from.
315  :param bool with_boolean_influence: Set ``True`` to use the Boolean influence as the matrix entry, ``False`` to use ``1.0`` for every connection.
316  :returns: A tuple consisting of a dict from the original gate IDs to the corresponding matrix indices and the flip-flop dependency matrix itself, ``None`` otherwise.
317  :rtype: tuple(dict[int,hal_py.Gate], list[list[float]]) or None
318  )");
319  ;
320 
321 #ifndef PYBIND11_MODULE
322  return m.ptr();
323 #endif // PYBIND11_MODULE
324  }
325 } // 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
uint32_t u32
Definition: defines.h:41
#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)
Definition: defines.h:45
PYBIND11_PLUGIN(hal_py)
This file contains all functions related to the HAL plugin API.