aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt57
-rw-r--r--common/handle_error.cc32
-rw-r--r--common/pybindings.cc64
-rw-r--r--common/pybindings.h13
-rw-r--r--common/pycontainers.h170
-rw-r--r--common/pywrappers.h52
-rw-r--r--ecp5/arch_pybindings.cc34
-rw-r--r--generic/arch_pybindings.cc70
-rw-r--r--ice40/arch_pybindings.cc36
9 files changed, 223 insertions, 305 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 78c72b53..9591c216 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,17 +45,9 @@ if (STATIC_BUILD)
set(CMAKE_CXX_FLAGS_RELEASE "/MT")
set(CMAKE_CXX_FLAGS_DEBUG "/MTd")
endif()
- if (BUILD_PYTHON)
- add_definitions(-DBOOST_PYTHON_STATIC_LIB)
- endif()
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so")
set(link_param "-static")
- if (BUILD_PYTHON)
- find_package(ZLIB)
- find_package(EXPAT)
- find_package(Threads)
- endif()
endif()
endif()
@@ -173,54 +165,7 @@ configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/common/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/generated/version.h
)
-if (BUILD_PYTHON)
- # Find Boost::Python of a suitable version in a cross-platform way
- # Some distributions (Arch) call it libboost_python3, others such as Ubuntu
- # call it libboost_python35. In the latter case we must consider all minor versions
- # Original source: https://github.com/BVLC/caffe/blob/master/cmake/Dependencies.cmake#L148
- set(version ${PYTHONLIBS_VERSION_STRING})
-
- STRING(REGEX REPLACE "[^0-9]" "" boost_py_version "${version}")
- find_package(Boost QUIET COMPONENTS "python-py${boost_py_version}" ${boost_libs})
- set(Boost_PYTHON_FOUND ${Boost_PYTHON-PY${boost_py_version}_FOUND})
-
- while (NOT "${version}" STREQUAL "" AND NOT Boost_PYTHON_FOUND)
- STRING(REGEX REPLACE "([0-9.]+).[0-9]+" "\\1" version "${version}")
-
- STRING(REGEX REPLACE "[^0-9]" "" boost_py_version "${version}")
- find_package(Boost QUIET COMPONENTS "python-py${boost_py_version}" ${boost_libs})
- set(Boost_PYTHON_FOUND ${Boost_PYTHON-PY${boost_py_version}_FOUND})
-
- STRING(REGEX MATCHALL "([0-9.]+).[0-9]+" has_more_version "${version}")
- if ("${has_more_version}" STREQUAL "")
- break()
- endif ()
- endwhile ()
-
- if (NOT Boost_PYTHON_FOUND)
- foreach (PyVer 3 36 37 38 39)
- find_package(Boost QUIET COMPONENTS python${PyVer} ${boost_libs})
- if ("${Boost_LIBRARIES}" MATCHES ".*(python|PYTHON).*" )
- set(Boost_PYTHON_FOUND TRUE)
- break()
- endif ()
- endforeach ()
- endif ()
-
- if (NOT Boost_PYTHON_FOUND)
- STRING(REGEX REPLACE "([0-9]+\\.[0-9]+).*" "\\1" gentoo_version "${PYTHONLIBS_VERSION_STRING}")
- find_package(Boost QUIET COMPONENTS python-${gentoo_version} ${boost_libs})
- if ("${Boost_LIBRARIES}" MATCHES ".*(python|PYTHON).*" )
- set(Boost_PYTHON_FOUND TRUE)
- endif ()
- endif ()
-
- if (NOT Boost_PYTHON_FOUND )
- message( FATAL_ERROR "No version of Boost::Python 3.x could be found.")
- endif ()
-endif()
-
-include_directories(common/ json/ frontend/ 3rdparty/json11/ ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
+include_directories(common/ json/ frontend/ 3rdparty/json11/ 3rdparty/pybind11/include ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
if(BUILD_HEAP)
find_package (Eigen3 REQUIRED NO_MODULE)
diff --git a/common/handle_error.cc b/common/handle_error.cc
index a091f07e..d5542369 100644
--- a/common/handle_error.cc
+++ b/common/handle_error.cc
@@ -1,10 +1,10 @@
#ifndef NO_PYTHON
#include <Python.h>
-#include <boost/python.hpp>
+#include <pybind11/pybind11.h>
#include "nextpnr.h"
-namespace py = boost::python;
+namespace py = pybind11;
NEXTPNR_NAMESPACE_BEGIN
@@ -20,42 +20,36 @@ std::string parse_python_exception()
std::string ret("Unfetchable Python error");
// If the fetch got a type pointer, parse the type into the exception string
if (type_ptr != NULL) {
- py::handle<> h_type(type_ptr);
- py::str type_pstr(h_type);
- // Extract the string from the boost::python object
- py::extract<std::string> e_type_pstr(type_pstr);
+ py::object obj = py::reinterpret_borrow<py::object>(type_ptr);
// If a valid string extraction is available, use it
// otherwise use fallback
- if (e_type_pstr.check())
- ret = e_type_pstr();
+ if (py::isinstance<py::str>(obj))
+ ret = obj.cast<std::string>();
else
ret = "Unknown exception type";
}
// Do the same for the exception value (the stringification of the
// exception)
if (value_ptr != NULL) {
- py::handle<> h_val(value_ptr);
- py::str a(h_val);
- py::extract<std::string> returned(a);
- if (returned.check())
- ret += ": " + returned();
+ py::object obj = py::reinterpret_borrow<py::object>(value_ptr);
+ if (py::isinstance<py::str>(obj))
+ ret += ": " + obj.cast<std::string>();
else
ret += std::string(": Unparseable Python error: ");
}
// Parse lines from the traceback using the Python traceback module
if (traceback_ptr != NULL) {
- py::handle<> h_tb(traceback_ptr);
+ py::handle h_tb(traceback_ptr);
// Load the traceback module and the format_tb function
- py::object tb(py::import("traceback"));
+ py::object tb(py::module::import("traceback"));
py::object fmt_tb(tb.attr("format_tb"));
// Call format_tb to get a list of traceback strings
py::object tb_list(fmt_tb(h_tb));
// Join the traceback strings into a single string
- py::object tb_str(py::str("\n").join(tb_list));
+ py::object tb_str(py::str("\n") + tb_list);
// Extract the string, check the extraction, and fallback in necessary
- py::extract<std::string> returned(tb_str);
- if (returned.check())
- ret += ": " + returned();
+ if (py::isinstance<py::str>(tb_str))
+ ret += ": " + tb_str.cast<std::string>();
else
ret += std::string(": Unparseable Python traceback");
}
diff --git a/common/pybindings.cc b/common/pybindings.cc
index 51da00e9..49acb996 100644
--- a/common/pybindings.cc
+++ b/common/pybindings.cc
@@ -43,7 +43,7 @@ NEXTPNR_NAMESPACE_BEGIN
// Architecture-specific bindings should be created in the below function, which
// must be implemented in all architectures
-void arch_wrap_python();
+void arch_wrap_python(py::module &m);
bool operator==(const PortRef &a, const PortRef &b) { return (a.cell == b.cell) && (a.port == b.port); }
@@ -90,13 +90,13 @@ template <> struct string_converter<Property>
} // namespace PythonConversion
-BOOST_PYTHON_MODULE(MODULE_NAME)
+PYBIND11_MODULE(MODULE_NAME, m)
{
- register_exception_translator<assertion_failure>(&translate_assertfail);
+ //register_exception_translator<assertion_failure>(&translate_assertfail);
using namespace PythonConversion;
- enum_<GraphicElement::type_t>("GraphicElementType")
+ py::enum_<GraphicElement::type_t>(m, "GraphicElementType")
.value("TYPE_NONE", GraphicElement::TYPE_NONE)
.value("TYPE_LINE", GraphicElement::TYPE_LINE)
.value("TYPE_ARROW", GraphicElement::TYPE_ARROW)
@@ -105,7 +105,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
.value("TYPE_LABEL", GraphicElement::TYPE_LABEL)
.export_values();
- enum_<GraphicElement::style_t>("GraphicElementStyle")
+ py::enum_<GraphicElement::style_t>(m, "GraphicElementStyle")
.value("STYLE_GRID", GraphicElement::STYLE_GRID)
.value("STYLE_FRAME", GraphicElement::STYLE_FRAME)
.value("STYLE_HIDDEN", GraphicElement::STYLE_HIDDEN)
@@ -113,9 +113,11 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
.value("STYLE_ACTIVE", GraphicElement::STYLE_ACTIVE)
.export_values();
- class_<GraphicElement>("GraphicElement")
- .def(init<GraphicElement::type_t, GraphicElement::style_t, float, float, float, float, float>(
- (args("type"), "style", "x1", "y1", "x2", "y2", "z")))
+ py::class_<GraphicElement>(m, "GraphicElement")
+ .def(py::init<GraphicElement::type_t, GraphicElement::style_t, float, float, float, float, float>(
+ //FIXME
+ //(args("type"), "style", "x1", "y1", "x2", "y2", "z")
+ ))
.def_readwrite("type", &GraphicElement::type)
.def_readwrite("x1", &GraphicElement::x1)
.def_readwrite("y1", &GraphicElement::y1)
@@ -123,13 +125,13 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
.def_readwrite("y2", &GraphicElement::y2)
.def_readwrite("text", &GraphicElement::text);
- enum_<PortType>("PortType")
+ py::enum_<PortType>(m, "PortType")
.value("PORT_IN", PORT_IN)
.value("PORT_OUT", PORT_OUT)
.value("PORT_INOUT", PORT_INOUT)
.export_values();
- enum_<PlaceStrength>("PlaceStrength")
+ py::enum_<PlaceStrength>(m, "PlaceStrength")
.value("STRENGTH_NONE", STRENGTH_NONE)
.value("STRENGTH_WEAK", STRENGTH_WEAK)
.value("STRENGTH_STRONG", STRENGTH_STRONG)
@@ -143,15 +145,15 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
typedef std::unordered_map<IdString, IdString> IdIdMap;
typedef std::unordered_map<IdString, std::unique_ptr<Region>> RegionMap;
- class_<BaseCtx, BaseCtx *, boost::noncopyable>("BaseCtx", no_init);
+ py::class_<BaseCtx, std::unique_ptr<BaseCtx, py::nodelete>>(m, "BaseCtx");
- auto loc_cls = class_<Loc>("Loc")
- .def(init<int, int, int>())
+ auto loc_cls = py::class_<Loc>(m, "Loc")
+ .def(py::init<int, int, int>())
.def_readwrite("x", &Loc::x)
.def_readwrite("y", &Loc::y)
.def_readwrite("z", &Loc::z);
- auto ci_cls = class_<ContextualWrapper<CellInfo &>>("CellInfo", no_init);
+ auto ci_cls = py::class_<ContextualWrapper<CellInfo &>>(m, "CellInfo");
readwrite_wrapper<CellInfo &, decltype(&CellInfo::name), &CellInfo::name, conv_to_str<IdString>,
conv_from_str<IdString>>::def_wrap(ci_cls, "name");
readwrite_wrapper<CellInfo &, decltype(&CellInfo::type), &CellInfo::type, conv_to_str<IdString>,
@@ -185,7 +187,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
fn_wrapper_1a_v<CellInfo &, decltype(&CellInfo::unsetAttr), &CellInfo::unsetAttr,
conv_from_str<IdString>>::def_wrap(ci_cls, "unsetAttr");
- auto pi_cls = class_<ContextualWrapper<PortInfo &>>("PortInfo", no_init);
+ auto pi_cls = py::class_<ContextualWrapper<PortInfo &>>(m, "PortInfo");
readwrite_wrapper<PortInfo &, decltype(&PortInfo::name), &PortInfo::name, conv_to_str<IdString>,
conv_from_str<IdString>>::def_wrap(pi_cls, "name");
readonly_wrapper<PortInfo &, decltype(&PortInfo::net), &PortInfo::net, deref_and_wrap<NetInfo>>::def_wrap(pi_cls,
@@ -198,7 +200,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
typedef std::unordered_set<BelId> BelSet;
typedef std::unordered_set<WireId> WireSet;
- auto ni_cls = class_<ContextualWrapper<NetInfo &>>("NetInfo", no_init);
+ auto ni_cls = py::class_<ContextualWrapper<NetInfo &>>(m, "NetInfo");
readwrite_wrapper<NetInfo &, decltype(&NetInfo::name), &NetInfo::name, conv_to_str<IdString>,
conv_from_str<IdString>>::def_wrap(ni_cls, "name");
readwrite_wrapper<NetInfo &, decltype(&NetInfo::driver), &NetInfo::driver, wrap_context<PortRef &>,
@@ -208,7 +210,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
readonly_wrapper<NetInfo &, decltype(&NetInfo::wires), &NetInfo::wires, wrap_context<WireMap &>>::def_wrap(ni_cls,
"wires");
- auto pr_cls = class_<ContextualWrapper<PortRef &>>("PortRef", no_init);
+ auto pr_cls = py::class_<ContextualWrapper<PortRef &>>(m, "PortRef");
readonly_wrapper<PortRef &, decltype(&PortRef::cell), &PortRef::cell, deref_and_wrap<CellInfo>>::def_wrap(pr_cls,
"cell");
readwrite_wrapper<PortRef &, decltype(&PortRef::port), &PortRef::port, conv_to_str<IdString>,
@@ -216,16 +218,16 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
readwrite_wrapper<PortRef &, decltype(&PortRef::budget), &PortRef::budget, pass_through<delay_t>,
pass_through<delay_t>>::def_wrap(pr_cls, "budget");
- auto pm_cls = class_<ContextualWrapper<PipMap &>>("PipMap", no_init);
+ auto pm_cls = py::class_<ContextualWrapper<PipMap &>>(m, "PipMap");
readwrite_wrapper<PipMap &, decltype(&PipMap::pip), &PipMap::pip, conv_to_str<PipId>,
conv_from_str<PipId>>::def_wrap(pm_cls, "pip");
readwrite_wrapper<PipMap &, decltype(&PipMap::strength), &PipMap::strength, pass_through<PlaceStrength>,
pass_through<PlaceStrength>>::def_wrap(pm_cls, "strength");
- def("parse_json", parse_json_shim);
- def("load_design", load_design_shim, return_value_policy<manage_new_object>());
+ m.def("parse_json", parse_json_shim);
+ m.def("load_design", load_design_shim, py::return_value_policy::take_ownership);
- auto region_cls = class_<ContextualWrapper<Region &>>("Region", no_init);
+ auto region_cls = py::class_<ContextualWrapper<Region &>>(m, "Region");
readwrite_wrapper<Region &, decltype(&Region::name), &Region::name, conv_to_str<IdString>,
conv_from_str<IdString>>::def_wrap(region_cls, "name");
readwrite_wrapper<Region &, decltype(&Region::constr_bels), &Region::constr_bels, pass_through<bool>,
@@ -239,7 +241,7 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
readonly_wrapper<Region &, decltype(&Region::wires), &Region::wires, wrap_context<WireSet &>>::def_wrap(region_cls,
"wires");
- auto hierarchy_cls = class_<ContextualWrapper<HierarchicalCell &>>("HierarchicalCell", no_init);
+ auto hierarchy_cls = py::class_<ContextualWrapper<HierarchicalCell &>>(m, "HierarchicalCell");
readwrite_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::name), &HierarchicalCell::name,
conv_to_str<IdString>, conv_from_str<IdString>>::def_wrap(hierarchy_cls, "name");
readwrite_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::type), &HierarchicalCell::type,
@@ -255,15 +257,15 @@ BOOST_PYTHON_MODULE(MODULE_NAME)
wrap_context<IdIdMap &>>::def_wrap(hierarchy_cls, "nets");
readonly_wrapper<HierarchicalCell &, decltype(&HierarchicalCell::hier_cells), &HierarchicalCell::hier_cells,
wrap_context<IdIdMap &>>::def_wrap(hierarchy_cls, "hier_cells");
- WRAP_MAP(AttrMap, conv_to_str<Property>, "AttrMap");
- WRAP_MAP(PortMap, wrap_context<PortInfo &>, "PortMap");
- WRAP_MAP(IdIdMap, conv_to_str<IdString>, "IdIdMap");
- WRAP_MAP(WireMap, wrap_context<PipMap &>, "WireMap");
- WRAP_MAP_UPTR(RegionMap, "RegionMap");
+ WRAP_MAP(m, AttrMap, conv_to_str<Property>, "AttrMap");
+ WRAP_MAP(m, PortMap, wrap_context<PortInfo &>, "PortMap");
+ WRAP_MAP(m, IdIdMap, conv_to_str<IdString>, "IdIdMap");
+ WRAP_MAP(m, WireMap, wrap_context<PipMap &>, "WireMap");
+ WRAP_MAP_UPTR(m, RegionMap, "RegionMap");
- WRAP_VECTOR(PortRefVector, wrap_context<PortRef &>);
+ WRAP_VECTOR(m, PortRefVector, wrap_context<PortRef &>);
- arch_wrap_python();
+ arch_wrap_python(m);
}
#ifdef MAIN_EXECUTABLE
@@ -291,7 +293,7 @@ void init_python(const char *executable, bool first)
PyImport_ImportModule(TOSTRING(MODULE_NAME));
PyRun_SimpleString("from " TOSTRING(MODULE_NAME) " import *");
- } catch (boost::python::error_already_set const &) {
+ } catch (py::error_already_set const &) {
// Parse and output the exception
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str << std::endl;
@@ -321,7 +323,7 @@ void execute_python_file(const char *python_file)
if (result == -1) {
log_error("Error occurred while executing Python script %s\n", python_file);
}
- } catch (boost::python::error_already_set const &) {
+ } catch (py::error_already_set const &) {
// Parse and output the exception
std::string perror_str = parse_python_exception();
log_error("Error in Python: %s\n", perror_str.c_str());
diff --git a/common/pybindings.h b/common/pybindings.h
index c4d84442..4923c821 100644
--- a/common/pybindings.h
+++ b/common/pybindings.h
@@ -22,11 +22,10 @@
#define COMMON_PYBINDINGS_H
#include <Python.h>
-#include <boost/python.hpp>
-#include <boost/python/suite/indexing/map_indexing_suite.hpp>
-#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <pybind11/pybind11.h>
#include <stdexcept>
#include <utility>
+#include <iostream>
#include "pycontainers.h"
#include "pywrappers.h"
@@ -34,7 +33,7 @@
NEXTPNR_NAMESPACE_BEGIN
-using namespace boost::python;
+namespace py = pybind11;
std::string parse_python_exception();
@@ -46,9 +45,9 @@ template <typename Tn> void python_export_global(const char *name, Tn &x)
return;
d = PyModule_GetDict(m);
try {
- PyObject *p = incref(object(boost::ref(x)).ptr());
- PyDict_SetItemString(d, name, p);
- } catch (boost::python::error_already_set const &) {
+ py::object obj = py::cast(x);
+ PyDict_SetItemString(d, name, obj.ptr());
+ } catch (py::error_already_set const &) {
// Parse and output the exception
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str << std::endl;
diff --git a/common/pycontainers.h b/common/pycontainers.h
index 2b9ee208..15e502d1 100644
--- a/common/pycontainers.h
+++ b/common/pycontainers.h
@@ -21,9 +21,7 @@
#ifndef COMMON_PYCONTAINERS_H
#define COMMON_PYCONTAINERS_H
-#include <boost/python.hpp>
-#include <boost/python/suite/indexing/map_indexing_suite.hpp>
-#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <pybind11/pybind11.h>
#include <sstream>
#include <stdexcept>
#include <type_traits>
@@ -33,12 +31,12 @@
NEXTPNR_NAMESPACE_BEGIN
-using namespace boost::python;
+namespace py = pybind11;
inline void KeyError()
{
PyErr_SetString(PyExc_KeyError, "Key not found");
- boost::python::throw_error_already_set();
+ throw py::error_already_set();
}
/*
@@ -47,7 +45,7 @@ pair<Iterator, Iterator> containing (current, end), wrapped in a ContextualWrapp
*/
-template <typename T, typename P, typename value_conv = PythonConversion::pass_through<T>> struct iterator_wrapper
+template <typename T, py::return_value_policy P, typename value_conv = PythonConversion::pass_through<T>> struct iterator_wrapper
{
typedef decltype(*(std::declval<T>())) value_t;
@@ -62,16 +60,13 @@ template <typename T, typename P, typename value_conv = PythonConversion::pass_t
return val;
} else {
PyErr_SetString(PyExc_StopIteration, "End of range reached");
- boost::python::throw_error_already_set();
- // Should be unreachable, but prevent control may reach end of
- // non-void
- throw std::runtime_error("unreachable");
+ throw py::error_already_set();
}
}
- static void wrap(const char *python_name)
+ static void wrap(py::module &m, const char *python_name)
{
- class_<wrapped_iter_t>(python_name, no_init).def("__next__", next, P());
+ py::class_<wrapped_iter_t>(m, python_name).def("__next__", next, P);
}
};
@@ -81,7 +76,7 @@ and end() which return iterator-like objects supporting ++, * and !=
Full STL iterator semantics are not required, unlike the standard Boost wrappers
*/
-template <typename T, typename P = return_value_policy<return_by_value>,
+template <typename T, py::return_value_policy P = py::return_value_policy::copy,
typename value_conv = PythonConversion::pass_through<T>>
struct range_wrapper
{
@@ -110,23 +105,23 @@ struct range_wrapper
return ss.str();
}
- static void wrap(const char *range_name, const char *iter_name)
+ static void wrap(py::module &m, const char *range_name, const char *iter_name)
{
- class_<wrapped_range>(range_name, no_init).def("__iter__", iter).def("__repr__", repr);
- iterator_wrapper<iterator_t, P, value_conv>().wrap(iter_name);
+ py::class_<wrapped_range>(m, range_name).def("__iter__", iter).def("__repr__", repr);
+ iterator_wrapper<iterator_t, P, value_conv>().wrap(m, iter_name);
}
typedef iterator_wrapper<iterator_t, P, value_conv> iter_wrap;
};
-#define WRAP_RANGE(t, conv) \
- range_wrapper<t##Range, return_value_policy<return_by_value>, conv>().wrap(#t "Range", #t "Iterator")
+#define WRAP_RANGE(m, t, conv) \
+ range_wrapper<t##Range, py::return_value_policy::copy, conv>().wrap(m, #t "Range", #t "Iterator")
/*
A wrapper for a vector or similar structure. With support for conversion
*/
-template <typename T, typename P = return_value_policy<return_by_value>,
+template <typename T, py::return_value_policy P = py::return_value_policy::copy,
typename value_conv = PythonConversion::pass_through<T>>
struct vector_wrapper
{
@@ -163,21 +158,21 @@ struct vector_wrapper
return value_conv()(range.ctx, boost::ref(range.base.at(i)));
}
- static void wrap(const char *range_name, const char *iter_name)
+ static void wrap(py::module &m, const char *range_name, const char *iter_name)
{
- class_<wrapped_vector>(range_name, no_init)
+ py::class_<wrapped_vector>(m, range_name)
.def("__iter__", iter)
.def("__repr__", repr)
.def("__len__", len)
.def("__getitem__", getitem);
- iterator_wrapper<iterator_t, P, value_conv>().wrap(iter_name);
+ iterator_wrapper<iterator_t, P, value_conv>().wrap(m, iter_name);
}
typedef iterator_wrapper<iterator_t, P, value_conv> iter_wrap;
};
-#define WRAP_VECTOR(t, conv) vector_wrapper<t, return_value_policy<return_by_value>, conv>().wrap(#t, #t "Iterator")
+#define WRAP_VECTOR(m, t, conv) vector_wrapper<t, py::return_value_policy::copy, conv>().wrap(m, #t, #t "Iterator")
/*
Wrapper for a pair, allows accessing either using C++-style members (.first and
@@ -189,58 +184,55 @@ template <typename T1, typename T2> struct pair_wrapper
struct pair_iterator_wrapper
{
- static object next(std::pair<T &, int> &iter)
+ static py::object next(std::pair<T &, int> &iter)
{
if (iter.second == 0) {
iter.second++;
- return object(iter.first.first);
+ return py::cast(iter.first.first);
} else if (iter.second == 1) {
iter.second++;
- return object(iter.first.second);
+ return py::cast(iter.first.second);
} else {
PyErr_SetString(PyExc_StopIteration, "End of range reached");
- boost::python::throw_error_already_set();
- // Should be unreachable, but prevent control may reach end of
- // non-void
- throw std::runtime_error("unreachable");
+ throw py::error_already_set();
}
}
- static void wrap(const char *python_name)
+ static void wrap(py::module &m, const char *python_name)
{
- class_<std::pair<T &, int>>(python_name, no_init).def("__next__", next);
+ py::class_<std::pair<T &, int>>(m, python_name).def("__next__", next);
}
};
- static object get(T &x, int i)
+ static py::object get(T &x, int i)
{
if ((i >= 2) || (i < 0))
KeyError();
- return (i == 1) ? object(x.second) : object(x.first);
+ return (i == 1) ? py::object(x.second) : py::object(x.first);
}
- static void set(T &x, int i, object val)
+ static void set(T &x, int i, py::object val)
{
if ((i >= 2) || (i < 0))
KeyError();
if (i == 0)
- x.first = extract<T1>(val);
+ x.first = val.cast<T1>();
if (i == 1)
- x.second = extract<T2>(val);
+ x.second = val.cast<T2>();
}
static int len(T &x) { return 2; }
static std::pair<T &, int> iter(T &x) { return std::make_pair(boost::ref(x), 0); };
- static void wrap(const char *pair_name, const char *iter_name)
+ static void wrap(py::module &m, const char *pair_name, const char *iter_name)
{
- pair_iterator_wrapper::wrap(iter_name);
- class_<T>(pair_name, no_init)
+ pair_iterator_wrapper::wrap(m, iter_name);
+ py::class_<T>(m, pair_name)
.def("__iter__", iter)
.def("__len__", len)
.def("__getitem__", get)
- .def("__setitem__", set, with_custodian_and_ward<1, 2>())
+ .def("__setitem__", set, py::keep_alive<1, 2>())
.def_readwrite("first", &T::first)
.def_readwrite("second", &T::second);
}
@@ -257,36 +249,34 @@ template <typename T1, typename T2, typename value_conv> struct map_pair_wrapper
struct pair_iterator_wrapper
{
- static object next(std::pair<wrapped_pair &, int> &iter)
+ static py::object next(std::pair<wrapped_pair &, int> &iter)
{
if (iter.second == 0) {
iter.second++;
- return object(PythonConversion::string_converter<decltype(iter.first.base.first)>().to_str(
+ return py::cast(PythonConversion::string_converter<decltype(iter.first.base.first)>().to_str(
iter.first.ctx, iter.first.base.first));
} else if (iter.second == 1) {
iter.second++;
- return object(value_conv()(iter.first.ctx, iter.first.base.second));
+ return py::cast(value_conv()(iter.first.ctx, iter.first.base.second));
} else {
PyErr_SetString(PyExc_StopIteration, "End of range reached");
- boost::python::throw_error_already_set();
- // Should be unreachable, but prevent control may reach end of
- // non-void
- throw std::runtime_error("unreachable");
+ throw py::error_already_set();
}
}
- static void wrap(const char *python_name)
+ static void wrap(py::module &m, const char *python_name)
{
- class_<std::pair<wrapped_pair &, int>>(python_name, no_init).def("__next__", next);
+ //FIXME
+ //py::class_<std::pair<wrapped_pair &, int>>(m, python_name).def("__next__", next);
}
};
- static object get(wrapped_pair &x, int i)
+ static py::object get(wrapped_pair &x, int i)
{
if ((i >= 2) || (i < 0))
KeyError();
- return (i == 1) ? object(value_conv()(x.ctx, x.base.second))
- : object(PythonConversion::string_converter<decltype(x.base.first)>().to_str(x.ctx,
+ return (i == 1) ? py::cast(value_conv()(x.ctx, x.base.second))
+ : py::cast(PythonConversion::string_converter<decltype(x.base.first)>().to_str(x.ctx,
x.base.first));
}
@@ -301,15 +291,15 @@ template <typename T1, typename T2, typename value_conv> struct map_pair_wrapper
static typename value_conv::ret_type second_getter(wrapped_pair &t) { return value_conv()(t.ctx, t.base.second); }
- static void wrap(const char *pair_name, const char *iter_name)
+ static void wrap(py::module &m, const char *pair_name, const char *iter_name)
{
- pair_iterator_wrapper::wrap(iter_name);
- class_<wrapped_pair>(pair_name, no_init)
+ pair_iterator_wrapper::wrap(m, iter_name);
+ py::class_<wrapped_pair>(m, pair_name)
.def("__iter__", iter)
.def("__len__", len)
.def("__getitem__", get)
- .add_property("first", first_getter)
- .add_property("second", second_getter);
+ .def_property_readonly("first", first_getter)
+ .def_property_readonly("second", second_getter);
}
};
@@ -358,17 +348,17 @@ template <typename T, typename value_conv> struct map_wrapper
return x.base.count(k);
}
- static void wrap(const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name)
+ static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name)
{
- map_pair_wrapper<typename KV::first_type, typename KV::second_type, value_conv>::wrap(kv_name, kv_iter_name);
- typedef range_wrapper<T &, return_value_policy<return_by_value>, PythonConversion::wrap_context<KV &>> rw;
- typename rw::iter_wrap().wrap(iter_name);
- class_<wrapped_map>(map_name, no_init)
+ map_pair_wrapper<typename KV::first_type, typename KV::second_type, value_conv>::wrap(m, kv_name, kv_iter_name);
+ typedef range_wrapper<T &, py::return_value_policy::copy, PythonConversion::wrap_context<KV &>> rw;
+ typename rw::iter_wrap().wrap(m, iter_name);
+ py::class_<wrapped_map>(m, map_name)
.def("__iter__", rw::iter)
.def("__len__", len)
.def("__contains__", contains)
.def("__getitem__", get)
- .def("__setitem__", set, with_custodian_and_ward<1, 2>());
+ .def("__setitem__", set, py::keep_alive<1, 2>());
}
};
@@ -383,36 +373,34 @@ template <typename T1, typename T2> struct map_pair_wrapper_uptr
struct pair_iterator_wrapper
{
- static object next(std::pair<wrapped_pair &, int> &iter)
+ static py::object next(std::pair<wrapped_pair &, int> &iter)
{
if (iter.second == 0) {
iter.second++;
- return object(PythonConversion::string_converter<decltype(iter.first.base.first)>().to_str(
+ return py::cast(PythonConversion::string_converter<decltype(iter.first.base.first)>().to_str(
iter.first.ctx, iter.first.base.first));
} else if (iter.second == 1) {
iter.second++;
- return object(PythonConversion::ContextualWrapper<V &>(iter.first.ctx, *iter.first.base.second.get()));
+ return py::cast(PythonConversion::ContextualWrapper<V &>(iter.first.ctx, *iter.first.base.second.get()));
} else {
PyErr_SetString(PyExc_StopIteration, "End of range reached");
- boost::python::throw_error_already_set();
- // Should be unreachable, but prevent control may reach end of
- // non-void
- throw std::runtime_error("unreachable");
+ throw py::error_already_set();
}
}
- static void wrap(const char *python_name)
+ static void wrap(py::module &m, const char *python_name)
{
- class_<std::pair<wrapped_pair &, int>>(python_name, no_init).def("__next__", next);
+ //FIXME
+ //py::class_<std::pair<wrapped_pair &, int>>(m, python_name).def("__next__", next);
}
};
- static object get(wrapped_pair &x, int i)
+ static py::object get(wrapped_pair &x, int i)
{
if ((i >= 2) || (i < 0))
KeyError();
- return (i == 1) ? object(PythonConversion::ContextualWrapper<V &>(x.ctx, *x.base.second.get()))
- : object(PythonConversion::string_converter<decltype(x.base.first)>().to_str(x.ctx,
+ return (i == 1) ? py::cast(PythonConversion::ContextualWrapper<V &>(x.ctx, *x.base.second.get()))
+ : py::cast(PythonConversion::string_converter<decltype(x.base.first)>().to_str(x.ctx,
x.base.first));
}
@@ -430,15 +418,15 @@ template <typename T1, typename T2> struct map_pair_wrapper_uptr
return PythonConversion::ContextualWrapper<V &>(t.ctx, *t.base.second.get());
}
- static void wrap(const char *pair_name, const char *iter_name)
+ static void wrap(py::module &m, const char *pair_name, const char *iter_name)
{
- pair_iterator_wrapper::wrap(iter_name);
- class_<wrapped_pair>(pair_name, no_init)
+ pair_iterator_wrapper::wrap(m, iter_name);
+ py::class_<wrapped_pair>(m, pair_name)
.def("__iter__", iter)
.def("__len__", len)
.def("__getitem__", get)
- .add_property("first", first_getter)
- .add_property("second", second_getter);
+ .def_property_readonly("first", first_getter)
+ .def_property_readonly("second", second_getter);
}
};
@@ -487,24 +475,24 @@ template <typename T> struct map_wrapper_uptr
return x.base.count(k);
}
- static void wrap(const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name)
+ static void wrap(py::module &m, const char *map_name, const char *kv_name, const char *kv_iter_name, const char *iter_name)
{
- map_pair_wrapper_uptr<typename KV::first_type, typename KV::second_type>::wrap(kv_name, kv_iter_name);
- typedef range_wrapper<T &, return_value_policy<return_by_value>, PythonConversion::wrap_context<KV &>> rw;
- typename rw::iter_wrap().wrap(iter_name);
- class_<wrapped_map>(map_name, no_init)
+ map_pair_wrapper_uptr<typename KV::first_type, typename KV::second_type>::wrap(m, kv_name, kv_iter_name);
+ typedef range_wrapper<T &, py::return_value_policy::copy, PythonConversion::wrap_context<KV &>> rw;
+ typename rw::iter_wrap().wrap(m, iter_name);
+ py::class_<wrapped_map>(m, map_name)
.def("__iter__", rw::iter)
.def("__len__", len)
.def("__contains__", contains)
.def("__getitem__", get)
- .def("__setitem__", set, with_custodian_and_ward<1, 2>());
+ .def("__setitem__", set, py::keep_alive<1, 2>());
}
};
-#define WRAP_MAP(t, conv, name) \
- map_wrapper<t, conv>().wrap(#name, #name "KeyValue", #name "KeyValueIter", #name "Iterator")
-#define WRAP_MAP_UPTR(t, name) \
- map_wrapper_uptr<t>().wrap(#name, #name "KeyValue", #name "KeyValueIter", #name "Iterator")
+#define WRAP_MAP(m, t, conv, name) \
+ map_wrapper<t, conv>().wrap(m, #name, #name "KeyValue", #name "KeyValueIter", #name "Iterator")
+#define WRAP_MAP_UPTR(m, t, name) \
+ map_wrapper_uptr<t>().wrap(m, #name, #name "KeyValue", #name "KeyValueIter", #name "Iterator")
NEXTPNR_NAMESPACE_END
diff --git a/common/pywrappers.h b/common/pywrappers.h
index d50af4c3..e55039c0 100644
--- a/common/pywrappers.h
+++ b/common/pywrappers.h
@@ -21,19 +21,13 @@
#ifndef PYWRAPPERS_H
#define PYWRAPPERS_H
-#include <boost/function_types/function_arity.hpp>
-#include <boost/function_types/function_type.hpp>
-#include <boost/function_types/parameter_types.hpp>
-#include <boost/function_types/result_type.hpp>
-#include <boost/python.hpp>
-#include <boost/python/suite/indexing/map_indexing_suite.hpp>
-#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <pybind11/pybind11.h>
#include <utility>
#include "nextpnr.h"
NEXTPNR_NAMESPACE_BEGIN
-using namespace boost::python;
+namespace py = pybind11;
namespace PythonConversion {
template <typename T> struct ContextualWrapper
@@ -155,14 +149,14 @@ template <typename Class, typename FuncT, FuncT fn, typename rv_conv> struct fn_
using class_type = typename WrapIfNotContext<Class>::maybe_wrapped_t;
using conv_result_type = typename rv_conv::ret_type;
- static object wrapped_fn(class_type &cls)
+ static py::object wrapped_fn(class_type &cls)
{
Context *ctx = get_ctx<Class>(cls);
Class &base = get_base<Class>(cls);
try {
- return object(rv_conv()(ctx, (base.*fn)()));
+ return py::cast(rv_conv()(ctx, (base.*fn)()));
} catch (bad_wrap &) {
- return object();
+ return py::object();
}
}
@@ -176,14 +170,14 @@ template <typename Class, typename FuncT, FuncT fn, typename rv_conv, typename a
using conv_result_type = typename rv_conv::ret_type;
using conv_arg1_type = typename arg1_conv::arg_type;
- static object wrapped_fn(class_type &cls, conv_arg1_type arg1)
+ static py::object wrapped_fn(class_type &cls, conv_arg1_type arg1)
{
Context *ctx = get_ctx<Class>(cls);
Class &base = get_base<Class>(cls);
try {
- return object(rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1))));
+ return py::cast(rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1))));
} catch (bad_wrap &) {
- return object();
+ return py::object();
}
}
@@ -199,14 +193,14 @@ struct fn_wrapper_2a
using conv_arg1_type = typename arg1_conv::arg_type;
using conv_arg2_type = typename arg2_conv::arg_type;
- static object wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2)
+ static py::object wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2)
{
Context *ctx = get_ctx<Class>(cls);
Class &base = get_base<Class>(cls);
try {
- return object(rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2))));
+ return py::cast(rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2))));
} catch (bad_wrap &) {
- return object();
+ return py::object();
}
}
@@ -224,15 +218,15 @@ struct fn_wrapper_3a
using conv_arg2_type = typename arg2_conv::arg_type;
using conv_arg3_type = typename arg3_conv::arg_type;
- static object wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2, conv_arg3_type arg3)
+ static py::object wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2, conv_arg3_type arg3)
{
Context *ctx = get_ctx<Class>(cls);
Class &base = get_base<Class>(cls);
try {
- return object(
+ return py::cast(
rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2), arg3_conv()(ctx, arg3))));
} catch (bad_wrap &) {
- return object();
+ return py::object();
}
}
@@ -268,7 +262,7 @@ template <typename Class, typename FuncT, FuncT fn, typename arg1_conv> struct f
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); }
- template <typename WrapCls, typename Ta> static void def_wrap(WrapCls cls_, const char *name, Ta a = arg("arg1"))
+ template <typename WrapCls, typename Ta> static void def_wrap(WrapCls cls_, const char *name, Ta a = py::arg("arg1"))
{
cls_.def(name, wrapped_fn, a);
}
@@ -413,20 +407,20 @@ template <typename Class, typename MemT, MemT mem, typename v_conv> struct reado
using class_type = typename WrapIfNotContext<Class>::maybe_wrapped_t;
using conv_val_type = typename v_conv::ret_type;
- static object wrapped_getter(class_type &cls)
+ static py::object wrapped_getter(class_type &cls)
{
Context *ctx = get_ctx<Class>(cls);
Class &base = get_base<Class>(cls);
try {
- return object(v_conv()(ctx, (base.*mem)));
+ return py::cast(v_conv()(ctx, (base.*mem)));
} catch (bad_wrap &) {
- return object();
+ return py::object();
}
}
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name)
{
- cls_.add_property(name, wrapped_getter);
+ cls_.def_property_readonly(name, wrapped_getter);
}
};
@@ -436,14 +430,14 @@ template <typename Class, typename MemT, MemT mem, typename get_conv, typename s
using class_type = typename WrapIfNotContext<Class>::maybe_wrapped_t;
using conv_val_type = typename get_conv::ret_type;
- static object wrapped_getter(class_type &cls)
+ static py::object wrapped_getter(class_type &cls)
{
Context *ctx = get_ctx<Class>(cls);
Class &base = get_base<Class>(cls);
try {
- return object(get_conv()(ctx, (base.*mem)));
+ return py::cast(get_conv()(ctx, (base.*mem)));
} catch (bad_wrap &) {
- return object();
+ return py::object();
}
}
@@ -458,7 +452,7 @@ template <typename Class, typename MemT, MemT mem, typename get_conv, typename s
template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name)
{
- cls_.add_property(name, wrapped_getter, wrapped_setter);
+ cls_.def_property(name, wrapped_getter, wrapped_setter);
}
};
diff --git a/ecp5/arch_pybindings.cc b/ecp5/arch_pybindings.cc
index 951745af..b8e48ccf 100644
--- a/ecp5/arch_pybindings.cc
+++ b/ecp5/arch_pybindings.cc
@@ -26,21 +26,19 @@
NEXTPNR_NAMESPACE_BEGIN
-void arch_wrap_python()
+void arch_wrap_python(py::module &m)
{
using namespace PythonConversion;
- class_<ArchArgs>("ArchArgs").def_readwrite("type", &ArchArgs::type);
+ py::class_<ArchArgs>(m, "ArchArgs").def_readwrite("type", &ArchArgs::type);
- class_<BelId>("BelId").def_readwrite("index", &BelId::index);
+ py::class_<BelId>(m, "BelId").def_readwrite("index", &BelId::index);
- class_<WireId>("WireId").def_readwrite("index", &WireId::index);
+ py::class_<WireId>(m, "WireId").def_readwrite("index", &WireId::index);
- class_<PipId>("PipId").def_readwrite("index", &PipId::index);
+ py::class_<PipId>(m, "PipId").def_readwrite("index", &PipId::index);
- class_<BelPin>("BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin);
-
- auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>());
- auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init)
+ auto arch_cls = py::class_<Arch, BaseCtx>(m, "Arch").def(py::init<ArchArgs>());
+ auto ctx_cls = py::class_<Context, Arch>(m, "Context")
.def("checksum", &Context::checksum)
.def("pack", &Context::pack)
.def("place", &Context::place)
@@ -54,21 +52,21 @@ void arch_wrap_python()
typedef std::unordered_map<IdString, IdString> AliasMap;
typedef std::unordered_map<IdString, HierarchicalCell> HierarchyMap;
- auto belpin_cls = class_<ContextualWrapper<BelPin>>("BelPin", no_init);
+ auto belpin_cls = py::class_<ContextualWrapper<BelPin>>(m, "BelPin");
readonly_wrapper<BelPin, decltype(&BelPin::bel), &BelPin::bel, conv_to_str<BelId>>::def_wrap(belpin_cls, "bel");
readonly_wrapper<BelPin, decltype(&BelPin::pin), &BelPin::pin, conv_to_str<IdString>>::def_wrap(belpin_cls, "pin");
#include "arch_pybindings_shared.h"
- WRAP_RANGE(Bel, conv_to_str<BelId>);
- WRAP_RANGE(Wire, conv_to_str<WireId>);
- WRAP_RANGE(AllPip, conv_to_str<PipId>);
- WRAP_RANGE(Pip, conv_to_str<PipId>);
- WRAP_RANGE(BelPin, wrap_context<BelPin>);
+ WRAP_RANGE(m, Bel, conv_to_str<BelId>);
+ WRAP_RANGE(m, Wire, conv_to_str<WireId>);
+ WRAP_RANGE(m, AllPip, conv_to_str<PipId>);
+ WRAP_RANGE(m, Pip, conv_to_str<PipId>);
+ WRAP_RANGE(m, BelPin, wrap_context<BelPin>);
- WRAP_MAP_UPTR(CellMap, "IdCellMap");
- WRAP_MAP_UPTR(NetMap, "IdNetMap");
- WRAP_MAP(HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap");
+ WRAP_MAP_UPTR(m, CellMap, "IdCellMap");
+ WRAP_MAP_UPTR(m, NetMap, "IdNetMap");
+ WRAP_MAP(m, HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap");
}
NEXTPNR_NAMESPACE_END
diff --git a/generic/arch_pybindings.cc b/generic/arch_pybindings.cc
index 2600cac0..5c036ad0 100644
--- a/generic/arch_pybindings.cc
+++ b/generic/arch_pybindings.cc
@@ -35,13 +35,13 @@ template <> struct string_converter<const IdString &>
};
} // namespace PythonConversion
-void arch_wrap_python()
+void arch_wrap_python(py::module &m)
{
using namespace PythonConversion;
- auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>());
+ auto arch_cls = py::class_<Arch, BaseCtx>(m, "Arch").def(py::init<ArchArgs>());
- auto dxy_cls = class_<ContextualWrapper<DecalXY>>("DecalXY_", no_init);
+ auto dxy_cls = py::class_<ContextualWrapper<DecalXY>>(m, "DecalXY_");
readwrite_wrapper<DecalXY, decltype(&DecalXY::decal), &DecalXY::decal, conv_to_str<DecalId>,
conv_from_str<DecalId>>::def_wrap(dxy_cls, "decal");
readwrite_wrapper<DecalXY, decltype(&DecalXY::x), &DecalXY::x, pass_through<float>, pass_through<float>>::def_wrap(
@@ -49,15 +49,15 @@ void arch_wrap_python()
readwrite_wrapper<DecalXY, decltype(&DecalXY::y), &DecalXY::y, pass_through<float>, pass_through<float>>::def_wrap(
dxy_cls, "y");
- auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init)
+ auto ctx_cls = py::class_<Context, Arch>(m, "Context")
.def("checksum", &Context::checksum)
.def("pack", &Context::pack)
.def("place", &Context::place)
.def("route", &Context::route);
- class_<BelPin>("BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin);
+ py::class_<BelPin>(m, "BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin);
- class_<DelayInfo>("DelayInfo").def("maxDelay", &DelayInfo::maxDelay).def("minDelay", &DelayInfo::minDelay);
+ py::class_<DelayInfo>(m, "DelayInfo").def("maxDelay", &DelayInfo::maxDelay).def("minDelay", &DelayInfo::minDelay);
fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<IdString>,
conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelType");
@@ -154,86 +154,86 @@ void arch_wrap_python()
// Generic arch construction API
fn_wrapper_4a_v<Context, decltype(&Context::addWire), &Context::addWire, conv_from_str<IdString>,
conv_from_str<IdString>, pass_through<int>, pass_through<int>>::def_wrap(ctx_cls, "addWire",
- (arg("name"), "type", "x",
+ (py::arg("name"), "type", "x",
"y"));
fn_wrapper_6a_v<Context, decltype(&Context::addPip), &Context::addPip, conv_from_str<IdString>,
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>, pass_through<DelayInfo>,
pass_through<Loc>>::def_wrap(ctx_cls, "addPip",
- (arg("name"), "type", "srcWire", "dstWire", "delay", "loc"));
+ (py::arg("name"), "type", "srcWire", "dstWire", "delay", "loc"));
fn_wrapper_5a_v<Context, decltype(&Context::addAlias), &Context::addAlias, conv_from_str<IdString>,
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addAlias",
- (arg("name"), "type", "srcWire", "dstWire", "delay"));
+ (py::arg("name"), "type", "srcWire", "dstWire", "delay"));
fn_wrapper_4a_v<Context, decltype(&Context::addBel), &Context::addBel, conv_from_str<IdString>,
conv_from_str<IdString>, pass_through<Loc>, pass_through<bool>>::def_wrap(ctx_cls, "addBel",
- (arg("name"), "type",
+ (py::arg("name"), "type",
"loc", "gb"));
fn_wrapper_3a_v<Context, decltype(&Context::addBelInput), &Context::addBelInput, conv_from_str<IdString>,
conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "addBelInput",
- (arg("bel"), "name", "wire"));
+ (py::arg("bel"), "name", "wire"));
fn_wrapper_3a_v<Context, decltype(&Context::addBelOutput), &Context::addBelOutput, conv_from_str<IdString>,
conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "addBelOutput",
- (arg("bel"), "name", "wire"));
+ (py::arg("bel"), "name", "wire"));
fn_wrapper_3a_v<Context, decltype(&Context::addBelInout), &Context::addBelInout, conv_from_str<IdString>,
conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "addBelInout",
- (arg("bel"), "name", "wire"));
+ (py::arg("bel"), "name", "wire"));
fn_wrapper_2a_v<Context, decltype(&Context::addGroupBel), &Context::addGroupBel, conv_from_str<IdString>,
- conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupBel", (arg("group"), "bel"));
+ conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupBel", (py::arg("group"), "bel"));
fn_wrapper_2a_v<Context, decltype(&Context::addGroupWire), &Context::addGroupWire, conv_from_str<IdString>,
- conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupWire", (arg("group"), "wire"));
+ conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupWire", (py::arg("group"), "wire"));
fn_wrapper_2a_v<Context, decltype(&Context::addGroupPip), &Context::addGroupPip, conv_from_str<IdString>,
- conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupPip", (arg("group"), "pip"));
+ conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupPip", (py::arg("group"), "pip"));
fn_wrapper_2a_v<Context, decltype(&Context::addGroupGroup), &Context::addGroupPip, conv_from_str<IdString>,
- conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupGroup", (arg("group"), "grp"));
+ conv_from_str<IdString>>::def_wrap(ctx_cls, "addGroupGroup", (py::arg("group"), "grp"));
fn_wrapper_2a_v<Context, decltype(&Context::addDecalGraphic), &Context::addDecalGraphic, conv_from_str<DecalId>,
- pass_through<GraphicElement>>::def_wrap(ctx_cls, "addDecalGraphic", (arg("decal"), "graphic"));
+ pass_through<GraphicElement>>::def_wrap(ctx_cls, "addDecalGraphic", (py::arg("decal"), "graphic"));
fn_wrapper_2a_v<Context, decltype(&Context::setWireDecal), &Context::setWireDecal, conv_from_str<DecalId>,
- unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setWireDecal", (arg("wire"), "decalxy"));
+ unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setWireDecal", (py::arg("wire"), "decalxy"));
fn_wrapper_2a_v<Context, decltype(&Context::setPipDecal), &Context::setPipDecal, conv_from_str<DecalId>,
- unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setPipDecal", (arg("pip"), "decalxy"));
+ unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setPipDecal", (py::arg("pip"), "decalxy"));
fn_wrapper_2a_v<Context, decltype(&Context::setBelDecal), &Context::setBelDecal, conv_from_str<DecalId>,
- unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setBelDecal", (arg("bel"), "decalxy"));
+ unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setBelDecal", (py::arg("bel"), "decalxy"));
fn_wrapper_2a_v<Context, decltype(&Context::setGroupDecal), &Context::setGroupDecal, conv_from_str<DecalId>,
- unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setGroupDecal", (arg("group"), "decalxy"));
+ unwrap_context<DecalXY>>::def_wrap(ctx_cls, "setGroupDecal", (py::arg("group"), "decalxy"));
fn_wrapper_3a_v<Context, decltype(&Context::setWireAttr), &Context::setWireAttr, conv_from_str<DecalId>,
conv_from_str<IdString>, pass_through<std::string>>::def_wrap(ctx_cls, "setWireAttr",
- (arg("wire"), "key", "value"));
+ (py::arg("wire"), "key", "value"));
fn_wrapper_3a_v<Context, decltype(&Context::setBelAttr), &Context::setBelAttr, conv_from_str<DecalId>,
conv_from_str<IdString>, pass_through<std::string>>::def_wrap(ctx_cls, "setBelAttr",
- (arg("bel"), "key", "value"));
+ (py::arg("bel"), "key", "value"));
fn_wrapper_3a_v<Context, decltype(&Context::setPipAttr), &Context::setPipAttr, conv_from_str<DecalId>,
conv_from_str<IdString>, pass_through<std::string>>::def_wrap(ctx_cls, "setPipAttr",
- (arg("pip"), "key", "value"));
+ (py::arg("pip"), "key", "value"));
fn_wrapper_1a_v<Context, decltype(&Context::setLutK), &Context::setLutK, pass_through<int>>::def_wrap(
- ctx_cls, "setLutK", arg("K"));
+ ctx_cls, "setLutK", py::arg("K"));
fn_wrapper_2a_v<Context, decltype(&Context::setDelayScaling), &Context::setDelayScaling, pass_through<double>,
- pass_through<double>>::def_wrap(ctx_cls, "setDelayScaling", (arg("scale"), "offset"));
+ pass_through<double>>::def_wrap(ctx_cls, "setDelayScaling", (py::arg("scale"), "offset"));
fn_wrapper_2a_v<Context, decltype(&Context::addCellTimingClock), &Context::addCellTimingClock,
conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "addCellTimingClock",
- (arg("cell"), "port"));
+ (py::arg("cell"), "port"));
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingDelay), &Context::addCellTimingDelay,
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingDelay",
- (arg("cell"), "fromPort", "toPort", "delay"));
+ (py::arg("cell"), "fromPort", "toPort", "delay"));
fn_wrapper_5a_v<Context, decltype(&Context::addCellTimingSetupHold), &Context::addCellTimingSetupHold,
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>, pass_through<DelayInfo>,
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingSetupHold",
- (arg("cell"), "port", "clock", "setup", "hold"));
+ (py::arg("cell"), "port", "clock", "setup", "hold"));
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingClockToOut), &Context::addCellTimingClockToOut,
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingClockToOut",
- (arg("cell"), "port", "clock", "clktoq"));
+ (py::arg("cell"), "port", "clock", "clktoq"));
- WRAP_MAP_UPTR(CellMap, "IdCellMap");
- WRAP_MAP_UPTR(NetMap, "IdNetMap");
- WRAP_MAP(HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap");
- WRAP_VECTOR(const std::vector<IdString>, conv_to_str<IdString>);
+ WRAP_MAP_UPTR(m, CellMap, "IdCellMap");
+ WRAP_MAP_UPTR(m, NetMap, "IdNetMap");
+ WRAP_MAP(m, HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap");
+ WRAP_VECTOR(m, const std::vector<IdString>, conv_to_str<IdString>);
}
NEXTPNR_NAMESPACE_END
diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc
index 9dd17f01..9011d1dc 100644
--- a/ice40/arch_pybindings.cc
+++ b/ice40/arch_pybindings.cc
@@ -26,12 +26,12 @@
NEXTPNR_NAMESPACE_BEGIN
-void arch_wrap_python()
+void arch_wrap_python(py::module &m)
{
using namespace PythonConversion;
- class_<ArchArgs>("ArchArgs").def_readwrite("type", &ArchArgs::type);
+ py::class_<ArchArgs>(m, "ArchArgs").def_readwrite("type", &ArchArgs::type);
- enum_<decltype(std::declval<ArchArgs>().type)>("iCE40Type")
+ py::enum_<decltype(std::declval<ArchArgs>().type)>(m, "iCE40Type")
.value("NONE", ArchArgs::NONE)
.value("LP384", ArchArgs::LP384)
.value("LP1K", ArchArgs::LP1K)
@@ -47,16 +47,14 @@ void arch_wrap_python()
.value("U4K", ArchArgs::U4K)
.export_values();
- class_<BelId>("BelId").def_readwrite("index", &BelId::index);
+ py::class_<BelId>(m, "BelId").def_readwrite("index", &BelId::index);
- class_<WireId>("WireId").def_readwrite("index", &WireId::index);
+ py::class_<WireId>(m, "WireId").def_readwrite("index", &WireId::index);
- class_<PipId>("PipId").def_readwrite("index", &PipId::index);
+ py::class_<PipId>(m, "PipId").def_readwrite("index", &PipId::index);
- class_<BelPin>("BelPin").def_readwrite("bel", &BelPin::bel).def_readwrite("pin", &BelPin::pin);
-
- auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>());
- auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init)
+ auto arch_cls = py::class_<Arch, BaseCtx>(m, "Arch").def(py::init<ArchArgs>());
+ auto ctx_cls = py::class_<Context, Arch>(m, "Context")
.def("checksum", &Context::checksum)
.def("pack", &Context::pack)
.def("place", &Context::place)
@@ -70,21 +68,21 @@ void arch_wrap_python()
typedef std::unordered_map<IdString, IdString> AliasMap;
typedef std::unordered_map<IdString, HierarchicalCell> HierarchyMap;
- auto belpin_cls = class_<ContextualWrapper<BelPin>>("BelPin", no_init);
+ auto belpin_cls = py::class_<ContextualWrapper<BelPin>>(m, "BelPin");
readonly_wrapper<BelPin, decltype(&BelPin::bel), &BelPin::bel, conv_to_str<BelId>>::def_wrap(belpin_cls, "bel");
readonly_wrapper<BelPin, decltype(&BelPin::pin), &BelPin::pin, conv_to_str<IdString>>::def_wrap(belpin_cls, "pin");
#include "arch_pybindings_shared.h"
- WRAP_RANGE(Bel, conv_to_str<BelId>);
- WRAP_RANGE(Wire, conv_to_str<WireId>);
- WRAP_RANGE(AllPip, conv_to_str<PipId>);
- WRAP_RANGE(Pip, conv_to_str<PipId>);
- WRAP_RANGE(BelPin, wrap_context<BelPin>);
+ WRAP_RANGE(m, Bel, conv_to_str<BelId>);
+ WRAP_RANGE(m, Wire, conv_to_str<WireId>);
+ WRAP_RANGE(m, AllPip, conv_to_str<PipId>);
+ WRAP_RANGE(m, Pip, conv_to_str<PipId>);
+ WRAP_RANGE(m, BelPin, wrap_context<BelPin>);
- WRAP_MAP_UPTR(CellMap, "IdCellMap");
- WRAP_MAP_UPTR(NetMap, "IdNetMap");
- WRAP_MAP(HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap");
+ WRAP_MAP_UPTR(m, CellMap, "IdCellMap");
+ WRAP_MAP_UPTR(m, NetMap, "IdNetMap");
+ WRAP_MAP(m, HierarchyMap, wrap_context<HierarchicalCell &>, "HierarchyMap");
}
NEXTPNR_NAMESPACE_END