[Mlir-commits] [mlir] [MLIR][Python] Support dynamic traits in python-defined dialects (PR #179705)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Feb 9 07:29:51 PST 2026
================
@@ -2521,6 +2522,119 @@ void PyOpAdaptor::bind(nb::module_ &m) {
"Returns the attributes of the adaptor.");
}
+static MlirLogicalResult verifyTraitByMethod(MlirOperation op, void *userData,
+ const char *methodName) {
+ nb::handle targetObj(static_cast<PyObject *>(userData));
+ if (!nb::hasattr(targetObj, methodName)) {
+ return mlirLogicalResultSuccess();
+ }
+ PyMlirContextRef ctx = PyMlirContext::forContext(mlirOperationGetContext(op));
+ nb::object opView = PyOperation::forOperation(ctx, op)->createOpView();
+ bool success = nb::cast<bool>(targetObj.attr(methodName)(opView));
+ return success ? mlirLogicalResultSuccess() : mlirLogicalResultFailure();
+};
+
+static bool attachOpTrait(const nb::object &opName, MlirDynamicOpTrait trait,
+ PyMlirContext &context) {
+ std::string opNameStr;
+ if (opName.is_type()) {
+ opNameStr = nb::cast<std::string>(opName.attr("OPERATION_NAME"));
+ } else if (nb::isinstance<nb::str>(opName)) {
+ opNameStr = nb::cast<std::string>(opName);
+ } else {
+ throw nb::type_error("the root argument must be a type or a string");
+ }
+
+ return mlirDynamicOpTraitAttach(
+ trait, MlirStringRef{opNameStr.data(), opNameStr.size()}, context.get());
+}
+
+bool PyDynamicOpTrait::attach(const nb::object &opName,
+ const nb::object &target,
+ PyMlirContext &context) {
+ if (!nb::hasattr(target, "verify") && !nb::hasattr(target, "verify_region"))
+ throw nb::type_error(
+ "the target object must have at least one of 'verify' or "
+ "'verify_region' methods");
+
+ MlirDynamicOpTraitCallbacks callbacks;
+ callbacks.construct = [](void *userData) {
+ nb::handle(static_cast<PyObject *>(userData)).inc_ref();
+ };
+ callbacks.destruct = [](void *userData) {
+ nb::handle(static_cast<PyObject *>(userData)).dec_ref();
+ };
+
+ callbacks.verifyTrait = [](MlirOperation op,
+ void *userData) -> MlirLogicalResult {
+ return verifyTraitByMethod(op, userData, "verify");
+ };
+ callbacks.verifyRegionTrait = [](MlirOperation op,
+ void *userData) -> MlirLogicalResult {
+ return verifyTraitByMethod(op, userData, "verify_region");
+ };
+
+ constexpr const char *typeIDAttr = "_TYPE_ID";
+ if (!nb::hasattr(target, typeIDAttr)) {
+ nb::setattr(target, typeIDAttr,
+ nb::cast(PyTypeID(PyGlobals::get().allocateTypeID())));
+ }
----------------
PragmaTwice wrote:
Same trait should have same type id, in every constructing. So I store them to python objects.
https://github.com/llvm/llvm-project/pull/179705
More information about the Mlir-commits
mailing list