GeezerVison is showing patch-diff.githubusercontent.com — patch-diff.githubusercontent.com diff --git a/mlir/cmake/modules/MLIRDetectPythonEnv.cmake b/mlir/cmake/modules/MLIRDetectPythonEnv.cmake
index c62ac7fa615ea6..d6bb65c64b8292 100644
--- a/mlir/cmake/modules/MLIRDetectPythonEnv.cmake
+++ b/mlir/cmake/modules/MLIRDetectPythonEnv.cmake
@@ -39,7 +39,7 @@ macro(mlir_configure_python_dev_packages)
"extension = '${PYTHON_MODULE_EXTENSION}")
mlir_detect_nanobind_install()
- find_package(nanobind 2.2 CONFIG REQUIRED)
+ find_package(nanobind 2.4 CONFIG REQUIRED)
message(STATUS "Found nanobind v${nanobind_VERSION}: ${nanobind_INCLUDE_DIR}")
message(STATUS "Python prefix = '${PYTHON_MODULE_PREFIX}', "
"suffix = '${PYTHON_MODULE_SUFFIX}', "
diff --git a/mlir/include/mlir/Bindings/Python/IRTypes.h b/mlir/include/mlir/Bindings/Python/IRTypes.h
index 9afad4c23b3f35..ba9642cf2c6a2d 100644
--- a/mlir/include/mlir/Bindings/Python/IRTypes.h
+++ b/mlir/include/mlir/Bindings/Python/IRTypes.h
@@ -9,7 +9,7 @@
#ifndef MLIR_BINDINGS_PYTHON_IRTYPES_H
#define MLIR_BINDINGS_PYTHON_IRTYPES_H
-#include "mlir/Bindings/Python/PybindAdaptors.h"
+#include "mlir/Bindings/Python/NanobindAdaptors.h"
namespace mlir {
diff --git a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
index c8233355d1d67b..edc69774be9227 100644
--- a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
@@ -374,9 +374,8 @@ class pure_subclass {
static_assert(!std::is_member_function_pointer ::value,
"def_staticmethod(...) called with a non-static member "
"function pointer");
- py::cpp_function cf(
- std::forward(f), py::name(name), py::scope(thisClass),
- py::sibling(py::getattr(thisClass, name, py::none())), extra...);
+ py::cpp_function cf(std::forward(f), py::name(name),
+ py::scope(thisClass), extra...);
thisClass.attr(cf.name()) = py::staticmethod(cf);
return *this;
}
@@ -387,9 +386,8 @@ class pure_subclass {
static_assert(!std::is_member_function_pointer::value,
"def_classmethod(...) called with a non-static member "
"function pointer");
- py::cpp_function cf(
- std::forward(f), py::name(name), py::scope(thisClass),
- py::sibling(py::getattr(thisClass, name, py::none())), extra...);
+ py::cpp_function cf(std::forward(f), py::name(name),
+ py::scope(thisClass), extra...);
thisClass.attr(cf.name()) =
py::reinterpret_borrow(PyClassMethod_New(cf.ptr()));
return *this;
diff --git a/mlir/lib/Bindings/Python/Globals.h b/mlir/lib/Bindings/Python/Globals.h
index a022067f5c7e57..0ec522d14f74bd 100644
--- a/mlir/lib/Bindings/Python/Globals.h
+++ b/mlir/lib/Bindings/Python/Globals.h
@@ -9,18 +9,17 @@
#ifndef MLIR_BINDINGS_PYTHON_GLOBALS_H
#define MLIR_BINDINGS_PYTHON_GLOBALS_H
-#include "PybindUtils.h"
+#include
+#include
+#include
+#include "NanobindUtils.h"
#include "mlir-c/IR.h"
#include "mlir/CAPI/Support.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
-#include
-#include
-#include
-
namespace mlir {
namespace python {
@@ -57,55 +56,55 @@ class PyGlobals {
/// Raises an exception if the mapping already exists and replace == false.
/// This is intended to be called by implementation code.
void registerAttributeBuilder(const std::string &attributeKind,
- pybind11::function pyFunc,
+ nanobind::callable pyFunc,
bool replace = false);
/// Adds a user-friendly type caster. Raises an exception if the mapping
/// already exists and replace == false. This is intended to be called by
/// implementation code.
- void registerTypeCaster(MlirTypeID mlirTypeID, pybind11::function typeCaster,
+ void registerTypeCaster(MlirTypeID mlirTypeID, nanobind::callable typeCaster,
bool replace = false);
/// Adds a user-friendly value caster. Raises an exception if the mapping
/// already exists and replace == false. This is intended to be called by
/// implementation code.
void registerValueCaster(MlirTypeID mlirTypeID,
- pybind11::function valueCaster,
+ nanobind::callable valueCaster,
bool replace = false);
/// Adds a concrete implementation dialect class.
/// Raises an exception if the mapping already exists.
/// This is intended to be called by implementation code.
void registerDialectImpl(const std::string &dialectNamespace,
- pybind11::object pyClass);
+ nanobind::object pyClass);
/// Adds a concrete implementation operation class.
/// Raises an exception if the mapping already exists and replace == false.
/// This is intended to be called by implementation code.
void registerOperationImpl(const std::string &operationName,
- pybind11::object pyClass, bool replace = false);
+ nanobind::object pyClass, bool replace = false);
/// Returns the custom Attribute builder for Attribute kind.
- std::optional
+ std::optional
lookupAttributeBuilder(const std::string &attributeKind);
/// Returns the custom type caster for MlirTypeID mlirTypeID.
- std::optional lookupTypeCaster(MlirTypeID mlirTypeID,
+ std::optional lookupTypeCaster(MlirTypeID mlirTypeID,
MlirDialect dialect);
/// Returns the custom value caster for MlirTypeID mlirTypeID.
- std::optional lookupValueCaster(MlirTypeID mlirTypeID,
+ std::optional lookupValueCaster(MlirTypeID mlirTypeID,
MlirDialect dialect);
/// Looks up a registered dialect class by namespace. Note that this may
/// trigger loading of the defining module and can arbitrarily re-enter.
- std::optional
+ std::optional
lookupDialectClass(const std::string &dialectNamespace);
/// Looks up a registered operation class (deriving from OpView) by operation
/// name. Note that this may trigger a load of the dialect, which can
/// arbitrarily re-enter.
- std::optional
+ std::optional
lookupOperationClass(llvm::StringRef operationName);
private:
@@ -113,15 +112,15 @@ class PyGlobals {
/// Module name prefixes to search under for dialect implementation modules.
std::vector dialectSearchPrefixes;
/// Map of dialect namespace to external dialect class object.
- llvm::StringMap dialectClassMap;
+ llvm::StringMap dialectClassMap;
/// Map of full operation name to external operation class object.
- llvm::StringMap operationClassMap;
+ llvm::StringMap operationClassMap;
/// Map of attribute ODS name to custom builder.
- llvm::StringMap attributeBuilderMap;
+ llvm::StringMap attributeBuilderMap;
/// Map of MlirTypeID to custom type caster.
- llvm::DenseMap typeCasterMap;
+ llvm::DenseMap typeCasterMap;
/// Map of MlirTypeID to custom value caster.
- llvm::DenseMap valueCasterMap;
+ llvm::DenseMap valueCasterMap;
/// Set of dialect namespaces that we have attempted to import implementation
/// modules for.
llvm::StringSet<> loadedDialectModules;
diff --git a/mlir/lib/Bindings/Python/IRAffine.cpp b/mlir/lib/Bindings/Python/IRAffine.cpp
index b138e131e851ea..2db690309fab8c 100644
--- a/mlir/lib/Bindings/Python/IRAffine.cpp
+++ b/mlir/lib/Bindings/Python/IRAffine.cpp
@@ -6,20 +6,19 @@
//
//===----------------------------------------------------------------------===//
+#include
+#include
+#include
+
#include
#include
-#include
-#include
-#include
-#include
+#include
#include
#include
#include
#include "IRModule.h"
-
-#include "PybindUtils.h"
-
+#include "NanobindUtils.h"
#include "mlir-c/AffineExpr.h"
#include "mlir-c/AffineMap.h"
#include "mlir-c/Bindings/Python/Interop.h"
@@ -30,7 +29,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-namespace py = pybind11;
+namespace nb = nanobind;
using namespace mlir;
using namespace mlir::python;
@@ -46,23 +45,23 @@ static const char kDumpDocstring[] =
/// Throws errors in case of failure, using "action" to describe what the caller
/// was attempting to do.
template
-static void pyListToVector(const py::list &list,
+static void pyListToVector(const nb::list &list,
llvm::SmallVectorImpl &result,
StringRef action) {
- result.reserve(py::len(list));
- for (py::handle item : list) {
+ result.reserve(nb::len(list));
+ for (nb::handle item : list) {
try {
- result.push_back(item.cast());
- } catch (py::cast_error &err) {
+ result.push_back(nb::cast(item));
+ } catch (nb::cast_error &err) {
std::string msg = (llvm::Twine("Invalid expression when ") + action +
" (" + err.what() + ")")
.str();
- throw py::cast_error(msg);
- } catch (py::reference_cast_error &err) {
+ throw std::runtime_error(msg.c_str());
+ } catch (std::runtime_error &err) {
std::string msg = (llvm::Twine("Invalid expression (None?) when ") +
action + " (" + err.what() + ")")
.str();
- throw py::cast_error(msg);
+ throw std::runtime_error(msg.c_str());
}
}
}
@@ -94,7 +93,7 @@ class PyConcreteAffineExpr : public BaseTy {
// IsAFunctionTy isaFunction
// const char *pyClassName
// and redefine bindDerived.
- using ClassTy = py::class_;
+ using ClassTy = nb::class_;
using IsAFunctionTy = bool (*)(MlirAffineExpr);
PyConcreteAffineExpr() = default;
@@ -105,24 +104,25 @@ class PyConcreteAffineExpr : public BaseTy {
static MlirAffineExpr castFrom(PyAffineExpr &orig) {
if (!DerivedTy::isaFunction(orig)) {
- auto origRepr = py::repr(py::cast(orig)).cast();
- throw py::value_error((Twine("Cannot cast affine expression to ") +
+ auto origRepr = nb::cast(nb::repr(nb::cast(orig)));
+ throw nb::value_error((Twine("Cannot cast affine expression to ") +
DerivedTy::pyClassName + " (from " + origRepr +
")")
- .str());
+ .str()
+ .c_str());
}
return orig;
}
- static void bind(py::module &m) {
- auto cls = ClassTy(m, DerivedTy::pyClassName, py::module_local());
- cls.def(py::init(), py::arg("expr"));
+ static void bind(nb::module_ &m) {
+ auto cls = ClassTy(m, DerivedTy::pyClassName);
+ cls.def(nb::init(), nb::arg("expr"));
cls.def_static(
"isinstance",
[](PyAffineExpr &otherAffineExpr) -> bool {
return DerivedTy::isaFunction(otherAffineExpr);
},
- py::arg("other"));
+ nb::arg("other"));
DerivedTy::bindDerived(cls);
}
@@ -144,9 +144,9 @@ class PyAffineConstantExpr : public PyConcreteAffineExpr {
}
static void bindDerived(ClassTy &c) {
- c.def_static("get", &PyAffineConstantExpr::get, py::arg("value"),
- py::arg("context") = py::none());
- c.def_property_readonly("value", [](PyAffineConstantExpr &self) {
+ c.def_static("get", &PyAffineConstantExpr::get, nb::arg("value"),
+ nb::arg("context").none() = nb::none());
+ c.def_prop_ro("value", [](PyAffineConstantExpr &self) {
return mlirAffineConstantExprGetValue(self);
});
}
@@ -164,9 +164,9 @@ class PyAffineDimExpr : public PyConcreteAffineExpr {
}
static void bindDerived(ClassTy &c) {
- c.def_static("get", &PyAffineDimExpr::get, py::arg("position"),
- py::arg("context") = py::none());
- c.def_property_readonly("position", [](PyAffineDimExpr &self) {
+ c.def_static("get", &PyAffineDimExpr::get, nb::arg("position"),
+ nb::arg("context").none() = nb::none());
+ c.def_prop_ro("position", [](PyAffineDimExpr &self) {
return mlirAffineDimExprGetPosition(self);
});
}
@@ -184,9 +184,9 @@ class PyAffineSymbolExpr : public PyConcreteAffineExpr {
}
static void bindDerived(ClassTy &c) {
- c.def_static("get", &PyAffineSymbolExpr::get, py::arg("position"),
- py::arg("context") = py::none());
- c.def_property_readonly("position", [](PyAffineSymbolExpr &self) {
+ c.def_static("get", &PyAffineSymbolExpr::get, nb::arg("position"),
+ nb::arg("context").none() = nb::none());
+ c.def_prop_ro("position", [](PyAffineSymbolExpr &self) {
return mlirAffineSymbolExprGetPosition(self);
});
}
@@ -209,8 +209,8 @@ class PyAffineBinaryExpr : public PyConcreteAffineExpr {
}
static void bindDerived(ClassTy &c) {
- c.def_property_readonly("lhs", &PyAffineBinaryExpr::lhs);
- c.def_property_readonly("rhs", &PyAffineBinaryExpr::rhs);
+ c.def_prop_ro("lhs", &PyAffineBinaryExpr::lhs);
+ c.def_prop_ro("rhs", &PyAffineBinaryExpr::rhs);
}
};
@@ -365,15 +365,14 @@ bool PyAffineExpr::operator==(const PyAffineExpr &other) const {
return mlirAffineExprEqual(affineExpr, other.affineExpr);
}
-py::object PyAffineExpr::getCapsule() {
- return py::reinterpret_steal(
- mlirPythonAffineExprToCapsule(*this));
+nb::object PyAffineExpr::getCapsule() {
+ return nb::steal(mlirPythonAffineExprToCapsule(*this));
}
-PyAffineExpr PyAffineExpr::createFromCapsule(py::object capsule) {
+PyAffineExpr PyAffineExpr::createFromCapsule(nb::object capsule) {
MlirAffineExpr rawAffineExpr = mlirPythonCapsuleToAffineExpr(capsule.ptr());
if (mlirAffineExprIsNull(rawAffineExpr))
- throw py::error_already_set();
+ throw nb::python_error();
return PyAffineExpr(
PyMlirContext::forContext(mlirAffineExprGetContext(rawAffineExpr)),
rawAffineExpr);
@@ -424,14 +423,14 @@ bool PyAffineMap::operator==(const PyAffineMap &other) const {
return mlirAffineMapEqual(affineMap, other.affineMap);
}
-py::object PyAffineMap::getCapsule() {
- return py::reinterpret_steal(mlirPythonAffineMapToCapsule(*this));
+nb::object PyAffineMap::getCapsule() {
+ return nb::steal(mlirPythonAffineMapToCapsule(*this));
}
-PyAffineMap PyAffineMap::createFromCapsule(py::object capsule) {
+PyAffineMap PyAffineMap::createFromCapsule(nb::object capsule) {
MlirAffineMap rawAffineMap = mlirPythonCapsuleToAffineMap(capsule.ptr());
if (mlirAffineMapIsNull(rawAffineMap))
- throw py::error_already_set();
+ throw nb::python_error();
return PyAffineMap(
PyMlirContext::forContext(mlirAffineMapGetContext(rawAffineMap)),
rawAffineMap);
@@ -454,11 +453,10 @@ class PyIntegerSetConstraint {
bool isEq() { return mlirIntegerSetIsConstraintEq(set, pos); }
- static void bind(py::module &m) {
- py::class_(m, "IntegerSetConstraint",
- py::module_local())
- .def_property_readonly("expr", &PyIntegerSetConstraint::getExpr)
- .def_property_readonly("is_eq", &PyIntegerSetConstraint::isEq);
+ static void bind(nb::module_ &m) {
+ nb::class_(m, "IntegerSetConstraint")
+ .def_prop_ro("expr", &PyIntegerSetConstraint::getExpr)
+ .def_prop_ro("is_eq", &PyIntegerSetConstraint::isEq);
}
private:
@@ -501,27 +499,25 @@ bool PyIntegerSet::operator==(const PyIntegerSet &other) const {
return mlirIntegerSetEqual(integerSet, other.integerSet);
}
-py::object PyIntegerSet::getCapsule() {
- return py::reinterpret_steal(
- mlirPythonIntegerSetToCapsule(*this));
+nb::object PyIntegerSet::getCapsule() {
+ return nb::steal(mlirPythonIntegerSetToCapsule(*this));
}
-PyIntegerSet PyIntegerSet::createFromCapsule(py::object capsule) {
+PyIntegerSet PyIntegerSet::createFromCapsule(nb::object capsule) {
MlirIntegerSet rawIntegerSet = mlirPythonCapsuleToIntegerSet(capsule.ptr());
if (mlirIntegerSetIsNull(rawIntegerSet))
- throw py::error_already_set();
+ throw nb::python_error();
return PyIntegerSet(
PyMlirContext::forContext(mlirIntegerSetGetContext(rawIntegerSet)),
rawIntegerSet);
}
-void mlir::python::populateIRAffine(py::module &m) {
+void mlir::python::populateIRAffine(nb::module_ &m) {
//----------------------------------------------------------------------------
// Mapping of PyAffineExpr and derived classes.
//----------------------------------------------------------------------------
- py::class_(m, "AffineExpr", py::module_local())
- .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
- &PyAffineExpr::getCapsule)
+ nb::class_(m, "AffineExpr")
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyAffineExpr::getCapsule)
.def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAffineExpr::createFromCapsule)
.def("__add__", &PyAffineAddExpr::get)
.def("__add__", &PyAffineAddExpr::getRHSConstant)
@@ -558,7 +554,7 @@ void mlir::python::populateIRAffine(py::module &m) {
.def("__eq__", [](PyAffineExpr &self,
PyAffineExpr &other) { return self == other; })
.def("__eq__",
- [](PyAffineExpr &self, py::object &other) { return false; })
+ [](PyAffineExpr &self, nb::object &other) { return false; })
.def("__str__",
[](PyAffineExpr &self) {
PyPrintAccumulator printAccum;
@@ -579,7 +575,7 @@ void mlir::python::populateIRAffine(py::module &m) {
[](PyAffineExpr &self) {
return static_cast(llvm::hash_value(self.get().ptr));
})
- .def_property_readonly(
+ .def_prop_ro(
"context",
[](PyAffineExpr &self) { return self.getContext().getObject(); })
.def("compose",
@@ -632,16 +628,16 @@ void mlir::python::populateIRAffine(py::module &m) {
.def_static("get_ceil_div", &PyAffineCeilDivExpr::getRHSConstant,
"Gets an affine expression containing the rounded-up result "
"of dividing an expression by a constant.")
- .def_static("get_constant", &PyAffineConstantExpr::get, py::arg("value"),
- py::arg("context") = py::none(),
+ .def_static("get_constant", &PyAffineConstantExpr::get, nb::arg("value"),
+ nb::arg("context").none() = nb::none(),
"Gets a constant affine expression with the given value.")
.def_static(
- "get_dim", &PyAffineDimExpr::get, py::arg("position"),
- py::arg("context") = py::none(),
+ "get_dim", &PyAffineDimExpr::get, nb::arg("position"),
+ nb::arg("context").none() = nb::none(),
"Gets an affine expression of a dimension at the given position.")
.def_static(
- "get_symbol", &PyAffineSymbolExpr::get, py::arg("position"),
- py::arg("context") = py::none(),
+ "get_symbol", &PyAffineSymbolExpr::get, nb::arg("position"),
+ nb::arg("context").none() = nb::none(),
"Gets an affine expression of a symbol at the given position.")
.def(
"dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); },
@@ -659,13 +655,12 @@ void mlir::python::populateIRAffine(py::module &m) {
//----------------------------------------------------------------------------
// Mapping of PyAffineMap.
//----------------------------------------------------------------------------
- py::class_(m, "AffineMap", py::module_local())
- .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
- &PyAffineMap::getCapsule)
+ nb::class_(m, "AffineMap")
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyAffineMap::getCapsule)
.def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAffineMap::createFromCapsule)
.def("__eq__",
[](PyAffineMap &self, PyAffineMap &other) { return self == other; })
- .def("__eq__", [](PyAffineMap &self, py::object &other) { return false; })
+ .def("__eq__", [](PyAffineMap &self, nb::object &other) { return false; })
.def("__str__",
[](PyAffineMap &self) {
PyPrintAccumulator printAccum;
@@ -687,7 +682,7 @@ void mlir::python::populateIRAffine(py::module &m) {
return static_cast(llvm::hash_value(self.get().ptr));
})
.def_static("compress_unused_symbols",
- [](py::list affineMaps, DefaultingPyMlirContext context) {
+ [](nb::list affineMaps, DefaultingPyMlirContext context) {
SmallVector maps;
pyListToVector(
affineMaps, maps, "attempting to create an AffineMap");
@@ -704,7 +699,7 @@ void mlir::python::populateIRAffine(py::module &m) {
res.emplace_back(context->getRef(), m);
return res;
})
- .def_property_readonly(
+ .def_prop_ro(
"context",
[](PyAffineMap &self) { return self.getContext().getObject(); },
"Context that owns the Affine Map")
@@ -713,7 +708,7 @@ void mlir::python::populateIRAffine(py::module &m) {
kDumpDocstring)
.def_static(
"get",
- [](intptr_t dimCount, intptr_t symbolCount, py::list exprs,
+ [](intptr_t dimCount, intptr_t symbolCount, nb::list exprs,
DefaultingPyMlirContext context) {
SmallVector affineExprs;
pyListToVector(
@@ -723,8 +718,8 @@ void mlir::python::populateIRAffine(py::module &m) {
affineExprs.size(), affineExprs.data());
return PyAffineMap(context->getRef(), map);
},
- py::arg("dim_count"), py::arg("symbol_count"), py::arg("exprs"),
- py::arg("context") = py::none(),
+ nb::arg("dim_count"), nb::arg("symbol_count"), nb::arg("exprs"),
+ nb::arg("context").none() = nb::none(),
"Gets a map with the given expressions as results.")
.def_static(
"get_constant",
@@ -733,7 +728,7 @@ void mlir::python::populateIRAffine(py::module &m) {
mlirAffineMapConstantGet(context->get(), value);
return PyAffineMap(context->getRef(), affineMap);
},
- py::arg("value"), py::arg("context") = py::none(),
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
"Gets an affine map with a single constant result")
.def_static(
"get_empty",
@@ -741,7 +736,7 @@ void mlir::python::populateIRAffine(py::module &m) {
MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get());
return PyAffineMap(context->getRef(), affineMap);
},
- py::arg("context") = py::none(), "Gets an empty affine map.")
+ nb::arg("context").none() = nb::none(), "Gets an empty affine map.")
.def_static(
"get_identity",
[](intptr_t nDims, DefaultingPyMlirContext context) {
@@ -749,7 +744,7 @@ void mlir::python::populateIRAffine(py::module &m) {
mlirAffineMapMultiDimIdentityGet(context->get(), nDims);
return PyAffineMap(context->getRef(), affineMap);
},
- py::arg("n_dims"), py::arg("context") = py::none(),
+ nb::arg("n_dims"), nb::arg("context").none() = nb::none(),
"Gets an identity map with the given number of dimensions.")
.def_static(
"get_minor_identity",
@@ -759,8 +754,8 @@ void mlir::python::populateIRAffine(py::module &m) {
mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults);
return PyAffineMap(context->getRef(), affineMap);
},
- py::arg("n_dims"), py::arg("n_results"),
- py::arg("context") = py::none(),
+ nb::arg("n_dims"), nb::arg("n_results"),
+ nb::arg("context").none() = nb::none(),
"Gets a minor identity map with the given number of dimensions and "
"results.")
.def_static(
@@ -768,13 +763,13 @@ void mlir::python::populateIRAffine(py::module &m) {
[](std::vector permutation,
DefaultingPyMlirContext context) {
if (!isPermutation(permutation))
- throw py::cast_error("Invalid permutation when attempting to "
- "create an AffineMap");
+ throw std::runtime_error("Invalid permutation when attempting to "
+ "create an AffineMap");
MlirAffineMap affineMap = mlirAffineMapPermutationGet(
context->get(), permutation.size(), permutation.data());
return PyAffineMap(context->getRef(), affineMap);
},
- py::arg("permutation"), py::arg("context") = py::none(),
+ nb::arg("permutation"), nb::arg("context").none() = nb::none(),
"Gets an affine map that permutes its inputs.")
.def(
"get_submap",
@@ -782,33 +777,33 @@ void mlir::python::populateIRAffine(py::module &m) {
intptr_t numResults = mlirAffineMapGetNumResults(self);
for (intptr_t pos : resultPos) {
if (pos < 0 || pos >= numResults)
- throw py::value_error("result position out of bounds");
+ throw nb::value_error("result position out of bounds");
}
MlirAffineMap affineMap = mlirAffineMapGetSubMap(
self, resultPos.size(), resultPos.data());
return PyAffineMap(self.getContext(), affineMap);
},
- py::arg("result_positions"))
+ nb::arg("result_positions"))
.def(
"get_major_submap",
[](PyAffineMap &self, intptr_t nResults) {
if (nResults >= mlirAffineMapGetNumResults(self))
- throw py::value_error("number of results out of bounds");
+ throw nb::value_error("number of results out of bounds");
MlirAffineMap affineMap =
mlirAffineMapGetMajorSubMap(self, nResults);
return PyAffineMap(self.getContext(), affineMap);
},
- py::arg("n_results"))
+ nb::arg("n_results"))
.def(
"get_minor_submap",
[](PyAffineMap &self, intptr_t nResults) {
if (nResults >= mlirAffineMapGetNumResults(self))
- throw py::value_error("number of results out of bounds");
+ throw nb::value_error("number of results out of bounds");
MlirAffineMap affineMap =
mlirAffineMapGetMinorSubMap(self, nResults);
return PyAffineMap(self.getContext(), affineMap);
},
- py::arg("n_results"))
+ nb::arg("n_results"))
.def(
"replace",
[](PyAffineMap &self, PyAffineExpr &expression,
@@ -818,39 +813,37 @@ void mlir::python::populateIRAffine(py::module &m) {
self, expression, replacement, numResultDims, numResultSyms);
return PyAffineMap(self.getContext(), affineMap);
},
- py::arg("expr"), py::arg("replacement"), py::arg("n_result_dims"),
- py::arg("n_result_syms"))
- .def_property_readonly(
+ nb::arg("expr"), nb::arg("replacement"), nb::arg("n_result_dims"),
+ nb::arg("n_result_syms"))
+ .def_prop_ro(
"is_permutation",
[](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); })
- .def_property_readonly("is_projected_permutation",
- [](PyAffineMap &self) {
- return mlirAffineMapIsProjectedPermutation(self);
- })
- .def_property_readonly(
+ .def_prop_ro("is_projected_permutation",
+ [](PyAffineMap &self) {
+ return mlirAffineMapIsProjectedPermutation(self);
+ })
+ .def_prop_ro(
"n_dims",
[](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); })
- .def_property_readonly(
+ .def_prop_ro(
"n_inputs",
[](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); })
- .def_property_readonly(
+ .def_prop_ro(
"n_symbols",
[](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); })
- .def_property_readonly("results", [](PyAffineMap &self) {
- return PyAffineMapExprList(self);
- });
+ .def_prop_ro("results",
+ [](PyAffineMap &self) { return PyAffineMapExprList(self); });
PyAffineMapExprList::bind(m);
//----------------------------------------------------------------------------
// Mapping of PyIntegerSet.
//----------------------------------------------------------------------------
- py::class_(m, "IntegerSet", py::module_local())
- .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
- &PyIntegerSet::getCapsule)
+ nb::class_(m, "IntegerSet")
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyIntegerSet::getCapsule)
.def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyIntegerSet::createFromCapsule)
.def("__eq__", [](PyIntegerSet &self,
PyIntegerSet &other) { return self == other; })
- .def("__eq__", [](PyIntegerSet &self, py::object other) { return false; })
+ .def("__eq__", [](PyIntegerSet &self, nb::object other) { return false; })
.def("__str__",
[](PyIntegerSet &self) {
PyPrintAccumulator printAccum;
@@ -871,7 +864,7 @@ void mlir::python::populateIRAffine(py::module &m) {
[](PyIntegerSet &self) {
return static_cast(llvm::hash_value(self.get().ptr));
})
- .def_property_readonly(
+ .def_prop_ro(
"context",
[](PyIntegerSet &self) { return self.getContext().getObject(); })
.def(
@@ -879,14 +872,14 @@ void mlir::python::populateIRAffine(py::module &m) {
kDumpDocstring)
.def_static(
"get",
- [](intptr_t numDims, intptr_t numSymbols, py::list exprs,
+ [](intptr_t numDims, intptr_t numSymbols, nb::list exprs,
std::vector eqFlags, DefaultingPyMlirContext context) {
if (exprs.size() != eqFlags.size())
- throw py::value_error(
+ throw nb::value_error(
"Expected the number of constraints to match "
"that of equality flags");
- if (exprs.empty())
- throw py::value_error("Expected non-empty list of constraints");
+ if (exprs.size() == 0)
+ throw nb::value_error("Expected non-empty list of constraints");
// Copy over to a SmallVector because std::vector has a
// specialization for booleans that packs data and does not
@@ -901,8 +894,8 @@ void mlir::python::populateIRAffine(py::module &m) {
affineExprs.data(), flags.data());
return PyIntegerSet(context->getRef(), set);
},
- py::arg("num_dims"), py::arg("num_symbols"), py::arg("exprs"),
- py::arg("eq_flags"), py::arg("context") = py::none())
+ nb::arg("num_dims"), nb::arg("num_symbols"), nb::arg("exprs"),
+ nb::arg("eq_flags"), nb::arg("context").none() = nb::none())
.def_static(
"get_empty",
[](intptr_t numDims, intptr_t numSymbols,
@@ -911,20 +904,20 @@ void mlir::python::populateIRAffine(py::module &m) {
mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols);
return PyIntegerSet(context->getRef(), set);
},
- py::arg("num_dims"), py::arg("num_symbols"),
- py::arg("context") = py::none())
+ nb::arg("num_dims"), nb::arg("num_symbols"),
+ nb::arg("context").none() = nb::none())
.def(
"get_replaced",
- [](PyIntegerSet &self, py::list dimExprs, py::list symbolExprs,
+ [](PyIntegerSet &self, nb::list dimExprs, nb::list symbolExprs,
intptr_t numResultDims, intptr_t numResultSymbols) {
if (static_cast(dimExprs.size()) !=
mlirIntegerSetGetNumDims(self))
- throw py::value_error(
+ throw nb::value_error(
"Expected the number of dimension replacement expressions "
"to match that of dimensions");
if (static_cast(symbolExprs.size()) !=
mlirIntegerSetGetNumSymbols(self))
- throw py::value_error(
+ throw nb::value_error(
"Expected the number of symbol replacement expressions "
"to match that of symbols");
@@ -940,30 +933,30 @@ void mlir::python::populateIRAffine(py::module &m) {
numResultDims, numResultSymbols);
return PyIntegerSet(self.getContext(), set);
},
- py::arg("dim_exprs"), py::arg("symbol_exprs"),
- py::arg("num_result_dims"), py::arg("num_result_symbols"))
- .def_property_readonly("is_canonical_empty",
- [](PyIntegerSet &self) {
- return mlirIntegerSetIsCanonicalEmpty(self);
- })
- .def_property_readonly(
+ nb::arg("dim_exprs"), nb::arg("symbol_exprs"),
+ nb::arg("num_result_dims"), nb::arg("num_result_symbols"))
+ .def_prop_ro("is_canonical_empty",
+ [](PyIntegerSet &self) {
+ return mlirIntegerSetIsCanonicalEmpty(self);
+ })
+ .def_prop_ro(
"n_dims",
[](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); })
- .def_property_readonly(
+ .def_prop_ro(
"n_symbols",
[](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); })
- .def_property_readonly(
+ .def_prop_ro(
"n_inputs",
[](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); })
- .def_property_readonly("n_equalities",
- [](PyIntegerSet &self) {
- return mlirIntegerSetGetNumEqualities(self);
- })
- .def_property_readonly("n_inequalities",
- [](PyIntegerSet &self) {
- return mlirIntegerSetGetNumInequalities(self);
- })
- .def_property_readonly("constraints", [](PyIntegerSet &self) {
+ .def_prop_ro("n_equalities",
+ [](PyIntegerSet &self) {
+ return mlirIntegerSetGetNumEqualities(self);
+ })
+ .def_prop_ro("n_inequalities",
+ [](PyIntegerSet &self) {
+ return mlirIntegerSetGetNumInequalities(self);
+ })
+ .def_prop_ro("constraints", [](PyIntegerSet &self) {
return PyIntegerSetConstraintList(self);
});
PyIntegerSetConstraint::bind(m);
diff --git a/mlir/lib/Bindings/Python/IRAttributes.cpp b/mlir/lib/Bindings/Python/IRAttributes.cpp
index cc9532f4e33b2c..f9656eb2315f13 100644
--- a/mlir/lib/Bindings/Python/IRAttributes.cpp
+++ b/mlir/lib/Bindings/Python/IRAttributes.cpp
@@ -6,23 +6,29 @@
//
//===----------------------------------------------------------------------===//
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
#include
+#include
#include
#include
#include "IRModule.h"
-
-#include "PybindUtils.h"
-#include
-
-#include "llvm/ADT/ScopeExit.h"
-#include "llvm/Support/raw_ostream.h"
-
+#include "NanobindUtils.h"
#include "mlir-c/BuiltinAttributes.h"
#include "mlir-c/BuiltinTypes.h"
-#include "mlir/Bindings/Python/PybindAdaptors.h"
+#include "mlir/Bindings/Python/NanobindAdaptors.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/raw_ostream.h"
-namespace py = pybind11;
+namespace nb = nanobind;
+using namespace nanobind::literals;
using namespace mlir;
using namespace mlir::python;
@@ -123,10 +129,119 @@ subsequent processing.
namespace {
+struct nb_buffer_info {
+ void *ptr = nullptr;
+ ssize_t itemsize = 0;
+ ssize_t size = 0;
+ const char *format = nullptr;
+ ssize_t ndim = 0;
+ SmallVector shape;
+ SmallVector strides;
+ bool readonly = false;
+
+ nb_buffer_info(
+ void *ptr, ssize_t itemsize, const char *format, ssize_t ndim,
+ SmallVector shape_in, SmallVector strides_in,
+ bool readonly = false,
+ std::unique_ptr owned_view_in =
+ std::unique_ptr(nullptr, nullptr))
+ : ptr(ptr), itemsize(itemsize), format(format), ndim(ndim),
+ shape(std::move(shape_in)), strides(std::move(strides_in)),
+ readonly(readonly), owned_view(std::move(owned_view_in)) {
+ size = 1;
+ for (ssize_t i = 0; i < ndim; ++i) {
+ size *= shape[i];
+ }
+ }
+
+ explicit nb_buffer_info(Py_buffer *view)
+ : nb_buffer_info(view->buf, view->itemsize, view->format, view->ndim,
+ {view->shape, view->shape + view->ndim},
+ // TODO(phawkins): check for null strides
+ {view->strides, view->strides + view->ndim},
+ view->readonly != 0,
+ std::unique_ptr(
+ view, PyBuffer_Release)) {}
+
+ nb_buffer_info(const nb_buffer_info &) = delete;
+ nb_buffer_info(nb_buffer_info &&) = default;
+ nb_buffer_info &operator=(const nb_buffer_info &) = delete;
+ nb_buffer_info &operator=(nb_buffer_info &&) = default;
+
+private:
+ std::unique_ptr owned_view;
+};
+
+class nb_buffer : public nb::object {
+ NB_OBJECT_DEFAULT(nb_buffer, object, "buffer", PyObject_CheckBuffer);
+
+ nb_buffer_info request() const {
+ int flags = PyBUF_STRIDES | PyBUF_FORMAT;
+ auto *view = new Py_buffer();
+ if (PyObject_GetBuffer(ptr(), view, flags) != 0) {
+ delete view;
+ throw nb::python_error();
+ }
+ return nb_buffer_info(view);
+ }
+};
+
+template
+struct nb_format_descriptor {};
+
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "?"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "b"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "B"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "h"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "H"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "i"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "I"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "q"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "Q"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "f"; }
+};
+template <>
+struct nb_format_descriptor {
+ static const char *format() { return "d"; }
+};
+
static MlirStringRef toMlirStringRef(const std::string &s) {
return mlirStringRefCreate(s.data(), s.size());
}
+static MlirStringRef toMlirStringRef(const nb::bytes &s) {
+ return mlirStringRefCreate(static_cast(s.data()), s.size());
+}
+
class PyAffineMapAttribute : public PyConcreteAttribute {
public:
static constexpr IsAFunctionTy isaFunction = mlirAttributeIsAAffineMap;
@@ -142,9 +257,9 @@ class PyAffineMapAttribute : public PyConcreteAttribute {
MlirAttribute attr = mlirAffineMapAttrGet(affineMap.get());
return PyAffineMapAttribute(affineMap.getContext(), attr);
},
- py::arg("affine_map"), "Gets an attribute wrapping an AffineMap.");
- c.def_property_readonly("value", mlirAffineMapAttrGetValue,
- "Returns the value of the AffineMap attribute");
+ nb::arg("affine_map"), "Gets an attribute wrapping an AffineMap.");
+ c.def_prop_ro("value", mlirAffineMapAttrGetValue,
+ "Returns the value of the AffineMap attribute");
}
};
@@ -164,25 +279,24 @@ class PyIntegerSetAttribute
MlirAttribute attr = mlirIntegerSetAttrGet(integerSet.get());
return PyIntegerSetAttribute(integerSet.getContext(), attr);
},
- py::arg("integer_set"), "Gets an attribute wrapping an IntegerSet.");
+ nb::arg("integer_set"), "Gets an attribute wrapping an IntegerSet.");
}
};
template
-static T pyTryCast(py::handle object) {
+static T pyTryCast(nb::handle object) {
try {
- return object.cast();
- } catch (py::cast_error &err) {
- std::string msg =
- std::string(
- "Invalid attribute when attempting to create an ArrayAttribute (") +
- err.what() + ")";
- throw py::cast_error(msg);
- } catch (py::reference_cast_error &err) {
+ return nb::cast(object);
+ } catch (nb::cast_error &err) {
+ std::string msg = std::string("Invalid attribute when attempting to "
+ "create an ArrayAttribute (") +
+ err.what() + ")";
+ throw std::runtime_error(msg.c_str());
+ } catch (std::runtime_error &err) {
std::string msg = std::string("Invalid attribute (None?) when attempting "
"to create an ArrayAttribute (") +
err.what() + ")";
- throw py::cast_error(msg);
+ throw std::runtime_error(msg.c_str());
}
}
@@ -205,14 +319,13 @@ class PyDenseArrayAttribute : public PyConcreteAttribute {
EltTy dunderNext() {
// Throw if the index has reached the end.
if (nextIndex >= mlirDenseArrayGetNumElements(attr.get()))
- throw py::stop_iteration();
+ throw nb::stop_iteration();
return DerivedT::getElement(attr.get(), nextIndex++);
}
/// Bind the iterator class.
- static void bind(py::module &m) {
- py::class_(m, DerivedT::pyIteratorName,
- py::module_local())
+ static void bind(nb::module_ &m) {
+ nb::class_(m, DerivedT::pyIteratorName)
.def("__iter__", &PyDenseArrayIterator::dunderIter)
.def("__next__", &PyDenseArrayIterator::dunderNext);
}
@@ -230,17 +343,35 @@ class PyDenseArrayAttribute : public PyConcreteAttribute {
/// Bind the attribute class.
static void bindDerived(typename PyConcreteAttribute::ClassTy &c) {
// Bind the constructor.
- c.def_static(
- "get",
- [](const std::vector &values, DefaultingPyMlirContext ctx) {
- return getAttribute(values, ctx->getRef());
- },
- py::arg("values"), py::arg("context") = py::none(),
- "Gets a uniqued dense array attribute");
+ if constexpr (std::is_same_v) {
+ c.def_static(
+ "get",
+ [](const nb::sequence &py_values, DefaultingPyMlirContext ctx) {
+ std::vector values;
+ for (nb::handle py_value : py_values) {
+ int is_true = PyObject_IsTrue(py_value.ptr());
+ if (is_true < 0) {
+ throw nb::python_error();
+ }
+ values.push_back(is_true);
+ }
+ return getAttribute(values, ctx->getRef());
+ },
+ nb::arg("values"), nb::arg("context").none() = nb::none(),
+ "Gets a uniqued dense array attribute");
+ } else {
+ c.def_static(
+ "get",
+ [](const std::vector &values, DefaultingPyMlirContext ctx) {
+ return getAttribute(values, ctx->getRef());
+ },
+ nb::arg("values"), nb::arg("context").none() = nb::none(),
+ "Gets a uniqued dense array attribute");
+ }
// Bind the array methods.
c.def("__getitem__", [](DerivedT &arr, intptr_t i) {
if (i >= mlirDenseArrayGetNumElements(arr))
- throw py::index_error("DenseArray index out of range");
+ throw nb::index_error("DenseArray index out of range");
return arr.getItem(i);
});
c.def("__len__", [](const DerivedT &arr) {
@@ -248,13 +379,13 @@ class PyDenseArrayAttribute : public PyConcreteAttribute {
});
c.def("__iter__",
[](const DerivedT &arr) { return PyDenseArrayIterator(arr); });
- c.def("__add__", [](DerivedT &arr, const py::list &extras) {
+ c.def("__add__", [](DerivedT &arr, const nb::list &extras) {
std::vector values;
intptr_t numOldElements = mlirDenseArrayGetNumElements(arr);
- values.reserve(numOldElements + py::len(extras));
+ values.reserve(numOldElements + nb::len(extras));
for (intptr_t i = 0; i < numOldElements; ++i)
values.push_back(arr.getItem(i));
- for (py::handle attr : extras)
+ for (nb::handle attr : extras)
values.push_back(pyTryCast(attr));
return getAttribute(values, arr.getContext());
});
@@ -358,13 +489,12 @@ class PyArrayAttribute : public PyConcreteAttribute {
MlirAttribute dunderNext() {
// TODO: Throw is an inefficient way to stop iteration.
if (nextIndex >= mlirArrayAttrGetNumElements(attr.get()))
- throw py::stop_iteration();
+ throw nb::stop_iteration();
return mlirArrayAttrGetElement(attr.get(), nextIndex++);
}
- static void bind(py::module &m) {
- py::class_(m, "ArrayAttributeIterator",
- py::module_local())
+ static void bind(nb::module_ &m) {
+ nb::class_(m, "ArrayAttributeIterator")
.def("__iter__", &PyArrayAttributeIterator::dunderIter)
.def("__next__", &PyArrayAttributeIterator::dunderNext);
}
@@ -381,9 +511,9 @@ class PyArrayAttribute : public PyConcreteAttribute {
static void bindDerived(ClassTy &c) {
c.def_static(
"get",
- [](py::list attributes, DefaultingPyMlirContext context) {
+ [](nb::list attributes, DefaultingPyMlirContext context) {
SmallVector mlirAttributes;
- mlirAttributes.reserve(py::len(attributes));
+ mlirAttributes.reserve(nb::len(attributes));
for (auto attribute : attributes) {
mlirAttributes.push_back(pyTryCast(attribute));
}
@@ -391,12 +521,12 @@ class PyArrayAttribute : public PyConcreteAttribute {
context->get(), mlirAttributes.size(), mlirAttributes.data());
return PyArrayAttribute(context->getRef(), attr);
},
- py::arg("attributes"), py::arg("context") = py::none(),
+ nb::arg("attributes"), nb::arg("context").none() = nb::none(),
"Gets a uniqued Array attribute");
c.def("__getitem__",
[](PyArrayAttribute &arr, intptr_t i) {
if (i >= mlirArrayAttrGetNumElements(arr))
- throw py::index_error("ArrayAttribute index out of range");
+ throw nb::index_error("ArrayAttribute index out of range");
return arr.getItem(i);
})
.def("__len__",
@@ -406,13 +536,13 @@ class PyArrayAttribute : public PyConcreteAttribute {
.def("__iter__", [](const PyArrayAttribute &arr) {
return PyArrayAttributeIterator(arr);
});
- c.def("__add__", [](PyArrayAttribute arr, py::list extras) {
+ c.def("__add__", [](PyArrayAttribute arr, nb::list extras) {
std::vector attributes;
intptr_t numOldElements = mlirArrayAttrGetNumElements(arr);
- attributes.reserve(numOldElements + py::len(extras));
+ attributes.reserve(numOldElements + nb::len(extras));
for (intptr_t i = 0; i < numOldElements; ++i)
attributes.push_back(arr.getItem(i));
- for (py::handle attr : extras)
+ for (nb::handle attr : extras)
attributes.push_back(pyTryCast(attr));
MlirAttribute arrayAttr = mlirArrayAttrGet(
arr.getContext()->get(), attributes.size(), attributes.data());
@@ -440,7 +570,7 @@ class PyFloatAttribute : public PyConcreteAttribute {
throw MLIRError("Invalid attribute", errors.take());
return PyFloatAttribute(type.getContext(), attr);
},
- py::arg("type"), py::arg("value"), py::arg("loc") = py::none(),
+ nb::arg("type"), nb::arg("value"), nb::arg("loc").none() = nb::none(),
"Gets an uniqued float point attribute associated to a type");
c.def_static(
"get_f32",
@@ -449,7 +579,7 @@ class PyFloatAttribute : public PyConcreteAttribute {
context->get(), mlirF32TypeGet(context->get()), value);
return PyFloatAttribute(context->getRef(), attr);
},
- py::arg("value"), py::arg("context") = py::none(),
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
"Gets an uniqued float point attribute associated to a f32 type");
c.def_static(
"get_f64",
@@ -458,10 +588,10 @@ class PyFloatAttribute : public PyConcreteAttribute {
context->get(), mlirF64TypeGet(context->get()), value);
return PyFloatAttribute(context->getRef(), attr);
},
- py::arg("value"), py::arg("context") = py::none(),
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
"Gets an uniqued float point attribute associated to a f64 type");
- c.def_property_readonly("value", mlirFloatAttrGetValueDouble,
- "Returns the value of the float attribute");
+ c.def_prop_ro("value", mlirFloatAttrGetValueDouble,
+ "Returns the value of the float attribute");
c.def("__float__", mlirFloatAttrGetValueDouble,
"Converts the value of the float attribute to a Python float");
}
@@ -481,20 +611,20 @@ class PyIntegerAttribute : public PyConcreteAttribute {
MlirAttribute attr = mlirIntegerAttrGet(type, value);
return PyIntegerAttribute(type.getContext(), attr);
},
- py::arg("type"), py::arg("value"),
+ nb::arg("type"), nb::arg("value"),
"Gets an uniqued integer attribute associated to a type");
- c.def_property_readonly("value", toPyInt,
- "Returns the value of the integer attribute");
+ c.def_prop_ro("value", toPyInt,
+ "Returns the value of the integer attribute");
c.def("__int__", toPyInt,
"Converts the value of the integer attribute to a Python int");
- c.def_property_readonly_static("static_typeid",
- [](py::object & /*class*/) -> MlirTypeID {
- return mlirIntegerAttrGetTypeID();
- });
+ c.def_prop_ro_static("static_typeid",
+ [](nb::object & /*class*/) -> MlirTypeID {
+ return mlirIntegerAttrGetTypeID();
+ });
}
private:
- static py::int_ toPyInt(PyIntegerAttribute &self) {
+ static int64_t toPyInt(PyIntegerAttribute &self) {
MlirType type = mlirAttributeGetType(self);
if (mlirTypeIsAIndex(type) || mlirIntegerTypeIsSignless(type))
return mlirIntegerAttrGetValueInt(self);
@@ -518,10 +648,10 @@ class PyBoolAttribute : public PyConcreteAttribute {
MlirAttribute attr = mlirBoolAttrGet(context->get(), value);
return PyBoolAttribute(context->getRef(), attr);
},
- py::arg("value"), py::arg("context") = py::none(),
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
"Gets an uniqued bool attribute");
- c.def_property_readonly("value", mlirBoolAttrGetValue,
- "Returns the value of the bool attribute");
+ c.def_prop_ro("value", mlirBoolAttrGetValue,
+ "Returns the value of the bool attribute");
c.def("__bool__", mlirBoolAttrGetValue,
"Converts the value of the bool attribute to a Python bool");
}
@@ -555,9 +685,9 @@ class PySymbolRefAttribute : public PyConcreteAttribute {
DefaultingPyMlirContext context) {
return PySymbolRefAttribute::fromList(symbols, context.resolve());
},
- py::arg("symbols"), py::arg("context") = py::none(),
+ nb::arg("symbols"), nb::arg("context").none() = nb::none(),
"Gets a uniqued SymbolRef attribute from a list of symbol names");
- c.def_property_readonly(
+ c.def_prop_ro(
"value",
[](PySymbolRefAttribute &self) {
std::vector symbols = {
@@ -589,13 +719,13 @@ class PyFlatSymbolRefAttribute
mlirFlatSymbolRefAttrGet(context->get(), toMlirStringRef(value));
return PyFlatSymbolRefAttribute(context->getRef(), attr);
},
- py::arg("value"), py::arg("context") = py::none(),
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
"Gets a uniqued FlatSymbolRef attribute");
- c.def_property_readonly(
+ c.def_prop_ro(
"value",
[](PyFlatSymbolRefAttribute &self) {
MlirStringRef stringRef = mlirFlatSymbolRefAttrGetValue(self);
- return py::str(stringRef.data, stringRef.length);
+ return nb::str(stringRef.data, stringRef.length);
},
"Returns the value of the FlatSymbolRef attribute as a string");
}
@@ -612,29 +742,29 @@ class PyOpaqueAttribute : public PyConcreteAttribute {
static void bindDerived(ClassTy &c) {
c.def_static(
"get",
- [](std::string dialectNamespace, py::buffer buffer, PyType &type,
+ [](std::string dialectNamespace, nb_buffer buffer, PyType &type,
DefaultingPyMlirContext context) {
- const py::buffer_info bufferInfo = buffer.request();
+ const nb_buffer_info bufferInfo = buffer.request();
intptr_t bufferSize = bufferInfo.size;
MlirAttribute attr = mlirOpaqueAttrGet(
context->get(), toMlirStringRef(dialectNamespace), bufferSize,
static_cast(bufferInfo.ptr), type);
return PyOpaqueAttribute(context->getRef(), attr);
},
- py::arg("dialect_namespace"), py::arg("buffer"), py::arg("type"),
- py::arg("context") = py::none(), "Gets an Opaque attribute.");
- c.def_property_readonly(
+ nb::arg("dialect_namespace"), nb::arg("buffer"), nb::arg("type"),
+ nb::arg("context").none() = nb::none(), "Gets an Opaque attribute.");
+ c.def_prop_ro(
"dialect_namespace",
[](PyOpaqueAttribute &self) {
MlirStringRef stringRef = mlirOpaqueAttrGetDialectNamespace(self);
- return py::str(stringRef.data, stringRef.length);
+ return nb::str(stringRef.data, stringRef.length);
},
"Returns the dialect namespace for the Opaque attribute as a string");
- c.def_property_readonly(
+ c.def_prop_ro(
"data",
[](PyOpaqueAttribute &self) {
MlirStringRef stringRef = mlirOpaqueAttrGetData(self);
- return py::bytes(stringRef.data, stringRef.length);
+ return nb::bytes(stringRef.data, stringRef.length);
},
"Returns the data for the Opaqued attributes as `bytes`");
}
@@ -656,7 +786,16 @@ class PyStringAttribute : public PyConcreteAttribute {
mlirStringAttrGet(context->get(), toMlirStringRef(value));
return PyStringAttribute(context->getRef(), attr);
},
- py::arg("value"), py::arg("context") = py::none(),
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
+ "Gets a uniqued string attribute");
+ c.def_static(
+ "get",
+ [](nb::bytes value, DefaultingPyMlirContext context) {
+ MlirAttribute attr =
+ mlirStringAttrGet(context->get(), toMlirStringRef(value));
+ return PyStringAttribute(context->getRef(), attr);
+ },
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
"Gets a uniqued string attribute");
c.def_static(
"get_typed",
@@ -665,20 +804,20 @@ class PyStringAttribute : public PyConcreteAttribute {
mlirStringAttrTypedGet(type, toMlirStringRef(value));
return PyStringAttribute(type.getContext(), attr);
},
- py::arg("type"), py::arg("value"),
+ nb::arg("type"), nb::arg("value"),
"Gets a uniqued string attribute associated to a type");
- c.def_property_readonly(
+ c.def_prop_ro(
"value",
[](PyStringAttribute &self) {
MlirStringRef stringRef = mlirStringAttrGetValue(self);
- return py::str(stringRef.data, stringRef.length);
+ return nb::str(stringRef.data, stringRef.length);
},
"Returns the value of the string attribute");
- c.def_property_readonly(
+ c.def_prop_ro(
"value_bytes",
[](PyStringAttribute &self) {
MlirStringRef stringRef = mlirStringAttrGetValue(self);
- return py::bytes(stringRef.data, stringRef.length);
+ return nb::bytes(stringRef.data, stringRef.length);
},
"Returns the value of the string attribute as `bytes`");
}
@@ -693,12 +832,11 @@ class PyDenseElementsAttribute
using PyConcreteAttribute::PyConcreteAttribute;
static PyDenseElementsAttribute
- getFromList(py::list attributes, std::optional explicitType,
+ getFromList(nb::list attributes, std::optional explicitType,
DefaultingPyMlirContext contextWrapper) {
-
- const size_t numAttributes = py::len(attributes);
+ const size_t numAttributes = nb::len(attributes);
if (numAttributes == 0)
- throw py::value_error("Attributes list must be non-empty.");
+ throw nb::value_error("Attributes list must be non-empty.");
MlirType shapedType;
if (explicitType) {
@@ -708,8 +846,8 @@ class PyDenseElementsAttribute
std::string message;
llvm::raw_string_ostream os(message);
os << "Expected a static ShapedType for the shaped_type parameter: "
- << py::repr(py::cast(*explicitType));
- throw py::value_error(message);
+ << nb::cast(nb::repr(nb::cast(*explicitType)));
+ throw nb::value_error(message.c_str());
}
shapedType = *explicitType;
} else {
@@ -722,7 +860,7 @@ class PyDenseElementsAttribute
SmallVector mlirAttributes;
mlirAttributes.reserve(numAttributes);
- for (const py::handle &attribute : attributes) {
+ for (const nb::handle &attribute : attributes) {
MlirAttribute mlirAttribute = pyTryCast(attribute);
MlirType attrType = mlirAttributeGetType(mlirAttribute);
mlirAttributes.push_back(mlirAttribute);
@@ -731,9 +869,11 @@ class PyDenseElementsAttribute
std::string message;
llvm::raw_string_ostream os(message);
os << "All attributes must be of the same type and match "
- << "the type parameter: expected=" << py::repr(py::cast(shapedType))
- << ", but got=" << py::repr(py::cast(attrType));
- throw py::value_error(message);
+ << "the type parameter: expected="
+ << nb::cast(nb::repr(nb::cast(shapedType)))
+ << ", but got="
+ << nb::cast(nb::repr(nb::cast(attrType)));
+ throw nb::value_error(message.c_str());
}
}
@@ -744,7 +884,7 @@ class PyDenseElementsAttribute
}
static PyDenseElementsAttribute
- getFromBuffer(py::buffer array, bool signless,
+ getFromBuffer(nb_buffer array, bool signless,
std::optional explicitType,
std::optional> explicitShape,
DefaultingPyMlirContext contextWrapper) {
@@ -755,7 +895,7 @@ class PyDenseElementsAttribute
}
Py_buffer view;
if (PyObject_GetBuffer(array.ptr(), &view, flags) != 0) {
- throw py::error_already_set();
+ throw nb::python_error();
}
auto freeBuffer = llvm::make_scope_exit([&]() { PyBuffer_Release(&view); });
@@ -778,25 +918,25 @@ class PyDenseElementsAttribute
if (!mlirAttributeIsAInteger(elementAttr) &&
!mlirAttributeIsAFloat(elementAttr)) {
std::string message = "Illegal element type for DenseElementsAttr: ";
- message.append(py::repr(py::cast(elementAttr)));
- throw py::value_error(message);
+ message.append(nb::cast(nb::repr(nb::cast(elementAttr))));
+ throw nb::value_error(message.c_str());
}
if (!mlirTypeIsAShaped(shapedType) ||
!mlirShapedTypeHasStaticShape(shapedType)) {
std::string message =
"Expected a static ShapedType for the shaped_type parameter: ";
- message.append(py::repr(py::cast(shapedType)));
- throw py::value_error(message);
+ message.append(nb::cast(nb::repr(nb::cast(shapedType))));
+ throw nb::value_error(message.c_str());
}
MlirType shapedElementType = mlirShapedTypeGetElementType(shapedType);
MlirType attrType = mlirAttributeGetType(elementAttr);
if (!mlirTypeEqual(shapedElementType, attrType)) {
std::string message =
"Shaped element type and attribute type must be equal: shaped=";
- message.append(py::repr(py::cast(shapedType)));
+ message.append(nb::cast(nb::repr(nb::cast(shapedType))));
message.append(", element=");
- message.append(py::repr(py::cast(elementAttr)));
- throw py::value_error(message);
+ message.append(nb::cast(nb::repr(nb::cast(elementAttr))));
+ throw nb::value_error(message.c_str());
}
MlirAttribute elements =
@@ -806,7 +946,7 @@ class PyDenseElementsAttribute
intptr_t dunderLen() { return mlirElementsAttrGetNumElements(*this); }
- py::buffer_info accessBuffer() {
+ std::unique_ptr accessBuffer() {
MlirType shapedType = mlirAttributeGetType(*this);
MlirType elementType = mlirShapedTypeGetElementType(shapedType);
std::string format;
@@ -889,32 +1029,36 @@ class PyDenseElementsAttribute
static void bindDerived(ClassTy &c) {
c.def("__len__", &PyDenseElementsAttribute::dunderLen)
.def_static("get", PyDenseElementsAttribute::getFromBuffer,
- py::arg("array"), py::arg("signless") = true,
- py::arg("type") = py::none(), py::arg("shape") = py::none(),
- py::arg("context") = py::none(),
+ nb::arg("array"), nb::arg("signless") = true,
+ nb::arg("type").none() = nb::none(),
+ nb::arg("shape").none() = nb::none(),
+ nb::arg("context").none() = nb::none(),
kDenseElementsAttrGetDocstring)
.def_static("get", PyDenseElementsAttribute::getFromList,
- py::arg("attrs"), py::arg("type") = py::none(),
- py::arg("context") = py::none(),
+ nb::arg("attrs"), nb::arg("type").none() = nb::none(),
+ nb::arg("context").none() = nb::none(),
kDenseElementsAttrGetFromListDocstring)
.def_static("get_splat", PyDenseElementsAttribute::getSplat,
- py::arg("shaped_type"), py::arg("element_attr"),
+ nb::arg("shaped_type"), nb::arg("element_attr"),
"Gets a DenseElementsAttr where all values are the same")
- .def_property_readonly("is_splat",
- [](PyDenseElementsAttribute &self) -> bool {
- return mlirDenseElementsAttrIsSplat(self);
- })
- .def("get_splat_value",
- [](PyDenseElementsAttribute &self) {
- if (!mlirDenseElementsAttrIsSplat(self))
- throw py::value_error(
- "get_splat_value called on a non-splat attribute");
- return mlirDenseElementsAttrGetSplatValue(self);
- })
- .def_buffer(&PyDenseElementsAttribute::accessBuffer);
+ .def_prop_ro("is_splat",
+ [](PyDenseElementsAttribute &self) -> bool {
+ return mlirDenseElementsAttrIsSplat(self);
+ })
+ .def("get_splat_value", [](PyDenseElementsAttribute &self) {
+ if (!mlirDenseElementsAttrIsSplat(self))
+ throw nb::value_error(
+ "get_splat_value called on a non-splat attribute");
+ return mlirDenseElementsAttrGetSplatValue(self);
+ });
}
+ static PyType_Slot slots[];
+
private:
+ static int bf_getbuffer(PyObject *exporter, Py_buffer *view, int flags);
+ static void bf_releasebuffer(PyObject *, Py_buffer *buffer);
+
static bool isUnsignedIntegerFormat(std::string_view format) {
if (format.empty())
return false;
@@ -1039,27 +1183,27 @@ class PyDenseElementsAttribute
return mlirDenseElementsAttrRawBufferGet(type, view.len, view.buf);
}
- // There is a complication for boolean numpy arrays, as numpy represents them
- // as 8 bits (1 byte) per boolean, whereas MLIR bitpacks them into 8 booleans
- // per byte.
+ // There is a complication for boolean numpy arrays, as numpy represents
+ // them as 8 bits (1 byte) per boolean, whereas MLIR bitpacks them into 8
+ // booleans per byte.
static MlirAttribute getBitpackedAttributeFromBooleanBuffer(
Py_buffer &view, std::optional> explicitShape,
MlirContext &context) {
if (llvm::endianness::native != llvm::endianness::little) {
- // Given we have no good way of testing the behavior on big-endian systems
- // we will throw
- throw py::type_error("Constructing a bit-packed MLIR attribute is "
+ // Given we have no good way of testing the behavior on big-endian
+ // systems we will throw
+ throw nb::type_error("Constructing a bit-packed MLIR attribute is "
"unsupported on big-endian systems");
}
+ nb::ndarray, nb::c_contig> unpackedArray(
+ /*data=*/static_cast(view.buf),
+ /*shape=*/{static_cast(view.len)});
- py::array_t unpackedArray(view.len,
- static_cast(view.buf));
-
- py::module numpy = py::module::import("numpy");
- py::object packbitsFunc = numpy.attr("packbits");
- py::object packedBooleans =
- packbitsFunc(unpackedArray, "bitorder"_a = "little");
- py::buffer_info pythonBuffer = packedBooleans.cast().request();
+ nb::module_ numpy = nb::module_::import_("numpy");
+ nb::object packbitsFunc = numpy.attr("packbits");
+ nb::object packedBooleans =
+ packbitsFunc(nb::cast(unpackedArray), "bitorder"_a = "little");
+ nb_buffer_info pythonBuffer = nb::cast(packedBooleans).request();
MlirType bitpackedType =
getShapedType(mlirIntegerTypeGet(context, 1), explicitShape, view);
@@ -1073,11 +1217,11 @@ class PyDenseElementsAttribute
// This does the opposite transformation of
// `getBitpackedAttributeFromBooleanBuffer`
- py::buffer_info getBooleanBufferFromBitpackedAttribute() {
+ std::unique_ptr getBooleanBufferFromBitpackedAttribute() {
if (llvm::endianness::native != llvm::endianness::little) {
- // Given we have no good way of testing the behavior on big-endian systems
- // we will throw
- throw py::type_error("Constructing a numpy array from a MLIR attribute "
+ // Given we have no good way of testing the behavior on big-endian
+ // systems we will throw
+ throw nb::type_error("Constructing a numpy array from a MLIR attribute "
"is unsupported on big-endian systems");
}
@@ -1085,21 +1229,24 @@ class PyDenseElementsAttribute
int64_t numBitpackedBytes = llvm::divideCeil(numBooleans, 8);
uint8_t *bitpackedData = static_cast(
const_cast(mlirDenseElementsAttrGetRawData(*this)));
- py::array_t packedArray(numBitpackedBytes, bitpackedData);
+ nb::ndarray, nb::c_contig> packedArray(
+ /*data=*/bitpackedData,
+ /*shape=*/{static_cast(numBitpackedBytes)});
- py::module numpy = py::module::import("numpy");
- py::object unpackbitsFunc = numpy.attr("unpackbits");
- py::object equalFunc = numpy.attr("equal");
- py::object reshapeFunc = numpy.attr("reshape");
- py::array unpackedBooleans =
- unpackbitsFunc(packedArray, "bitorder"_a = "little");
+ nb::module_ numpy = nb::module_::import_("numpy");
+ nb::object unpackbitsFunc = numpy.attr("unpackbits");
+ nb::object equalFunc = numpy.attr("equal");
+ nb::object reshapeFunc = numpy.attr("reshape");
+ nb::object unpackedBooleans =
+ unpackbitsFunc(nb::cast(packedArray), "bitorder"_a = "little");
// Unpackbits operates on bytes and gives back a flat 0 / 1 integer array.
// We need to:
// 1. Slice away the padded bits
// 2. Make the boolean array have the correct shape
// 3. Convert the array to a boolean array
- unpackedBooleans = unpackedBooleans[py::slice(0, numBooleans, 1)];
+ unpackedBooleans = unpackedBooleans[nb::slice(
+ nb::int_(0), nb::int_(numBooleans), nb::int_(1))];
unpackedBooleans = equalFunc(unpackedBooleans, 1);
MlirType shapedType = mlirAttributeGetType(*this);
@@ -1110,15 +1257,15 @@ class PyDenseElementsAttribute
}
unpackedBooleans = reshapeFunc(unpackedBooleans, shape);
- // Make sure the returned py::buffer_view claims ownership of the data in
+ // Make sure the returned nb::buffer_view claims ownership of the data in
// `pythonBuffer` so it remains valid when Python reads it
- py::buffer pythonBuffer = unpackedBooleans.cast();
- return pythonBuffer.request();
+ nb_buffer pythonBuffer = nb::cast(unpackedBooleans);
+ return std::make_unique(pythonBuffer.request());
}
template
- py::buffer_info bufferInfo(MlirType shapedType,
- const char *explicitFormat = nullptr) {
+ std::unique_ptr
+ bufferInfo(MlirType shapedType, const char *explicitFormat = nullptr) {
intptr_t rank = mlirShapedTypeGetRank(shapedType);
// Prepare the data for the buffer_info.
// Buffer is configured for read-only access below.
@@ -1142,19 +1289,69 @@ class PyDenseElementsAttribute
}
strides.push_back(sizeof(Type));
}
- std::string format;
+ const char *format;
if (explicitFormat) {
format = explicitFormat;
} else {
- format = py::format_descriptor::format();
+ format = nb_format_descriptor::format();
}
- return py::buffer_info(data, sizeof(Type), format, rank, shape, strides,
- /*readonly=*/true);
+ return std::make_unique(
+ data, sizeof(Type), format, rank, std::move(shape), std::move(strides),
+ /*readonly=*/true);
}
}; // namespace
-/// Refinement of the PyDenseElementsAttribute for attributes containing integer
-/// (and boolean) values. Supports element access.
+PyType_Slot PyDenseElementsAttribute::slots[] = {
+ {Py_bf_getbuffer,
+ reinterpret_cast(PyDenseElementsAttribute::bf_getbuffer)},
+ {Py_bf_releasebuffer,
+ reinterpret_cast(PyDenseElementsAttribute::bf_releasebuffer)},
+ {0, nullptr},
+};
+
+/*static*/ int PyDenseElementsAttribute::bf_getbuffer(PyObject *obj,
+ Py_buffer *view,
+ int flags) {
+ view->obj = nullptr;
+ std::unique_ptr info;
+ try {
+ auto *attr = nb::cast(nb::handle(obj));
+ info = attr->accessBuffer();
+ } catch (nb::python_error &e) {
+ e.restore();
+ nb::chain_error(PyExc_BufferError, "Error converting attribute to buffer");
+ return -1;
+ }
+ view->obj = obj;
+ view->ndim = 1;
+ view->buf = info->ptr;
+ view->itemsize = info->itemsize;
+ view->len = info->itemsize;
+ for (auto s : info->shape) {
+ view->len *= s;
+ }
+ view->readonly = info->readonly;
+ if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
+ view->format = const_cast(info->format);
+ }
+ if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
+ view->ndim = static_cast(info->ndim);
+ view->strides = info->strides.data();
+ view->shape = info->shape.data();
+ }
+ view->suboffsets = nullptr;
+ view->internal = info.release();
+ Py_INCREF(obj);
+ return 0;
+}
+
+/*static*/ void PyDenseElementsAttribute::bf_releasebuffer(PyObject *,
+ Py_buffer *view) {
+ delete reinterpret_cast(view->internal);
+}
+
+/// Refinement of the PyDenseElementsAttribute for attributes containing
+/// integer (and boolean) values. Supports element access.
class PyDenseIntElementsAttribute
: public PyConcreteAttribute {
@@ -1163,11 +1360,11 @@ class PyDenseIntElementsAttribute
static constexpr const char *pyClassName = "DenseIntElementsAttr";
using PyConcreteAttribute::PyConcreteAttribute;
- /// Returns the element at the given linear position. Asserts if the index is
- /// out of range.
- py::int_ dunderGetItem(intptr_t pos) {
+ /// Returns the element at the given linear position. Asserts if the index
+ /// is out of range.
+ nb::object dunderGetItem(intptr_t pos) {
if (pos < 0 || pos >= dunderLen()) {
- throw py::index_error("attempt to access out of bounds element");
+ throw nb::index_error("attempt to access out of bounds element");
}
MlirType type = mlirAttributeGetType(*this);
@@ -1175,7 +1372,7 @@ class PyDenseIntElementsAttribute
assert(mlirTypeIsAInteger(type) &&
"expected integer element type in dense int elements attribute");
// Dispatch element extraction to an appropriate C function based on the
- // elemental type of the attribute. py::int_ is implicitly constructible
+ // elemental type of the attribute. nb::int_ is implicitly constructible
// from any C++ integral type and handles bitwidth correctly.
// TODO: consider caching the type properties in the constructor to avoid
// querying them on each element access.
@@ -1183,38 +1380,38 @@ class PyDenseIntElementsAttribute
bool isUnsigned = mlirIntegerTypeIsUnsigned(type);
if (isUnsigned) {
if (width == 1) {
- return mlirDenseElementsAttrGetBoolValue(*this, pos);
+ return nb::int_(int(mlirDenseElementsAttrGetBoolValue(*this, pos)));
}
if (width == 8) {
- return mlirDenseElementsAttrGetUInt8Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetUInt8Value(*this, pos));
}
if (width == 16) {
- return mlirDenseElementsAttrGetUInt16Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetUInt16Value(*this, pos));
}
if (width == 32) {
- return mlirDenseElementsAttrGetUInt32Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetUInt32Value(*this, pos));
}
if (width == 64) {
- return mlirDenseElementsAttrGetUInt64Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetUInt64Value(*this, pos));
}
} else {
if (width == 1) {
- return mlirDenseElementsAttrGetBoolValue(*this, pos);
+ return nb::int_(int(mlirDenseElementsAttrGetBoolValue(*this, pos)));
}
if (width == 8) {
- return mlirDenseElementsAttrGetInt8Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetInt8Value(*this, pos));
}
if (width == 16) {
- return mlirDenseElementsAttrGetInt16Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetInt16Value(*this, pos));
}
if (width == 32) {
- return mlirDenseElementsAttrGetInt32Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetInt32Value(*this, pos));
}
if (width == 64) {
- return mlirDenseElementsAttrGetInt64Value(*this, pos);
+ return nb::int_(mlirDenseElementsAttrGetInt64Value(*this, pos));
}
}
- throw py::type_error("Unsupported integer type");
+ throw nb::type_error("Unsupported integer type");
}
static void bindDerived(ClassTy &c) {
@@ -1231,7 +1428,7 @@ class PyDenseResourceElementsAttribute
using PyConcreteAttribute::PyConcreteAttribute;
static PyDenseResourceElementsAttribute
- getFromBuffer(py::buffer buffer, const std::string &name, const PyType &type,
+ getFromBuffer(nb_buffer buffer, const std::string &name, const PyType &type,
std::optional alignment, bool isMutable,
DefaultingPyMlirContext contextWrapper) {
if (!mlirTypeIsAShaped(type)) {
@@ -1244,7 +1441,7 @@ class PyDenseResourceElementsAttribute
int flags = PyBUF_STRIDES;
std::unique_ptr view = std::make_unique();
if (PyObject_GetBuffer(buffer.ptr(), view.get(), flags) != 0) {
- throw py::error_already_set();
+ throw nb::python_error();
}
// This scope releaser will only release if we haven't yet transferred
@@ -1289,12 +1486,12 @@ class PyDenseResourceElementsAttribute
}
static void bindDerived(ClassTy &c) {
- c.def_static("get_from_buffer",
- PyDenseResourceElementsAttribute::getFromBuffer,
- py::arg("array"), py::arg("name"), py::arg("type"),
- py::arg("alignment") = py::none(),
- py::arg("is_mutable") = false, py::arg("context") = py::none(),
- kDenseResourceElementsAttrGetFromBufferDocstring);
+ c.def_static(
+ "get_from_buffer", PyDenseResourceElementsAttribute::getFromBuffer,
+ nb::arg("array"), nb::arg("name"), nb::arg("type"),
+ nb::arg("alignment").none() = nb::none(), nb::arg("is_mutable") = false,
+ nb::arg("context").none() = nb::none(),
+ kDenseResourceElementsAttrGetFromBufferDocstring);
}
};
@@ -1318,12 +1515,12 @@ class PyDictAttribute : public PyConcreteAttribute {
c.def("__len__", &PyDictAttribute::dunderLen);
c.def_static(
"get",
- [](py::dict attributes, DefaultingPyMlirContext context) {
+ [](nb::dict attributes, DefaultingPyMlirContext context) {
SmallVector mlirNamedAttributes;
mlirNamedAttributes.reserve(attributes.size());
- for (auto &it : attributes) {
- auto &mlirAttr = it.second.cast();
- auto name = it.first.cast();
+ for (std::pair it : attributes) {
+ auto &mlirAttr = nb::cast(it.second);
+ auto name = nb::cast(it.first);
mlirNamedAttributes.push_back(mlirNamedAttributeGet(
mlirIdentifierGet(mlirAttributeGetContext(mlirAttr),
toMlirStringRef(name)),
@@ -1334,18 +1531,18 @@ class PyDictAttribute : public PyConcreteAttribute {
mlirNamedAttributes.data());
return PyDictAttribute(context->getRef(), attr);
},
- py::arg("value") = py::dict(), py::arg("context") = py::none(),
+ nb::arg("value") = nb::dict(), nb::arg("context").none() = nb::none(),
"Gets an uniqued dict attribute");
c.def("__getitem__", [](PyDictAttribute &self, const std::string &name) {
MlirAttribute attr =
mlirDictionaryAttrGetElementByName(self, toMlirStringRef(name));
if (mlirAttributeIsNull(attr))
- throw py::key_error("attempt to access a non-existent attribute");
+ throw nb::key_error("attempt to access a non-existent attribute");
return attr;
});
c.def("__getitem__", [](PyDictAttribute &self, intptr_t index) {
if (index < 0 || index >= self.dunderLen()) {
- throw py::index_error("attempt to access out of bounds attribute");
+ throw nb::index_error("attempt to access out of bounds attribute");
}
MlirNamedAttribute namedAttr = mlirDictionaryAttrGetElement(self, index);
return PyNamedAttribute(
@@ -1365,25 +1562,25 @@ class PyDenseFPElementsAttribute
static constexpr const char *pyClassName = "DenseFPElementsAttr";
using PyConcreteAttribute::PyConcreteAttribute;
- py::float_ dunderGetItem(intptr_t pos) {
+ nb::float_ dunderGetItem(intptr_t pos) {
if (pos < 0 || pos >= dunderLen()) {
- throw py::index_error("attempt to access out of bounds element");
+ throw nb::index_error("attempt to access out of bounds element");
}
MlirType type = mlirAttributeGetType(*this);
type = mlirShapedTypeGetElementType(type);
// Dispatch element extraction to an appropriate C function based on the
- // elemental type of the attribute. py::float_ is implicitly constructible
+ // elemental type of the attribute. nb::float_ is implicitly constructible
// from float and double.
// TODO: consider caching the type properties in the constructor to avoid
// querying them on each element access.
if (mlirTypeIsAF32(type)) {
- return mlirDenseElementsAttrGetFloatValue(*this, pos);
+ return nb::float_(mlirDenseElementsAttrGetFloatValue(*this, pos));
}
if (mlirTypeIsAF64(type)) {
- return mlirDenseElementsAttrGetDoubleValue(*this, pos);
+ return nb::float_(mlirDenseElementsAttrGetDoubleValue(*this, pos));
}
- throw py::type_error("Unsupported floating-point type");
+ throw nb::type_error("Unsupported floating-point type");
}
static void bindDerived(ClassTy &c) {
@@ -1406,9 +1603,9 @@ class PyTypeAttribute : public PyConcreteAttribute {
MlirAttribute attr = mlirTypeAttrGet(value.get());
return PyTypeAttribute(context->getRef(), attr);
},
- py::arg("value"), py::arg("context") = py::none(),
+ nb::arg("value"), nb::arg("context").none() = nb::none(),
"Gets a uniqued Type attribute");
- c.def_property_readonly("value", [](PyTypeAttribute &self) {
+ c.def_prop_ro("value", [](PyTypeAttribute &self) {
return mlirTypeAttrGetValue(self.get());
});
}
@@ -1430,7 +1627,7 @@ class PyUnitAttribute : public PyConcreteAttribute {
return PyUnitAttribute(context->getRef(),
mlirUnitAttrGet(context->get()));
},
- py::arg("context") = py::none(), "Create a Unit attribute.");
+ nb::arg("context").none() = nb::none(), "Create a Unit attribute.");
}
};
@@ -1453,7 +1650,8 @@ class PyStridedLayoutAttribute
ctx->get(), offset, strides.size(), strides.data());
return PyStridedLayoutAttribute(ctx->getRef(), attr);
},
- py::arg("offset"), py::arg("strides"), py::arg("context") = py::none(),
+ nb::arg("offset"), nb::arg("strides"),
+ nb::arg("context").none() = nb::none(),
"Gets a strided layout attribute.");
c.def_static(
"get_fully_dynamic",
@@ -1465,16 +1663,17 @@ class PyStridedLayoutAttribute
ctx->get(), dynamic, strides.size(), strides.data());
return PyStridedLayoutAttribute(ctx->getRef(), attr);
},
- py::arg("rank"), py::arg("context") = py::none(),
- "Gets a strided layout attribute with dynamic offset and strides of a "
+ nb::arg("rank"), nb::arg("context").none() = nb::none(),
+ "Gets a strided layout attribute with dynamic offset and strides of "
+ "a "
"given rank.");
- c.def_property_readonly(
+ c.def_prop_ro(
"offset",
[](PyStridedLayoutAttribute &self) {
return mlirStridedLayoutAttrGetOffset(self);
},
"Returns the value of the float point attribute");
- c.def_property_readonly(
+ c.def_prop_ro(
"strides",
[](PyStridedLayoutAttribute &self) {
intptr_t size = mlirStridedLayoutAttrGetNumStrides(self);
@@ -1488,63 +1687,64 @@ class PyStridedLayoutAttribute
}
};
-py::object denseArrayAttributeCaster(PyAttribute &pyAttribute) {
+nb::object denseArrayAttributeCaster(PyAttribute &pyAttribute) {
if (PyDenseBoolArrayAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseBoolArrayAttribute(pyAttribute));
+ return nb::cast(PyDenseBoolArrayAttribute(pyAttribute));
if (PyDenseI8ArrayAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseI8ArrayAttribute(pyAttribute));
+ return nb::cast(PyDenseI8ArrayAttribute(pyAttribute));
if (PyDenseI16ArrayAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseI16ArrayAttribute(pyAttribute));
+ return nb::cast(PyDenseI16ArrayAttribute(pyAttribute));
if (PyDenseI32ArrayAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseI32ArrayAttribute(pyAttribute));
+ return nb::cast(PyDenseI32ArrayAttribute(pyAttribute));
if (PyDenseI64ArrayAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseI64ArrayAttribute(pyAttribute));
+ return nb::cast(PyDenseI64ArrayAttribute(pyAttribute));
if (PyDenseF32ArrayAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseF32ArrayAttribute(pyAttribute));
+ return nb::cast(PyDenseF32ArrayAttribute(pyAttribute));
if (PyDenseF64ArrayAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseF64ArrayAttribute(pyAttribute));
+ return nb::cast(PyDenseF64ArrayAttribute(pyAttribute));
std::string msg =
std::string("Can't cast unknown element type DenseArrayAttr (") +
- std::string(py::repr(py::cast(pyAttribute))) + ")";
- throw py::cast_error(msg);
+ nb::cast(nb::repr(nb::cast(pyAttribute))) + ")";
+ throw nb::type_error(msg.c_str());
}
-py::object denseIntOrFPElementsAttributeCaster(PyAttribute &pyAttribute) {
+nb::object denseIntOrFPElementsAttributeCaster(PyAttribute &pyAttribute) {
if (PyDenseFPElementsAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseFPElementsAttribute(pyAttribute));
+ return nb::cast(PyDenseFPElementsAttribute(pyAttribute));
if (PyDenseIntElementsAttribute::isaFunction(pyAttribute))
- return py::cast(PyDenseIntElementsAttribute(pyAttribute));
+ return nb::cast(PyDenseIntElementsAttribute(pyAttribute));
std::string msg =
std::string(
"Can't cast unknown element type DenseIntOrFPElementsAttr (") +
- std::string(py::repr(py::cast(pyAttribute))) + ")";
- throw py::cast_error(msg);
+ nb::cast(nb::repr(nb::cast(pyAttribute))) + ")";
+ throw nb::type_error(msg.c_str());
}
-py::object integerOrBoolAttributeCaster(PyAttribute &pyAttribute) {
+nb::object integerOrBoolAttributeCaster(PyAttribute &pyAttribute) {
if (PyBoolAttribute::isaFunction(pyAttribute))
- return py::cast(PyBoolAttribute(pyAttribute));
+ return nb::cast(PyBoolAttribute(pyAttribute));
if (PyIntegerAttribute::isaFunction(pyAttribute))
- return py::cast(PyIntegerAttribute(pyAttribute));
+ return nb::cast(PyIntegerAttribute(pyAttribute));
std::string msg =
std::string("Can't cast unknown element type DenseArrayAttr (") +
- std::string(py::repr(py::cast(pyAttribute))) + ")";
- throw py::cast_error(msg);
+ nb::cast(nb::repr(nb::cast(pyAttribute))) + ")";
+ throw nb::type_error(msg.c_str());
}
-py::object symbolRefOrFlatSymbolRefAttributeCaster(PyAttribute &pyAttribute) {
+nb::object symbolRefOrFlatSymbolRefAttributeCaster(PyAttribute &pyAttribute) {
if (PyFlatSymbolRefAttribute::isaFunction(pyAttribute))
- return py::cast(PyFlatSymbolRefAttribute(pyAttribute));
+ return nb::cast(PyFlatSymbolRefAttribute(pyAttribute));
if (PySymbolRefAttribute::isaFunction(pyAttribute))
- return py::cast(PySymbolRefAttribute(pyAttribute));
+ return nb::cast(PySymbolRefAttribute(pyAttribute));
std::string msg = std::string("Can't cast unknown SymbolRef attribute (") +
- std::string(py::repr(py::cast(pyAttribute))) + ")";
- throw py::cast_error(msg);
+ nb::cast(nb::repr(nb::cast(pyAttribute))) +
+ ")";
+ throw nb::type_error(msg.c_str());
}
} // namespace
-void mlir::python::populateIRAttributes(py::module &m) {
+void mlir::python::populateIRAttributes(nb::module_ &m) {
PyAffineMapAttribute::bind(m);
PyDenseBoolArrayAttribute::bind(m);
PyDenseBoolArrayAttribute::PyDenseArrayIterator::bind(m);
@@ -1562,24 +1762,26 @@ void mlir::python::populateIRAttributes(py::module &m) {
PyDenseF64ArrayAttribute::PyDenseArrayIterator::bind(m);
PyGlobals::get().registerTypeCaster(
mlirDenseArrayAttrGetTypeID(),
- pybind11::cpp_function(denseArrayAttributeCaster));
+ nb::cast(nb::cpp_function(denseArrayAttributeCaster)));
PyArrayAttribute::bind(m);
PyArrayAttribute::PyArrayAttributeIterator::bind(m);
PyBoolAttribute::bind(m);
- PyDenseElementsAttribute::bind(m);
+ PyDenseElementsAttribute::bind(m, PyDenseElementsAttribute::slots);
PyDenseFPElementsAttribute::bind(m);
PyDenseIntElementsAttribute::bind(m);
PyGlobals::get().registerTypeCaster(
mlirDenseIntOrFPElementsAttrGetTypeID(),
- pybind11::cpp_function(denseIntOrFPElementsAttributeCaster));
+ nb::cast(
+ nb::cpp_function(denseIntOrFPElementsAttributeCaster)));
PyDenseResourceElementsAttribute::bind(m);
PyDictAttribute::bind(m);
PySymbolRefAttribute::bind(m);
PyGlobals::get().registerTypeCaster(
mlirSymbolRefAttrGetTypeID(),
- pybind11::cpp_function(symbolRefOrFlatSymbolRefAttributeCaster));
+ nb::cast(
+ nb::cpp_function(symbolRefOrFlatSymbolRefAttributeCaster)));
PyFlatSymbolRefAttribute::bind(m);
PyOpaqueAttribute::bind(m);
@@ -1590,7 +1792,7 @@ void mlir::python::populateIRAttributes(py::module &m) {
PyTypeAttribute::bind(m);
PyGlobals::get().registerTypeCaster(
mlirIntegerAttrGetTypeID(),
- pybind11::cpp_function(integerOrBoolAttributeCaster));
+ nb::cast(nb::cpp_function(integerOrBoolAttributeCaster)));
PyUnitAttribute::bind(m);
PyStridedLayoutAttribute::bind(m);
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 3e96f8c60ba7cd..e1c56a3984314f 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -6,26 +6,31 @@
//
//===----------------------------------------------------------------------===//
-#include "IRModule.h"
+#include
+#include
+#include
+#include
+#include
+#include
-#include "Globals.h"
-#include "PybindUtils.h"
+#include
+#include
+#include "Globals.h"
+#include "IRModule.h"
+#include "NanobindUtils.h"
#include "mlir-c/Bindings/Python/Interop.h"
#include "mlir-c/BuiltinAttributes.h"
#include "mlir-c/Debug.h"
#include "mlir-c/Diagnostics.h"
#include "mlir-c/IR.h"
#include "mlir-c/Support.h"
-#include "mlir/Bindings/Python/PybindAdaptors.h"
+#include "mlir/Bindings/Python/NanobindAdaptors.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include
-#include
-
-namespace py = pybind11;
-using namespace py::literals;
+namespace nb = nanobind;
+using namespace nb::literals;
using namespace mlir;
using namespace mlir::python;
@@ -190,18 +195,18 @@ operations.
/// Helper for creating an @classmethod.
template
-py::object classmethod(Func f, Args... args) {
- py::object cf = py::cpp_function(f, args...);
- return py::reinterpret_borrow((PyClassMethod_New(cf.ptr())));
+nb::object classmethod(Func f, Args... args) {
+ nb::object cf = nb::cpp_function(f, args...);
+ return nb::borrow((PyClassMethod_New(cf.ptr())));
}
-static py::object
+static nb::object
createCustomDialectWrapper(const std::string &dialectNamespace,
- py::object dialectDescriptor) {
+ nb::object dialectDescriptor) {
auto dialectClass = PyGlobals::get().lookupDialectClass(dialectNamespace);
if (!dialectClass) {
// Use the base class.
- return py::cast(PyDialect(std::move(dialectDescriptor)));
+ return nb::cast(PyDialect(std::move(dialectDescriptor)));
}
// Create the custom implementation.
@@ -212,42 +217,47 @@ static MlirStringRef toMlirStringRef(const std::string &s) {
return mlirStringRefCreate(s.data(), s.size());
}
+static MlirStringRef toMlirStringRef(const nb::bytes &s) {
+ return mlirStringRefCreate(static_cast(s.data()), s.size());
+}
+
/// Create a block, using the current location context if no locations are
/// specified.
-static MlirBlock createBlock(const py::sequence &pyArgTypes,
- const std::optional &pyArgLocs) {
+static MlirBlock createBlock(const nb::sequence &pyArgTypes,
+ const std::optional &pyArgLocs) {
SmallVector argTypes;
- argTypes.reserve(pyArgTypes.size());
+ argTypes.reserve(nb::len(pyArgTypes));
for (const auto &pyType : pyArgTypes)
- argTypes.push_back(pyType.cast());
+ argTypes.push_back(nb::cast(pyType));
SmallVector argLocs;
if (pyArgLocs) {
- argLocs.reserve(pyArgLocs->size());
+ argLocs.reserve(nb::len(*pyArgLocs));
for (const auto &pyLoc : *pyArgLocs)
- argLocs.push_back(pyLoc.cast());
+ argLocs.push_back(nb::cast(pyLoc));
} else if (!argTypes.empty()) {
argLocs.assign(argTypes.size(), DefaultingPyLocation::resolve());
}
if (argTypes.size() != argLocs.size())
- throw py::value_error(("Expected " + Twine(argTypes.size()) +
+ throw nb::value_error(("Expected " + Twine(argTypes.size()) +
" locations, got: " + Twine(argLocs.size()))
- .str());
+ .str()
+ .c_str());
return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
}
/// Wrapper for the global LLVM debugging flag.
struct PyGlobalDebugFlag {
- static void set(py::object &o, bool enable) { mlirEnableGlobalDebug(enable); }
+ static void set(nb::object &o, bool enable) { mlirEnableGlobalDebug(enable); }
- static bool get(const py::object &) { return mlirIsGlobalDebugEnabled(); }
+ static bool get(const nb::object &) { return mlirIsGlobalDebugEnabled(); }
- static void bind(py::module &m) {
+ static void bind(nb::module_ &m) {
// Debug flags.
- py::class_(m, "_GlobalDebug", py::module_local())
- .def_property_static("flag", &PyGlobalDebugFlag::get,
- &PyGlobalDebugFlag::set, "LLVM-wide debug flag")
+ nb::class_(m, "_GlobalDebug")
+ .def_prop_rw_static("flag", &PyGlobalDebugFlag::get,
+ &PyGlobalDebugFlag::set, "LLVM-wide debug flag")
.def_static(
"set_types",
[](const std::string &type) {
@@ -268,20 +278,20 @@ struct PyAttrBuilderMap {
static bool dunderContains(const std::string &attributeKind) {
return PyGlobals::get().lookupAttributeBuilder(attributeKind).has_value();
}
- static py::function dundeGetItemNamed(const std::string &attributeKind) {
+ static nb::callable dundeGetItemNamed(const std::string &attributeKind) {
auto builder = PyGlobals::get().lookupAttributeBuilder(attributeKind);
if (!builder)
- throw py::key_error(attributeKind);
+ throw nb::key_error(attributeKind.c_str());
return *builder;
}
static void dundeSetItemNamed(const std::string &attributeKind,
- py::function func, bool replace) {
+ nb::callable func, bool replace) {
PyGlobals::get().registerAttributeBuilder(attributeKind, std::move(func),
replace);
}
- static void bind(py::module &m) {
- py::class_(m, "AttrBuilder", py::module_local())
+ static void bind(nb::module_ &m) {
+ nb::class_ |