HAL  v4.5.0-133-g64838ea8d
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  borrowed(),
180  R"(
181  Compute the Boolean influence of each input net of a subcircuit on one of its output nets.
182  The Boolean function of the start net is built from the given gates, translated into C code, and then compiled and executed for speed.
183  The influence is approximated by evaluating that function on randomly sampled input assignments.
184 
185  :param list[hal_py.Gate] gates: The gates of the subcircuit.
186  :param hal_py.Net start_net: The output net of the subcircuit at which to start the analysis.
187  :param int num_evaluations: The number of evaluations that are performed for each input variable.
188  :returns: A dict from each input net of the subcircuit to its Boolean influence on the start net on success, ``None`` otherwise.
189  :rtype: dict[hal_py.Net,float] or None
190  )");
191 
192  m.def(
193  "get_boolean_influences_of_gate",
194  [](const Gate* gate, const u32 num_evaluations = 32000) -> std::optional<std::map<Net*, double>> {
195  const auto res = boolean_influence::get_boolean_influences_of_gate(gate, num_evaluations);
196  if (res.is_ok())
197  {
198  return res.get();
199  }
200  else
201  {
202  log_error("python_context", "cannot get Boolean influence of flip-flop data fan-in:\n{}", res.get_error().get());
203  return std::nullopt;
204  }
205  },
206  py::arg("gate"),
207  py::arg("num_evaluations") = 32000,
208  borrowed(),
209  R"(
210  Compute the Boolean influence of each net that drives the data input of the given flip-flop.
211  The Boolean function of the data input net is built, translated into C code, and then compiled and executed for speed.
212  The influence is approximated by evaluating that function on randomly sampled input assignments.
213 
214  :param hal_py.Gate gate: The flip-flop whose data input net is used to build the Boolean function.
215  :param int num_evaluations: The number of evaluations that are performed for each input variable.
216  :returns: A dict from each net of the function to its Boolean influence on the data input net on success, ``None`` otherwise.
217  :rtype: dict[hal_py.Net,float]
218  )");
219 
220  m.def(
221  "get_boolean_influence_deterministic",
222  [](const BooleanFunction& bf) -> std::optional<std::unordered_map<std::string, double>> {
224  if (res.is_ok())
225  {
226  return res.get();
227  }
228  else
229  {
230  log_error("python_context", "cannot get Boolean influence of Boolean function:\n{}", res.get_error().get());
231  return std::nullopt;
232  }
233  },
234  py::arg("bf"),
235  R"(
236  Compute the exact Boolean influence of each input variable of a Boolean function.
237  In contrast to ``get_boolean_influence``, the function is evaluated on every possible input assignment instead of a random sample.
238  This is only feasible for functions of at most 16 variables.
239 
240  :param hal_py.BooleanFunction bf: The Boolean function.
241  :returns: A dict from each variable of the function to its Boolean influence on success, ``None`` otherwise.
242  :rtype: dict[str,float] or None
243  )");
244 
245  m.def(
246  "get_boolean_influences_of_subcircuit_deterministic",
247  [](const std::vector<Gate*>& gates, const Net* start_net) -> std::optional<std::map<Net*, double>> {
249  if (res.is_ok())
250  {
251  return res.get();
252  }
253  else
254  {
255  log_error("python_context", "cannot get Boolean influence of subcircuit function:\n{}", res.get_error().get());
256  return std::nullopt;
257  }
258  },
259  py::arg("gates"),
260  py::arg("start_net"),
261  borrowed(),
262  R"(
263  Compute the exact Boolean influence of each input net of a subcircuit on one of its output nets.
264  In contrast to ``get_boolean_influences_of_subcircuit``, the function is evaluated on every possible input assignment instead of a random sample.
265  This is only feasible for subcircuits with at most 16 input nets.
266 
267  :param list[hal_py.Gate] gates: The gates of the subcircuit.
268  :param hal_py.Net start_net: The output net of the subcircuit at which to start the analysis.
269  :returns: A dict from each input net of the subcircuit to its Boolean influence on the start net on success, ``None`` otherwise.
270  :rtype: dict[hal_py.Net,float] or None
271  )");
272 
273  m.def(
274  "get_boolean_influences_of_gate_deterministic",
275  [](const Gate* gate) -> std::optional<std::map<Net*, double>> {
277  if (res.is_ok())
278  {
279  return res.get();
280  }
281  else
282  {
283  log_error("python_context", "cannot get Boolean influence of flip-flop data fan-in:\n{}", res.get_error().get());
284  return std::nullopt;
285  }
286  },
287  py::arg("gate"),
288  borrowed(),
289  R"(
290  Compute the exact Boolean influence of each net that drives the data input of the given flip-flop.
291  In contrast to ``get_boolean_influences_of_gate``, the function is evaluated on every possible input assignment instead of a random sample.
292  This is only feasible for data input functions of at most 16 nets.
293 
294  :param hal_py.Gate gate: The flip-flop whose data input net is used to build the Boolean function.
295  :returns: A dict from each net of the function to its Boolean influence on the data input net on success, ``None`` otherwise.
296  :rtype: dict[hal_py.Net,float]
297  )");
298 
299  m.def(
300  "get_ff_dependency_matrix",
301  [](const Netlist* nl, bool with_boolean_influence) -> std::optional<std::pair<std::map<u32, Gate*>, std::vector<std::vector<double>>>> {
302  const auto res = boolean_influence::get_ff_dependency_matrix(nl, with_boolean_influence);
303  if (res.is_ok())
304  {
305  return res.get();
306  }
307  else
308  {
309  log_error("python_context", "{}", res.get_error().get());
310  return std::nullopt;
311  }
312  },
313  py::arg("netlist"),
314  py::arg("with_boolean_influence"),
315  R"(
316  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.
317 
318  :param hal_py.Netlist netlist: The netlist to extract the dependency matrix from.
319  :param bool with_boolean_influence: Set ``True`` to use the Boolean influence as the matrix entry, ``False`` to use ``1.0`` for every connection.
320  :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.
321  :rtype: tuple(dict[int,hal_py.Gate], list[list[float]]) or None
322  )");
323  ;
324 
325 #ifndef PYBIND11_MODULE
326  return m.ptr();
327 #endif // PYBIND11_MODULE
328  }
329 } // 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.