[Mlir-commits] [mlir] [MLIR][Python] add/fix docstrings in IRCore (PR #167063)
Maksim Levental
llvmlistbot at llvm.org
Mon Nov 10 07:36:46 PST 2025
https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/167063
>From e98d3cf334c3ec99cfa869cccbda22cd15c540b4 Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Fri, 7 Nov 2025 14:47:09 -0800
Subject: [PATCH 1/3] [MLIR][Python] add/fix docstrings in IRCore
---
mlir/lib/Bindings/Python/IRCore.cpp | 1802 +++++++++++++++++----------
1 file changed, 1110 insertions(+), 692 deletions(-)
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index cda4fe19c16f8..cb9bd4c82aa9f 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -32,33 +32,6 @@ using llvm::SmallVector;
using llvm::StringRef;
using llvm::Twine;
-//------------------------------------------------------------------------------
-// Docstrings (trivial, non-duplicated docstrings are included inline).
-//------------------------------------------------------------------------------
-
-static const char kContextParseTypeDocstring[] =
- R"(Parses the assembly form of a type.
-
-Returns a Type object or raises an MLIRError if the type cannot be parsed.
-
-See also: https://mlir.llvm.org/docs/LangRef/#type-system
-)";
-
-static const char kContextGetCallSiteLocationDocstring[] =
- R"(Gets a Location representing a caller and callsite)";
-
-static const char kContextGetFileLocationDocstring[] =
- R"(Gets a Location representing a file, line and column)";
-
-static const char kContextGetFileRangeDocstring[] =
- R"(Gets a Location representing a file, line and column range)";
-
-static const char kContextGetFusedLocationDocstring[] =
- R"(Gets a Location representing a fused location with optional metadata)";
-
-static const char kContextGetNameLocationDocString[] =
- R"(Gets a Location representing a named location with optional child location)";
-
static const char kModuleParseDocstring[] =
R"(Parses a module's assembly format from a string.
@@ -67,132 +40,12 @@ Returns a new MlirModule or raises an MLIRError if the parsing fails.
See also: https://mlir.llvm.org/docs/LangRef/
)";
-static const char kModuleCAPICreate[] =
- R"(Creates a Module from a MlirModule wrapped by a capsule (i.e. module._CAPIPtr).
-Note this returns a new object BUT _clear_mlir_module(module) must be called to
-prevent double-frees (of the underlying mlir::Module).
-)";
-
-static const char kOperationCreateDocstring[] =
- R"(Creates a new operation.
-
-Args:
- name: Operation name (e.g. "dialect.operation").
- results: Sequence of Type representing op result types.
- attributes: Dict of str:Attribute.
- successors: List of Block for the operation's successors.
- regions: Number of regions to create.
- location: A Location object (defaults to resolve from context manager).
- ip: An InsertionPoint (defaults to resolve from context manager or set to
- False to disable insertion, even with an insertion point set in the
- context manager).
- infer_type: Whether to infer result types.
-Returns:
- A new "detached" Operation object. Detached operations can be added
- to blocks, which causes them to become "attached."
-)";
-
-static const char kOperationPrintDocstring[] =
- R"(Prints the assembly form of the operation to a file like object.
-
-Args:
- file: The file like object to write to. Defaults to sys.stdout.
- binary: Whether to write bytes (True) or str (False). Defaults to False.
- large_elements_limit: Whether to elide elements attributes above this
- number of elements. Defaults to None (no limit).
- large_resource_limit: Whether to elide resource attributes above this
- number of characters. Defaults to None (no limit). If large_elements_limit
- is set and this is None, the behavior will be to use large_elements_limit
- as large_resource_limit.
- enable_debug_info: Whether to print debug/location information. Defaults
- to False.
- pretty_debug_info: Whether to format debug information for easier reading
- by a human (warning: the result is unparseable).
- print_generic_op_form: Whether to print the generic assembly forms of all
- ops. Defaults to False.
- use_local_Scope: Whether to print in a way that is more optimized for
- multi-threaded access but may not be consistent with how the overall
- module prints.
- assume_verified: By default, if not printing generic form, the verifier
- will be run and if it fails, generic form will be printed with a comment
- about failed verification. While a reasonable default for interactive use,
- for systematic use, it is often better for the caller to verify explicitly
- and report failures in a more robust fashion. Set this to True if doing this
- in order to avoid running a redundant verification. If the IR is actually
- invalid, behavior is undefined.
- skip_regions: Whether to skip printing regions. Defaults to False.
-)";
-
-static const char kOperationPrintStateDocstring[] =
- R"(Prints the assembly form of the operation to a file like object.
-
-Args:
- file: The file like object to write to. Defaults to sys.stdout.
- binary: Whether to write bytes (True) or str (False). Defaults to False.
- state: AsmState capturing the operation numbering and flags.
-)";
-
-static const char kOperationGetAsmDocstring[] =
- R"(Gets the assembly form of the operation with all options available.
-
-Args:
- binary: Whether to return a bytes (True) or str (False) object. Defaults to
- False.
- ... others ...: See the print() method for common keyword arguments for
- configuring the printout.
-Returns:
- Either a bytes or str object, depending on the setting of the 'binary'
- argument.
-)";
-
-static const char kOperationPrintBytecodeDocstring[] =
- R"(Write the bytecode form of the operation to a file like object.
-
-Args:
- file: The file like object to write to.
- desired_version: The version of bytecode to emit.
-Returns:
- The bytecode writer status.
-)";
-
-static const char kOperationStrDunderDocstring[] =
- R"(Gets the assembly form of the operation with default options.
-
-If more advanced control over the assembly formatting or I/O options is needed,
-use the dedicated print or get_asm method, which supports keyword arguments to
-customize behavior.
-)";
-
static const char kDumpDocstring[] =
- R"(Dumps a debug representation of the object to stderr.)";
-
-static const char kAppendBlockDocstring[] =
- R"(Appends a new block, with argument types as positional args.
-
-Returns:
- The created block.
-)";
-
-static const char kValueDunderStrDocstring[] =
- R"(Returns the string form of the value.
-
-If the value is a block argument, this is the assembly form of its type and the
-position in the argument list. If the value is an operation result, this is
-equivalent to printing the operation that produced it.
-)";
-
-static const char kGetNameAsOperand[] =
- R"(Returns the string form of value as an operand (i.e., the ValueID).
-)";
-
-static const char kValueReplaceAllUsesWithDocstring[] =
- R"(Replace all uses of value with the new value, updating anything in
-the IR that uses 'self' to use the other value instead.
-)";
+ "Dumps a debug representation of the object to stderr.";
static const char kValueReplaceAllUsesExceptDocstring[] =
- R"("Replace all uses of this value with the 'with' value, except for those
-in 'exceptions'. 'exceptions' can be either a single operation or a list of
+ R"(Replace all uses of this value with the `with` value, except for those
+in `exceptions`. 'exceptions' can be either a single operation or a list of
operations.
)";
@@ -274,22 +127,26 @@ struct PyGlobalDebugFlag {
// Debug flags.
nb::class_<PyGlobalDebugFlag>(m, "_GlobalDebug")
.def_prop_rw_static("flag", &PyGlobalDebugFlag::get,
- &PyGlobalDebugFlag::set, "LLVM-wide debug flag")
+ &PyGlobalDebugFlag::set, "LLVM-wide debug flag.")
.def_static(
"set_types",
[](const std::string &type) {
nb::ft_lock_guard lock(mutex);
mlirSetGlobalDebugType(type.c_str());
},
- "types"_a, "Sets specific debug types to be produced by LLVM")
- .def_static("set_types", [](const std::vector<std::string> &types) {
- std::vector<const char *> pointers;
- pointers.reserve(types.size());
- for (const std::string &str : types)
- pointers.push_back(str.c_str());
- nb::ft_lock_guard lock(mutex);
- mlirSetGlobalDebugTypes(pointers.data(), pointers.size());
- });
+ "types"_a, "Sets specific debug types to be produced by LLVM.")
+ .def_static(
+ "set_types",
+ [](const std::vector<std::string> &types) {
+ std::vector<const char *> pointers;
+ pointers.reserve(types.size());
+ for (const std::string &str : types)
+ pointers.push_back(str.c_str());
+ nb::ft_lock_guard lock(mutex);
+ mlirSetGlobalDebugTypes(pointers.data(), pointers.size());
+ },
+ "types"_a,
+ "Sets multiple specific debug types to be produced by LLVM.");
}
private:
@@ -316,12 +173,18 @@ struct PyAttrBuilderMap {
static void bind(nb::module_ &m) {
nb::class_<PyAttrBuilderMap>(m, "AttrBuilder")
- .def_static("contains", &PyAttrBuilderMap::dunderContains)
- .def_static("get", &PyAttrBuilderMap::dunderGetItemNamed)
+ .def_static("contains", &PyAttrBuilderMap::dunderContains,
+ "attribute_kind"_a,
+ "Checks whether an attribute builder is registered for the "
+ "given attribute kind.")
+ .def_static("get", &PyAttrBuilderMap::dunderGetItemNamed,
+ "attribute_kind"_a,
+ "Gets the registered attribute builder for the given "
+ "attribute kind.")
.def_static("insert", &PyAttrBuilderMap::dunderSetItemNamed,
"attribute_kind"_a, "attr_builder"_a, "replace"_a = false,
"Register an attribute builder for building MLIR "
- "attributes from python values.");
+ "attributes from Python values.");
}
};
@@ -357,8 +220,10 @@ class PyRegionIterator {
static void bind(nb::module_ &m) {
nb::class_<PyRegionIterator>(m, "RegionIterator")
- .def("__iter__", &PyRegionIterator::dunderIter)
- .def("__next__", &PyRegionIterator::dunderNext);
+ .def("__iter__", &PyRegionIterator::dunderIter,
+ "Returns an iterator over the regions in the operation.")
+ .def("__next__", &PyRegionIterator::dunderNext,
+ "Returns the next region in the iteration.");
}
private:
@@ -386,7 +251,8 @@ class PyRegionList : public Sliceable<PyRegionList, PyRegion> {
}
static void bindDerived(ClassTy &c) {
- c.def("__iter__", &PyRegionList::dunderIter);
+ c.def("__iter__", &PyRegionList::dunderIter,
+ "Returns an iterator over the regions in the sequence.");
}
private:
@@ -430,8 +296,10 @@ class PyBlockIterator {
static void bind(nb::module_ &m) {
nb::class_<PyBlockIterator>(m, "BlockIterator")
- .def("__iter__", &PyBlockIterator::dunderIter)
- .def("__next__", &PyBlockIterator::dunderNext);
+ .def("__iter__", &PyBlockIterator::dunderIter,
+ "Returns an iterator over the blocks in the operation's region.")
+ .def("__next__", &PyBlockIterator::dunderNext,
+ "Returns the next block in the iteration.");
}
private:
@@ -493,10 +361,19 @@ class PyBlockList {
static void bind(nb::module_ &m) {
nb::class_<PyBlockList>(m, "BlockList")
- .def("__getitem__", &PyBlockList::dunderGetItem)
- .def("__iter__", &PyBlockList::dunderIter)
- .def("__len__", &PyBlockList::dunderLen)
- .def("append", &PyBlockList::appendBlock, kAppendBlockDocstring,
+ .def("__getitem__", &PyBlockList::dunderGetItem,
+ "Returns the block at the specified index.")
+ .def("__iter__", &PyBlockList::dunderIter,
+ "Returns an iterator over blocks in the operation's region.")
+ .def("__len__", &PyBlockList::dunderLen,
+ "Returns the number of blocks in the operation's region.")
+ .def("append", &PyBlockList::appendBlock,
+ R"(
+ Appends a new block, with argument types as positional args.
+
+ Returns:
+ The created block.
+ )",
nb::arg("args"), nb::kw_only(),
nb::arg("arg_locs") = std::nullopt);
}
@@ -527,8 +404,10 @@ class PyOperationIterator {
static void bind(nb::module_ &m) {
nb::class_<PyOperationIterator>(m, "OperationIterator")
- .def("__iter__", &PyOperationIterator::dunderIter)
- .def("__next__", &PyOperationIterator::dunderNext);
+ .def("__iter__", &PyOperationIterator::dunderIter,
+ "Returns an iterator over the operations in an operation's block.")
+ .def("__next__", &PyOperationIterator::dunderNext,
+ "Returns the next operation in the iteration.");
}
private:
@@ -584,9 +463,12 @@ class PyOperationList {
static void bind(nb::module_ &m) {
nb::class_<PyOperationList>(m, "OperationList")
- .def("__getitem__", &PyOperationList::dunderGetItem)
- .def("__iter__", &PyOperationList::dunderIter)
- .def("__len__", &PyOperationList::dunderLen);
+ .def("__getitem__", &PyOperationList::dunderGetItem,
+ "Returns the operation at the specified index.")
+ .def("__iter__", &PyOperationList::dunderIter,
+ "Returns an iterator over operations in the list.")
+ .def("__len__", &PyOperationList::dunderLen,
+ "Returns the number of operations in the list.");
}
private:
@@ -609,8 +491,10 @@ class PyOpOperand {
static void bind(nb::module_ &m) {
nb::class_<PyOpOperand>(m, "OpOperand")
- .def_prop_ro("owner", &PyOpOperand::getOwner)
- .def_prop_ro("operand_number", &PyOpOperand::getOperandNumber);
+ .def_prop_ro("owner", &PyOpOperand::getOwner,
+ "Returns the operation that owns this operand.")
+ .def_prop_ro("operand_number", &PyOpOperand::getOperandNumber,
+ "Returns the operand number in the owning operation.");
}
private:
@@ -634,8 +518,10 @@ class PyOpOperandIterator {
static void bind(nb::module_ &m) {
nb::class_<PyOpOperandIterator>(m, "OpOperandIterator")
- .def("__iter__", &PyOpOperandIterator::dunderIter)
- .def("__next__", &PyOpOperandIterator::dunderNext);
+ .def("__iter__", &PyOpOperandIterator::dunderIter,
+ "Returns an iterator over operands.")
+ .def("__next__", &PyOpOperandIterator::dunderNext,
+ "Returns the next operand in the iteration.");
}
private:
@@ -1626,16 +1512,21 @@ class PyOpResult : public PyConcreteValue<PyOpResult> {
static void bindDerived(ClassTy &c) {
c.def_prop_ro(
- "owner", [](PyOpResult &self) -> nb::typed<nb::object, PyOperation> {
+ "owner",
+ [](PyOpResult &self) -> nb::typed<nb::object, PyOperation> {
assert(mlirOperationEqual(self.getParentOperation()->get(),
mlirOpResultGetOwner(self.get())) &&
"expected the owner of the value in Python to match that in "
"the IR");
return self.getParentOperation().getObject();
- });
- c.def_prop_ro("result_number", [](PyOpResult &self) {
- return mlirOpResultGetResultNumber(self.get());
- });
+ },
+ "Returns the operation that produces this result.");
+ c.def_prop_ro(
+ "result_number",
+ [](PyOpResult &self) {
+ return mlirOpResultGetResultNumber(self.get());
+ },
+ "Returns the position of this result in the operation's result list.");
}
};
@@ -1671,13 +1562,18 @@ class PyOpResultList : public Sliceable<PyOpResultList, PyOpResult> {
operation(std::move(operation)) {}
static void bindDerived(ClassTy &c) {
- c.def_prop_ro("types", [](PyOpResultList &self) {
- return getValueTypes(self, self.operation->getContext());
- });
- c.def_prop_ro("owner",
- [](PyOpResultList &self) -> nb::typed<nb::object, PyOpView> {
- return self.operation->createOpView();
- });
+ c.def_prop_ro(
+ "types",
+ [](PyOpResultList &self) {
+ return getValueTypes(self, self.operation->getContext());
+ },
+ "Returns a list of types for all results in this result list.");
+ c.def_prop_ro(
+ "owner",
+ [](PyOpResultList &self) -> nb::typed<nb::object, PyOpView> {
+ return self.operation->createOpView();
+ },
+ "Returns the operation that owns this result list.");
}
PyOperationRef &getOperation() { return operation; }
@@ -2427,19 +2323,25 @@ class PyBlockArgument : public PyConcreteValue<PyBlockArgument> {
using PyConcreteValue::PyConcreteValue;
static void bindDerived(ClassTy &c) {
- c.def_prop_ro("owner", [](PyBlockArgument &self) {
- return PyBlock(self.getParentOperation(),
- mlirBlockArgumentGetOwner(self.get()));
- });
- c.def_prop_ro("arg_number", [](PyBlockArgument &self) {
- return mlirBlockArgumentGetArgNumber(self.get());
- });
+ c.def_prop_ro(
+ "owner",
+ [](PyBlockArgument &self) {
+ return PyBlock(self.getParentOperation(),
+ mlirBlockArgumentGetOwner(self.get()));
+ },
+ "Returns the block that owns this argument.");
+ c.def_prop_ro(
+ "arg_number",
+ [](PyBlockArgument &self) {
+ return mlirBlockArgumentGetArgNumber(self.get());
+ },
+ "Returns the position of this argument in the block's argument list.");
c.def(
"set_type",
[](PyBlockArgument &self, PyType type) {
return mlirBlockArgumentSetType(self.get(), type);
},
- nb::arg("type"));
+ nb::arg("type"), "Sets the type of this block argument.");
}
};
@@ -2462,9 +2364,12 @@ class PyBlockArgumentList
operation(std::move(operation)), block(block) {}
static void bindDerived(ClassTy &c) {
- c.def_prop_ro("types", [](PyBlockArgumentList &self) {
- return getValueTypes(self, self.operation->getContext());
- });
+ c.def_prop_ro(
+ "types",
+ [](PyBlockArgumentList &self) {
+ return getValueTypes(self, self.operation->getContext());
+ },
+ "Returns a list of types for all arguments in this argument list.");
}
private:
@@ -2516,7 +2421,9 @@ class PyOpOperandList : public Sliceable<PyOpOperandList, PyValue> {
}
static void bindDerived(ClassTy &c) {
- c.def("__setitem__", &PyOpOperandList::dunderSetItem);
+ c.def("__setitem__", &PyOpOperandList::dunderSetItem, nb::arg("index"),
+ nb::arg("value"),
+ "Sets the operand at the specified index to a new value.");
}
private:
@@ -2571,7 +2478,8 @@ class PyOpSuccessors : public Sliceable<PyOpSuccessors, PyBlock> {
}
static void bindDerived(ClassTy &c) {
- c.def("__setitem__", &PyOpSuccessors::dunderSetItem);
+ c.def("__setitem__", &PyOpSuccessors::dunderSetItem, nb::arg("index"),
+ nb::arg("block"), "Sets the successor block at the specified index.");
}
private:
@@ -2743,55 +2651,70 @@ class PyOpAttributeMap {
static void bind(nb::module_ &m) {
nb::class_<PyOpAttributeMap>(m, "OpAttributeMap")
- .def("__contains__", &PyOpAttributeMap::dunderContains)
- .def("__len__", &PyOpAttributeMap::dunderLen)
- .def("__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
- .def("__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
- .def("__setitem__", &PyOpAttributeMap::dunderSetItem)
- .def("__delitem__", &PyOpAttributeMap::dunderDelItem)
- .def("__iter__",
- [](PyOpAttributeMap &self) {
- nb::list keys;
- PyOpAttributeMap::forEachAttr(
- self.operation->get(),
- [&](MlirStringRef name, MlirAttribute) {
- keys.append(nb::str(name.data, name.length));
- });
- return nb::iter(keys);
- })
- .def("keys",
- [](PyOpAttributeMap &self) {
- nb::list out;
- PyOpAttributeMap::forEachAttr(
- self.operation->get(),
- [&](MlirStringRef name, MlirAttribute) {
- out.append(nb::str(name.data, name.length));
- });
- return out;
- })
- .def("values",
- [](PyOpAttributeMap &self) {
- nb::list out;
- PyOpAttributeMap::forEachAttr(
- self.operation->get(),
- [&](MlirStringRef, MlirAttribute attr) {
- out.append(PyAttribute(self.operation->getContext(), attr)
- .maybeDownCast());
- });
- return out;
- })
- .def("items", [](PyOpAttributeMap &self) {
- nb::list out;
- PyOpAttributeMap::forEachAttr(
- self.operation->get(),
- [&](MlirStringRef name, MlirAttribute attr) {
- out.append(nb::make_tuple(
- nb::str(name.data, name.length),
- PyAttribute(self.operation->getContext(), attr)
- .maybeDownCast()));
- });
- return out;
- });
+ .def("__contains__", &PyOpAttributeMap::dunderContains, nb::arg("name"),
+ "Checks if an attribute with the given name exists in the map.")
+ .def("__len__", &PyOpAttributeMap::dunderLen,
+ "Returns the number of attributes in the map.")
+ .def("__getitem__", &PyOpAttributeMap::dunderGetItemNamed,
+ nb::arg("name"), "Gets an attribute by name.")
+ .def("__getitem__", &PyOpAttributeMap::dunderGetItemIndexed,
+ nb::arg("index"), "Gets a named attribute by index.")
+ .def("__setitem__", &PyOpAttributeMap::dunderSetItem, nb::arg("name"),
+ nb::arg("attr"), "Sets an attribute with the given name.")
+ .def("__delitem__", &PyOpAttributeMap::dunderDelItem, nb::arg("name"),
+ "Deletes an attribute with the given name.")
+ .def(
+ "__iter__",
+ [](PyOpAttributeMap &self) {
+ nb::list keys;
+ PyOpAttributeMap::forEachAttr(
+ self.operation->get(),
+ [&](MlirStringRef name, MlirAttribute) {
+ keys.append(nb::str(name.data, name.length));
+ });
+ return nb::iter(keys);
+ },
+ "Iterates over attribute names.")
+ .def(
+ "keys",
+ [](PyOpAttributeMap &self) {
+ nb::list out;
+ PyOpAttributeMap::forEachAttr(
+ self.operation->get(),
+ [&](MlirStringRef name, MlirAttribute) {
+ out.append(nb::str(name.data, name.length));
+ });
+ return out;
+ },
+ "Returns a list of attribute names.")
+ .def(
+ "values",
+ [](PyOpAttributeMap &self) {
+ nb::list out;
+ PyOpAttributeMap::forEachAttr(
+ self.operation->get(),
+ [&](MlirStringRef, MlirAttribute attr) {
+ out.append(PyAttribute(self.operation->getContext(), attr)
+ .maybeDownCast());
+ });
+ return out;
+ },
+ "Returns a list of attribute values.")
+ .def(
+ "items",
+ [](PyOpAttributeMap &self) {
+ nb::list out;
+ PyOpAttributeMap::forEachAttr(
+ self.operation->get(),
+ [&](MlirStringRef name, MlirAttribute attr) {
+ out.append(nb::make_tuple(
+ nb::str(name.data, name.length),
+ PyAttribute(self.operation->getContext(), attr)
+ .maybeDownCast()));
+ });
+ return out;
+ },
+ "Returns a list of (name, attribute) tuples.");
}
private:
@@ -2979,62 +2902,103 @@ void mlir::python::populateIRCore(nb::module_ &m) {
// Mapping of Diagnostics.
//----------------------------------------------------------------------------
nb::class_<PyDiagnostic>(m, "Diagnostic")
- .def_prop_ro("severity", &PyDiagnostic::getSeverity)
- .def_prop_ro("location", &PyDiagnostic::getLocation)
- .def_prop_ro("message", &PyDiagnostic::getMessage)
- .def_prop_ro("notes", &PyDiagnostic::getNotes)
- .def("__str__", [](PyDiagnostic &self) -> nb::str {
- if (!self.isValid())
- return nb::str("<Invalid Diagnostic>");
- return self.getMessage();
- });
+ .def_prop_ro("severity", &PyDiagnostic::getSeverity,
+ "Returns the severity of the diagnostic.")
+ .def_prop_ro("location", &PyDiagnostic::getLocation,
+ "Returns the location associated with the diagnostic.")
+ .def_prop_ro("message", &PyDiagnostic::getMessage,
+ "Returns the message text of the diagnostic.")
+ .def_prop_ro("notes", &PyDiagnostic::getNotes,
+ "Returns a tuple of attached note diagnostics.")
+ .def(
+ "__str__",
+ [](PyDiagnostic &self) -> nb::str {
+ if (!self.isValid())
+ return nb::str("<Invalid Diagnostic>");
+ return self.getMessage();
+ },
+ "Returns the diagnostic message as a string.");
nb::class_<PyDiagnostic::DiagnosticInfo>(m, "DiagnosticInfo")
- .def("__init__",
- [](PyDiagnostic::DiagnosticInfo &self, PyDiagnostic diag) {
- new (&self) PyDiagnostic::DiagnosticInfo(diag.getInfo());
- })
- .def_ro("severity", &PyDiagnostic::DiagnosticInfo::severity)
- .def_ro("location", &PyDiagnostic::DiagnosticInfo::location)
- .def_ro("message", &PyDiagnostic::DiagnosticInfo::message)
- .def_ro("notes", &PyDiagnostic::DiagnosticInfo::notes)
- .def("__str__",
- [](PyDiagnostic::DiagnosticInfo &self) { return self.message; });
+ .def(
+ "__init__",
+ [](PyDiagnostic::DiagnosticInfo &self, PyDiagnostic diag) {
+ new (&self) PyDiagnostic::DiagnosticInfo(diag.getInfo());
+ },
+ "diag"_a, "Creates a DiagnosticInfo from a Diagnostic.")
+ .def_ro("severity", &PyDiagnostic::DiagnosticInfo::severity,
+ "The severity level of the diagnostic.")
+ .def_ro("location", &PyDiagnostic::DiagnosticInfo::location,
+ "The location associated with the diagnostic.")
+ .def_ro("message", &PyDiagnostic::DiagnosticInfo::message,
+ "The message text of the diagnostic.")
+ .def_ro("notes", &PyDiagnostic::DiagnosticInfo::notes,
+ "List of attached note diagnostics.")
+ .def(
+ "__str__",
+ [](PyDiagnostic::DiagnosticInfo &self) { return self.message; },
+ "Returns the diagnostic message as a string.");
nb::class_<PyDiagnosticHandler>(m, "DiagnosticHandler")
- .def("detach", &PyDiagnosticHandler::detach)
- .def_prop_ro("attached", &PyDiagnosticHandler::isAttached)
- .def_prop_ro("had_error", &PyDiagnosticHandler::getHadError)
- .def("__enter__", &PyDiagnosticHandler::contextEnter)
+ .def("detach", &PyDiagnosticHandler::detach,
+ "Detaches the diagnostic handler from the context.")
+ .def_prop_ro("attached", &PyDiagnosticHandler::isAttached,
+ "Returns True if the handler is attached to a context.")
+ .def_prop_ro("had_error", &PyDiagnosticHandler::getHadError,
+ "Returns True if an error was encountered during diagnostic "
+ "handling.")
+ .def("__enter__", &PyDiagnosticHandler::contextEnter,
+ "Enters the diagnostic handler as a context manager.")
.def("__exit__", &PyDiagnosticHandler::contextExit,
nb::arg("exc_type").none(), nb::arg("exc_value").none(),
- nb::arg("traceback").none());
+ nb::arg("traceback").none(),
+ "Exits the diagnostic handler context manager.");
// Expose DefaultThreadPool to python
nb::class_<PyThreadPool>(m, "ThreadPool")
- .def("__init__", [](PyThreadPool &self) { new (&self) PyThreadPool(); })
- .def("get_max_concurrency", &PyThreadPool::getMaxConcurrency)
- .def("_mlir_thread_pool_ptr", &PyThreadPool::_mlir_thread_pool_ptr);
+ .def(
+ "__init__", [](PyThreadPool &self) { new (&self) PyThreadPool(); },
+ "Creates a new thread pool with default concurrency.")
+ .def("get_max_concurrency", &PyThreadPool::getMaxConcurrency,
+ "Returns the maximum number of threads in the pool.")
+ .def("_mlir_thread_pool_ptr", &PyThreadPool::_mlir_thread_pool_ptr,
+ "Returns the raw pointer to the LLVM thread pool as a string.");
nb::class_<PyMlirContext>(m, "Context")
- .def("__init__",
- [](PyMlirContext &self) {
- MlirContext context = mlirContextCreateWithThreading(false);
- new (&self) PyMlirContext(context);
- })
- .def_static("_get_live_count", &PyMlirContext::getLiveCount)
- .def("_get_context_again",
- [](PyMlirContext &self) -> nb::typed<nb::object, PyMlirContext> {
- PyMlirContextRef ref = PyMlirContext::forContext(self.get());
- return ref.releaseObject();
- })
- .def("_get_live_module_count", &PyMlirContext::getLiveModuleCount)
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyMlirContext::getCapsule)
+ .def(
+ "__init__",
+ [](PyMlirContext &self) {
+ MlirContext context = mlirContextCreateWithThreading(false);
+ new (&self) PyMlirContext(context);
+ },
+ R"(
+ Creates a new MLIR context.
+
+ The context is the top-level container for all MLIR objects. It owns the storage
+ for types, attributes, locations, and other core IR objects. A context can be
+ configured to allow or disallow unregistered dialects and can have dialects
+ loaded on-demand.)")
+ .def_static("_get_live_count", &PyMlirContext::getLiveCount,
+ "Gets the number of live Context objects.")
+ .def(
+ "_get_context_again",
+ [](PyMlirContext &self) -> nb::typed<nb::object, PyMlirContext> {
+ PyMlirContextRef ref = PyMlirContext::forContext(self.get());
+ return ref.releaseObject();
+ },
+ "Gets another reference to the same context.")
+ .def("_get_live_module_count", &PyMlirContext::getLiveModuleCount,
+ "Gets the number of live modules owned by this context.")
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyMlirContext::getCapsule,
+ "Gets a capsule wrapping the MlirContext.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR,
- &PyMlirContext::createFromCapsule)
- .def("__enter__", &PyMlirContext::contextEnter)
+ &PyMlirContext::createFromCapsule,
+ "Creates a Context from a capsule wrapping MlirContext.")
+ .def("__enter__", &PyMlirContext::contextEnter,
+ "Enters the context as a context manager.")
.def("__exit__", &PyMlirContext::contextExit, nb::arg("exc_type").none(),
- nb::arg("exc_value").none(), nb::arg("traceback").none())
+ nb::arg("exc_value").none(), nb::arg("traceback").none(),
+ "Exits the context manager.")
.def_prop_ro_static(
"current",
[](nb::object & /*class*/)
@@ -3045,14 +3009,15 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return nb::cast(context);
},
nb::sig("def current(/) -> Context | None"),
- "Gets the Context bound to the current thread or raises ValueError")
+ "Gets the Context bound to the current thread or returns None if no "
+ "context is set.")
.def_prop_ro(
"dialects",
[](PyMlirContext &self) { return PyDialects(self.getRef()); },
- "Gets a container for accessing dialects by name")
+ "Gets a container for accessing dialects by name.")
.def_prop_ro(
"d", [](PyMlirContext &self) { return PyDialects(self.getRef()); },
- "Alias for 'dialect'")
+ "Alias for 'dialects'.")
.def(
"get_dialect_descriptor",
[=](PyMlirContext &self, std::string &name) {
@@ -3065,7 +3030,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return PyDialectDescriptor(self.getRef(), dialect);
},
nb::arg("dialect_name"),
- "Gets or loads a dialect by name, returning its descriptor object")
+ "Gets or loads a dialect by name, returning its descriptor object.")
.def_prop_rw(
"allow_unregistered_dialects",
[](PyMlirContext &self) -> bool {
@@ -3073,67 +3038,110 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
[](PyMlirContext &self, bool value) {
mlirContextSetAllowUnregisteredDialects(self.get(), value);
- })
+ },
+ "Controls whether unregistered dialects are allowed in this context.")
.def("attach_diagnostic_handler", &PyMlirContext::attachDiagnosticHandler,
nb::arg("callback"),
- "Attaches a diagnostic handler that will receive callbacks")
+ "Attaches a diagnostic handler that will receive callbacks.")
.def(
"enable_multithreading",
[](PyMlirContext &self, bool enable) {
mlirContextEnableMultithreading(self.get(), enable);
},
- nb::arg("enable"))
- .def("set_thread_pool",
- [](PyMlirContext &self, PyThreadPool &pool) {
- // we should disable multi-threading first before setting
- // new thread pool otherwise the assert in
- // MLIRContext::setThreadPool will be raised.
- mlirContextEnableMultithreading(self.get(), false);
- mlirContextSetThreadPool(self.get(), pool.get());
- })
- .def("get_num_threads",
- [](PyMlirContext &self) {
- return mlirContextGetNumThreads(self.get());
- })
- .def("_mlir_thread_pool_ptr",
- [](PyMlirContext &self) {
- MlirLlvmThreadPool pool = mlirContextGetThreadPool(self.get());
- std::stringstream ss;
- ss << pool.ptr;
- return ss.str();
- })
+ nb::arg("enable"),
+ R"(
+ Enables or disables multi-threading support in the context.
+
+ Args:
+ enable: Whether to enable (True) or disable (False) multi-threading.
+ )")
+ .def(
+ "set_thread_pool",
+ [](PyMlirContext &self, PyThreadPool &pool) {
+ // we should disable multi-threading first before setting
+ // new thread pool otherwise the assert in
+ // MLIRContext::setThreadPool will be raised.
+ mlirContextEnableMultithreading(self.get(), false);
+ mlirContextSetThreadPool(self.get(), pool.get());
+ },
+ R"(
+ Sets a custom thread pool for the context to use.
+
+ Args:
+ pool: A ThreadPool object to use for parallel operations.
+
+ Note:
+ Multi-threading is automatically disabled before setting the thread pool.)")
+ .def(
+ "get_num_threads",
+ [](PyMlirContext &self) {
+ return mlirContextGetNumThreads(self.get());
+ },
+ "Gets the number of threads in the context's thread pool.")
+ .def(
+ "_mlir_thread_pool_ptr",
+ [](PyMlirContext &self) {
+ MlirLlvmThreadPool pool = mlirContextGetThreadPool(self.get());
+ std::stringstream ss;
+ ss << pool.ptr;
+ return ss.str();
+ },
+ "Gets the raw pointer to the LLVM thread pool as a string.")
.def(
"is_registered_operation",
[](PyMlirContext &self, std::string &name) {
return mlirContextIsRegisteredOperation(
self.get(), MlirStringRef{name.data(), name.size()});
},
- nb::arg("operation_name"))
+ nb::arg("operation_name"),
+ R"(
+ Checks whether an operation with the given name is registered.
+
+ Args:
+ operation_name: The fully qualified name of the operation (e.g., `arith.addf`).
+
+ Returns:
+ True if the operation is registered, False otherwise.)")
.def(
"append_dialect_registry",
[](PyMlirContext &self, PyDialectRegistry ®istry) {
mlirContextAppendDialectRegistry(self.get(), registry);
},
- nb::arg("registry"))
+ nb::arg("registry"),
+ R"(
+ Appends the contents of a dialect registry to the context.
+
+ Args:
+ registry: A DialectRegistry containing dialects to append.)")
.def_prop_rw("emit_error_diagnostics",
&PyMlirContext::getEmitErrorDiagnostics,
&PyMlirContext::setEmitErrorDiagnostics,
- "Emit error diagnostics to diagnostic handlers. By default "
- "error diagnostics are captured and reported through "
- "MLIRError exceptions.")
- .def("load_all_available_dialects", [](PyMlirContext &self) {
- mlirContextLoadAllAvailableDialects(self.get());
- });
+ R"(
+ Controls whether error diagnostics are emitted to diagnostic handlers.
+
+ By default, error diagnostics are captured and reported through MLIRError exceptions.)")
+ .def(
+ "load_all_available_dialects",
+ [](PyMlirContext &self) {
+ mlirContextLoadAllAvailableDialects(self.get());
+ },
+ R"(
+ Loads all dialects available in the registry into the context.
+
+ This eagerly loads all dialects that have been registered, making them
+ immediately available for use.)");
//----------------------------------------------------------------------------
// Mapping of PyDialectDescriptor
//----------------------------------------------------------------------------
nb::class_<PyDialectDescriptor>(m, "DialectDescriptor")
- .def_prop_ro("namespace",
- [](PyDialectDescriptor &self) {
- MlirStringRef ns = mlirDialectGetNamespace(self.get());
- return nb::str(ns.data, ns.length);
- })
+ .def_prop_ro(
+ "namespace",
+ [](PyDialectDescriptor &self) {
+ MlirStringRef ns = mlirDialectGetNamespace(self.get());
+ return nb::str(ns.data, ns.length);
+ },
+ "Returns the namespace of the dialect.")
.def(
"__repr__",
[](PyDialectDescriptor &self) {
@@ -3143,35 +3151,43 @@ void mlir::python::populateIRCore(nb::module_ &m) {
repr.append(">");
return repr;
},
- nb::sig("def __repr__(self) -> str"));
+ nb::sig("def __repr__(self) -> str"),
+ "Returns a string representation of the dialect descriptor.");
//----------------------------------------------------------------------------
// Mapping of PyDialects
//----------------------------------------------------------------------------
nb::class_<PyDialects>(m, "Dialects")
- .def("__getitem__",
- [=](PyDialects &self, std::string keyName) {
- MlirDialect dialect =
- self.getDialectForKey(keyName, /*attrError=*/false);
- nb::object descriptor =
- nb::cast(PyDialectDescriptor{self.getContext(), dialect});
- return createCustomDialectWrapper(keyName, std::move(descriptor));
- })
- .def("__getattr__", [=](PyDialects &self, std::string attrName) {
- MlirDialect dialect =
- self.getDialectForKey(attrName, /*attrError=*/true);
- nb::object descriptor =
- nb::cast(PyDialectDescriptor{self.getContext(), dialect});
- return createCustomDialectWrapper(attrName, std::move(descriptor));
- });
+ .def(
+ "__getitem__",
+ [=](PyDialects &self, std::string keyName) {
+ MlirDialect dialect =
+ self.getDialectForKey(keyName, /*attrError=*/false);
+ nb::object descriptor =
+ nb::cast(PyDialectDescriptor{self.getContext(), dialect});
+ return createCustomDialectWrapper(keyName, std::move(descriptor));
+ },
+ "Gets a dialect by name using subscript notation.")
+ .def(
+ "__getattr__",
+ [=](PyDialects &self, std::string attrName) {
+ MlirDialect dialect =
+ self.getDialectForKey(attrName, /*attrError=*/true);
+ nb::object descriptor =
+ nb::cast(PyDialectDescriptor{self.getContext(), dialect});
+ return createCustomDialectWrapper(attrName, std::move(descriptor));
+ },
+ "Gets a dialect by name using attribute notation.");
//----------------------------------------------------------------------------
// Mapping of PyDialect
//----------------------------------------------------------------------------
nb::class_<PyDialect>(m, "Dialect")
- .def(nb::init<nb::object>(), nb::arg("descriptor"))
- .def_prop_ro("descriptor",
- [](PyDialect &self) { return self.getDescriptor(); })
+ .def(nb::init<nb::object>(), nb::arg("descriptor"),
+ "Creates a Dialect from a DialectDescriptor.")
+ .def_prop_ro(
+ "descriptor", [](PyDialect &self) { return self.getDescriptor(); },
+ "Returns the DialectDescriptor for this dialect.")
.def(
"__repr__",
[](const nb::object &self) {
@@ -3181,31 +3197,43 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::str(" (class ") + clazz.attr("__module__") +
nb::str(".") + clazz.attr("__name__") + nb::str(")>");
},
- nb::sig("def __repr__(self) -> str"));
+ nb::sig("def __repr__(self) -> str"),
+ "Returns a string representation of the dialect.");
//----------------------------------------------------------------------------
// Mapping of PyDialectRegistry
//----------------------------------------------------------------------------
nb::class_<PyDialectRegistry>(m, "DialectRegistry")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyDialectRegistry::getCapsule)
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyDialectRegistry::getCapsule,
+ "Gets a capsule wrapping the MlirDialectRegistry.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR,
- &PyDialectRegistry::createFromCapsule)
- .def(nb::init<>());
+ &PyDialectRegistry::createFromCapsule,
+ "Creates a DialectRegistry from a capsule wrapping "
+ "MlirDialectRegistry.")
+ .def(nb::init<>(), "Creates a new empty dialect registry.");
//----------------------------------------------------------------------------
// Mapping of Location
//----------------------------------------------------------------------------
nb::class_<PyLocation>(m, "Location")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyLocation::getCapsule)
- .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyLocation::createFromCapsule)
- .def("__enter__", &PyLocation::contextEnter)
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyLocation::getCapsule,
+ "Gets a capsule wrapping the MlirLocation.")
+ .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyLocation::createFromCapsule,
+ "Creates a Location from a capsule wrapping MlirLocation.")
+ .def("__enter__", &PyLocation::contextEnter,
+ "Enters the location as a context manager.")
.def("__exit__", &PyLocation::contextExit, nb::arg("exc_type").none(),
- nb::arg("exc_value").none(), nb::arg("traceback").none())
- .def("__eq__",
- [](PyLocation &self, PyLocation &other) -> bool {
- return mlirLocationEqual(self, other);
- })
- .def("__eq__", [](PyLocation &self, nb::object other) { return false; })
+ nb::arg("exc_value").none(), nb::arg("traceback").none(),
+ "Exits the location context manager.")
+ .def(
+ "__eq__",
+ [](PyLocation &self, PyLocation &other) -> bool {
+ return mlirLocationEqual(self, other);
+ },
+ "Compares two locations for equality.")
+ .def(
+ "__eq__", [](PyLocation &self, nb::object other) { return false; },
+ "Compares location with non-location object (always returns False).")
.def_prop_ro_static(
"current",
[](nb::object & /*class*/) -> std::optional<PyLocation *> {
@@ -3217,7 +3245,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
// clang-format off
nb::sig("def current(/) -> Location | None"),
// clang-format on
- "Gets the Location bound to the current thread or raises ValueError")
+ "Gets the Location bound to the current thread or raises ValueError.")
.def_static(
"unknown",
[](DefaultingPyMlirContext context) {
@@ -3225,13 +3253,13 @@ void mlir::python::populateIRCore(nb::module_ &m) {
mlirLocationUnknownGet(context->get()));
},
nb::arg("context") = nb::none(),
- "Gets a Location representing an unknown location")
+ "Gets a Location representing an unknown location.")
.def_static(
"callsite",
[](PyLocation callee, const std::vector<PyLocation> &frames,
DefaultingPyMlirContext context) {
if (frames.empty())
- throw nb::value_error("No caller frames provided");
+ throw nb::value_error("No caller frames provided.");
MlirLocation caller = frames.back().get();
for (const PyLocation &frame :
llvm::reverse(llvm::ArrayRef(frames).drop_back()))
@@ -3240,18 +3268,23 @@ void mlir::python::populateIRCore(nb::module_ &m) {
mlirLocationCallSiteGet(callee.get(), caller));
},
nb::arg("callee"), nb::arg("frames"), nb::arg("context") = nb::none(),
- kContextGetCallSiteLocationDocstring)
- .def("is_a_callsite", mlirLocationIsACallSite)
- .def_prop_ro("callee",
- [](PyLocation &self) {
- return PyLocation(self.getContext(),
- mlirLocationCallSiteGetCallee(self));
- })
- .def_prop_ro("caller",
- [](PyLocation &self) {
- return PyLocation(self.getContext(),
- mlirLocationCallSiteGetCaller(self));
- })
+ "Gets a Location representing a caller and callsite.")
+ .def("is_a_callsite", mlirLocationIsACallSite,
+ "Returns True if this location is a CallSiteLoc.")
+ .def_prop_ro(
+ "callee",
+ [](PyLocation &self) {
+ return PyLocation(self.getContext(),
+ mlirLocationCallSiteGetCallee(self));
+ },
+ "Gets the callee location from a CallSiteLoc.")
+ .def_prop_ro(
+ "caller",
+ [](PyLocation &self) {
+ return PyLocation(self.getContext(),
+ mlirLocationCallSiteGetCaller(self));
+ },
+ "Gets the caller location from a CallSiteLoc.")
.def_static(
"file",
[](std::string filename, int line, int col,
@@ -3262,7 +3295,8 @@ void mlir::python::populateIRCore(nb::module_ &m) {
context->get(), toMlirStringRef(filename), line, col));
},
nb::arg("filename"), nb::arg("line"), nb::arg("col"),
- nb::arg("context") = nb::none(), kContextGetFileLocationDocstring)
+ nb::arg("context") = nb::none(),
+ "Gets a Location representing a file, line and column.")
.def_static(
"file",
[](std::string filename, int startLine, int startCol, int endLine,
@@ -3274,17 +3308,25 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
nb::arg("filename"), nb::arg("start_line"), nb::arg("start_col"),
nb::arg("end_line"), nb::arg("end_col"),
- nb::arg("context") = nb::none(), kContextGetFileRangeDocstring)
- .def("is_a_file", mlirLocationIsAFileLineColRange)
- .def_prop_ro("filename",
- [](MlirLocation loc) {
- return mlirIdentifierStr(
- mlirLocationFileLineColRangeGetFilename(loc));
- })
- .def_prop_ro("start_line", mlirLocationFileLineColRangeGetStartLine)
- .def_prop_ro("start_col", mlirLocationFileLineColRangeGetStartColumn)
- .def_prop_ro("end_line", mlirLocationFileLineColRangeGetEndLine)
- .def_prop_ro("end_col", mlirLocationFileLineColRangeGetEndColumn)
+ nb::arg("context") = nb::none(),
+ "Gets a Location representing a file, line and column range.")
+ .def("is_a_file", mlirLocationIsAFileLineColRange,
+ "Returns True if this location is a FileLineColLoc.")
+ .def_prop_ro(
+ "filename",
+ [](MlirLocation loc) {
+ return mlirIdentifierStr(
+ mlirLocationFileLineColRangeGetFilename(loc));
+ },
+ "Gets the filename from a FileLineColLoc.")
+ .def_prop_ro("start_line", mlirLocationFileLineColRangeGetStartLine,
+ "Gets the start line number from a FileLineColLoc.")
+ .def_prop_ro("start_col", mlirLocationFileLineColRangeGetStartColumn,
+ "Gets the start column number from a FileLineColLoc.")
+ .def_prop_ro("end_line", mlirLocationFileLineColRangeGetEndLine,
+ "Gets the end line number from a FileLineColLoc.")
+ .def_prop_ro("end_col", mlirLocationFileLineColRangeGetEndColumn,
+ "Gets the end column number from a FileLineColLoc.")
.def_static(
"fused",
[](const std::vector<PyLocation> &pyLocations,
@@ -3300,8 +3342,11 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return PyLocation(context->getRef(), location);
},
nb::arg("locations"), nb::arg("metadata") = nb::none(),
- nb::arg("context") = nb::none(), kContextGetFusedLocationDocstring)
- .def("is_a_fused", mlirLocationIsAFused)
+ nb::arg("context") = nb::none(),
+ "Gets a Location representing a fused location with optional "
+ "metadata.")
+ .def("is_a_fused", mlirLocationIsAFused,
+ "Returns True if this location is a FusedLoc.")
.def_prop_ro(
"locations",
[](PyLocation &self) {
@@ -3314,7 +3359,8 @@ void mlir::python::populateIRCore(nb::module_ &m) {
for (unsigned i = 0; i < numLocations; ++i)
pyLocations.emplace_back(self.getContext(), locations[i]);
return pyLocations;
- })
+ },
+ "Gets the list of locations from a FusedLoc.")
.def_static(
"name",
[](std::string name, std::optional<PyLocation> childLoc,
@@ -3327,17 +3373,24 @@ void mlir::python::populateIRCore(nb::module_ &m) {
: mlirLocationUnknownGet(context->get())));
},
nb::arg("name"), nb::arg("childLoc") = nb::none(),
- nb::arg("context") = nb::none(), kContextGetNameLocationDocString)
- .def("is_a_name", mlirLocationIsAName)
- .def_prop_ro("name_str",
- [](MlirLocation loc) {
- return mlirIdentifierStr(mlirLocationNameGetName(loc));
- })
- .def_prop_ro("child_loc",
- [](PyLocation &self) {
- return PyLocation(self.getContext(),
- mlirLocationNameGetChildLoc(self));
- })
+ nb::arg("context") = nb::none(),
+ "Gets a Location representing a named location with optional child "
+ "location.")
+ .def("is_a_name", mlirLocationIsAName,
+ "Returns True if this location is a NameLoc.")
+ .def_prop_ro(
+ "name_str",
+ [](MlirLocation loc) {
+ return mlirIdentifierStr(mlirLocationNameGetName(loc));
+ },
+ "Gets the name string from a NameLoc.")
+ .def_prop_ro(
+ "child_loc",
+ [](PyLocation &self) {
+ return PyLocation(self.getContext(),
+ mlirLocationNameGetChildLoc(self));
+ },
+ "Gets the child location from a NameLoc.")
.def_static(
"from_attr",
[](PyAttribute &attribute, DefaultingPyMlirContext context) {
@@ -3345,41 +3398,59 @@ void mlir::python::populateIRCore(nb::module_ &m) {
mlirLocationFromAttribute(attribute));
},
nb::arg("attribute"), nb::arg("context") = nb::none(),
- "Gets a Location from a LocationAttr")
+ "Gets a Location from a LocationAttr.")
.def_prop_ro(
"context",
[](PyLocation &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that owns the Location")
+ "Context that owns the Location.")
.def_prop_ro(
"attr",
[](PyLocation &self) {
return PyAttribute(self.getContext(),
mlirLocationGetAttribute(self));
},
- "Get the underlying LocationAttr")
+ "Get the underlying LocationAttr.")
.def(
"emit_error",
[](PyLocation &self, std::string message) {
mlirEmitError(self, message.c_str());
},
- nb::arg("message"), "Emits an error at this location")
- .def("__repr__", [](PyLocation &self) {
- PyPrintAccumulator printAccum;
- mlirLocationPrint(self, printAccum.getCallback(),
- printAccum.getUserData());
- return printAccum.join();
- });
+ nb::arg("message"),
+ R"(
+ Emits an error diagnostic at this location.
+
+ Args:
+ message: The error message to emit.)")
+ .def(
+ "__repr__",
+ [](PyLocation &self) {
+ PyPrintAccumulator printAccum;
+ mlirLocationPrint(self, printAccum.getCallback(),
+ printAccum.getUserData());
+ return printAccum.join();
+ },
+ "Returns the assembly representation of the location.");
//----------------------------------------------------------------------------
// Mapping of Module
//----------------------------------------------------------------------------
nb::class_<PyModule>(m, "Module", nb::is_weak_referenceable())
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyModule::getCapsule)
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyModule::getCapsule,
+ "Gets a capsule wrapping the MlirModule.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyModule::createFromCapsule,
- kModuleCAPICreate)
- .def("_clear_mlir_module", &PyModule::clearMlirModule)
+ R"(
+ Creates a Module from a MlirModule wrapped by a capsule (i.e. module._CAPIPtr).
+
+ This returns a new object **BUT** _clear_mlir_module(module) must be called to
+ prevent double-frees (of the underlying mlir::Module).)")
+ .def("_clear_mlir_module", &PyModule::clearMlirModule,
+ R"(
+ Clears the internal MLIR module reference.
+
+ This is used internally to prevent double-free when ownership is transferred
+ via the C API capsule mechanism. Not intended for normal use.)")
.def_static(
"parse",
[](const std::string &moduleAsm, DefaultingPyMlirContext context)
@@ -3427,13 +3498,13 @@ void mlir::python::populateIRCore(nb::module_ &m) {
MlirModule module = mlirModuleCreateEmpty(pyLoc.get());
return PyModule::forModule(module).releaseObject();
},
- nb::arg("loc") = nb::none(), "Creates an empty module")
+ nb::arg("loc") = nb::none(), "Creates an empty module.")
.def_prop_ro(
"context",
[](PyModule &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that created the Module")
+ "Context that created the Module.")
.def_prop_ro(
"operation",
[](PyModule &self) -> nb::typed<nb::object, PyOperation> {
@@ -3442,7 +3513,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
self.getRef().releaseObject())
.releaseObject();
},
- "Accesses the module as an operation")
+ "Accesses the module as an operation.")
.def_prop_ro(
"body",
[](PyModule &self) {
@@ -3452,7 +3523,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
PyBlock returnBlock(moduleOp, mlirModuleGetBody(self.get()));
return returnBlock;
},
- "Return the block for this module")
+ "Return the block for this module.")
.def(
"dump",
[](PyModule &self) {
@@ -3465,39 +3536,59 @@ void mlir::python::populateIRCore(nb::module_ &m) {
// Defer to the operation's __str__.
return self.attr("operation").attr("__str__")();
},
- nb::sig("def __str__(self) -> str"), kOperationStrDunderDocstring)
+ nb::sig("def __str__(self) -> str"),
+ R"(
+ Gets the assembly form of the operation with default options.
+
+ If more advanced control over the assembly formatting or I/O options is needed,
+ use the dedicated print or get_asm method, which supports keyword arguments to
+ customize behavior.
+ )")
.def(
"__eq__",
[](PyModule &self, PyModule &other) {
return mlirModuleEqual(self.get(), other.get());
},
- "other"_a)
- .def("__hash__",
- [](PyModule &self) { return mlirModuleHashValue(self.get()); });
+ "other"_a, "Compares two modules for equality.")
+ .def(
+ "__hash__",
+ [](PyModule &self) { return mlirModuleHashValue(self.get()); },
+ "Returns the hash value of the module.");
//----------------------------------------------------------------------------
// Mapping of Operation.
//----------------------------------------------------------------------------
nb::class_<PyOperationBase>(m, "_OperationBase")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR,
- [](PyOperationBase &self) {
- return self.getOperation().getCapsule();
- })
- .def("__eq__",
- [](PyOperationBase &self, PyOperationBase &other) {
- return mlirOperationEqual(self.getOperation().get(),
- other.getOperation().get());
- })
- .def("__eq__",
- [](PyOperationBase &self, nb::object other) { return false; })
- .def("__hash__",
- [](PyOperationBase &self) {
- return mlirOperationHashValue(self.getOperation().get());
- })
- .def_prop_ro("attributes",
- [](PyOperationBase &self) {
- return PyOpAttributeMap(self.getOperation().getRef());
- })
+ .def_prop_ro(
+ MLIR_PYTHON_CAPI_PTR_ATTR,
+ [](PyOperationBase &self) {
+ return self.getOperation().getCapsule();
+ },
+ "Gets a capsule wrapping the MlirOperation.")
+ .def(
+ "__eq__",
+ [](PyOperationBase &self, PyOperationBase &other) {
+ return mlirOperationEqual(self.getOperation().get(),
+ other.getOperation().get());
+ },
+ "Compares two operations for equality.")
+ .def(
+ "__eq__",
+ [](PyOperationBase &self, nb::object other) { return false; },
+ "Compares operation with non-operation object (always returns "
+ "False).")
+ .def(
+ "__hash__",
+ [](PyOperationBase &self) {
+ return mlirOperationHashValue(self.getOperation().get());
+ },
+ "Returns the hash value of the operation.")
+ .def_prop_ro(
+ "attributes",
+ [](PyOperationBase &self) {
+ return PyOpAttributeMap(self.getOperation().getRef());
+ },
+ "Returns a dictionary-like map of operation attributes.")
.def_prop_ro(
"context",
[](PyOperationBase &self) -> nb::typed<nb::object, PyMlirContext> {
@@ -3505,22 +3596,28 @@ void mlir::python::populateIRCore(nb::module_ &m) {
concreteOperation.checkValid();
return concreteOperation.getContext().getObject();
},
- "Context that owns the Operation")
- .def_prop_ro("name",
- [](PyOperationBase &self) {
- auto &concreteOperation = self.getOperation();
- concreteOperation.checkValid();
- MlirOperation operation = concreteOperation.get();
- return mlirIdentifierStr(mlirOperationGetName(operation));
- })
- .def_prop_ro("operands",
- [](PyOperationBase &self) {
- return PyOpOperandList(self.getOperation().getRef());
- })
- .def_prop_ro("regions",
- [](PyOperationBase &self) {
- return PyRegionList(self.getOperation().getRef());
- })
+ "Context that owns the Operation.")
+ .def_prop_ro(
+ "name",
+ [](PyOperationBase &self) {
+ auto &concreteOperation = self.getOperation();
+ concreteOperation.checkValid();
+ MlirOperation operation = concreteOperation.get();
+ return mlirIdentifierStr(mlirOperationGetName(operation));
+ },
+ "Returns the fully qualified name of the operation.")
+ .def_prop_ro(
+ "operands",
+ [](PyOperationBase &self) {
+ return PyOpOperandList(self.getOperation().getRef());
+ },
+ "Returns the list of operation operands.")
+ .def_prop_ro(
+ "regions",
+ [](PyOperationBase &self) {
+ return PyRegionList(self.getOperation().getRef());
+ },
+ "Returns the list of operation regions.")
.def_prop_ro(
"results",
[](PyOperationBase &self) {
@@ -3551,14 +3648,16 @@ void mlir::python::populateIRCore(nb::module_ &m) {
"defined or derived from."),
nb::for_setter("Sets the source location the operation was defined "
"or derived from."))
- .def_prop_ro("parent",
- [](PyOperationBase &self)
- -> std::optional<nb::typed<nb::object, PyOperation>> {
- auto parent = self.getOperation().getParentOperation();
- if (parent)
- return parent->getObject();
- return {};
- })
+ .def_prop_ro(
+ "parent",
+ [](PyOperationBase &self)
+ -> std::optional<nb::typed<nb::object, PyOperation>> {
+ auto parent = self.getOperation().getParentOperation();
+ if (parent)
+ return parent->getObject();
+ return {};
+ },
+ "Returns the parent operation, or None if at top level.")
.def(
"__str__",
[](PyOperationBase &self) {
@@ -3579,7 +3678,14 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::overload_cast<PyAsmState &, nb::object, bool>(
&PyOperationBase::print),
nb::arg("state"), nb::arg("file") = nb::none(),
- nb::arg("binary") = false, kOperationPrintStateDocstring)
+ nb::arg("binary") = false,
+ R"(
+ Prints the assembly form of the operation to a file like object.
+
+ Args:
+ state: AsmState capturing the operation numbering and flags.
+ file: Optional file like object to write to. Defaults to sys.stdout.
+ binary: Whether to write bytes (True) or str (False). Defaults to False.)")
.def("print",
nb::overload_cast<std::optional<int64_t>, std::optional<int64_t>,
bool, bool, bool, bool, bool, bool, nb::object,
@@ -3594,10 +3700,47 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::arg("use_name_loc_as_prefix") = false,
nb::arg("assume_verified") = false, nb::arg("file") = nb::none(),
nb::arg("binary") = false, nb::arg("skip_regions") = false,
- kOperationPrintDocstring)
+ R"(
+ Prints the assembly form of the operation to a file like object.
+
+ Args:
+ large_elements_limit: Whether to elide elements attributes above this
+ number of elements. Defaults to None (no limit).
+ large_resource_limit: Whether to elide resource attributes above this
+ number of characters. Defaults to None (no limit). If large_elements_limit
+ is set and this is None, the behavior will be to use large_elements_limit
+ as large_resource_limit.
+ enable_debug_info: Whether to print debug/location information. Defaults
+ to False.
+ pretty_debug_info: Whether to format debug information for easier reading
+ by a human (warning: the result is unparseable). Defaults to False.
+ print_generic_op_form: Whether to print the generic assembly forms of all
+ ops. Defaults to False.
+ use_local_scope: Whether to print in a way that is more optimized for
+ multi-threaded access but may not be consistent with how the overall
+ module prints.
+ use_name_loc_as_prefix: Whether to use location attributes (NameLoc) as
+ prefixes for the SSA identifiers. Defaults to False.
+ assume_verified: By default, if not printing generic form, the verifier
+ will be run and if it fails, generic form will be printed with a comment
+ about failed verification. While a reasonable default for interactive use,
+ for systematic use, it is often better for the caller to verify explicitly
+ and report failures in a more robust fashion. Set this to True if doing this
+ in order to avoid running a redundant verification. If the IR is actually
+ invalid, behavior is undefined.
+ file: The file like object to write to. Defaults to sys.stdout.
+ binary: Whether to write bytes (True) or str (False). Defaults to False.
+ skip_regions: Whether to skip printing regions. Defaults to False.)")
.def("write_bytecode", &PyOperationBase::writeBytecode, nb::arg("file"),
nb::arg("desired_version") = nb::none(),
- kOperationPrintBytecodeDocstring)
+ R"(
+ Write the bytecode form of the operation to a file like object.
+
+ Args:
+ file: The file like object to write to.
+ desired_version: Optional version of bytecode to emit.
+ Returns:
+ The bytecode writer status.)")
.def("get_asm", &PyOperationBase::getAsm,
// Careful: Lots of arguments must match up with get_asm method.
nb::arg("binary") = false,
@@ -3609,7 +3752,17 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::arg("use_local_scope") = false,
nb::arg("use_name_loc_as_prefix") = false,
nb::arg("assume_verified") = false, nb::arg("skip_regions") = false,
- kOperationGetAsmDocstring)
+ R"(
+ Gets the assembly form of the operation with all options available.
+
+ Args:
+ binary: Whether to return a bytes (True) or str (False) object. Defaults to
+ False.
+ ... others ...: See the print() method for common keyword arguments for
+ configuring the printout.
+ Returns:
+ Either a bytes or str object, depending on the setting of the 'binary'
+ argument.)")
.def("verify", &PyOperationBase::verify,
"Verify the operation. Raises MLIRError if verification fails, and "
"returns true otherwise.")
@@ -3621,18 +3774,31 @@ void mlir::python::populateIRCore(nb::module_ &m) {
"block.")
.def("is_before_in_block", &PyOperationBase::isBeforeInBlock,
nb::arg("other"),
- "Given an operation 'other' that is within the same parent block, "
- "return"
- "whether the current operation is before 'other' in the operation "
- "list"
- "of the parent block.")
+ R"(
+ Checks if this operation is before another in the same block.
+
+ Args:
+ other: Another operation in the same parent block.
+
+ Returns:
+ True if this operation is before 'other' in the operation list of the parent block.)")
.def(
"clone",
[](PyOperationBase &self,
const nb::object &ip) -> nb::typed<nb::object, PyOperation> {
return self.getOperation().clone(ip);
},
- nb::arg("ip") = nb::none())
+ nb::arg("ip") = nb::none(),
+ R"(
+ Creates a deep copy of the operation.
+
+ Args:
+ ip: Optional insertion point where the cloned operation should be inserted.
+ If None, the current insertion point is used. If False, the operation
+ remains detached.
+
+ Returns:
+ A new Operation that is a clone of this operation.)")
.def(
"detach_from_parent",
[](PyOperationBase &self) -> nb::typed<nb::object, PyOpView> {
@@ -3653,13 +3819,24 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return operation.isAttached();
},
"Reports if the operation is attached to its parent block.")
- .def("erase", [](PyOperationBase &self) { self.getOperation().erase(); })
+ .def(
+ "erase", [](PyOperationBase &self) { self.getOperation().erase(); },
+ R"(
+ Erases the operation and frees its memory.
+
+ Note:
+ After erasing, any Python references to the operation become invalid.)")
.def("walk", &PyOperationBase::walk, nb::arg("callback"),
nb::arg("walk_order") = MlirWalkPostOrder,
// clang-format off
- nb::sig("def walk(self, callback: Callable[[Operation], WalkResult], walk_order: WalkOrder) -> None")
+ nb::sig("def walk(self, callback: Callable[[Operation], WalkResult], walk_order: WalkOrder) -> None"),
// clang-format on
- );
+ R"(
+ Walks the operation tree with a callback function.
+
+ Args:
+ callback: A callable that takes an Operation and returns a WalkResult.
+ walk_order: The order of traversal (PRE_ORDER or POST_ORDER).)");
nb::class_<PyOperation, PyOperationBase>(m, "Operation")
.def_static(
@@ -3692,7 +3869,22 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::arg("operands") = nb::none(), nb::arg("attributes") = nb::none(),
nb::arg("successors") = nb::none(), nb::arg("regions") = 0,
nb::arg("loc") = nb::none(), nb::arg("ip") = nb::none(),
- nb::arg("infer_type") = false, kOperationCreateDocstring)
+ nb::arg("infer_type") = false,
+ R"(
+ Creates a new operation.
+
+ Args:
+ name: Operation name (e.g. "dialect.operation").
+ results: Optional sequence of Type representing op result types.
+ operands: Optional operands of the operation.
+ attributes: Optional Dict of {str: Attribute}.
+ successors: Optional List of Block for the operation's successors.
+ regions: Number of regions to create (default = 0).
+ location: Optional Location object (defaults to resolve from context manager).
+ ip: Optional InsertionPoint (defaults to resolve from context manager or set to False to disable insertion, even with an insertion point set in the context manager).
+ infer_type: Whether to infer result types (default = False).
+ Returns:
+ A new "detached" Operation object. Detached operations can be added to blocks, which causes them to become "attached.")")
.def_static(
"parse",
[](const std::string &sourceStr, const std::string &sourceName,
@@ -3705,18 +3897,30 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::arg("context") = nb::none(),
"Parses an operation. Supports both text assembly format and binary "
"bytecode format.")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyOperation::getCapsule)
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyOperation::getCapsule,
+ "Gets a capsule wrapping the MlirOperation.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR,
- &PyOperation::createFromCapsule)
- .def_prop_ro("operation",
- [](nb::object self) -> nb::typed<nb::object, PyOperation> {
- return self;
- })
- .def_prop_ro("opview",
- [](PyOperation &self) -> nb::typed<nb::object, PyOpView> {
- return self.createOpView();
- })
- .def_prop_ro("block", &PyOperation::getBlock)
+ &PyOperation::createFromCapsule,
+ "Creates an Operation from a capsule wrapping MlirOperation.")
+ .def_prop_ro(
+ "operation",
+ [](nb::object self) -> nb::typed<nb::object, PyOperation> {
+ return self;
+ },
+ "Returns self (the operation).")
+ .def_prop_ro(
+ "opview",
+ [](PyOperation &self) -> nb::typed<nb::object, PyOpView> {
+ return self.createOpView();
+ },
+ R"(
+ Returns an OpView of this operation.
+
+ Note:
+ If the operation has a registered and loaded dialect then this OpView will
+ be concrete wrapper class.)")
+ .def_prop_ro("block", &PyOperation::getBlock,
+ "Returns the block containing this operation.")
.def_prop_ro(
"successors",
[](PyOperationBase &self) {
@@ -3830,7 +4034,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
nb::arg("cls"), nb::arg("source"), nb::kw_only(),
nb::arg("source_name") = "", nb::arg("context") = nb::none(),
- "Parses a specific, generated OpView based on class level attributes");
+ "Parses a specific, generated OpView based on class level attributes.");
//----------------------------------------------------------------------------
// Mapping of PyRegion.
@@ -3856,17 +4060,22 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return PyBlockIterator(self.getParentOperation(), firstBlock);
},
"Iterates over blocks in the region.")
- .def("__eq__",
- [](PyRegion &self, PyRegion &other) {
- return self.get().ptr == other.get().ptr;
- })
- .def("__eq__", [](PyRegion &self, nb::object &other) { return false; });
+ .def(
+ "__eq__",
+ [](PyRegion &self, PyRegion &other) {
+ return self.get().ptr == other.get().ptr;
+ },
+ "Compares two regions for pointer equality.")
+ .def(
+ "__eq__", [](PyRegion &self, nb::object &other) { return false; },
+ "Compares region with non-region object (always returns False).");
//----------------------------------------------------------------------------
// Mapping of PyBlock.
//----------------------------------------------------------------------------
nb::class_<PyBlock>(m, "Block")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyBlock::getCapsule)
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyBlock::getCapsule,
+ "Gets a capsule wrapping the MlirBlock.")
.def_prop_ro(
"owner",
[](PyBlock &self) -> nb::typed<nb::object, PyOpView> {
@@ -3893,14 +4102,26 @@ void mlir::python::populateIRCore(nb::module_ &m) {
mlirBlockAddArgument(self.get(), type, loc));
},
"type"_a, "loc"_a,
- "Append an argument of the specified type to the block and returns "
- "the newly added argument.")
+ R"(
+ Appends an argument of the specified type to the block.
+
+ Args:
+ type: The type of the argument to add.
+ loc: The source location for the argument.
+
+ Returns:
+ The newly added block argument.)")
.def(
"erase_argument",
[](PyBlock &self, unsigned index) {
return mlirBlockEraseArgument(self.get(), index);
},
- "Erase the argument at 'index' and remove it from the argument list.")
+ nb::arg("index"),
+ R"(
+ Erases the argument at the specified index.
+
+ Args:
+ index: The index of the argument to erase.)")
.def_prop_ro(
"operations",
[](PyBlock &self) {
@@ -3928,7 +4149,14 @@ void mlir::python::populateIRCore(nb::module_ &m) {
mlirBlockDetach(b);
mlirRegionAppendOwnedBlock(region.get(), b);
},
- "Append this block to a region, transferring ownership if necessary")
+ nb::arg("region"),
+ R"(
+ Appends this block to a region.
+
+ Transfers ownership if the block is currently owned by another region.
+
+ Args:
+ region: The region to append the block to.)")
.def(
"create_before",
[](PyBlock &self, const nb::args &pyArgTypes,
@@ -3969,15 +4197,21 @@ void mlir::python::populateIRCore(nb::module_ &m) {
firstOperation);
},
"Iterates over operations in the block.")
- .def("__eq__",
- [](PyBlock &self, PyBlock &other) {
- return self.get().ptr == other.get().ptr;
- })
- .def("__eq__", [](PyBlock &self, nb::object &other) { return false; })
- .def("__hash__",
- [](PyBlock &self) {
- return static_cast<size_t>(llvm::hash_value(self.get().ptr));
- })
+ .def(
+ "__eq__",
+ [](PyBlock &self, PyBlock &other) {
+ return self.get().ptr == other.get().ptr;
+ },
+ "Compares two blocks for pointer equality.")
+ .def(
+ "__eq__", [](PyBlock &self, nb::object &other) { return false; },
+ "Compares block with non-block object (always returns False).")
+ .def(
+ "__hash__",
+ [](PyBlock &self) {
+ return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+ },
+ "Returns the hash value of the block.")
.def(
"__str__",
[](PyBlock &self) {
@@ -4000,8 +4234,13 @@ void mlir::python::populateIRCore(nb::module_ &m) {
self.getParentOperation().getObject());
},
nb::arg("operation"),
- "Appends an operation to this block. If the operation is currently "
- "in another block, it will be moved.")
+ R"(
+ Appends an operation to this block.
+
+ If the operation is currently in another block, it will be moved.
+
+ Args:
+ operation: The operation to append to the block.)")
.def_prop_ro(
"successors",
[](PyBlock &self) {
@@ -4022,10 +4261,12 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::class_<PyInsertionPoint>(m, "InsertionPoint")
.def(nb::init<PyBlock &>(), nb::arg("block"),
"Inserts after the last operation but still inside the block.")
- .def("__enter__", &PyInsertionPoint::contextEnter)
+ .def("__enter__", &PyInsertionPoint::contextEnter,
+ "Enters the insertion point as a context manager.")
.def("__exit__", &PyInsertionPoint::contextExit,
nb::arg("exc_type").none(), nb::arg("exc_value").none(),
- nb::arg("traceback").none())
+ nb::arg("traceback").none(),
+ "Exits the insertion point context manager.")
.def_prop_ro_static(
"current",
[](nb::object & /*class*/) {
@@ -4036,17 +4277,47 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
nb::sig("def current(/) -> InsertionPoint"),
"Gets the InsertionPoint bound to the current thread or raises "
- "ValueError if none has been set")
+ "ValueError if none has been set.")
.def(nb::init<PyOperationBase &>(), nb::arg("beforeOperation"),
"Inserts before a referenced operation.")
.def_static("at_block_begin", &PyInsertionPoint::atBlockBegin,
- nb::arg("block"), "Inserts at the beginning of the block.")
+ nb::arg("block"),
+ R"(
+ Creates an insertion point at the beginning of a block.
+
+ Args:
+ block: The block at whose beginning operations should be inserted.
+
+ Returns:
+ An InsertionPoint at the block's beginning.)")
.def_static("at_block_terminator", &PyInsertionPoint::atBlockTerminator,
- nb::arg("block"), "Inserts before the block terminator.")
+ nb::arg("block"),
+ R"(
+ Creates an insertion point before a block's terminator.
+
+ Args:
+ block: The block whose terminator to insert before.
+
+ Returns:
+ An InsertionPoint before the terminator.
+
+ Raises:
+ ValueError: If the block has no terminator.)")
.def_static("after", &PyInsertionPoint::after, nb::arg("operation"),
- "Inserts after the operation.")
+ R"(
+ Creates an insertion point immediately after an operation.
+
+ Args:
+ operation: The operation after which to insert.
+
+ Returns:
+ An InsertionPoint after the operation.)")
.def("insert", &PyInsertionPoint::insert, nb::arg("operation"),
- "Inserts an operation.")
+ R"(
+ Inserts an operation at this insertion point.
+
+ Args:
+ operation: The operation to insert.)")
.def_prop_ro(
"block", [](PyInsertionPoint &self) { return self.getBlock(); },
"Returns the block that this InsertionPoint points to.")
@@ -4061,7 +4332,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
"The reference operation before which new operations are "
"inserted, or None if the insertion point is at the end of "
- "the block");
+ "the block.");
//----------------------------------------------------------------------------
// Mapping of PyAttribute.
@@ -4070,10 +4341,12 @@ void mlir::python::populateIRCore(nb::module_ &m) {
// Delegate to the PyAttribute copy constructor, which will also lifetime
// extend the backing context which owns the MlirAttribute.
.def(nb::init<PyAttribute &>(), nb::arg("cast_from_type"),
- "Casts the passed attribute to the generic Attribute")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyAttribute::getCapsule)
+ "Casts the passed attribute to the generic Attribute.")
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyAttribute::getCapsule,
+ "Gets a capsule wrapping the MlirAttribute.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR,
- &PyAttribute::createFromCapsule)
+ &PyAttribute::createFromCapsule,
+ "Creates an Attribute from a capsule wrapping MlirAttribute.")
.def_static(
"parse",
[](const std::string &attrSpec, DefaultingPyMlirContext context)
@@ -4093,26 +4366,42 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyAttribute &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that owns the Attribute")
- .def_prop_ro("type",
- [](PyAttribute &self) -> nb::typed<nb::object, PyType> {
- return PyType(self.getContext(),
- mlirAttributeGetType(self))
- .maybeDownCast();
- })
+ "Context that owns the Attribute.")
+ .def_prop_ro(
+ "type",
+ [](PyAttribute &self) -> nb::typed<nb::object, PyType> {
+ return PyType(self.getContext(), mlirAttributeGetType(self))
+ .maybeDownCast();
+ },
+ "Returns the type of the attribute.")
.def(
"get_named",
[](PyAttribute &self, std::string name) {
return PyNamedAttribute(self, std::move(name));
},
- nb::keep_alive<0, 1>(), "Binds a name to the attribute")
- .def("__eq__",
- [](PyAttribute &self, PyAttribute &other) { return self == other; })
- .def("__eq__", [](PyAttribute &self, nb::object &other) { return false; })
- .def("__hash__",
- [](PyAttribute &self) {
- return static_cast<size_t>(llvm::hash_value(self.get().ptr));
- })
+ nb::keep_alive<0, 1>(),
+ R"(
+ Binds a name to the attribute, creating a NamedAttribute.
+
+ Args:
+ name: The name to bind to the attribute.
+
+ Returns:
+ A NamedAttribute with the given name and this attribute.)")
+ .def(
+ "__eq__",
+ [](PyAttribute &self, PyAttribute &other) { return self == other; },
+ "Compares two attributes for equality.")
+ .def(
+ "__eq__", [](PyAttribute &self, nb::object &other) { return false; },
+ "Compares attribute with non-attribute object (always returns "
+ "False).")
+ .def(
+ "__hash__",
+ [](PyAttribute &self) {
+ return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+ },
+ "Returns the hash value of the attribute.")
.def(
"dump", [](PyAttribute &self) { mlirAttributeDump(self); },
kDumpDocstring)
@@ -4125,61 +4414,69 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return printAccum.join();
},
"Returns the assembly form of the Attribute.")
- .def("__repr__",
- [](PyAttribute &self) {
- // Generally, assembly formats are not printed for __repr__ because
- // this can cause exceptionally long debug output and exceptions.
- // However, attribute values are generally considered useful and
- // are printed. This may need to be re-evaluated if debug dumps end
- // up being excessive.
- PyPrintAccumulator printAccum;
- printAccum.parts.append("Attribute(");
- mlirAttributePrint(self, printAccum.getCallback(),
- printAccum.getUserData());
- printAccum.parts.append(")");
- return printAccum.join();
- })
- .def_prop_ro("typeid",
- [](PyAttribute &self) {
- MlirTypeID mlirTypeID = mlirAttributeGetTypeID(self);
- assert(!mlirTypeIDIsNull(mlirTypeID) &&
- "mlirTypeID was expected to be non-null.");
- return PyTypeID(mlirTypeID);
- })
- .def(MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
- [](PyAttribute &self) -> nb::typed<nb::object, PyAttribute> {
- return self.maybeDownCast();
- });
+ .def(
+ "__repr__",
+ [](PyAttribute &self) {
+ // Generally, assembly formats are not printed for __repr__ because
+ // this can cause exceptionally long debug output and exceptions.
+ // However, attribute values are generally considered useful and
+ // are printed. This may need to be re-evaluated if debug dumps end
+ // up being excessive.
+ PyPrintAccumulator printAccum;
+ printAccum.parts.append("Attribute(");
+ mlirAttributePrint(self, printAccum.getCallback(),
+ printAccum.getUserData());
+ printAccum.parts.append(")");
+ return printAccum.join();
+ },
+ "Returns a string representation of the attribute.")
+ .def_prop_ro(
+ "typeid",
+ [](PyAttribute &self) {
+ MlirTypeID mlirTypeID = mlirAttributeGetTypeID(self);
+ assert(!mlirTypeIDIsNull(mlirTypeID) &&
+ "mlirTypeID was expected to be non-null.");
+ return PyTypeID(mlirTypeID);
+ },
+ "Returns the TypeID of the attribute.")
+ .def(
+ MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
+ [](PyAttribute &self) -> nb::typed<nb::object, PyAttribute> {
+ return self.maybeDownCast();
+ },
+ "Downcasts the attribute to a more specific attribute if possible.");
//----------------------------------------------------------------------------
// Mapping of PyNamedAttribute
//----------------------------------------------------------------------------
nb::class_<PyNamedAttribute>(m, "NamedAttribute")
- .def("__repr__",
- [](PyNamedAttribute &self) {
- PyPrintAccumulator printAccum;
- printAccum.parts.append("NamedAttribute(");
- printAccum.parts.append(
- nb::str(mlirIdentifierStr(self.namedAttr.name).data,
- mlirIdentifierStr(self.namedAttr.name).length));
- printAccum.parts.append("=");
- mlirAttributePrint(self.namedAttr.attribute,
- printAccum.getCallback(),
- printAccum.getUserData());
- printAccum.parts.append(")");
- return printAccum.join();
- })
+ .def(
+ "__repr__",
+ [](PyNamedAttribute &self) {
+ PyPrintAccumulator printAccum;
+ printAccum.parts.append("NamedAttribute(");
+ printAccum.parts.append(
+ nb::str(mlirIdentifierStr(self.namedAttr.name).data,
+ mlirIdentifierStr(self.namedAttr.name).length));
+ printAccum.parts.append("=");
+ mlirAttributePrint(self.namedAttr.attribute,
+ printAccum.getCallback(),
+ printAccum.getUserData());
+ printAccum.parts.append(")");
+ return printAccum.join();
+ },
+ "Returns a string representation of the named attribute.")
.def_prop_ro(
"name",
[](PyNamedAttribute &self) {
return mlirIdentifierStr(self.namedAttr.name);
},
- "The name of the NamedAttribute binding")
+ "The name of the NamedAttribute binding.")
.def_prop_ro(
"attr",
[](PyNamedAttribute &self) { return self.namedAttr.attribute; },
nb::keep_alive<0, 1>(), nb::sig("def attr(self) -> Attribute"),
- "The underlying generic attribute of the NamedAttribute binding");
+ "The underlying generic attribute of the NamedAttribute binding.");
//----------------------------------------------------------------------------
// Mapping of PyType.
@@ -4188,9 +4485,11 @@ void mlir::python::populateIRCore(nb::module_ &m) {
// Delegate to the PyType copy constructor, which will also lifetime
// extend the backing context which owns the MlirType.
.def(nb::init<PyType &>(), nb::arg("cast_from_type"),
- "Casts the passed type to the generic Type")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyType::getCapsule)
- .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyType::createFromCapsule)
+ "Casts the passed type to the generic Type.")
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyType::getCapsule,
+ "Gets a capsule wrapping the MlirType.")
+ .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyType::createFromCapsule,
+ "Creates a Type from a capsule wrapping MlirType.")
.def_static(
"parse",
[](std::string typeSpec,
@@ -4203,21 +4502,31 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return PyType(context.get()->getRef(), type).maybeDownCast();
},
nb::arg("asm"), nb::arg("context") = nb::none(),
- kContextParseTypeDocstring)
+ R"(
+ Parses the assembly form of a type.
+
+ Returns a Type object or raises an MLIRError if the type cannot be parsed.
+
+ See also: https://mlir.llvm.org/docs/LangRef/#type-system)")
.def_prop_ro(
"context",
[](PyType &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that owns the Type")
- .def("__eq__", [](PyType &self, PyType &other) { return self == other; })
+ "Context that owns the Type.")
+ .def(
+ "__eq__", [](PyType &self, PyType &other) { return self == other; },
+ "Compares two types for equality.")
.def(
"__eq__", [](PyType &self, nb::object &other) { return false; },
- nb::arg("other").none())
- .def("__hash__",
- [](PyType &self) {
- return static_cast<size_t>(llvm::hash_value(self.get().ptr));
- })
+ nb::arg("other").none(),
+ "Compares type with non-type object (always returns False).")
+ .def(
+ "__hash__",
+ [](PyType &self) {
+ return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+ },
+ "Returns the hash value of the type.")
.def(
"dump", [](PyType &self) { mlirTypeDump(self); }, kDumpDocstring)
.def(
@@ -4229,59 +4538,79 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return printAccum.join();
},
"Returns the assembly form of the type.")
- .def("__repr__",
- [](PyType &self) {
- // Generally, assembly formats are not printed for __repr__ because
- // this can cause exceptionally long debug output and exceptions.
- // However, types are an exception as they typically have compact
- // assembly forms and printing them is useful.
- PyPrintAccumulator printAccum;
- printAccum.parts.append("Type(");
- mlirTypePrint(self, printAccum.getCallback(),
- printAccum.getUserData());
- printAccum.parts.append(")");
- return printAccum.join();
- })
- .def(MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
- [](PyType &self) -> nb::typed<nb::object, PyType> {
- return self.maybeDownCast();
- })
- .def_prop_ro("typeid", [](PyType &self) {
- MlirTypeID mlirTypeID = mlirTypeGetTypeID(self);
- if (!mlirTypeIDIsNull(mlirTypeID))
- return PyTypeID(mlirTypeID);
- auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(self)));
- throw nb::value_error(
- (origRepr + llvm::Twine(" has no typeid.")).str().c_str());
- });
+ .def(
+ "__repr__",
+ [](PyType &self) {
+ // Generally, assembly formats are not printed for __repr__ because
+ // this can cause exceptionally long debug output and exceptions.
+ // However, types are an exception as they typically have compact
+ // assembly forms and printing them is useful.
+ PyPrintAccumulator printAccum;
+ printAccum.parts.append("Type(");
+ mlirTypePrint(self, printAccum.getCallback(),
+ printAccum.getUserData());
+ printAccum.parts.append(")");
+ return printAccum.join();
+ },
+ "Returns a string representation of the Type.")
+ .def(
+ MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
+ [](PyType &self) -> nb::typed<nb::object, PyType> {
+ return self.maybeDownCast();
+ },
+ "Downcasts the Type to a more specific Type if possible.")
+ .def_prop_ro(
+ "typeid",
+ [](PyType &self) {
+ MlirTypeID mlirTypeID = mlirTypeGetTypeID(self);
+ if (!mlirTypeIDIsNull(mlirTypeID))
+ return PyTypeID(mlirTypeID);
+ auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(self)));
+ throw nb::value_error(
+ (origRepr + llvm::Twine(" has no typeid.")).str().c_str());
+ },
+ "Returns the TypeID of the Type, or raises ValueError if Type has no "
+ "TypeID.");
//----------------------------------------------------------------------------
// Mapping of PyTypeID.
//----------------------------------------------------------------------------
nb::class_<PyTypeID>(m, "TypeID")
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyTypeID::getCapsule)
- .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyTypeID::createFromCapsule)
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyTypeID::getCapsule,
+ "Gets a capsule wrapping the MlirTypeID.")
+ .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyTypeID::createFromCapsule,
+ "Creates a TypeID from a capsule wrapping MlirTypeID.")
// Note, this tests whether the underlying TypeIDs are the same,
// not whether the wrapper MlirTypeIDs are the same, nor whether
// the Python objects are the same (i.e., PyTypeID is a value type).
- .def("__eq__",
- [](PyTypeID &self, PyTypeID &other) { return self == other; })
- .def("__eq__",
- [](PyTypeID &self, const nb::object &other) { return false; })
+ .def(
+ "__eq__",
+ [](PyTypeID &self, PyTypeID &other) { return self == other; },
+ "Compares two TypeIDs for equality.")
+ .def(
+ "__eq__",
+ [](PyTypeID &self, const nb::object &other) { return false; },
+ "Compares TypeID with non-TypeID object (always returns False).")
// Note, this gives the hash value of the underlying TypeID, not the
// hash value of the Python object, nor the hash value of the
// MlirTypeID wrapper.
- .def("__hash__", [](PyTypeID &self) {
- return static_cast<size_t>(mlirTypeIDHashValue(self));
- });
+ .def(
+ "__hash__",
+ [](PyTypeID &self) {
+ return static_cast<size_t>(mlirTypeIDHashValue(self));
+ },
+ "Returns the hash value of the TypeID.");
//----------------------------------------------------------------------------
// Mapping of Value.
//----------------------------------------------------------------------------
nb::class_<PyValue>(m, "Value")
- .def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(), nb::arg("value"))
- .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyValue::getCapsule)
- .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyValue::createFromCapsule)
+ .def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(), nb::arg("value"),
+ "Creates a Value reference from another Value.")
+ .def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyValue::getCapsule,
+ "Gets a capsule wrapping the MlirValue.")
+ .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyValue::createFromCapsule,
+ "Creates a Value from a capsule wrapping MlirValue.")
.def_prop_ro(
"context",
[](PyValue &self) -> nb::typed<nb::object, PyMlirContext> {
@@ -4312,23 +4641,29 @@ void mlir::python::populateIRCore(nb::module_ &m) {
assert(false && "Value must be a block argument or an op result");
return nb::none();
},
- // clang-format off
- nb::sig("def owner(self) -> Operation | Block | None"))
- // clang-format on
- .def_prop_ro("uses",
- [](PyValue &self) {
- return PyOpOperandIterator(
- mlirValueGetFirstUse(self.get()));
- })
- .def("__eq__",
- [](PyValue &self, PyValue &other) {
- return self.get().ptr == other.get().ptr;
- })
- .def("__eq__", [](PyValue &self, nb::object other) { return false; })
- .def("__hash__",
- [](PyValue &self) {
- return static_cast<size_t>(llvm::hash_value(self.get().ptr));
- })
+ "Returns the owner of the value (Operation for results, Block for "
+ "arguments).")
+ .def_prop_ro(
+ "uses",
+ [](PyValue &self) {
+ return PyOpOperandIterator(mlirValueGetFirstUse(self.get()));
+ },
+ "Returns an iterator over uses of this value.")
+ .def(
+ "__eq__",
+ [](PyValue &self, PyValue &other) {
+ return self.get().ptr == other.get().ptr;
+ },
+ "Compares two values for pointer equality.")
+ .def(
+ "__eq__", [](PyValue &self, nb::object other) { return false; },
+ "Compares value with non-value object (always returns False).")
+ .def(
+ "__hash__",
+ [](PyValue &self) {
+ return static_cast<size_t>(llvm::hash_value(self.get().ptr));
+ },
+ "Returns the hash value of the value.")
.def(
"__str__",
[](PyValue &self) {
@@ -4339,7 +4674,13 @@ void mlir::python::populateIRCore(nb::module_ &m) {
printAccum.parts.append(")");
return printAccum.join();
},
- kValueDunderStrDocstring)
+ R"(
+ Returns the string form of the value.
+
+ If the value is a block argument, this is the assembly form of its type and the
+ position in the argument list. If the value is an operation result, this is
+ equivalent to printing the operation that produced it.
+ )")
.def(
"get_name",
[](PyValue &self, bool useLocalScope, bool useNameLocAsPrefix) {
@@ -4359,7 +4700,16 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return printAccum.join();
},
nb::arg("use_local_scope") = false,
- nb::arg("use_name_loc_as_prefix") = false)
+ nb::arg("use_name_loc_as_prefix") = false,
+ R"(
+ Returns the string form of value as an operand.
+
+ Args:
+ use_local_scope: Whether to use local scope for naming.
+ use_name_loc_as_prefix: Whether to use the location attribute (NameLoc) as prefix.
+
+ Returns:
+ The value's name as it appears in IR (e.g., %0, %arg0).)")
.def(
"get_name",
[](PyValue &self, PyAsmState &state) {
@@ -4370,25 +4720,29 @@ void mlir::python::populateIRCore(nb::module_ &m) {
printAccum.getUserData());
return printAccum.join();
},
- nb::arg("state"), kGetNameAsOperand)
- .def_prop_ro("type",
- [](PyValue &self) -> nb::typed<nb::object, PyType> {
- return PyType(self.getParentOperation()->getContext(),
- mlirValueGetType(self.get()))
- .maybeDownCast();
- })
+ nb::arg("state"),
+ "Returns the string form of value as an operand (i.e., the ValueID).")
+ .def_prop_ro(
+ "type",
+ [](PyValue &self) -> nb::typed<nb::object, PyType> {
+ return PyType(self.getParentOperation()->getContext(),
+ mlirValueGetType(self.get()))
+ .maybeDownCast();
+ },
+ "Returns the type of the value.")
.def(
"set_type",
[](PyValue &self, const PyType &type) {
- return mlirValueSetType(self.get(), type);
+ mlirValueSetType(self.get(), type);
},
- nb::arg("type"))
+ nb::arg("type"), "Sets the type of the value.")
.def(
"replace_all_uses_with",
[](PyValue &self, PyValue &with) {
mlirValueReplaceAllUsesOfWith(self.get(), with.get());
},
- kValueReplaceAllUsesWithDocstring)
+ "Replace all uses of value with the new value, updating anything in "
+ "the IR that uses 'self' to use the other value instead.")
.def(
"replace_all_uses_except",
[](PyValue &self, PyValue &with, PyOperation &exception) {
@@ -4434,10 +4788,12 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
nb::arg("with_"), nb::arg("exceptions"),
kValueReplaceAllUsesExceptDocstring)
- .def(MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
- [](PyValue &self) -> nb::typed<nb::object, PyValue> {
- return self.maybeDownCast();
- })
+ .def(
+ MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
+ [](PyValue &self) -> nb::typed<nb::object, PyValue> {
+ return self.maybeDownCast();
+ },
+ "Downcasts the Value to a more specific kind if possible.")
.def_prop_ro(
"location",
[](MlirValue self) {
@@ -4445,7 +4801,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
PyMlirContext::forContext(mlirValueGetContext(self)),
mlirValueGetLocation(self));
},
- "Returns the source location the value");
+ "Returns the source location of the value.");
PyBlockArgument::bind(m);
PyOpResult::bind(m);
@@ -4453,43 +4809,105 @@ void mlir::python::populateIRCore(nb::module_ &m) {
nb::class_<PyAsmState>(m, "AsmState")
.def(nb::init<PyValue &, bool>(), nb::arg("value"),
- nb::arg("use_local_scope") = false)
+ nb::arg("use_local_scope") = false,
+ R"(
+ Creates an AsmState for consistent SSA value naming.
+
+ Args:
+ value: The value to create state for.
+ use_local_scope: Whether to use local scope for naming.)")
.def(nb::init<PyOperationBase &, bool>(), nb::arg("op"),
- nb::arg("use_local_scope") = false);
+ nb::arg("use_local_scope") = false,
+ R"(
+ Creates an AsmState for consistent SSA value naming.
+
+ Args:
+ op: The operation to create state for.
+ use_local_scope: Whether to use local scope for naming.)");
//----------------------------------------------------------------------------
// Mapping of SymbolTable.
//----------------------------------------------------------------------------
nb::class_<PySymbolTable>(m, "SymbolTable")
- .def(nb::init<PyOperationBase &>())
- .def("__getitem__",
- [](PySymbolTable &self,
- const std::string &name) -> nb::typed<nb::object, PyOpView> {
- return self.dunderGetItem(name);
- })
- .def("insert", &PySymbolTable::insert, nb::arg("operation"))
- .def("erase", &PySymbolTable::erase, nb::arg("operation"))
- .def("__delitem__", &PySymbolTable::dunderDel)
- .def("__contains__",
- [](PySymbolTable &table, const std::string &name) {
- return !mlirOperationIsNull(mlirSymbolTableLookup(
- table, mlirStringRefCreate(name.data(), name.length())));
- })
+ .def(nb::init<PyOperationBase &>(),
+ R"(
+ Creates a symbol table for an operation.
+
+ Args:
+ operation: The Operation that defines a symbol table (e.g., a Module).
+
+ Raises:
+ TypeError: If the operation is not a symbol table.)")
+ .def(
+ "__getitem__",
+ [](PySymbolTable &self,
+ const std::string &name) -> nb::typed<nb::object, PyOpView> {
+ return self.dunderGetItem(name);
+ },
+ R"(
+ Looks up a symbol by name in the symbol table.
+
+ Args:
+ name: The name of the symbol to look up.
+
+ Returns:
+ The operation defining the symbol.
+
+ Raises:
+ KeyError: If the symbol is not found.)")
+ .def("insert", &PySymbolTable::insert, nb::arg("operation"),
+ R"(
+ Inserts a symbol operation into the symbol table.
+
+ Args:
+ operation: An operation with a symbol name to insert.
+
+ Returns:
+ The symbol name attribute of the inserted operation.
+
+ Raises:
+ ValueError: If the operation does not have a symbol name.)")
+ .def("erase", &PySymbolTable::erase, nb::arg("operation"),
+ R"(
+ Erases a symbol operation from the symbol table.
+
+ Args:
+ operation: The symbol operation to erase.
+
+ Note:
+ The operation is also erased from the IR and invalidated.)")
+ .def("__delitem__", &PySymbolTable::dunderDel,
+ "Deletes a symbol by name from the symbol table.")
+ .def(
+ "__contains__",
+ [](PySymbolTable &table, const std::string &name) {
+ return !mlirOperationIsNull(mlirSymbolTableLookup(
+ table, mlirStringRefCreate(name.data(), name.length())));
+ },
+ "Checks if a symbol with the given name exists in the table.")
// Static helpers.
.def_static("set_symbol_name", &PySymbolTable::setSymbolName,
- nb::arg("symbol"), nb::arg("name"))
+ nb::arg("symbol"), nb::arg("name"),
+ "Sets the symbol name for a symbol operation.")
.def_static("get_symbol_name", &PySymbolTable::getSymbolName,
- nb::arg("symbol"))
+ nb::arg("symbol"),
+ "Gets the symbol name from a symbol operation.")
.def_static("get_visibility", &PySymbolTable::getVisibility,
- nb::arg("symbol"))
+ nb::arg("symbol"),
+ "Gets the visibility attribute of a symbol operation.")
.def_static("set_visibility", &PySymbolTable::setVisibility,
- nb::arg("symbol"), nb::arg("visibility"))
+ nb::arg("symbol"), nb::arg("visibility"),
+ "Sets the visibility attribute of a symbol operation.")
.def_static("replace_all_symbol_uses",
&PySymbolTable::replaceAllSymbolUses, nb::arg("old_symbol"),
- nb::arg("new_symbol"), nb::arg("from_op"))
+ nb::arg("new_symbol"), nb::arg("from_op"),
+ "Replaces all uses of a symbol with a new symbol name within "
+ "the given operation.")
.def_static("walk_symbol_tables", &PySymbolTable::walkSymbolTables,
nb::arg("from_op"), nb::arg("all_sym_uses_visible"),
- nb::arg("callback"));
+ nb::arg("callback"),
+ "Walks symbol tables starting from an operation with a "
+ "callback function.");
// Container bindings.
PyBlockArgumentList::bind(m);
>From 482b715e8fe317fda01083f2502eb06d082f5179 Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Mon, 10 Nov 2025 05:55:28 -0800
Subject: [PATCH 2/3] Update mlir/lib/Bindings/Python/IRCore.cpp
Co-authored-by: Copilot <175728472+Copilot at users.noreply.github.com>
---
mlir/lib/Bindings/Python/IRCore.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index cb9bd4c82aa9f..f1d19f608979f 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -45,7 +45,7 @@ static const char kDumpDocstring[] =
static const char kValueReplaceAllUsesExceptDocstring[] =
R"(Replace all uses of this value with the `with` value, except for those
-in `exceptions`. 'exceptions' can be either a single operation or a list of
+in `exceptions`. `exceptions` can be either a single operation or a list of
operations.
)";
>From 63972ba4c762af0f77606b17d5370953b65b4883 Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Mon, 10 Nov 2025 07:36:31 -0800
Subject: [PATCH 3/3] fix backticks
---
mlir/lib/Bindings/Python/IRCore.cpp | 134 ++++++++++++++--------------
1 file changed, 68 insertions(+), 66 deletions(-)
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index f1d19f608979f..d90f27bd037e6 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -2714,7 +2714,7 @@ class PyOpAttributeMap {
});
return out;
},
- "Returns a list of (name, attribute) tuples.");
+ "Returns a list of `(name, attribute)` tuples.");
}
private:
@@ -3017,7 +3017,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
"Gets a container for accessing dialects by name.")
.def_prop_ro(
"d", [](PyMlirContext &self) { return PyDialects(self.getRef()); },
- "Alias for 'dialects'.")
+ "Alias for `dialects`.")
.def(
"get_dialect_descriptor",
[=](PyMlirContext &self, std::string &name) {
@@ -3209,7 +3209,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR,
&PyDialectRegistry::createFromCapsule,
"Creates a DialectRegistry from a capsule wrapping "
- "MlirDialectRegistry.")
+ "`MlirDialectRegistry`.")
.def(nb::init<>(), "Creates a new empty dialect registry.");
//----------------------------------------------------------------------------
@@ -3320,13 +3320,13 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
"Gets the filename from a FileLineColLoc.")
.def_prop_ro("start_line", mlirLocationFileLineColRangeGetStartLine,
- "Gets the start line number from a FileLineColLoc.")
+ "Gets the start line number from a `FileLineColLoc`.")
.def_prop_ro("start_col", mlirLocationFileLineColRangeGetStartColumn,
- "Gets the start column number from a FileLineColLoc.")
+ "Gets the start column number from a `FileLineColLoc`.")
.def_prop_ro("end_line", mlirLocationFileLineColRangeGetEndLine,
- "Gets the end line number from a FileLineColLoc.")
+ "Gets the end line number from a `FileLineColLoc`.")
.def_prop_ro("end_col", mlirLocationFileLineColRangeGetEndColumn,
- "Gets the end column number from a FileLineColLoc.")
+ "Gets the end column number from a `FileLineColLoc`.")
.def_static(
"fused",
[](const std::vector<PyLocation> &pyLocations,
@@ -3346,7 +3346,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
"Gets a Location representing a fused location with optional "
"metadata.")
.def("is_a_fused", mlirLocationIsAFused,
- "Returns True if this location is a FusedLoc.")
+ "Returns True if this location is a `FusedLoc`.")
.def_prop_ro(
"locations",
[](PyLocation &self) {
@@ -3360,7 +3360,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
pyLocations.emplace_back(self.getContext(), locations[i]);
return pyLocations;
},
- "Gets the list of locations from a FusedLoc.")
+ "Gets the list of locations from a `FusedLoc`.")
.def_static(
"name",
[](std::string name, std::optional<PyLocation> childLoc,
@@ -3377,20 +3377,20 @@ void mlir::python::populateIRCore(nb::module_ &m) {
"Gets a Location representing a named location with optional child "
"location.")
.def("is_a_name", mlirLocationIsAName,
- "Returns True if this location is a NameLoc.")
+ "Returns True if this location is a `NameLoc`.")
.def_prop_ro(
"name_str",
[](MlirLocation loc) {
return mlirIdentifierStr(mlirLocationNameGetName(loc));
},
- "Gets the name string from a NameLoc.")
+ "Gets the name string from a `NameLoc`.")
.def_prop_ro(
"child_loc",
[](PyLocation &self) {
return PyLocation(self.getContext(),
mlirLocationNameGetChildLoc(self));
},
- "Gets the child location from a NameLoc.")
+ "Gets the child location from a `NameLoc`.")
.def_static(
"from_attr",
[](PyAttribute &attribute, DefaultingPyMlirContext context) {
@@ -3398,20 +3398,20 @@ void mlir::python::populateIRCore(nb::module_ &m) {
mlirLocationFromAttribute(attribute));
},
nb::arg("attribute"), nb::arg("context") = nb::none(),
- "Gets a Location from a LocationAttr.")
+ "Gets a Location from a `LocationAttr`.")
.def_prop_ro(
"context",
[](PyLocation &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that owns the Location.")
+ "Context that owns the `Location`.")
.def_prop_ro(
"attr",
[](PyLocation &self) {
return PyAttribute(self.getContext(),
mlirLocationGetAttribute(self));
},
- "Get the underlying LocationAttr.")
+ "Get the underlying `LocationAttr`.")
.def(
"emit_error",
[](PyLocation &self, std::string message) {
@@ -3441,10 +3441,10 @@ void mlir::python::populateIRCore(nb::module_ &m) {
"Gets a capsule wrapping the MlirModule.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyModule::createFromCapsule,
R"(
- Creates a Module from a MlirModule wrapped by a capsule (i.e. module._CAPIPtr).
+ Creates a Module from a `MlirModule` wrapped by a capsule (i.e. `module._CAPIPtr`).
- This returns a new object **BUT** _clear_mlir_module(module) must be called to
- prevent double-frees (of the underlying mlir::Module).)")
+ This returns a new object **BUT** `_clear_mlir_module(module)` must be called to
+ prevent double-frees (of the underlying `mlir::Module`).)")
.def("_clear_mlir_module", &PyModule::clearMlirModule,
R"(
Clears the internal MLIR module reference.
@@ -3504,7 +3504,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyModule &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that created the Module.")
+ "Context that created the `Module`.")
.def_prop_ro(
"operation",
[](PyModule &self) -> nb::typed<nb::object, PyOperation> {
@@ -3564,7 +3564,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyOperationBase &self) {
return self.getOperation().getCapsule();
},
- "Gets a capsule wrapping the MlirOperation.")
+ "Gets a capsule wrapping the `MlirOperation`.")
.def(
"__eq__",
[](PyOperationBase &self, PyOperationBase &other) {
@@ -3596,7 +3596,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
concreteOperation.checkValid();
return concreteOperation.getContext().getObject();
},
- "Context that owns the Operation.")
+ "Context that owns the operation.")
.def_prop_ro(
"name",
[](PyOperationBase &self) {
@@ -3657,7 +3657,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return parent->getObject();
return {};
},
- "Returns the parent operation, or None if at top level.")
+ "Returns the parent operation, or `None` if at top level.")
.def(
"__str__",
[](PyOperationBase &self) {
@@ -3683,9 +3683,9 @@ void mlir::python::populateIRCore(nb::module_ &m) {
Prints the assembly form of the operation to a file like object.
Args:
- state: AsmState capturing the operation numbering and flags.
+ state: `AsmState` capturing the operation numbering and flags.
file: Optional file like object to write to. Defaults to sys.stdout.
- binary: Whether to write bytes (True) or str (False). Defaults to False.)")
+ binary: Whether to write `bytes` (True) or `str` (False). Defaults to False.)")
.def("print",
nb::overload_cast<std::optional<int64_t>, std::optional<int64_t>,
bool, bool, bool, bool, bool, bool, nb::object,
@@ -3761,7 +3761,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
... others ...: See the print() method for common keyword arguments for
configuring the printout.
Returns:
- Either a bytes or str object, depending on the setting of the 'binary'
+ Either a bytes or str object, depending on the setting of the `binary`
argument.)")
.def("verify", &PyOperationBase::verify,
"Verify the operation. Raises MLIRError if verification fails, and "
@@ -3781,7 +3781,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
other: Another operation in the same parent block.
Returns:
- True if this operation is before 'other' in the operation list of the parent block.)")
+ True if this operation is before `other` in the operation list of the parent block.)")
.def(
"clone",
[](PyOperationBase &self,
@@ -3874,7 +3874,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
Creates a new operation.
Args:
- name: Operation name (e.g. "dialect.operation").
+ name: Operation name (e.g. `dialect.operation`).
results: Optional sequence of Type representing op result types.
operands: Optional operands of the operation.
attributes: Optional Dict of {str: Attribute}.
@@ -3884,7 +3884,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
ip: Optional InsertionPoint (defaults to resolve from context manager or set to False to disable insertion, even with an insertion point set in the context manager).
infer_type: Whether to infer result types (default = False).
Returns:
- A new "detached" Operation object. Detached operations can be added to blocks, which causes them to become "attached.")")
+ A new detached Operation object. Detached operations can be added to blocks, which causes them to become attached.)")
.def_static(
"parse",
[](const std::string &sourceStr, const std::string &sourceName,
@@ -4320,7 +4320,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
operation: The operation to insert.)")
.def_prop_ro(
"block", [](PyInsertionPoint &self) { return self.getBlock(); },
- "Returns the block that this InsertionPoint points to.")
+ "Returns the block that this `InsertionPoint` points to.")
.def_prop_ro(
"ref_operation",
[](PyInsertionPoint &self)
@@ -4341,12 +4341,12 @@ void mlir::python::populateIRCore(nb::module_ &m) {
// Delegate to the PyAttribute copy constructor, which will also lifetime
// extend the backing context which owns the MlirAttribute.
.def(nb::init<PyAttribute &>(), nb::arg("cast_from_type"),
- "Casts the passed attribute to the generic Attribute.")
+ "Casts the passed attribute to the generic `Attribute`.")
.def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyAttribute::getCapsule,
"Gets a capsule wrapping the MlirAttribute.")
- .def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR,
- &PyAttribute::createFromCapsule,
- "Creates an Attribute from a capsule wrapping MlirAttribute.")
+ .def_static(
+ MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAttribute::createFromCapsule,
+ "Creates an Attribute from a capsule wrapping `MlirAttribute`.")
.def_static(
"parse",
[](const std::string &attrSpec, DefaultingPyMlirContext context)
@@ -4359,21 +4359,21 @@ void mlir::python::populateIRCore(nb::module_ &m) {
return PyAttribute(context.get()->getRef(), attr).maybeDownCast();
},
nb::arg("asm"), nb::arg("context") = nb::none(),
- "Parses an attribute from an assembly form. Raises an MLIRError on "
+ "Parses an attribute from an assembly form. Raises an `MLIRError` on "
"failure.")
.def_prop_ro(
"context",
[](PyAttribute &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that owns the Attribute.")
+ "Context that owns the `Attribute`.")
.def_prop_ro(
"type",
[](PyAttribute &self) -> nb::typed<nb::object, PyType> {
return PyType(self.getContext(), mlirAttributeGetType(self))
.maybeDownCast();
},
- "Returns the type of the attribute.")
+ "Returns the type of the `Attribute`.")
.def(
"get_named",
[](PyAttribute &self, std::string name) {
@@ -4381,13 +4381,13 @@ void mlir::python::populateIRCore(nb::module_ &m) {
},
nb::keep_alive<0, 1>(),
R"(
- Binds a name to the attribute, creating a NamedAttribute.
+ Binds a name to the attribute, creating a `NamedAttribute`.
Args:
- name: The name to bind to the attribute.
+ name: The name to bind to the `Attribute`.
Returns:
- A NamedAttribute with the given name and this attribute.)")
+ A `NamedAttribute` with the given name and this attribute.)")
.def(
"__eq__",
[](PyAttribute &self, PyAttribute &other) { return self == other; },
@@ -4438,7 +4438,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
"mlirTypeID was expected to be non-null.");
return PyTypeID(mlirTypeID);
},
- "Returns the TypeID of the attribute.")
+ "Returns the `TypeID` of the attribute.")
.def(
MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
[](PyAttribute &self) -> nb::typed<nb::object, PyAttribute> {
@@ -4471,12 +4471,12 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyNamedAttribute &self) {
return mlirIdentifierStr(self.namedAttr.name);
},
- "The name of the NamedAttribute binding.")
+ "The name of the `NamedAttribute` binding.")
.def_prop_ro(
"attr",
[](PyNamedAttribute &self) { return self.namedAttr.attribute; },
nb::keep_alive<0, 1>(), nb::sig("def attr(self) -> Attribute"),
- "The underlying generic attribute of the NamedAttribute binding.");
+ "The underlying generic attribute of the `NamedAttribute` binding.");
//----------------------------------------------------------------------------
// Mapping of PyType.
@@ -4485,11 +4485,11 @@ void mlir::python::populateIRCore(nb::module_ &m) {
// Delegate to the PyType copy constructor, which will also lifetime
// extend the backing context which owns the MlirType.
.def(nb::init<PyType &>(), nb::arg("cast_from_type"),
- "Casts the passed type to the generic Type.")
+ "Casts the passed type to the generic `Type`.")
.def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyType::getCapsule,
- "Gets a capsule wrapping the MlirType.")
+ "Gets a capsule wrapping the `MlirType`.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyType::createFromCapsule,
- "Creates a Type from a capsule wrapping MlirType.")
+ "Creates a Type from a capsule wrapping `MlirType`.")
.def_static(
"parse",
[](std::string typeSpec,
@@ -4505,7 +4505,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
R"(
Parses the assembly form of a type.
- Returns a Type object or raises an MLIRError if the type cannot be parsed.
+ Returns a Type object or raises an `MLIRError` if the type cannot be parsed.
See also: https://mlir.llvm.org/docs/LangRef/#type-system)")
.def_prop_ro(
@@ -4513,7 +4513,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyType &self) -> nb::typed<nb::object, PyMlirContext> {
return self.getContext().getObject();
},
- "Context that owns the Type.")
+ "Context that owns the `Type`.")
.def(
"__eq__", [](PyType &self, PyType &other) { return self == other; },
"Compares two types for equality.")
@@ -4526,7 +4526,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyType &self) {
return static_cast<size_t>(llvm::hash_value(self.get().ptr));
},
- "Returns the hash value of the type.")
+ "Returns the hash value of the `Type`.")
.def(
"dump", [](PyType &self) { mlirTypeDump(self); }, kDumpDocstring)
.def(
@@ -4537,7 +4537,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
printAccum.getUserData());
return printAccum.join();
},
- "Returns the assembly form of the type.")
+ "Returns the assembly form of the `Type`.")
.def(
"__repr__",
[](PyType &self) {
@@ -4552,13 +4552,13 @@ void mlir::python::populateIRCore(nb::module_ &m) {
printAccum.parts.append(")");
return printAccum.join();
},
- "Returns a string representation of the Type.")
+ "Returns a string representation of the `Type`.")
.def(
MLIR_PYTHON_MAYBE_DOWNCAST_ATTR,
[](PyType &self) -> nb::typed<nb::object, PyType> {
return self.maybeDownCast();
},
- "Downcasts the Type to a more specific Type if possible.")
+ "Downcasts the Type to a more specific `Type` if possible.")
.def_prop_ro(
"typeid",
[](PyType &self) {
@@ -4569,24 +4569,25 @@ void mlir::python::populateIRCore(nb::module_ &m) {
throw nb::value_error(
(origRepr + llvm::Twine(" has no typeid.")).str().c_str());
},
- "Returns the TypeID of the Type, or raises ValueError if Type has no "
- "TypeID.");
+ "Returns the `TypeID` of the `Type`, or raises `ValueError` if "
+ "`Type` has no "
+ "`TypeID`.");
//----------------------------------------------------------------------------
// Mapping of PyTypeID.
//----------------------------------------------------------------------------
nb::class_<PyTypeID>(m, "TypeID")
.def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyTypeID::getCapsule,
- "Gets a capsule wrapping the MlirTypeID.")
+ "Gets a capsule wrapping the `MlirTypeID`.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyTypeID::createFromCapsule,
- "Creates a TypeID from a capsule wrapping MlirTypeID.")
+ "Creates a `TypeID` from a capsule wrapping `MlirTypeID`.")
// Note, this tests whether the underlying TypeIDs are the same,
// not whether the wrapper MlirTypeIDs are the same, nor whether
// the Python objects are the same (i.e., PyTypeID is a value type).
.def(
"__eq__",
[](PyTypeID &self, PyTypeID &other) { return self == other; },
- "Compares two TypeIDs for equality.")
+ "Compares two `TypeID`s for equality.")
.def(
"__eq__",
[](PyTypeID &self, const nb::object &other) { return false; },
@@ -4599,18 +4600,18 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyTypeID &self) {
return static_cast<size_t>(mlirTypeIDHashValue(self));
},
- "Returns the hash value of the TypeID.");
+ "Returns the hash value of the `TypeID`.");
//----------------------------------------------------------------------------
// Mapping of Value.
//----------------------------------------------------------------------------
nb::class_<PyValue>(m, "Value")
.def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(), nb::arg("value"),
- "Creates a Value reference from another Value.")
+ "Creates a Value reference from another `Value`.")
.def_prop_ro(MLIR_PYTHON_CAPI_PTR_ATTR, &PyValue::getCapsule,
- "Gets a capsule wrapping the MlirValue.")
+ "Gets a capsule wrapping the `MlirValue`.")
.def_static(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyValue::createFromCapsule,
- "Creates a Value from a capsule wrapping MlirValue.")
+ "Creates a `Value` from a capsule wrapping `MlirValue`.")
.def_prop_ro(
"context",
[](PyValue &self) -> nb::typed<nb::object, PyMlirContext> {
@@ -4641,7 +4642,8 @@ void mlir::python::populateIRCore(nb::module_ &m) {
assert(false && "Value must be a block argument or an op result");
return nb::none();
},
- "Returns the owner of the value (Operation for results, Block for "
+ "Returns the owner of the value (`Operation` for results, `Block` "
+ "for "
"arguments).")
.def_prop_ro(
"uses",
@@ -4709,7 +4711,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
use_name_loc_as_prefix: Whether to use the location attribute (NameLoc) as prefix.
Returns:
- The value's name as it appears in IR (e.g., %0, %arg0).)")
+ The value's name as it appears in IR (e.g., `%0`, `%arg0`).)")
.def(
"get_name",
[](PyValue &self, PyAsmState &state) {
@@ -4742,7 +4744,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
mlirValueReplaceAllUsesOfWith(self.get(), with.get());
},
"Replace all uses of value with the new value, updating anything in "
- "the IR that uses 'self' to use the other value instead.")
+ "the IR that uses `self` to use the other value instead.")
.def(
"replace_all_uses_except",
[](PyValue &self, PyValue &with, PyOperation &exception) {
@@ -4793,7 +4795,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
[](PyValue &self) -> nb::typed<nb::object, PyValue> {
return self.maybeDownCast();
},
- "Downcasts the Value to a more specific kind if possible.")
+ "Downcasts the `Value` to a more specific kind if possible.")
.def_prop_ro(
"location",
[](MlirValue self) {
@@ -4811,7 +4813,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
.def(nb::init<PyValue &, bool>(), nb::arg("value"),
nb::arg("use_local_scope") = false,
R"(
- Creates an AsmState for consistent SSA value naming.
+ Creates an `AsmState` for consistent SSA value naming.
Args:
value: The value to create state for.
@@ -4834,7 +4836,7 @@ void mlir::python::populateIRCore(nb::module_ &m) {
Creates a symbol table for an operation.
Args:
- operation: The Operation that defines a symbol table (e.g., a Module).
+ operation: The `Operation` that defines a symbol table (e.g., a `ModuleOp`).
Raises:
TypeError: If the operation is not a symbol table.)")
More information about the Mlir-commits
mailing list