30using namespace nb::literals;
35 R
"(Parses a module's assembly format from a string.
37Returns a new MlirModule or raises an MLIRError if the parsing fails.
39See also: https://mlir.llvm.org/docs/LangRef/
43 "Dumps a debug representation of the object to stderr.";
46 R
"(Replace all uses of this value with the `with` value, except for those
47in `exceptions`. `exceptions` can be either a single operation or a list of
57static size_t hash(
const T &value) {
58 return std::hash<T>{}(value);
63 nb::object dialectDescriptor) {
70 std::move(dialectDescriptor)));
74 return (*dialectClass)(std::move(dialectDescriptor));
81 const nb::typed<nb::sequence, PyType> &pyArgTypes,
82 const std::optional<nb::typed<nb::sequence, PyLocation>> &pyArgLocs) {
83 std::vector<MlirType> argTypes;
84 argTypes.reserve(nb::len(pyArgTypes));
85 for (nb::handle pyType : pyArgTypes)
87 nb::cast<python::MLIR_BINDINGS_PYTHON_DOMAIN::PyType &>(pyType));
89 std::vector<MlirLocation> argLocs;
91 argLocs.reserve(nb::len(*pyArgLocs));
92 for (nb::handle pyLoc : *pyArgLocs)
94 nb::cast<python::MLIR_BINDINGS_PYTHON_DOMAIN::PyLocation &>(pyLoc));
95 }
else if (!argTypes.empty()) {
101 if (argTypes.size() != argLocs.size())
102 throw nb::value_error(
103 join(
"Expected ", argTypes.size(),
" locations, got: ", argLocs.size())
105 return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
109 nb::ft_lock_guard lock(mutex);
114 nb::ft_lock_guard lock(mutex);
120 nb::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug")
125 [](
const std::string &type) {
126 nb::ft_lock_guard lock(mutex);
129 "types"_a,
"Sets specific debug types to be produced by LLVM.")
132 [](
const std::vector<std::string> &types) {
133 std::vector<const char *> pointers;
134 pointers.reserve(types.size());
135 for (
const std::string &str : types)
136 pointers.push_back(str.c_str());
137 nb::ft_lock_guard lock(mutex);
141 "Sets multiple specific debug types to be produced by LLVM.");
144nb::ft_mutex PyGlobalDebugFlag::mutex;
154 throw nb::key_error(attributeKind.c_str());
159 nb::callable
func,
bool replace,
160 bool allow_existing) {
162 replace, allow_existing);
166 nb::class_<PyAttrBuilderMap>(m,
"AttrBuilder")
169 "Checks whether an attribute builder is registered for the "
170 "given attribute kind.")
173 "Gets the registered attribute builder for the given "
176 "attribute_kind"_a,
"attr_builder"_a,
"replace"_a =
false,
177 "allow_existing"_a =
false,
178 "Register an attribute builder for building MLIR "
179 "attributes from Python values.");
200 operation(std::move(operation)) {}
202intptr_t PyRegionList::getRawNumElements() {
218 operation->checkValid();
220 PyErr_SetNone(PyExc_StopIteration);
225 PyBlock returnBlock(operation, next);
227 return nb::cast(returnBlock);
231 nb::class_<PyBlockIterator>(m,
"BlockIterator")
233 "Returns an iterator over the blocks in the operation's region.")
235 "Returns the next block in the iteration.");
239 operation->checkValid();
244 operation->checkValid();
260 throw nb::index_error(
"attempt to access out of bounds block");
265 return PyBlock(operation, block);
270 throw nb::index_error(
"attempt to access out of bounds block");
274 const std::optional<nb::sequence> &pyArgLocs) {
276 MlirBlock block =
createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
278 return PyBlock(operation, block);
282 nb::class_<PyBlockList>(m,
"BlockList")
284 "Returns the block at the specified index.")
286 "Returns an iterator over blocks in the operation's region.")
288 "Returns the number of blocks in the operation's region.")
291 Appends a new block, with argument types as positional args.
296 "args"_a, nb::kw_only(),
"arg_locs"_a = std::nullopt);
301 if (mlirOperationIsNull(next)) {
302 PyErr_SetNone(PyExc_StopIteration);
314 nb::class_<PyOperationIterator>(m,
"OperationIterator")
316 "Returns an iterator over the operations in an operation's block.")
318 "Returns the next operation in the iteration.");
322 parentOperation->checkValid();
331 while (!mlirOperationIsNull(childOp)) {
344 throw nb::index_error(
"attempt to access out of bounds operation");
347 while (!mlirOperationIsNull(childOp)) {
355 throw nb::index_error(
"attempt to access out of bounds operation");
359 nb::class_<PyOperationList>(m,
"OperationList")
361 "Returns the operation at the specified index.")
363 "Returns an iterator over operations in the list.")
365 "Returns the number of operations in the list.");
380 nb::class_<PyOpOperand>(m,
"OpOperand")
382 "Returns the operation that owns this operand.")
384 "Returns the operand number in the owning operation.");
389 PyErr_SetNone(PyExc_StopIteration);
396 return nb::cast(returnOpOperand);
400 nb::class_<PyOpOperandIterator>(m,
"OpOperandIterator")
402 "Returns an iterator over operands.")
404 "Returns the next operand in the iteration.");
423 std::stringstream ss;
424 ss << threadPool.ptr;
433 nb::gil_scoped_acquire acquire;
434 nb::ft_lock_guard lock(live_contexts_mutex);
435 auto &liveContexts = getLiveContexts();
436 liveContexts[context.ptr] =
this;
443 nb::gil_scoped_acquire acquire;
445 nb::ft_lock_guard lock(live_contexts_mutex);
446 getLiveContexts().erase(context.ptr);
462 throw nb::python_error();
467 nb::gil_scoped_acquire acquire;
468 nb::ft_lock_guard lock(live_contexts_mutex);
469 auto &liveContexts = getLiveContexts();
470 auto it = liveContexts.find(context.ptr);
471 if (it == liveContexts.end()) {
474 nb::object pyRef = nb::cast(unownedContextWrapper);
475 assert(pyRef &&
"cast to nb::object failed");
476 liveContexts[context.ptr] = unownedContextWrapper;
480 nb::object pyRef = nb::cast(it->second);
484nb::ft_mutex PyMlirContext::live_contexts_mutex;
486PyMlirContext::LiveContextMap &PyMlirContext::getLiveContexts() {
487 static LiveContextMap liveContexts;
492 nb::ft_lock_guard lock(live_contexts_mutex);
493 return getLiveContexts().size();
501 const nb::object &excVal,
502 const nb::object &excTb) {
511 nb::object pyHandlerObject =
512 nb::cast(pyHandler, nb::rv_policy::take_ownership);
513 (
void)pyHandlerObject.inc_ref();
517 auto handlerCallback =
520 nb::gil_scoped_acquire gil;
522 nb::object pyDiagnosticObject =
523 nb::cast(pyDiagnostic, nb::rv_policy::take_ownership);
528 result = nb::cast<bool>(pyHandler->callback(pyDiagnostic));
529 }
catch (std::exception &e) {
530 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
532 pyHandler->hadError =
true;
538 auto deleteCallback = +[](
void *userData) {
540 nb::gil_scoped_acquire gil;
542 assert(pyHandler->registeredID &&
"handler is not registered");
543 pyHandler->registeredID.reset();
546 nb::object pyHandlerObject = nb::cast(pyHandler, nb::rv_policy::reference);
547 pyHandlerObject.dec_ref();
551 get(), handlerCallback,
static_cast<void *
>(pyHandler), deleteCallback);
552 return pyHandlerObject;
559 if (self->ctx->emitErrorDiagnostics)
563 MlirDiagnosticSeverity::MlirDiagnosticError)
569 nb::gil_scoped_acquire acquire;
577 throw std::runtime_error(
578 "An MLIR function requires a Context but none was provided in the call "
579 "or from the surrounding environment. Either pass to the function with "
580 "a 'context=' argument or establish a default using 'with Context():'");
590 static thread_local std::vector<PyThreadContextEntry> stack;
595 auto &stack = getStack();
598 return &stack.back();
601void PyThreadContextEntry::push(FrameKind frameKind, nb::object context,
602 nb::object insertionPoint,
603 nb::object location) {
604 auto &stack = getStack();
605 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
606 std::move(location));
610 if (stack.size() > 1) {
611 auto &prev = *(stack.rbegin() + 1);
612 auto ¤t = stack.back();
613 if (current.context.is(prev.context)) {
615 if (!current.insertionPoint)
616 current.insertionPoint = prev.insertionPoint;
617 if (!current.location)
618 current.location = prev.location;
626 return nb::cast<PyMlirContext *>(context);
632 return nb::cast<PyInsertionPoint *>(insertionPoint);
638 return nb::cast<PyLocation *>(location);
643 return tos ? tos->getContext() :
nullptr;
648 return tos ? tos->getInsertionPoint() :
nullptr;
653 return tos ? tos->getLocation() :
nullptr;
657 push(FrameKind::Context, context,
664 auto &stack = getStack();
666 throw std::runtime_error(
"Unbalanced Context enter/exit");
667 auto &tos = stack.back();
668 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
669 throw std::runtime_error(
"Unbalanced Context enter/exit");
676 nb::cast<PyInsertionPoint &>(insertionPointObj);
677 nb::object contextObj =
679 push(FrameKind::InsertionPoint,
683 return insertionPointObj;
687 auto &stack = getStack();
689 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
690 auto &tos = stack.back();
691 if (tos.frameKind != FrameKind::InsertionPoint &&
692 tos.getInsertionPoint() != &insertionPoint)
693 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
698 PyLocation &location = nb::cast<PyLocation &>(locationObj);
700 push(FrameKind::Location, contextObj,
707 auto &stack = getStack();
709 throw std::runtime_error(
"Unbalanced Location enter/exit");
710 auto &tos = stack.back();
711 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
712 throw std::runtime_error(
"Unbalanced Location enter/exit");
722 if (materializedNotes) {
723 for (nb::handle noteObject : *materializedNotes) {
724 PyDiagnostic *note = nb::cast<PyDiagnostic *>(noteObject);
732 : context(context), callback(std::move(callback)) {}
741 assert(!registeredID &&
"should have unregistered");
747void PyDiagnostic::checkValid() {
749 throw std::invalid_argument(
750 "Diagnostic is invalid (used outside of callback)");
769 nb::object fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
772 return nb::cast<nb::str>(fileObject.attr(
"getvalue")());
777 if (materializedNotes)
778 return *materializedNotes;
780 nb::tuple notes = nb::steal<nb::tuple>(PyTuple_New(numNotes));
781 for (
intptr_t i = 0; i < numNotes; ++i) {
783 nb::object diagnostic = nb::cast(
PyDiagnostic(noteDiag));
784 PyTuple_SetItem(notes.ptr(), i, diagnostic.release().ptr());
786 materializedNotes = std::move(notes);
788 return *materializedNotes;
792 std::vector<DiagnosticInfo> notes;
794 notes.emplace_back(nb::cast<PyDiagnostic>(n).
getInfo());
796 nb::cast<std::string>(
getMessage()), std::move(notes)};
806 {key.data(), key.size()});
808 std::string msg =
join(
"Dialect '", key,
"' not found");
810 throw nb::attribute_error(msg.c_str());
811 throw nb::index_error(msg.c_str());
821 MlirDialectRegistry rawRegistry =
824 throw nb::python_error();
839 throw nb::python_error();
849 const nb::object &excVal,
850 const nb::object &excTb) {
857 throw std::runtime_error(
858 "An MLIR function requires a Location but none was provided in the "
859 "call or from the surrounding environment. Either pass to the function "
860 "with a 'loc=' argument or establish a default using 'with loc:'");
873 nb::gil_scoped_acquire acquire;
874 auto &liveModules =
getContext()->liveModules;
875 assert(liveModules.count(module.ptr) == 1 &&
876 "destroying module not in live map");
877 liveModules.erase(module.ptr);
885 nb::gil_scoped_acquire acquire;
886 auto &liveModules = contextRef->liveModules;
887 auto it = liveModules.find(module.ptr);
888 if (it == liveModules.end()) {
894 nb::object pyRef = nb::cast(unownedModule, nb::rv_policy::take_ownership);
895 unownedModule->handle = pyRef;
896 liveModules[module.ptr] =
897 std::make_pair(unownedModule->handle, unownedModule);
898 return PyModuleRef(unownedModule, std::move(pyRef));
902 nb::object pyRef = nb::borrow<nb::object>(it->second.first);
908 if (mlirModuleIsNull(rawModule))
909 throw nb::python_error();
940template <
typename T,
class... Args>
942 nb::handle type = nb::type<T>();
943 nb::object instance = nb::inst_alloc(type);
944 T *
ptr = nb::inst_ptr<T>(instance);
945 new (
ptr) T(std::forward<Args>(args)...);
946 nb::inst_mark_ready(instance);
952 MlirOperation operation,
953 nb::object parentKeepAlive) {
956 makeObjectRef<PyOperation>(std::move(contextRef), operation);
957 unownedOperation->handle = unownedOperation.
getObject();
958 if (parentKeepAlive) {
959 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
961 return unownedOperation;
965 MlirOperation operation,
966 nb::object parentKeepAlive) {
967 return createInstance(std::move(contextRef), operation,
968 std::move(parentKeepAlive));
972 MlirOperation operation,
973 nb::object parentKeepAlive) {
974 PyOperationRef created = createInstance(std::move(contextRef), operation,
975 std::move(parentKeepAlive));
976 created->attached =
false;
981 const std::string &sourceStr,
982 const std::string &sourceName) {
987 if (mlirOperationIsNull(op))
988 throw MLIRError(
"Unable to parse operation assembly", errors.take());
995 parentKeepAlive = nb::object();
1008 assert(!attached &&
"operation already attached");
1013 assert(attached &&
"operation already detached");
1019 throw std::runtime_error(
"the operation has been invalidated");
1024 std::optional<int64_t> largeResourceLimit,
1025 bool enableDebugInfo,
bool prettyDebugInfo,
1026 bool printGenericOpForm,
bool useLocalScope,
1027 bool useNameLocAsPrefix,
bool assumeVerified,
1028 nb::object fileObject,
bool binary,
1032 if (fileObject.is_none())
1033 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1036 if (largeElementsLimit)
1038 if (largeResourceLimit)
1040 if (enableDebugInfo)
1043 if (printGenericOpForm)
1051 if (useNameLocAsPrefix)
1056 accum.getUserData());
1064 if (fileObject.is_none())
1065 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1068 accum.getUserData());
1072 std::optional<int64_t> bytecodeVersion) {
1077 if (!bytecodeVersion.has_value())
1079 accum.getUserData());
1084 operation, config, accum.getCallback(), accum.getUserData());
1087 throw nb::value_error(
1088 join(
"Unable to honor desired bytecode version ", *bytecodeVersion)
1099 std::string exceptionWhat;
1100 nb::object exceptionType;
1102 UserData userData{callback,
false, {}, {}};
1105 UserData *calleeUserData =
static_cast<UserData *
>(userData);
1107 return static_cast<MlirWalkResult>((calleeUserData->callback)(op));
1108 }
catch (nb::python_error &e) {
1109 calleeUserData->gotException =
true;
1110 calleeUserData->exceptionWhat = std::string(e.what());
1111 calleeUserData->exceptionType = nb::borrow(e.type());
1112 return MlirWalkResult::MlirWalkResultInterrupt;
1117 if (userData.gotException) {
1118 std::string message(
"Exception raised in callback: ");
1119 message.append(userData.exceptionWhat);
1120 throw std::runtime_error(message);
1125 std::optional<int64_t> largeElementsLimit,
1126 std::optional<int64_t> largeResourceLimit,
1127 bool enableDebugInfo,
bool prettyDebugInfo,
1128 bool printGenericOpForm,
bool useLocalScope,
1129 bool useNameLocAsPrefix,
bool assumeVerified,
1131 nb::object fileObject;
1133 fileObject = nb::module_::import_(
"io").attr(
"BytesIO")();
1135 fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
1137 print(largeElementsLimit,
1149 return fileObject.attr(
"getvalue")();
1158 operation.parentKeepAlive = otherOp.parentKeepAlive;
1167 operation.parentKeepAlive = otherOp.parentKeepAlive;
1182 throw MLIRError(
"Verification failed", errors.take());
1189 throw nb::value_error(
"Detached operations have no parent");
1191 if (mlirOperationIsNull(operation))
1201 assert(parentOperation &&
"Operation has no parent");
1202 return PyBlock{std::move(*parentOperation), block};
1212 if (mlirOperationIsNull(rawOperation))
1213 throw nb::python_error();
1220 const nb::object &maybeIp) {
1222 if (!maybeIp.is(nb::cast(
false))) {
1224 if (maybeIp.is_none()) {
1227 ip = nb::cast<PyInsertionPoint *>(maybeIp);
1235 std::optional<std::vector<PyType *>> results,
1236 const MlirValue *operands,
size_t numOperands,
1237 std::optional<nb::dict> attributes,
1238 std::optional<std::vector<PyBlock *>> successors,
1240 const nb::object &maybeIp,
bool inferType) {
1241 std::vector<MlirType> mlirResults;
1242 std::vector<MlirBlock> mlirSuccessors;
1243 std::vector<std::pair<std::string, MlirAttribute>> mlirAttributes;
1247 throw nb::value_error(
"number of regions must be >= 0");
1251 mlirResults.reserve(results->size());
1255 throw nb::value_error(
"result type cannot be None");
1256 mlirResults.push_back(*
result);
1261 mlirAttributes.reserve(attributes->size());
1262 for (std::pair<nb::handle, nb::handle> it : *attributes) {
1265 key = nb::cast<std::string>(it.first);
1266 }
catch (nb::cast_error &err) {
1267 std::string msg =
join(
"Invalid attribute key (not a string) when "
1268 "attempting to create the operation \"",
1269 name,
"\" (", err.what(),
")");
1270 throw nb::type_error(msg.c_str());
1273 auto &attribute = nb::cast<PyAttribute &>(it.second);
1275 mlirAttributes.emplace_back(std::move(key), attribute);
1276 }
catch (std::exception &err) {
1277 if (it.second.is_none()) {
1278 std::string msg =
join(
1279 "Found an invalid (`None`?) attribute value for the key \"", key,
1280 "\" when attempting to create the operation \"", name,
"\"");
1281 throw std::runtime_error(msg);
1283 std::string msg =
join(
"Invalid attribute value for the key \"", key,
1284 "\" when attempting to create the operation \"",
1285 name,
"\" (", err.what(),
")");
1286 throw nb::type_error(msg.c_str());
1292 mlirSuccessors.reserve(successors->size());
1293 for (PyBlock *successor : *successors) {
1296 throw nb::value_error(
"successor block cannot be None");
1297 mlirSuccessors.push_back(successor->get());
1303 MlirOperationState state =
1305 if (numOperands > 0)
1307 state.enableResultTypeInference = inferType;
1308 if (!mlirResults.empty())
1310 mlirResults.data());
1311 if (!mlirAttributes.empty()) {
1315 std::vector<MlirNamedAttribute> mlirNamedAttributes;
1316 mlirNamedAttributes.reserve(mlirAttributes.size());
1317 for (
const std::pair<std::string, MlirAttribute> &it : mlirAttributes)
1323 mlirNamedAttributes.data());
1325 if (!mlirSuccessors.empty())
1327 mlirSuccessors.data());
1329 std::vector<MlirRegion> mlirRegions;
1330 mlirRegions.resize(regions);
1331 for (
int i = 0; i < regions; ++i)
1334 mlirRegions.data());
1338 PyMlirContext::ErrorCapture errors(location.
getContext());
1341 throw MLIRError(
"Operation creation failed", errors.take());
1363 std::string_view(identStr.
data, identStr.
length));
1378 [](
PyOpResult &self) -> nb::typed<nb::object, PyOpView> {
1381 "expected the owner of the value in Python to match that in "
1385 "Returns the operation that produces this result.");
1389 "Returns the position of this result in the operation's result list.");
1393template <
typename Container>
1394static std::vector<nb::typed<nb::object, PyType>>
1396 std::vector<nb::typed<nb::object, PyType>>
result;
1397 result.reserve(container.size());
1398 for (
int i = 0, e = container.size(); i < e; ++i) {
1412 operation(std::move(operation)) {}
1420 "Returns a list of types for all results in this result list.");
1426 "Returns the operation that owns this result list.");
1429intptr_t PyOpResultList::getRawNumElements() {
1430 operation->checkValid();
1434PyOpResult PyOpResultList::getRawElement(intptr_t index) {
1436 return PyOpResult(value);
1439PyOpResultList PyOpResultList::slice(intptr_t startIndex, intptr_t length,
1440 intptr_t step)
const {
1449 nb::sequence resultTypeList,
1450 const nb::object &resultSegmentSpecObj,
1451 std::vector<int32_t> &resultSegmentLengths,
1452 std::vector<PyType *> &resultTypes) {
1453 resultTypes.reserve(nb::len(resultTypeList));
1454 if (resultSegmentSpecObj.is_none()) {
1457 for (nb::handle resultType : resultTypeList) {
1459 resultTypes.push_back(nb::cast<PyType *>(resultType));
1460 if (!resultTypes.back())
1461 throw nb::cast_error();
1462 }
catch (nb::cast_error &err) {
1463 throw nb::value_error(
join(
"Result ",
index,
" of operation \"", name,
1464 "\" must be a Type (", err.what(),
")")
1471 auto resultSegmentSpec = nb::cast<std::vector<int>>(resultSegmentSpecObj);
1472 if (resultSegmentSpec.size() != nb::len(resultTypeList)) {
1473 throw nb::value_error(
1474 join(
"Operation \"", name,
"\" requires ", resultSegmentSpec.size(),
1475 " result segments but was provided ", nb::len(resultTypeList))
1478 resultSegmentLengths.reserve(nb::len(resultTypeList));
1479 for (
size_t i = 0, e = resultSegmentSpec.size(); i < e; ++i) {
1480 int segmentSpec = resultSegmentSpec[i];
1481 if (segmentSpec == 1 || segmentSpec == 0) {
1484 auto *resultType = nb::cast<PyType *>(resultTypeList[i]);
1486 resultTypes.push_back(resultType);
1487 resultSegmentLengths.push_back(1);
1488 }
else if (segmentSpec == 0) {
1490 resultSegmentLengths.push_back(0);
1492 throw nb::value_error(
1493 join(
"Result ", i,
" of operation \"", name,
1494 "\" must be a Type (was None and result is not optional)")
1497 }
catch (nb::cast_error &err) {
1498 throw nb::value_error(
join(
"Result ", i,
" of operation \"", name,
1499 "\" must be a Type (", err.what(),
")")
1502 }
else if (segmentSpec == -1) {
1505 if (resultTypeList[i].is_none()) {
1507 resultSegmentLengths.push_back(0);
1510 auto segment = nb::cast<nb::sequence>(resultTypeList[i]);
1511 for (nb::handle segmentItem : segment) {
1512 resultTypes.push_back(nb::cast<PyType *>(segmentItem));
1513 if (!resultTypes.back()) {
1514 throw nb::type_error(
"contained a None item");
1517 resultSegmentLengths.push_back(nb::len(segment));
1519 }
catch (std::exception &err) {
1523 throw nb::value_error(
join(
"Result ", i,
" of operation \"", name,
1524 "\" must be a Sequence of Types (",
1529 throw nb::value_error(
"Unexpected segment spec");
1537 if (numResults != 1) {
1539 throw nb::value_error(
1540 join(
"Cannot call .result on operation ",
1541 std::string_view(name.data, name.length),
" which has ",
1543 " results (it is only valid for operations with a "
1551 if (operand.is_none()) {
1552 throw nb::value_error(
"contained a None item");
1555 if (nb::try_cast<PyOperationBase *>(operand, op)) {
1559 if (nb::try_cast<PyOpResultList *>(operand, opResultList)) {
1563 if (nb::try_cast<PyValue *>(operand, value)) {
1566 throw nb::value_error(
"is not a Value");
1570 std::string_view name, std::tuple<int, bool> opRegionSpec,
1571 nb::object operandSegmentSpecObj, nb::object resultSegmentSpecObj,
1572 std::optional<nb::sequence> resultTypeList, nb::sequence operandList,
1573 std::optional<nb::dict> attributes,
1574 std::optional<std::vector<PyBlock *>> successors,
1575 std::optional<int> regions,
PyLocation &location,
1576 const nb::object &maybeIp) {
1585 std::vector<int32_t> operandSegmentLengths;
1586 std::vector<int32_t> resultSegmentLengths;
1589 int opMinRegionCount = std::get<0>(opRegionSpec);
1590 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1592 regions = opMinRegionCount;
1594 if (*regions < opMinRegionCount) {
1595 throw nb::value_error(
join(
"Operation \"", name,
1596 "\" requires a minimum of ", opMinRegionCount,
1597 " regions but was built with regions=", *regions)
1600 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1601 throw nb::value_error(
join(
"Operation \"", name,
1602 "\" requires a maximum of ", opMinRegionCount,
1603 " regions but was built with regions=", *regions)
1608 std::vector<PyType *> resultTypes;
1609 if (resultTypeList.has_value()) {
1611 resultSegmentLengths, resultTypes);
1615 std::vector<MlirValue> operands;
1616 operands.reserve(operands.size());
1618 if (operandSegmentSpecObj.is_none()) {
1620 for (nb::handle operand : operandList) {
1623 }
catch (nb::builtin_exception &err) {
1624 throw nb::value_error(
join(
"Operand ", index,
" of operation \"", name,
1625 "\" must be a Value (", err.what(),
")")
1632 auto operandSegmentSpec = nb::cast<std::vector<int>>(operandSegmentSpecObj);
1633 if (operandSegmentSpec.size() != nb::len(operandList)) {
1634 throw nb::value_error(
1635 join(
"Operation \"", name,
"\" requires ", operandSegmentSpec.size(),
1636 "operand segments but was provided ", nb::len(operandList))
1639 operandSegmentLengths.reserve(nb::len(operandList));
1640 for (
size_t i = 0, e = operandSegmentSpec.size(); i < e; ++i) {
1641 int segmentSpec = operandSegmentSpec[i];
1642 if (segmentSpec == 1 || segmentSpec == 0) {
1644 const nanobind::handle operand = operandList[i];
1645 if (!operand.is_none()) {
1648 }
catch (nb::builtin_exception &err) {
1649 throw nb::value_error(
join(
"Operand ", i,
" of operation \"", name,
1650 "\" must be a Value (", err.what(),
")")
1654 operandSegmentLengths.push_back(1);
1655 }
else if (segmentSpec == 0) {
1657 operandSegmentLengths.push_back(0);
1659 throw nb::value_error(
1660 join(
"Operand ", i,
" of operation \"", name,
1661 "\" must be a Value (was None and operand is not optional)")
1664 }
else if (segmentSpec == -1) {
1667 if (operandList[i].is_none()) {
1669 operandSegmentLengths.push_back(0);
1672 auto segment = nb::cast<nb::sequence>(operandList[i]);
1673 for (nb::handle segmentItem : segment) {
1676 operandSegmentLengths.push_back(nb::len(segment));
1678 }
catch (std::exception &err) {
1682 throw nb::value_error(
join(
"Operand ", i,
" of operation \"", name,
1683 "\" must be a Sequence of Values (",
1688 throw nb::value_error(
"Unexpected segment spec");
1694 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
1697 attributes = nb::dict(*attributes);
1699 attributes = nb::dict();
1701 if (attributes->contains(
"resultSegmentSizes") ||
1702 attributes->contains(
"operandSegmentSizes")) {
1703 throw nb::value_error(
"Manually setting a 'resultSegmentSizes' or "
1704 "'operandSegmentSizes' attribute is unsupported. "
1705 "Use Operation.create for such low-level access.");
1709 if (!resultSegmentLengths.empty()) {
1710 MlirAttribute segmentLengthAttr =
1712 resultSegmentLengths.data());
1713 (*attributes)[
"resultSegmentSizes"] =
1714 PyAttribute(context, segmentLengthAttr);
1718 if (!operandSegmentLengths.empty()) {
1719 MlirAttribute segmentLengthAttr =
1721 operandSegmentLengths.data());
1722 (*attributes)[
"operandSegmentSizes"] =
1723 PyAttribute(context, segmentLengthAttr);
1729 std::move(resultTypes),
1732 std::move(attributes),
1733 std::move(successors),
1734 *regions, location, maybeIp,
1739 const nb::object &operation) {
1740 nb::handle opViewType = nb::type<PyOpView>();
1741 nb::object instance = cls.attr(
"__new__")(cls);
1742 opViewType.attr(
"__init__")(instance, operation);
1750 operationObject(operation.getRef().getObject()) {}
1781 : refOperation(beforeOperationBase.getOperation().getRef()),
1785 : refOperation(beforeOperationRef), block((*refOperation)->getBlock()) {}
1790 throw nb::value_error(
1791 "Attempt to insert operation that is already attached");
1792 block.getParentOperation()->checkValid();
1793 MlirOperation beforeOp = {
nullptr};
1796 (*refOperation)->checkValid();
1797 beforeOp = (*refOperation)->get();
1803 throw nb::index_error(
"Cannot insert operation at the end of a block "
1804 "that already has a terminator. Did you mean to "
1805 "use 'InsertionPoint.at_block_terminator(block)' "
1806 "versus 'InsertionPoint(block)'?");
1815 if (mlirOperationIsNull(firstOp)) {
1822 block.getParentOperation()->getContext(), firstOp);
1828 if (mlirOperationIsNull(terminator))
1829 throw nb::value_error(
"Block has no terminator");
1831 block.getParentOperation()->getContext(), terminator);
1839 if (mlirOperationIsNull(nextOperation))
1853 const nb::object &excVal,
1854 const nb::object &excTb) {
1872 if (mlirAttributeIsNull(rawAttr))
1873 throw nb::python_error();
1881 "mlirTypeID was expected to be non-null.");
1886 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
1889 return typeCaster.value()(thisObj);
1900 "mlirTypeID was expected to be non-null.");
1903 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
1906 return typeCaster.value()(thisObj);
1914 : ownedName(new std::string(std::move(ownedName))) {
1936 throw nb::python_error();
1944 "mlirTypeID was expected to be non-null.");
1949 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
1952 return typeCaster.value()(thisObj);
1966 throw nb::python_error();
1982 MlirOperation owner;
1988 assert(
false &&
"Value must be an block arg or op result.");
1989 if (mlirOperationIsNull(owner))
1990 throw nb::python_error();
1995nb::typed<nb::object, std::variant<PyBlockArgument, PyOpResult, PyValue>>
2000 "mlirTypeID was expected to be non-null.");
2001 std::optional<nb::callable> valueCaster =
2007 thisObj = nb::cast<PyOpResult>(*
this, nb::rv_policy::move);
2009 thisObj = nb::cast<PyBlockArgument>(*
this, nb::rv_policy::move);
2011 assert(
false &&
"Value must be an block arg or op result.");
2013 return valueCaster.value()(thisObj);
2019 if (mlirValueIsNull(value))
2020 throw nb::python_error();
2022 return PyValue(ownerRef, value);
2030 : operation(operation.getOperation().getRef()) {
2033 throw nb::type_error(
"Operation is not a Symbol Table.");
2038 operation->checkValid();
2041 if (mlirOperationIsNull(symbol))
2042 throw nb::key_error(
2043 join(
"Symbol '", name,
"' not in the symbol table.").c_str());
2046 operation.getObject())
2051 operation->checkValid();
2062 erase(nb::cast<PyOperationBase &>(operation));
2066 operation->checkValid();
2070 if (mlirAttributeIsNull(symbolAttr))
2071 throw nb::value_error(
"Expected operation to have a symbol name.");
2082 MlirAttribute existingNameAttr =
2084 if (mlirAttributeIsNull(existingNameAttr))
2085 throw nb::value_error(
"Expected operation to have a symbol name.");
2091 const std::string &name) {
2096 MlirAttribute existingNameAttr =
2098 if (mlirAttributeIsNull(existingNameAttr))
2099 throw nb::value_error(
"Expected operation to have a symbol name.");
2100 MlirAttribute newNameAttr =
2109 MlirAttribute existingVisAttr =
2111 if (mlirAttributeIsNull(existingVisAttr))
2112 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2117 const std::string &visibility) {
2118 if (visibility !=
"public" && visibility !=
"private" &&
2119 visibility !=
"nested")
2120 throw nb::value_error(
2121 "Expected visibility to be 'public', 'private' or 'nested'");
2125 MlirAttribute existingVisAttr =
2127 if (mlirAttributeIsNull(existingVisAttr))
2128 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2135 const std::string &newSymbol,
2143 throw nb::value_error(
"Symbol rename failed");
2147 bool allSymUsesVisible,
2148 nb::object callback) {
2153 nb::object callback;
2155 std::string exceptionWhat;
2156 nb::object exceptionType;
2159 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
2161 fromOperation.
get(), allSymUsesVisible,
2162 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
2163 UserData *calleeUserData = static_cast<UserData *>(calleeUserDataVoid);
2165 PyOperation::forOperation(calleeUserData->context, foundOp);
2166 if (calleeUserData->gotException)
2169 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
2170 } catch (nb::python_error &e) {
2171 calleeUserData->gotException =
true;
2172 calleeUserData->exceptionWhat = e.what();
2173 calleeUserData->exceptionType = nb::borrow(e.type());
2176 static_cast<void *
>(&userData));
2177 if (userData.gotException) {
2178 std::string message(
"Exception raised in callback: ");
2179 message.append(userData.exceptionWhat);
2180 throw std::runtime_error(message);
2191 "Returns the block that owns this argument.");
2197 "Returns the position of this argument in the block's argument list.");
2203 "type"_a,
"Sets the type of this block argument.");
2206 [](PyBlockArgument &self, PyLocation loc) {
2209 "loc"_a,
"Sets the location of this block argument.");
2213 MlirBlock block,
intptr_t startIndex,
2217 operation(std::move(operation)), block(block) {}
2225 "Returns a list of types for all arguments in this argument list.");
2228intptr_t PyBlockArgumentList::getRawNumElements() {
2250 operation(operation) {}
2259 "Sets the operand at the specified index to a new value.");
2262intptr_t PyOpOperandList::getRawNumElements() {
2270 return PyValue(pyOwner, operand);
2284 static constexpr const char *
pyClassName =
"OpOperands";
2293 operation(operation) {}
2300 operation->checkValid();
2322 operation(operation) {}
2331 "Sets the successor block at the specified index.");
2334intptr_t PyOpSuccessors::getRawNumElements() {
2341 return PyBlock(operation, block);
2355 operation(operation), block(block) {}
2357intptr_t PyBlockSuccessors::getRawNumElements() {
2364 return PyBlock(operation, block);
2380 operation(operation), block(block) {}
2382intptr_t PyBlockPredecessors::getRawNumElements() {
2389 return PyBlock(operation, block);
2398nb::typed<nb::object, PyAttribute>
2400 MlirAttribute attr =
2402 if (mlirAttributeIsNull(attr)) {
2403 throw nb::key_error(
"attempt to access a non-existent attribute");
2408nb::typed<nb::object, std::optional<PyAttribute>>
2410 MlirAttribute attr =
2412 if (mlirAttributeIsNull(attr))
2413 return defaultValue;
2421 if (index < 0 || index >=
dunderLen()) {
2422 throw nb::index_error(
"attempt to access out of bounds attribute");
2442 throw nb::key_error(
"attempt to delete a non-existent attribute");
2450 return !mlirAttributeIsNull(
2455 MlirOperation op, std::function<
void(
MlirStringRef, MlirAttribute)> fn) {
2465 nb::class_<PyOpAttributeMap>(m,
"OpAttributeMap")
2467 "Checks if an attribute with the given name exists in the map.")
2469 "Returns the number of attributes in the map.")
2471 "Gets an attribute by name.")
2473 "Gets a named attribute by index.")
2475 "Sets an attribute with the given name.")
2477 "Deletes an attribute with the given name.")
2479 nb::arg(
"default") = nb::none(),
2480 "Gets an attribute by name or the default value, if it does not "
2488 keys.append(nb::str(name.data, name.length));
2490 return nb::iter(keys);
2492 "Iterates over attribute names.")
2499 out.append(nb::str(name.data, name.length));
2503 "Returns a list of attribute names.")
2510 out.append(PyAttribute(self.operation->getContext(), attr)
2515 "Returns a list of attribute values.")
2519 -> nb::typed<nb::list,
2520 nb::typed<nb::tuple, nb::str, PyAttribute>> {
2523 self.operation->
get(),
2525 out.append(nb::make_tuple(
2526 nb::str(name.data, name.length),
2527 PyAttribute(self.operation->getContext(), attr)
2532 "Returns a list of `(name, attribute)` tuples.");
2536 nb::class_<PyOpAdaptor>(m,
"OpAdaptor")
2538 "Creates an OpAdaptor with the given operands and attributes.",
2539 "operands"_a,
"attributes"_a)
2540 .def(nb::init<nb::typed<nb::list, PyValue>,
PyOpView &>(),
2541 "Creates an OpAdaptor with the given operands and operation view.",
2542 "operands"_a,
"opview"_a)
2544 "operands", [](
PyOpAdaptor &self) {
return self.operands; },
2545 "Returns the operands of the adaptor.")
2547 "attributes", [](
PyOpAdaptor &self) {
return self.attributes; },
2548 "Returns the attributes of the adaptor.");
2552 const char *methodName) {
2553 nb::handle targetObj(
static_cast<PyObject *
>(userData));
2554 if (!nb::hasattr(targetObj, methodName))
2558 bool success = nb::cast<bool>(targetObj.attr(methodName)(opView));
2562static bool attachOpTrait(
const nb::object &opName, MlirDynamicOpTrait trait,
2564 std::string opNameStr;
2565 if (opName.is_type()) {
2566 opNameStr = nb::cast<std::string>(opName.attr(
"OPERATION_NAME"));
2567 }
else if (nb::isinstance<nb::str>(opName)) {
2568 opNameStr = nb::cast<std::string>(opName);
2570 throw nb::type_error(
"the root argument must be a type or a string");
2578 const nb::object &
target,
2580 if (!nb::hasattr(
target,
"verify_invariants") &&
2581 !nb::hasattr(
target,
"verify_region_invariants"))
2582 throw nb::type_error(
2583 "the target object must have at least one of 'verify_invariants' or "
2584 "'verify_region_invariants' methods");
2587 callbacks.
construct = [](
void *userData) {
2588 nb::handle(
static_cast<PyObject *
>(userData)).inc_ref();
2590 callbacks.
destruct = [](
void *userData) {
2591 nb::handle(
static_cast<PyObject *
>(userData)).dec_ref();
2611 static_cast<void *
>(
target.ptr()));
2616 nb::class_<PyDynamicOpTrait> cls(m,
"DynamicOpTrait");
2618 [](
const nb::object &cls,
2619 const nb::typed<nb::object, std::variant<nb::type_object, nb::str>>
2626 nb::arg(
"cls"), nb::arg(
"op_name"), nb::arg(
"target").none() = nb::none(),
2627 nb::arg(
"context").none() = nb::none(),
2628 "Attach the dynamic op trait subclass to the given operation name.");
2638 nb::class_<PyDynamicOpTraits::IsTerminator, PyDynamicOpTrait> cls(
2639 m,
"IsTerminatorTrait");
2640 cls.def_prop_ro_static(typeIDAttr, [](nanobind::object & ) {
2644 [](
const nb::object &cls,
2645 const nb::typed<nb::object, std::variant<nb::type_object, nb::str>>
2650 "Attach IsTerminator trait to the given operation name.", nb::arg(
"cls"),
2651 nb::arg(
"op_name"), nb::arg(
"context").none() = nb::none());
2661 nb::class_<PyDynamicOpTraits::NoTerminator, PyDynamicOpTrait> cls(
2662 m,
"NoTerminatorTrait");
2663 cls.def_prop_ro_static(typeIDAttr, [](nanobind::object & ) {
2667 [](
const nb::object &cls,
2668 const nb::typed<nb::object, std::variant<nb::type_object, nb::str>>
2673 "Attach NoTerminator trait to the given operation name.", nb::arg(
"cls"),
2674 nb::arg(
"op_name"), nb::arg(
"context").none() = nb::none());
2684 nb::class_<PyDynamicOpTraits::IsIsolatedFromAbove, PyDynamicOpTrait> cls(
2685 m,
"IsIsolatedFromAboveTrait");
2686 cls.def_prop_ro_static(typeIDAttr, [](nanobind::object & ) {
2690 [](
const nb::object &cls,
2691 const nb::typed<nb::object, std::variant<nb::type_object, nb::str>>
2697 "Attach IsIsolatedFromAbove trait to the given operation name.",
2698 nb::arg(
"cls"), nb::arg(
"op_name"),
2699 nb::arg(
"context").none() = nb::none());
2709 nb::class_<PyDynamicOpTraits::RecursiveMemoryEffects, PyDynamicOpTrait> cls(
2710 m,
"RecursiveMemoryEffectsTrait");
2711 cls.def_prop_ro_static(typeIDAttr, [](nanobind::object & ) {
2715 [](
const nb::object &cls,
2716 const nb::typed<nb::object, std::variant<nb::type_object, nb::str>>
2720 opName, *context.
get());
2722 "Attach RecursiveMemoryEffects trait to the given operation name.",
2723 nb::arg(
"cls"), nb::arg(
"op_name"),
2724 nb::arg(
"context").none() = nb::none());
2731using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
2733MlirLocation tracebackToLocation(MlirContext ctx) {
2734#if defined(Py_LIMITED_API)
2739 size_t framesLimit =
2742 thread_local std::array<MlirLocation, PyGlobals::TracebackLoc::kMaxFrames>
2746 nb::gil_scoped_acquire acquire;
2748 PyThreadState *tstate = PyThreadState_GET();
2749 PyFrameObject *
next;
2750 PyFrameObject *pyFrame = PyThreadState_GetFrame(tstate);
2756 for (; pyFrame !=
nullptr && count < framesLimit;
2757 next = PyFrame_GetBack(pyFrame), Py_XDECREF(pyFrame), pyFrame =
next) {
2758 PyCodeObject *code = PyFrame_GetCode(pyFrame);
2760 nb::cast<std::string>(nb::borrow<nb::str>(code->co_filename));
2761 std::string_view fileName(fileNameStr);
2762 if (!
PyGlobals::get().getTracebackLoc().isUserTracebackFilename(fileName))
2766#if PY_VERSION_HEX < 0x030B00F0
2768 nb::cast<std::string>(nb::borrow<nb::str>(code->co_name));
2769 std::string_view funcName(name);
2770 int startLine = PyFrame_GetLineNumber(pyFrame);
2776 nb::cast<std::string>(nb::borrow<nb::str>(code->co_qualname));
2777 std::string_view funcName(name);
2778 int startLine, startCol, endLine, endCol;
2779 int lasti = PyFrame_GetLasti(pyFrame);
2780 if (!PyCode_Addr2Location(code, lasti, &startLine, &startCol, &endLine,
2782 throw nb::python_error();
2786 startCol, endLine, endCol);
2795 Py_XDECREF(pyFrame);
2800 MlirLocation callee = frames[0];
2805 MlirLocation caller = frames[count - 1];
2807 for (
int i = count - 2; i >= 1; i--)
2816applyCurrentLocAction(MlirContext ctx, MlirLocation baseLoc,
2819 if (action == Action::Fallback)
2826 "Location.current must belong to the current MLIR context");
2832 thread_local std::vector<MlirStringRef> scopeNames;
2834 MlirLocation
walk = currentLoc->get();
2839 for (
auto it = scopeNames.rbegin(); it != scopeNames.rend(); ++it)
2845maybeGetTracebackLocation(
const std::optional<PyLocation> &location) {
2850 if (!tbl.locTracebacksEnabled())
2851 return location.has_value() ? location.value()
2857 MlirLocation baseLoc;
2860 if (location.has_value()) {
2861 switch (tbl.tracebackActionOnExplicitLoc()) {
2862 case OnExplicit::UseExplicit:
2863 baseLoc = location->get();
2865 case OnExplicit::UseTraceback:
2866 baseLoc = tracebackToLocation(ctx.
get());
2870 baseLoc = tracebackToLocation(ctx.
get());
2874 baseLoc = applyCurrentLocAction(ctx.
get(), baseLoc,
2875 tbl.tracebackActionOnCurrentLoc());
2878 return {ref, baseLoc};
2889 std::string s = nb::cast<std::string>(nb::str(accum.
join()));
2890 std::string_view sv(s);
2891 if (sv.size() > 5) {
2892 sv.remove_prefix(4);
2893 sv.remove_suffix(1);
2895 return std::string(sv);
2897 auto indent = [](std::string s) {
2899 while ((pos = s.find(
'\n', pos)) != std::string::npos) {
2900 s.replace(pos, 1,
"\n ");
2906 std::ostringstream os;
2911 os <<
"\nerror: " << locStr(
diag.location) <<
": " << indent(
diag.message);
2912 for (
const auto ¬e :
diag.notes) {
2913 os <<
"\n note: " << locStr(note.location) <<
": "
2914 << indent(note.message);
2921 auto cls = nb::exception<MLIRError>(m,
"MLIRError", PyExc_Exception);
2922 nb::register_exception_translator(
2923 [](
const std::exception_ptr &p,
void *payload) {
2926 std::rethrow_exception(p);
2929 nb::object ty = nb::borrow(
static_cast<PyObject *
>(payload));
2930 nb::object obj = ty(formatted);
2931 obj.attr(
"_message") = nb::cast(std::move(e.
message));
2932 obj.attr(
"_error_diagnostics") =
2934 PyErr_SetObject(
static_cast<PyObject *
>(payload), obj.ptr());
2938 auto propertyType = nb::borrow<nb::type_object>(
2939 reinterpret_cast<PyObject *
>(&PyProperty_Type));
2942 propertyType(nb::cpp_function(
2943 [](nb::object self) -> nb::str {
return self.attr(
"_message"); },
2945 nb::setattr(cls,
"error_diagnostics",
2946 propertyType(nb::cpp_function(
2948 -> nb::typed<nb::list, PyDiagnostic::DiagnosticInfo> {
2949 return self.attr(
"_error_diagnostics");
2955 m.attr(
"T") = nb::type_var(
"T");
2956 m.attr(
"U") = nb::type_var(
"U");
2960 nb::enum_<PyGlobals::TracebackLoc::OnExplicitAction>(m,
"OnExplicitAction")
2961 .value(
"USE_EXPLICIT",
2963 .value(
"USE_TRACEBACK",
2966 nb::enum_<PyGlobals::TracebackLoc::CurrentLocAction>(m,
"CurrentLocAction")
2968 .value(
"NAMELOC_WRAP",
2971 nb::class_<PyGlobals>(m,
"_Globals")
2972 .def_prop_rw(
"dialect_search_modules",
2978 "_check_dialect_module_loaded",
2979 [](
PyGlobals &self,
const std::string &dialectNamespace) {
2982 "dialect_namespace"_a)
2984 "dialect_namespace"_a,
"dialect_class"_a, nb::kw_only(),
2985 "replace"_a =
false,
2986 "Testing hook for directly registering a dialect")
2988 "operation_name"_a,
"operation_class"_a, nb::kw_only(),
2989 "replace"_a =
false,
2990 "Testing hook for directly registering an operation")
2991 .def(
"loc_tracebacks_enabled",
2995 .def(
"set_loc_tracebacks_enabled",
2999 .def(
"loc_tracebacks_frame_limit",
3003 .def(
"set_loc_tracebacks_frame_limit",
3004 [](
PyGlobals &self, std::optional<int> n) {
3008 .def(
"register_traceback_file_inclusion",
3009 [](
PyGlobals &self,
const std::string &filename) {
3012 .def(
"register_traceback_file_exclusion",
3013 [](
PyGlobals &self,
const std::string &filename) {
3016 .def(
"traceback_action_on_explicit_loc",
3020 .def(
"set_traceback_action_on_explicit_loc",
3025 .def(
"traceback_action_on_current_loc",
3029 .def(
"set_traceback_action_on_current_loc",
3038 m.attr(
"globals") = nb::cast(
new PyGlobals, nb::rv_policy::take_ownership);
3043 [](nb::type_object pyClass) {
3044 std::string dialectNamespace =
3045 nb::cast<std::string>(pyClass.attr(
"DIALECT_NAMESPACE"));
3050 "Class decorator for registering a custom Dialect wrapper");
3052 "register_operation",
3053 [](
const nb::type_object &dialectClass,
bool replace) -> nb::object {
3054 return nb::cpp_function(
3056 replace](nb::type_object opClass) -> nb::type_object {
3057 std::string operationName =
3058 nb::cast<std::string>(opClass.attr(
"OPERATION_NAME"));
3062 nb::object opClassName = opClass.attr(
"__name__");
3063 dialectClass.attr(opClassName) = opClass;
3068 nb::sig(
"def register_operation(dialect_class: type, *, replace: bool = False) "
3069 "-> typing.Callable[[type[T]], type[T]]"),
3071 "dialect_class"_a, nb::kw_only(),
"replace"_a =
false,
3072 "Produce a class decorator for registering an Operation class as part of "
3075 "register_op_adaptor",
3076 [](
const nb::type_object &opClass,
bool replace) -> nb::object {
3077 return nb::cpp_function(
3079 replace](nb::type_object adaptorClass) -> nb::type_object {
3080 std::string operationName =
3081 nb::cast<std::string>(adaptorClass.attr(
"OPERATION_NAME"));
3083 adaptorClass, replace);
3085 opClass.attr(
"Adaptor") = adaptorClass;
3086 return adaptorClass;
3090 nb::sig(
"def register_op_adaptor(op_class: type, *, replace: bool = False) "
3091 "-> typing.Callable[[type[T]], type[T]]"),
3093 "op_class"_a, nb::kw_only(),
"replace"_a =
false,
3094 "Produce a class decorator for registering an OpAdaptor class for an "
3098 [](
PyTypeID mlirTypeID,
bool replace) -> nb::object {
3099 return nb::cpp_function([mlirTypeID, replace](
3100 nb::callable typeCaster) -> nb::object {
3106 nb::sig(
"def register_type_caster(typeid: _mlir.ir.TypeID, *, replace: bool = False) "
3107 "-> typing.Callable[[typing.Callable[[T], U]], typing.Callable[[T], U]]"),
3109 "typeid"_a, nb::kw_only(),
"replace"_a =
false,
3110 "Register a type caster for casting MLIR types to custom user types.");
3113 [](
PyTypeID mlirTypeID,
bool replace) -> nb::object {
3114 return nb::cpp_function(
3115 [mlirTypeID, replace](nb::callable valueCaster) -> nb::object {
3122 nb::sig(
"def register_value_caster(typeid: _mlir.ir.TypeID, *, replace: bool = False) "
3123 "-> typing.Callable[[typing.Callable[[T], U]], typing.Callable[[T], U]]"),
3125 "typeid"_a, nb::kw_only(),
"replace"_a =
false,
3126 "Register a value caster for casting MLIR values to custom user values.");
3140 "context"_a = nb::none(),
3141 "Gets a Location representing an unknown location.");
3147 [](std::string filename,
int line,
int col,
3154 "filename"_a,
"line"_a,
"col"_a,
"context"_a = nb::none(),
3155 "Gets a FileLineColLoc for a file, line, and column.");
3158 [](std::string filename,
int startLine,
int startCol,
int endLine,
3163 startLine, startCol, endLine, endCol));
3165 "filename"_a,
"start_line"_a,
"start_col"_a,
"end_line"_a,
"end_col"_a,
3166 "context"_a = nb::none(),
3167 "Gets a FileLineColLoc spanning a file and line/column range.");
3174 "Gets the filename from a `FileLineColLoc`.");
3180 "Gets the start line number from a `FileLineColLoc`.");
3186 "Gets the start column number from a `FileLineColLoc`.");
3192 "Gets the end line number from a `FileLineColLoc`.");
3198 "Gets the end column number from a `FileLineColLoc`.");
3204 [](std::string name, std::optional<PyLocation> childLoc,
3213 "name"_a,
"child_loc"_a = nb::none(),
"context"_a = nb::none(),
3214 "Gets a NameLoc with an optional child location.");
3220 "Gets the name string from a `NameLoc`.");
3228 "Gets the child location from a `NameLoc`.");
3234 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
3237 throw nb::value_error(
"No caller frames provided.");
3238 MlirLocation caller = frames.back().get();
3239 for (
size_t index = frames.size() - 1;
index-- > 0;) {
3245 "callee"_a,
"frames"_a,
"context"_a = nb::none(),
3246 "Gets a CallSiteLoc chaining a callee and one or more caller frames.");
3254 "Gets the callee location from a `CallSiteLoc`.");
3262 "Gets the caller location from a `CallSiteLoc`.");
3268 [](
const std::vector<PyLocation> &pyLocations,
3270 std::vector<MlirLocation> locations;
3271 locations.reserve(pyLocations.size());
3272 for (
const PyLocation &pyLocation : pyLocations)
3273 locations.push_back(pyLocation.get());
3275 context->
get(), locations.size(), locations.data(),
3276 metadata ? metadata->
get() : MlirAttribute{0});
3279 throw nb::value_error(
3280 "FusedLoc.get would collapse to a non-fused location; use "
3281 "Location.fused(...) for the permissive variant.");
3284 "locations"_a,
"metadata"_a = nb::none(),
"context"_a = nb::none(),
3285 "Gets a FusedLoc from an array of locations and optional metadata. "
3286 "Raises if the fuse would collapse to a non-fused location; use "
3287 "`Location.fused(...)` for the permissive variant.");
3292 std::vector<MlirLocation> locations(numLocations);
3295 std::vector<nb::object> pyLocations;
3296 pyLocations.reserve(numLocations);
3297 for (
unsigned i = 0; i < numLocations; ++i)
3298 pyLocations.push_back(
3302 "Gets the list of locations from a `FusedLoc`.");
3307 if (mlirAttributeIsNull(metadata))
3308 return std::nullopt;
3311 "Gets the metadata attribute from a `FusedLoc`, or None if absent.");
3321 nb::enum_<PyDiagnosticSeverity>(m,
"DiagnosticSeverity")
3327 nb::enum_<PyWalkOrder>(m,
"WalkOrder")
3331 nb::enum_<PyOperationEquivalenceFlags>(m,
"OperationEquivalenceFlags",
3332 nb::is_arithmetic(), nb::is_flag())
3335 .value(
"IGNORE_DISCARDABLE_ATTRS",
3338 .value(
"IGNORE_COMMUTATIVITY",
3341 nb::enum_<PyWalkResult>(m,
"WalkResult")
3349 nb::class_<PyDiagnostic>(m,
"Diagnostic")
3351 "Returns the severity of the diagnostic.")
3353 "Returns the location associated with the diagnostic.")
3355 "Returns the message text of the diagnostic.")
3357 "Returns a tuple of attached note diagnostics.")
3362 return nb::str(
"<Invalid Diagnostic>");
3365 "Returns the diagnostic message as a string.");
3367 nb::class_<PyDiagnostic::DiagnosticInfo>(m,
"DiagnosticInfo")
3373 "diag"_a,
"Creates a DiagnosticInfo from a Diagnostic.")
3375 "The severity level of the diagnostic.")
3377 "The location associated with the diagnostic.")
3379 "The message text of the diagnostic.")
3381 "List of attached note diagnostics.")
3385 "Returns the diagnostic message as a string.");
3387 nb::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler")
3389 "Detaches the diagnostic handler from the context.")
3391 "Returns True if the handler is attached to a context.")
3393 "Returns True if an error was encountered during diagnostic "
3396 "Enters the diagnostic handler as a context manager.",
3397 nb::sig(
"def __enter__(self, /) -> DiagnosticHandler"))
3399 "exc_value"_a.none(),
"traceback"_a.none(),
3400 "Exits the diagnostic handler context manager.");
3403 nb::class_<PyThreadPool>(m,
"ThreadPool")
3406 "Creates a new thread pool with default concurrency.")
3408 "Returns the maximum number of threads in the pool.")
3410 "Returns the raw pointer to the LLVM thread pool as a string.");
3412 nb::class_<PyMlirContext>(m,
"Context")
3420 Creates a new MLIR context.
3422 The context is the top-level container for all MLIR objects. It owns the storage
3423 for types, attributes, locations, and other core IR objects. A context can be
3424 configured to allow or disallow unregistered dialects and can have dialects
3425 loaded on-demand.)")
3427 "Gets the number of live Context objects.")
3429 "_get_context_again",
3430 [](
PyMlirContext &self) -> nb::typed<nb::object, PyMlirContext> {
3434 "Gets another reference to the same context.")
3436 "Gets the number of live modules owned by this context.")
3438 "Gets a capsule wrapping the MlirContext.")
3441 "Creates a Context from a capsule wrapping MlirContext.")
3443 "Enters the context as a context manager.",
3444 nb::sig(
"def __enter__(self, /) -> Context"))
3446 "exc_value"_a.none(),
"traceback"_a.none(),
3447 "Exits the context manager.")
3448 .def_prop_ro_static(
3451 -> std::optional<nb::typed<nb::object, PyMlirContext>> {
3455 return nb::cast(context);
3457 nb::sig(
"def current(/) -> Context | None"),
3458 "Gets the Context bound to the current thread or returns None if no "
3463 "Gets a container for accessing dialects by name.")
3466 "Alias for `dialects`.")
3468 "get_dialect_descriptor",
3471 self.get(), {name.data(), name.size()});
3473 throw nb::value_error(
3474 join(
"Dialect '", name,
"' not found").c_str());
3479 "Gets or loads a dialect by name, returning its descriptor object.")
3481 "is_dialect_loaded",
3484 self.get(), {name.data(), name.size()});
3487 "dialect_name"_a,
"Checks if a dialect is loaded in the context.")
3489 "allow_unregistered_dialects",
3496 "Controls whether unregistered dialects are allowed in this context.")
3499 "Attaches a diagnostic handler that will receive callbacks.")
3502 "output_file"_a.none() = nb::none(),
3504 "passed_filter"_a =
"",
"missed_filter"_a =
"",
3505 "analysis_filter"_a =
"",
"failed_filter"_a =
"",
3506 "callback"_a.none() = nb::none(),
3507 "print_as_emit_remarks"_a.none() = nb::none(),
3509 Enables the optimization remark engine on this context.
3511 Remarks are reported by passes (and by `Location.emit_remark`) and
3512 selected by the category filters, regular expressions anchored by
3513 the engine: `all_filter` applies to every kind, the other filters to
3514 one kind each; a kind without a matching filter is not reported.
3516 The sink is selected by the arguments: `output_file` streams the
3517 remarks to a file in `format`, `callback` delivers them to Python,
3518 and without either they are emitted as MLIR remark diagnostics.
3521 policy: `RemarkPolicy.ALL` reports remarks as they are emitted;
3522 `RemarkPolicy.FINAL` postpones them until `finalize_remarks()`
3523 and reports the final set, grouping related remarks under
3525 output_file: Path of the remark file, written on
3526 `finalize_remarks()`.
3527 format: The serialization format of `output_file`.
3528 all_filter: Category regex applied to every remark kind.
3529 passed_filter: Category regex for passed remarks.
3530 missed_filter: Category regex for missed remarks.
3531 analysis_filter: Category regex for analysis remarks.
3532 failed_filter: Category regex for failed remarks.
3533 callback: A callable receiving one `Remark` per reported remark;
3534 the remark is only valid during the call.
3535 print_as_emit_remarks: Also emit every remark as an MLIR remark
3536 diagnostic; defaults to True only without an output file or
3540 ValueError: When both an output file and a callback are given,
3541 when remarks are already enabled, or when the output file
3542 cannot be written.)")
3545 Finalizes and removes the remark engine of this context.
3547 Postponed remarks (policy "final") are reported, the output file is
3548 written and the callback is released. Does nothing when no engine
3549 is enabled; `enable_remarks` may be called again afterwards.)")
3552 "Returns True if a remark engine is enabled on this context.")
3554 "enable_multithreading",
3560 Enables or disables multi-threading support in the context.
3563 enable: Whether to enable (True) or disable (False) multi-threading.
3575 Sets a custom thread pool for the context to use.
3578 pool: A ThreadPool object to use for parallel operations.
3581 Multi-threading is automatically disabled before setting the thread pool.)")
3587 "Gets the number of threads in the context's thread pool.")
3589 "_mlir_thread_pool_ptr",
3592 std::stringstream ss;
3596 "Gets the raw pointer to the LLVM thread pool as a string.")
3598 "is_registered_operation",
3605 Checks whether an operation with the given name is registered.
3608 operation_name: The fully qualified name of the operation (e.g., `arith.addf`).
3611 True if the operation is registered, False otherwise.)")
3613 "append_dialect_registry",
3619 Appends the contents of a dialect registry to the context.
3622 registry: A DialectRegistry containing dialects to append.)")
3623 .def_prop_rw("emit_error_diagnostics",
3627 Controls whether error diagnostics are emitted to diagnostic handlers.
3629 By default, error diagnostics are captured and reported through MLIRError exceptions.)")
3631 "load_all_available_dialects",
3636 Loads all dialects available in the registry into the context.
3638 This eagerly loads all dialects that have been registered, making them
3639 immediately available for use.)")
3641 "begin_transient_scope",
3644 throw nb::value_error(
"Context is already in a transient scope");
3648 Begins a transient scope on the context, freezing the base layer.
3650 All subsequently allocated types, attributes, and unregistered operations
3651 are treated as transient and will be deallocated with end_transient_scope().
3652 Raises a ValueError if the context is already in a transient scope.)")
3654 "end_transient_scope",
3657 Ends the transient scope and resets the context to the base state.
3659 Prunes all transient types, attributes, affine expressions, distinct
3660 attributes, and unregistered operations added during the transient scope.
3662 Note: Any Python objects referencing transient IR entities become invalid
3663 after this call and must not be accessed.)")
3665 "is_in_transient_scope",
3669 "Returns whether the context is currently in a transient scope.");
3674 nb::class_<PyDialectDescriptor>(m,
"DialectDescriptor")
3681 "Returns the namespace of the dialect.")
3686 std::string repr(
"<DialectDescriptor ");
3691 nb::sig(
"def __repr__(self) -> str"),
3692 "Returns a string representation of the dialect descriptor.");
3697 nb::class_<PyDialects>(m,
"Dialects")
3701 MlirDialect dialect =
3702 self.getDialectForKey(keyName,
false);
3703 nb::object descriptor =
3707 "Gets a dialect by name using subscript notation.")
3711 MlirDialect dialect =
3712 self.getDialectForKey(attrName,
true);
3713 nb::object descriptor =
3717 "Gets a dialect by name using attribute notation.");
3722 nb::class_<PyDialect>(m,
"Dialect")
3723 .def(nb::init<nb::object>(),
"descriptor"_a,
3724 "Creates a Dialect from a DialectDescriptor.")
3726 "descriptor", [](
PyDialect &self) {
return self.getDescriptor(); },
3727 "Returns the DialectDescriptor for this dialect.")
3730 [](
const nb::object &self) {
3731 auto clazz = self.attr(
"__class__");
3732 return nb::str(
"<Dialect ") +
3733 self.attr(
"descriptor").attr(
"namespace") +
3734 nb::str(
" (class ") + clazz.attr(
"__module__") +
3735 nb::str(
".") + clazz.attr(
"__name__") + nb::str(
")>");
3737 nb::sig(
"def __repr__(self) -> str"),
3738 "Returns a string representation of the dialect.");
3743 nb::class_<PyDialectRegistry>(m,
"DialectRegistry")
3745 "Gets a capsule wrapping the MlirDialectRegistry.")
3748 "Creates a DialectRegistry from a capsule wrapping "
3749 "`MlirDialectRegistry`.")
3750 .def(nb::init<>(),
"Creates a new empty dialect registry.");
3755 nb::class_<PyLocation>(m,
"Location")
3757 "Gets a capsule wrapping the MlirLocation.")
3759 "Creates a Location from a capsule wrapping MlirLocation.")
3761 "Enters the location as a context manager.",
3762 nb::sig(
"def __enter__(self, /) -> Location"))
3764 "exc_value"_a.none(),
"traceback"_a.none(),
3765 "Exits the location context manager.")
3771 "Compares two locations for equality.")
3773 "__eq__", [](
PyLocation &self, nb::object other) {
return false; },
3774 "Compares location with non-location object (always returns False).")
3775 .def_prop_ro_static(
3777 [](nb::object & ) -> std::optional<PyLocation *> {
3780 return std::nullopt;
3784 nb::sig(
"def current(/) -> Location | None"),
3786 "Gets the Location bound to the current thread or raises ValueError.")
3794 "attribute"_a,
"context"_a = nb::none(),
3795 "Gets a Location from a `LocationAttr`.")
3804 "context"_a = nb::none(),
"Alias for `UnknownLoc.get()`.")
3807 [](std::string filename,
int line,
int col,
3814 "filename"_a,
"line"_a,
"col"_a,
"context"_a = nb::none(),
3815 "Alias for `FileLineColLoc.get()`.")
3818 [](std::string filename,
int startLine,
int startCol,
int endLine,
3824 startCol, endLine, endCol));
3826 "filename"_a,
"start_line"_a,
"start_col"_a,
"end_line"_a,
3827 "end_col"_a,
"context"_a = nb::none(),
3828 "Alias for `FileLineColLoc.get()` over a range.")
3831 [](std::string name, std::optional<PyLocation> childLoc,
3837 childLoc ? childLoc->get()
3840 "name"_a,
"childLoc"_a = nb::none(),
"context"_a = nb::none(),
3841 "Alias for `NameLoc.get()`.")
3844 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
3847 throw nb::value_error(
"No caller frames provided.");
3848 MlirLocation caller = frames.back().get();
3849 for (
size_t index = frames.size() - 1;
index-- > 0;)
3855 "callee"_a,
"frames"_a,
"context"_a = nb::none(),
3856 "Alias for `CallSiteLoc.get()`.")
3859 [](
const std::vector<PyLocation> &pyLocations,
3860 std::optional<PyAttribute> metadata,
3862 std::vector<MlirLocation> locations;
3863 locations.reserve(pyLocations.size());
3864 for (
const PyLocation &pyLocation : pyLocations)
3865 locations.push_back(pyLocation.get());
3867 context->
get(), locations.size(), locations.data(),
3868 metadata ? metadata->
get() : MlirAttribute{0});
3871 "locations"_a,
"metadata"_a = nb::none(),
"context"_a = nb::none(),
3872 "Alias for `FusedLoc.get()` (may collapse to a non-fused location).")
3875 [](
PyLocation &self) -> nb::typed<nb::object, PyMlirContext> {
3876 return self.getContext().getObject();
3878 "Context that owns the `Location`.")
3885 "Get the underlying `LocationAttr`.")
3889 MlirTypeID mlirTypeID =
3892 "mlirTypeID was expected to be non-null.");
3895 "Gets the `TypeID` of the underlying LocationAttr.")
3903 Emits an error diagnostic at this location.
3906 message: The error message to emit.)")
3910 const std::string &category,
const std::string &subCategory,
3911 const std::string &functionName,
const std::string &message,
3912 const std::vector<std::pair<std::string, std::string>> &args)
3915 std::vector<MlirStringRef> keys, values;
3916 keys.reserve(args.size());
3917 values.reserve(args.size());
3918 for (
const auto &[key, value] : args) {
3926 static_cast<intptr_t>(keys.size()), keys.data(), values.data());
3928 "kind"_a,
"remark_name"_a, nb::kw_only(),
"category"_a =
"",
3929 "sub_category"_a =
"",
"function_name"_a =
"",
"message"_a =
"",
3930 "args"_a = std::vector<std::pair<std::string, std::string>>(),
3932 Emits an optimization remark at this location through the remark
3933 engine of the context (see `Context.enable_remarks`).
3936 kind: The `RemarkKind` of the remark.
3937 remark_name: The name identifying the remark.
3938 category: The category the filters are matched against.
3939 sub_category: An optional sub-category.
3940 function_name: The function the remark refers to.
3941 message: Free text attached to the remark.
3942 args: Key/value pairs attached to the remark.
3945 True if the remark was reported; False when no remark engine is
3946 enabled or the category is filtered out.)")
3953 return printAccum.
join();
3955 "Returns the assembly form of the Location.")
3962 return printAccum.
join();
3964 "Returns the assembly representation of the location.");
3975 nb::class_<PyModule>(m,
"Module", nb::is_weak_referenceable())
3977 "Gets a capsule wrapping the MlirModule.")
3980 Creates a Module from a `MlirModule` wrapped by a capsule (i.e. `module._CAPIPtr`).
3982 This returns a new object **BUT** `_clear_mlir_module(module)` must be called to
3983 prevent double-frees (of the underlying `mlir::Module`).)")
3986 Clears the internal MLIR module reference.
3988 This is used internally to prevent double-free when ownership is transferred
3989 via the C API capsule mechanism. Not intended for normal use.)")
3993 -> nb::typed<nb::object, PyModule> {
3997 if (mlirModuleIsNull(module))
3998 throw MLIRError(
"Unable to parse module assembly", errors.
take());
4005 -> nb::typed<nb::object, PyModule> {
4009 if (mlirModuleIsNull(module))
4010 throw MLIRError(
"Unable to parse module assembly", errors.
take());
4017 -> nb::typed<nb::object, PyModule> {
4021 if (mlirModuleIsNull(module))
4022 throw MLIRError(
"Unable to parse module assembly", errors.
take());
4028 [](
const std::optional<PyLocation> &loc)
4029 -> nb::typed<nb::object, PyModule> {
4030 PyLocation pyLoc = maybeGetTracebackLocation(loc);
4034 "loc"_a = nb::none(),
"Creates an empty module.")
4037 [](
PyModule &self) -> nb::typed<nb::object, PyMlirContext> {
4038 return self.getContext().getObject();
4040 "Context that created the `Module`.")
4043 [](
PyModule &self) -> nb::typed<nb::object, PyOperation> {
4046 self.getRef().releaseObject())
4049 "Accesses the module as an operation.")
4055 self.getRef().releaseObject());
4059 "Return the block for this module.")
4068 [](
const nb::object &self) {
4070 return self.attr(
"operation").attr(
"__str__")();
4072 nb::sig(
"def __str__(self) -> str"),
4074 Gets the assembly form of the operation with default options.
4076 If more advanced control over the assembly formatting or I/O options is needed,
4077 use the dedicated print or get_asm method, which supports keyword arguments to
4085 "other"_a,
"Compares two modules for equality.")
4089 "Returns the hash value of the module.");
4094 nb::class_<PyOperationBase>(m,
"_OperationBase")
4098 return self.getOperation().getCapsule();
4100 "Gets a capsule wrapping the `MlirOperation`.")
4105 other.getOperation().
get());
4107 "Compares two operations for equality.")
4111 "Compares operation with non-operation object (always returns "
4118 "Returns the hash value of the operation.")
4120 "is_structurally_equivalent",
4123 self.getOperation().checkValid();
4124 other.getOperation().checkValid();
4126 self.getOperation().get(), other.getOperation().
get(),
4127 static_cast<uint32_t
>(flags));
4130 R
"("Checks whether two operations are structurally equivalent. The predicate recursively compares regions.")")
4134 self.getOperation().checkValid();
4136 self.getOperation().get(),
static_cast<uint32_t
>(flags));
4139 R
"(Computes a structural hash for the operation. The hash does not recurse into regions, unlike the predicate.")")
4145 "Returns a dictionary-like map of operation attributes.")
4149 PyOperation &concreteOperation = self.getOperation();
4153 "Context that owns the operation.")
4157 auto &concreteOperation = self.getOperation();
4158 concreteOperation.checkValid();
4159 MlirOperation operation = concreteOperation.
get();
4162 "Returns the fully qualified name of the operation.")
4168 "Returns the list of operation operands.")
4174 "Returns the list of op operands.")
4180 "Returns the list of operation regions.")
4186 "Returns the list of Operation results.")
4190 auto &operation = self.getOperation();
4194 "Shortcut to get an op result if it has only one (throws an error "
4208 nb::for_getter(
"Returns the source location the operation was "
4209 "defined or derived from."),
4210 nb::for_setter(
"Sets the source location the operation was defined "
4211 "or derived from."))
4215 -> std::optional<nb::typed<nb::object, PyOperation>> {
4216 auto parent = self.getOperation().getParentOperation();
4218 return parent->getObject();
4221 "Returns the parent operation, or `None` if at top level.")
4225 return self.getAsm(
false,
4236 nb::sig(
"def __str__(self) -> str"),
4237 "Returns the assembly form of the operation.")
4239 nb::overload_cast<PyAsmState &, nb::object, bool>(
4241 "state"_a,
"file"_a = nb::none(),
"binary"_a =
false,
4243 Prints the assembly form of the operation to a file like object.
4246 state: `AsmState` capturing the operation numbering and flags.
4247 file: Optional file like object to write to. Defaults to sys.stdout.
4248 binary: Whether to write `bytes` (True) or `str` (False). Defaults to False.)")
4250 nb::overload_cast<std::optional<int64_t>, std::optional<int64_t>,
4251 bool,
bool,
bool,
bool,
bool,
bool, nb::object,
4254 "large_elements_limit"_a = nb::none(),
4255 "large_resource_limit"_a = nb::none(),
"enable_debug_info"_a =
false,
4256 "pretty_debug_info"_a =
false,
"print_generic_op_form"_a =
false,
4257 "use_local_scope"_a =
false,
"use_name_loc_as_prefix"_a =
false,
4258 "assume_verified"_a =
false,
"file"_a = nb::none(),
4259 "binary"_a =
false,
"skip_regions"_a =
false,
4261 Prints the assembly form of the operation to a file like object.
4264 large_elements_limit: Whether to elide elements attributes above this
4265 number of elements. Defaults to None (no limit).
4266 large_resource_limit: Whether to elide resource attributes above this
4267 number of characters. Defaults to None (no limit). If large_elements_limit
4268 is set and this is None, the behavior will be to use large_elements_limit
4269 as large_resource_limit.
4270 enable_debug_info: Whether to print debug/location information. Defaults
4272 pretty_debug_info: Whether to format debug information for easier reading
4273 by a human (warning: the result is unparseable). Defaults to False.
4274 print_generic_op_form: Whether to print the generic assembly forms of all
4275 ops. Defaults to False.
4276 use_local_scope: Whether to print in a way that is more optimized for
4277 multi-threaded access but may not be consistent with how the overall
4279 use_name_loc_as_prefix: Whether to use location attributes (NameLoc) as
4280 prefixes for the SSA identifiers. Defaults to False.
4281 assume_verified: By default, if not printing generic form, the verifier
4282 will be run and if it fails, generic form will be printed with a comment
4283 about failed verification. While a reasonable default for interactive use,
4284 for systematic use, it is often better for the caller to verify explicitly
4285 and report failures in a more robust fashion. Set this to True if doing this
4286 in order to avoid running a redundant verification. If the IR is actually
4287 invalid, behavior is undefined.
4288 file: The file like object to write to. Defaults to sys.stdout.
4289 binary: Whether to write bytes (True) or str (False). Defaults to False.
4290 skip_regions: Whether to skip printing regions. Defaults to False.)")
4292 "desired_version"_a = nb::none(),
4294 Write the bytecode form of the operation to a file like object.
4297 file: The file like object to write to.
4298 desired_version: Optional version of bytecode to emit.
4300 The bytecode writer status.)")
4303 "binary"_a =
false,
"large_elements_limit"_a = nb::none(),
4304 "large_resource_limit"_a = nb::none(),
"enable_debug_info"_a =
false,
4305 "pretty_debug_info"_a =
false,
"print_generic_op_form"_a =
false,
4306 "use_local_scope"_a =
false,
"use_name_loc_as_prefix"_a =
false,
4307 "assume_verified"_a =
false,
"skip_regions"_a =
false,
4309 Gets the assembly form of the operation with all options available.
4312 binary: Whether to return a bytes (True) or str (False) object. Defaults to
4314 ... others ...: See the print() method for common keyword arguments for
4315 configuring the printout.
4317 Either a bytes or str object, depending on the setting of the `binary`
4320 "Verify the operation. Raises MLIRError if verification fails, and "
4321 "returns true otherwise.")
4323 "Puts self immediately after the other operation in its parent "
4326 "Puts self immediately before the other operation in its parent "
4330 Checks if this operation is before another in the same block.
4333 other: Another operation in the same parent block.
4336 True if this operation is before `other` in the operation list of the parent block.)")
4340 const nb::object &ip) -> nb::typed<nb::object, PyOperation> {
4341 return self.getOperation().clone(ip);
4343 "ip"_a = nb::none(),
4345 Creates a deep copy of the operation.
4348 ip: Optional insertion point where the cloned operation should be inserted.
4349 If None, the current insertion point is used. If False, the operation
4353 A new Operation that is a clone of this operation.)")
4355 "detach_from_parent",
4360 throw nb::value_error(
"Detached operation has no parent.");
4365 "Detaches the operation from its parent block.")
4373 "Reports if the operation is attached to its parent block.")
4377 Erases the operation and frees its memory.
4380 After erasing, any Python references to the operation become invalid.)")
4385 PyWalkOrder walkOrder, std::optional<nb::object> opClass) {
4387 return self.walk(callback, walkOrder);
4392 self.getOperation().getContext(), mlirOp)
4394 if (nb::isinstance(opview, *opClass))
4395 return callback(mlirOp);
4401 "op_class"_a = nb::none(),
4403 nb::sig(
"def walk(self, callback: Callable[[Operation], WalkResult], walk_order: WalkOrder = ..., op_class: type[OpView] | None = None) -> None"),
4406 Walks the operation tree with a callback function.
4408 If op_class is provided, the callback is only invoked on operations
4409 of that type; all other operations are skipped silently.
4412 callback: A callable that takes an Operation and returns a WalkResult.
4413 walk_order: The order of traversal (PRE_ORDER or POST_ORDER).
4414 op_class: If provided, only operations of this type are passed to the callback.)")
4420 MlirIdentifier opName =
4424 self.getOperation().getContext()->get());
4426 "trait_cls"_a,
"Checks if the operation has a given trait.");
4428 nb::class_<PyOperation, PyOperationBase>(m,
"Operation")
4431 [](std::string_view name,
4432 std::optional<std::vector<PyType *>> results,
4433 std::optional<std::vector<PyValue *>> operands,
4434 std::optional<nb::typed<nb::dict, nb::str, PyAttribute>>
4436 std::optional<std::vector<PyBlock *>> successors,
int regions,
4437 const std::optional<PyLocation> &location,
4438 const nb::object &maybeIp,
4439 bool inferType) -> nb::typed<nb::object, PyOperation> {
4441 std::vector<MlirValue> mlirOperands;
4443 mlirOperands.reserve(operands->size());
4444 for (
PyValue *operand : *operands) {
4446 throw nb::value_error(
"operand value cannot be None");
4447 mlirOperands.push_back(operand->get());
4451 PyLocation pyLoc = maybeGetTracebackLocation(location);
4453 name, results, mlirOperands.data(), mlirOperands.size(),
4454 attributes, successors, regions, pyLoc, maybeIp, inferType);
4456 "name"_a,
"results"_a = nb::none(),
"operands"_a = nb::none(),
4457 "attributes"_a = nb::none(),
"successors"_a = nb::none(),
4458 "regions"_a = 0,
"loc"_a = nb::none(),
"ip"_a = nb::none(),
4459 "infer_type"_a =
false,
4461 Creates a new operation.
4464 name: Operation name (e.g. `dialect.operation`).
4465 results: Optional sequence of Type representing op result types.
4466 operands: Optional operands of the operation.
4467 attributes: Optional Dict of {str: Attribute}.
4468 successors: Optional List of Block for the operation's successors.
4469 regions: Number of regions to create (default = 0).
4470 location: Optional Location object (defaults to resolve from context manager).
4471 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).
4472 infer_type: Whether to infer result types (default = False).
4474 A new detached Operation object. Detached operations can be added to blocks, which causes them to become attached.)")
4477 [](
const std::string &sourceStr,
const std::string &sourceName,
4479 -> nb::typed<nb::object, PyOpView> {
4483 "source"_a, nb::kw_only(),
"source_name"_a =
"",
4484 "context"_a = nb::none(),
4485 "Parses an operation. Supports both text assembly format and binary "
4488 "Gets a capsule wrapping the MlirOperation.")
4491 "Creates an Operation from a capsule wrapping MlirOperation.")
4494 [](nb::object self) -> nb::typed<nb::object, PyOperation> {
4497 "Returns self (the operation).")
4500 [](
PyOperation &self) -> nb::typed<nb::object, PyOpView> {
4501 return self.createOpView();
4504 Returns an OpView of this operation.
4507 If the operation has a registered and loaded dialect then this OpView will
4508 be concrete wrapper class.)")
4510 "Returns the block containing this operation.")
4516 "Returns the list of Operation successors.")
4518 "replace_uses_of_with",
4523 "Replaces uses of the 'of' value with the 'with' value inside the "
4526 "Invalidate the operation.");
4529 nb::class_<PyOpView, PyOperationBase>(m,
"OpView")
4530 .def(nb::init<nb::typed<nb::object, PyOperation>>(),
"operation"_a)
4533 [](
PyOpView *self, std::string_view name,
4534 std::tuple<int, bool> opRegionSpec,
4535 nb::object operandSegmentSpecObj,
4536 nb::object resultSegmentSpecObj,
4537 std::optional<nb::sequence> resultTypeList,
4538 nb::sequence operandList,
4539 std::optional<nb::typed<nb::dict, nb::str, PyAttribute>>
4541 std::optional<std::vector<PyBlock *>> successors,
4542 std::optional<int> regions,
4543 const std::optional<PyLocation> &location,
4544 const nb::object &maybeIp) {
4545 PyLocation pyLoc = maybeGetTracebackLocation(location);
4547 name, opRegionSpec, operandSegmentSpecObj,
4548 resultSegmentSpecObj, resultTypeList, operandList,
4549 attributes, successors, regions, pyLoc, maybeIp));
4551 "name"_a,
"opRegionSpec"_a,
4552 "operandSegmentSpecObj"_a = nb::none(),
4553 "resultSegmentSpecObj"_a = nb::none(),
"results"_a = nb::none(),
4554 "operands"_a = nb::none(),
"attributes"_a = nb::none(),
4555 "successors"_a = nb::none(),
"regions"_a = nb::none(),
4556 "loc"_a = nb::none(),
"ip"_a = nb::none())
4559 [](
PyOpView &self) -> nb::typed<nb::object, PyOperation> {
4560 return self.getOperationObject();
4562 .def_prop_ro(
"opview",
4563 [](nb::object self) -> nb::typed<nb::object, PyOpView> {
4568 [](
PyOpView &self) {
return nb::str(self.getOperationObject()); })
4574 "Returns the list of Operation successors.")
4577 [](
PyOpView &self) { self.getOperation().setInvalid(); },
4578 "Invalidate the operation.");
4579 opViewClass.attr(
"_ODS_REGIONS") = nb::make_tuple(0,
true);
4580 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = nb::none();
4581 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = nb::none();
4586 [](nb::handle cls, std::optional<nb::sequence> resultTypeList,
4587 nb::sequence operandList,
4588 std::optional<nb::typed<nb::dict, nb::str, PyAttribute>> attributes,
4589 std::optional<std::vector<PyBlock *>> successors,
4590 std::optional<int> regions, std::optional<PyLocation> location,
4591 const nb::object &maybeIp) {
4592 std::string name = nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
4593 std::tuple<int, bool> opRegionSpec =
4594 nb::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
4595 nb::object operandSegmentSpec = cls.attr(
"_ODS_OPERAND_SEGMENTS");
4596 nb::object resultSegmentSpec = cls.attr(
"_ODS_RESULT_SEGMENTS");
4597 PyLocation pyLoc = maybeGetTracebackLocation(location);
4599 resultSegmentSpec, resultTypeList,
4600 operandList, attributes, successors,
4601 regions, pyLoc, maybeIp);
4603 "cls"_a,
"results"_a = nb::none(),
"operands"_a = nb::none(),
4604 "attributes"_a = nb::none(),
"successors"_a = nb::none(),
4605 "regions"_a = nb::none(),
"loc"_a = nb::none(),
"ip"_a = nb::none(),
4607 nb::sig(
"def build_generic(cls, results: Sequence[Type] | None = None, operands: Sequence[Value] | None = None, attributes: dict[str, Attribute] | None = None, successors: Sequence[Block] | None = None, regions: int | None = None, loc: Location | None = None, ip: InsertionPoint | None = None) -> typing.Self"),
4609 "Builds a specific, generated OpView based on class level attributes.");
4611 [](
const nb::object &cls,
const std::string &sourceStr,
4612 const std::string &sourceName,
4622 std::string clsOpName =
4623 nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
4626 std::string_view parsedOpName(identifier.
data, identifier.
length);
4627 if (clsOpName != parsedOpName)
4628 throw MLIRError(
join(
"Expected a '", clsOpName,
"' op, got: '",
4629 parsedOpName,
"'"));
4632 "cls"_a,
"source"_a, nb::kw_only(),
"source_name"_a =
"",
4633 "context"_a = nb::none(),
4635 nb::sig(
"def parse(cls, source: str, *, source_name: str = '', context: Context | None = None) -> typing.Self"),
4637 "Parses a specific, generated OpView based on class level attributes.");
4639 [](nb::object &self, nb::type_object &traitCls,
4643 std::string opName = nb::cast<std::string>(self.attr(
"OPERATION_NAME"));
4646 traitTypeID.
get(), context->
get());
4648 "cls"_a,
"trait_cls"_a,
"context"_a = nb::none(),
4649 "Checks if the operation has a given trait.");
4656 nb::class_<PyRegion>(m,
"Region")
4660 return PyBlockList(self.getParentOperation(), self.get());
4662 "Returns a forward-optimized sequence of blocks.")
4665 [](
PyRegion &self) -> nb::typed<nb::object, PyOpView> {
4666 return self.getParentOperation()->createOpView();
4668 "Returns the operation owning this region.")
4676 "Iterates over blocks in the region.")
4680 return self.get().ptr == other.
get().ptr;
4682 "Compares two regions for pointer equality.")
4684 "__eq__", [](
PyRegion &self, nb::object &other) {
return false; },
4685 "Compares region with non-region object (always returns False).");
4690 nb::class_<PyBlock>(m,
"Block")
4692 "Gets a capsule wrapping the MlirBlock.")
4695 [](
PyBlock &self) -> nb::typed<nb::object, PyOpView> {
4696 return self.getParentOperation()->createOpView();
4698 "Returns the owning operation of this block.")
4703 return PyRegion(self.getParentOperation(), region);
4705 "Returns the owning region of this block.")
4711 "Returns a list of block arguments.")
4720 Appends an argument of the specified type to the block.
4723 type: The type of the argument to add.
4724 loc: The source location for the argument.
4727 The newly added block argument.)")
4735 Erases the argument at the specified index.
4738 index: The index of the argument to erase.)")
4744 "Returns a forward-optimized sequence of operations.")
4747 [](
PyRegion &parent, nb::typed<nb::sequence, PyType> pyArgTypes,
4748 const std::optional<nb::typed<nb::sequence, PyLocation>>
4751 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
4755 "parent"_a,
"arg_types"_a = nb::list(),
"arg_locs"_a = std::nullopt,
4756 "Creates and returns a new Block at the beginning of the given "
4757 "region (with given argument types and locations).")
4761 MlirBlock
b = self.get();
4768 Appends this block to a region.
4770 Transfers ownership if the block is currently owned by another region.
4773 region: The region to append the block to.)")
4776 [](
PyBlock &self,
const nb::args &pyArgTypes,
4777 const std::optional<nb::typed<nb::sequence, PyLocation>>
4781 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
4784 return PyBlock(self.getParentOperation(), block);
4786 "arg_types"_a, nb::kw_only(),
"arg_locs"_a = std::nullopt,
4787 "Creates and returns a new Block before this block "
4788 "(with given argument types and locations).")
4791 [](
PyBlock &self,
const nb::args &pyArgTypes,
4792 const std::optional<nb::typed<nb::sequence, PyLocation>>
4796 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
4799 return PyBlock(self.getParentOperation(), block);
4801 "arg_types"_a, nb::kw_only(),
"arg_locs"_a = std::nullopt,
4802 "Creates and returns a new Block after this block "
4803 "(with given argument types and locations).")
4808 MlirOperation firstOperation =
4813 "Iterates over operations in the block.")
4817 return self.get().ptr == other.
get().ptr;
4819 "Compares two blocks for pointer equality.")
4821 "__eq__", [](
PyBlock &self, nb::object &other) {
return false; },
4822 "Compares block with non-block object (always returns False).")
4824 "__hash__", [](
PyBlock &self) {
return hash(self.get().ptr); },
4825 "Returns the hash value of the block.")
4833 return printAccum.
join();
4835 "Returns the assembly form of the block.")
4845 self.getParentOperation().getObject());
4849 Appends an operation to this block.
4851 If the operation is currently in another block, it will be moved.
4854 operation: The operation to append to the block.)")
4860 "Returns the list of Block successors.")
4866 "Returns the list of Block predecessors.");
4872 nb::class_<PyInsertionPoint>(m,
"InsertionPoint")
4873 .def(nb::init<PyBlock &>(),
"block"_a,
4874 "Inserts after the last operation but still inside the block.")
4876 "Enters the insertion point as a context manager.",
4877 nb::sig(
"def __enter__(self, /) -> InsertionPoint"))
4879 "exc_value"_a.none(),
"traceback"_a.none(),
4880 "Exits the insertion point context manager.")
4881 .def_prop_ro_static(
4886 throw nb::value_error(
"No current InsertionPoint");
4889 nb::sig(
"def current(/) -> InsertionPoint"),
4890 "Gets the InsertionPoint bound to the current thread or raises "
4891 "ValueError if none has been set.")
4892 .def(nb::init<PyOperationBase &>(),
"beforeOperation"_a,
4893 "Inserts before a referenced operation.")
4896 Creates an insertion point at the beginning of a block.
4899 block: The block at whose beginning operations should be inserted.
4902 An InsertionPoint at the block's beginning.)")
4906 Creates an insertion point before a block's terminator.
4909 block: The block whose terminator to insert before.
4912 An InsertionPoint before the terminator.
4915 ValueError: If the block has no terminator.)")
4918 Creates an insertion point immediately after an operation.
4921 operation: The operation after which to insert.
4924 An InsertionPoint after the operation.)")
4927 Inserts an operation at this insertion point.
4930 operation: The operation to insert.)")
4933 "Returns the block that this `InsertionPoint` points to.")
4937 -> std::optional<nb::typed<nb::object, PyOperation>> {
4938 auto refOperation = self.getRefOperation();
4940 return refOperation->getObject();
4943 "The reference operation before which new operations are "
4944 "inserted, or None if the insertion point is at the end of "
4950 nb::class_<PyAttribute>(m,
"Attribute")
4953 .def(nb::init<PyAttribute &>(),
"cast_from_type"_a,
4954 "Casts the passed attribute to the generic `Attribute`.")
4956 "Gets a capsule wrapping the MlirAttribute.")
4959 "Creates an Attribute from a capsule wrapping `MlirAttribute`.")
4963 -> nb::typed<nb::object, PyAttribute> {
4967 if (mlirAttributeIsNull(attr))
4968 throw MLIRError(
"Unable to parse attribute", errors.
take());
4971 "asm"_a,
"context"_a = nb::none(),
4972 "Parses an attribute from an assembly form. Raises an `MLIRError` on "
4976 [](
PyAttribute &self) -> nb::typed<nb::object, PyMlirContext> {
4977 return self.getContext().getObject();
4979 "Context that owns the `Attribute`.")
4982 [](
PyAttribute &self) -> nb::typed<nb::object, PyType> {
4986 "Returns the type of the `Attribute`.")
4992 nb::keep_alive<0, 1>(),
4994 Binds a name to the attribute, creating a `NamedAttribute`.
4997 name: The name to bind to the `Attribute`.
5000 A `NamedAttribute` with the given name and this attribute.)")
5004 "Compares two attributes for equality.")
5006 "__eq__", [](
PyAttribute &self, nb::object &other) {
return false; },
5007 "Compares attribute with non-attribute object (always returns "
5011 "Returns the hash value of the attribute.")
5021 return printAccum.
join();
5023 "Returns the assembly form of the Attribute.")
5033 printAccum.
parts.append(
"Attribute(");
5036 printAccum.
parts.append(
")");
5037 return printAccum.
join();
5039 "Returns a string representation of the attribute.")
5045 "mlirTypeID was expected to be non-null.");
5048 "Returns the `TypeID` of the attribute.")
5051 [](
PyAttribute &self) -> nb::typed<nb::object, PyAttribute> {
5052 return self.maybeDownCast();
5054 "Downcasts the attribute to a more specific attribute if possible.");
5059 nb::class_<PyNamedAttribute>(m,
"NamedAttribute")
5064 printAccum.
parts.append(
"NamedAttribute(");
5065 printAccum.
parts.append(
5068 printAccum.
parts.append(
"=");
5072 printAccum.
parts.append(
")");
5073 return printAccum.
join();
5075 "Returns a string representation of the named attribute.")
5081 "The name of the `NamedAttribute` binding.")
5085 nb::keep_alive<0, 1>(), nb::sig(
"def attr(self) -> Attribute"),
5086 "The underlying generic attribute of the `NamedAttribute` binding.");
5091 nb::class_<PyType>(m,
"Type")
5094 .def(nb::init<PyType &>(),
"cast_from_type"_a,
5095 "Casts the passed type to the generic `Type`.")
5097 "Gets a capsule wrapping the `MlirType`.")
5099 "Creates a Type from a capsule wrapping `MlirType`.")
5102 [](std::string typeSpec,
5111 "asm"_a,
"context"_a = nb::none(),
5113 Parses the assembly form of a type.
5115 Returns a Type object or raises an `MLIRError` if the type cannot be parsed.
5117 See also: https://mlir.llvm.org/docs/LangRef/#type-system)")
5120 [](
PyType &self) -> nb::typed<nb::object, PyMlirContext> {
5121 return self.getContext().getObject();
5123 "Context that owns the `Type`.")
5125 "__eq__", [](
PyType &self,
PyType &other) {
return self == other; },
5126 "Compares two types for equality.")
5128 "__eq__", [](
PyType &self, nb::object &other) {
return false; },
5130 "Compares type with non-type object (always returns False).")
5132 "__hash__", [](
PyType &self) {
return hash(self.get().ptr); },
5133 "Returns the hash value of the `Type`.")
5142 return printAccum.
join();
5144 "Returns the assembly form of the `Type`.")
5153 printAccum.
parts.append(
"Type(");
5156 printAccum.
parts.append(
")");
5157 return printAccum.
join();
5159 "Returns a string representation of the `Type`.")
5162 [](
PyType &self) -> nb::typed<nb::object, PyType> {
5163 return self.maybeDownCast();
5165 "Downcasts the Type to a more specific `Type` if possible.")
5172 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(self)));
5173 throw nb::value_error(
join(origRepr,
" has no typeid.").c_str());
5175 "Returns the `TypeID` of the `Type`, or raises `ValueError` if "
5182 nb::class_<PyTypeID>(m,
"TypeID")
5184 "Gets a capsule wrapping the `MlirTypeID`.")
5186 "Creates a `TypeID` from a capsule wrapping `MlirTypeID`.")
5193 "Compares two `TypeID`s for equality.")
5196 [](
PyTypeID &self,
const nb::object &other) {
return false; },
5197 "Compares TypeID with non-TypeID object (always returns False).")
5206 "Returns the hash value of the `TypeID`.");
5211 m.attr(
"_T") = nb::type_var(
"_T",
"bound"_a = m.attr(
"Type"));
5213 nb::class_<PyValue>(m,
"Value", nb::is_generic(),
5214 nb::sig(
"class Value(typing.Generic[_T])"))
5215 .def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(),
"value"_a,
5216 "Creates a Value reference from another `Value`.")
5218 "Gets a capsule wrapping the `MlirValue`.")
5220 "Creates a `Value` from a capsule wrapping `MlirValue`.")
5223 [](
PyValue &self) -> nb::typed<nb::object, PyMlirContext> {
5224 return self.getParentOperation()->getContext().getObject();
5226 "Context in which the value lives.")
5233 -> nb::typed<nb::object, std::variant<PyOpView, PyBlock>> {
5234 MlirValue v = self.get();
5238 "expected the owner of the value in Python to match "
5241 return self.getParentOperation()->createOpView();
5246 return nb::cast(
PyBlock(self.getParentOperation(), block));
5249 assert(
false &&
"Value must be a block argument or an op result");
5252 "Returns the owner of the value (`Operation` for results, `Block` "
5260 "Returns an iterator over uses of this value.")
5264 return self.get().ptr == other.
get().ptr;
5266 "Compares two values for pointer equality.")
5268 "__eq__", [](
PyValue &self, nb::object other) {
return false; },
5269 "Compares value with non-value object (always returns False).")
5271 "__hash__", [](
PyValue &self) {
return hash(self.get().ptr); },
5272 "Returns the hash value of the value.")
5277 printAccum.
parts.append(
"Value(");
5280 printAccum.
parts.append(
")");
5281 return printAccum.
join();
5284 Returns the string form of the value.
5286 If the value is a block argument, this is the assembly form of its type and the
5287 position in the argument list. If the value is an operation result, this is
5288 equivalent to printing the operation that produced it.
5292 [](
PyValue &self,
bool useLocalScope,
bool useNameLocAsPrefix) {
5297 if (useNameLocAsPrefix)
5299 MlirAsmState valueState =
5306 return printAccum.
join();
5308 "use_local_scope"_a =
false,
"use_name_loc_as_prefix"_a =
false,
5310 Returns the string form of value as an operand.
5313 use_local_scope: Whether to use local scope for naming.
5314 use_name_loc_as_prefix: Whether to use the location attribute (NameLoc) as prefix.
5317 The value's name as it appears in IR (e.g., `%0`, `%arg0`).)")
5322 MlirAsmState valueState = state.
get();
5326 return printAccum.
join();
5329 "Returns the string form of value as an operand (i.e., the ValueID).")
5333 return PyType(self.getParentOperation()->getContext(),
5337 "Returns the type of the value.", nb::sig(
"def type(self) -> _T"))
5343 "type"_a,
"Sets the type of the value.",
5344 nb::sig(
"def set_type(self, type: _T)"))
5346 "replace_all_uses_with",
5350 "Replace all uses of value with the new value, updating anything in "
5351 "the IR that uses `self` to use the other value instead.")
5353 "replace_all_uses_except",
5355 MlirOperation exceptedUser = exception.
get();
5360 "replace_all_uses_except",
5362 std::vector<PyOperation> &exceptions) {
5364 std::vector<MlirOperation> exceptionOps;
5366 exceptionOps.push_back(exception);
5368 self, with,
static_cast<intptr_t>(exceptionOps.size()),
5369 exceptionOps.data());
5374 [](
PyValue &self) {
return self.maybeDownCast(); },
5375 "Downcasts the `Value` to a more specific kind if possible.")
5384 "Returns the source location of the value.");
5390 nb::class_<PyAsmState>(m,
"AsmState")
5391 .def(nb::init<PyValue &, bool>(),
"value"_a,
"use_local_scope"_a =
false,
5393 Creates an `AsmState` for consistent SSA value naming.
5396 value: The value to create state for.
5397 use_local_scope: Whether to use local scope for naming.)")
5398 .def(nb::init<PyOperationBase &, bool>(), "op"_a,
5399 "use_local_scope"_a =
false,
5401 Creates an AsmState for consistent SSA value naming.
5404 op: The operation to create state for.
5405 use_local_scope: Whether to use local scope for naming.)");
5410 nb::class_<PySymbolTable>(m,
"SymbolTable")
5411 .def(nb::init<PyOperationBase &>(),
5413 Creates a symbol table for an operation.
5416 operation: The `Operation` that defines a symbol table (e.g., a `ModuleOp`).
5419 TypeError: If the operation is not a symbol table.)")
5423 const std::string &name) -> nb::typed<nb::object, PyOpView> {
5424 return self.dunderGetItem(name);
5427 Looks up a symbol by name in the symbol table.
5430 name: The name of the symbol to look up.
5433 The operation defining the symbol.
5436 KeyError: If the symbol is not found.)")
5439 Inserts a symbol operation into the symbol table.
5442 operation: An operation with a symbol name to insert.
5445 The symbol name attribute of the inserted operation.
5448 ValueError: If the operation does not have a symbol name.)")
5451 Erases a symbol operation from the symbol table.
5454 operation: The symbol operation to erase.
5457 The operation is also erased from the IR and invalidated.)")
5459 "Deletes a symbol by name from the symbol table.")
5466 "Checks if a symbol with the given name exists in the table.")
5469 "name"_a,
"Sets the symbol name for a symbol operation.")
5471 "Gets the symbol name from a symbol operation.")
5473 "Gets the visibility attribute of a symbol operation.")
5476 "Sets the visibility attribute of a symbol operation.")
5477 .def_static(
"replace_all_symbol_uses",
5479 "new_symbol"_a,
"from_op"_a,
5480 "Replaces all uses of a symbol with a new symbol name within "
5481 "the given operation.")
5483 "from_op"_a,
"all_sym_uses_visible"_a,
"callback"_a,
5484 "Walks symbol tables starting from an operation with a "
5485 "callback function.");
5525 nb::module_::import_(
"atexit").attr(
"register")(
void mlirSetGlobalDebugTypes(const char **types, intptr_t n)
MLIR_CAPI_EXPORTED void mlirSetGlobalDebugType(const char *type)
Sets the current debug type, similarly to -debug-only=type in the command-line tools.
MLIR_CAPI_EXPORTED bool mlirIsGlobalDebugEnabled()
Retuns true if the global debugging flag is set, false otherwise.
MLIR_CAPI_EXPORTED void mlirEnableGlobalDebug(bool enable)
Sets the global debugging flag.
static const char kDumpDocstring[]
static const char kModuleParseDocstring[]
static size_t hash(const T &value)
Local helper to compute std::hash for a value.
static nb::object createCustomDialectWrapper(const std::string &dialectNamespace, nb::object dialectDescriptor)
std::string join(const Ts &...args)
Helper function to concatenate arguments into a std::string.
static const char kValueReplaceAllUsesExceptDocstring[]
MlirContext mlirModuleGetContext(MlirModule module)
size_t mlirModuleHashValue(MlirModule mod)
intptr_t mlirBlockGetNumPredecessors(MlirBlock block)
MlirIdentifier mlirOperationGetName(MlirOperation op)
bool mlirValueIsABlockArgument(MlirValue value)
intptr_t mlirOperationGetNumRegions(MlirOperation op)
MlirBlock mlirOperationGetBlock(MlirOperation op)
void mlirBlockArgumentSetType(MlirValue value, MlirType type)
void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n, MlirNamedAttribute const *attributes)
MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos)
MlirModule mlirModuleCreateParseFromFile(MlirContext context, MlirStringRef fileName)
bool mlirOperationNameHasTrait(MlirStringRef opName, MlirTypeID traitTypeID, MlirContext context)
MlirAsmState mlirAsmStateCreateForValue(MlirValue value, MlirOpPrintingFlags flags)
intptr_t mlirOperationGetNumResults(MlirOperation op)
void mlirOperationDestroy(MlirOperation op)
MlirContext mlirAttributeGetContext(MlirAttribute attribute)
MlirType mlirValueGetType(MlirValue value)
void mlirBlockPrint(MlirBlock block, MlirStringCallback callback, void *userData)
MlirOpPrintingFlags mlirOpPrintingFlagsCreate()
bool mlirModuleEqual(MlirModule lhs, MlirModule rhs)
void mlirOpPrintingFlagsElideLargeElementsAttrs(MlirOpPrintingFlags flags, intptr_t largeElementLimit)
void mlirOperationSetSuccessor(MlirOperation op, intptr_t pos, MlirBlock block)
MlirOperation mlirOperationGetNextInBlock(MlirOperation op)
void mlirOpPrintingFlagsEnableDebugInfo(MlirOpPrintingFlags flags, bool enable, bool prettyForm)
MlirOperation mlirModuleGetOperation(MlirModule module)
void mlirOpPrintingFlagsElideLargeResourceString(MlirOpPrintingFlags flags, intptr_t largeResourceLimit)
void mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags)
intptr_t mlirBlockArgumentGetArgNumber(MlirValue value)
MlirBlock mlirOperationGetSuccessor(MlirOperation op, intptr_t pos)
bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2)
MlirAsmState mlirAsmStateCreateForOperation(MlirOperation op, MlirOpPrintingFlags flags)
bool mlirOperationEqual(MlirOperation op, MlirOperation other)
void mlirOpPrintingFlagsAssumeVerified(MlirOpPrintingFlags flags)
void mlirBytecodeWriterConfigDestroy(MlirBytecodeWriterConfig config)
MlirBlock mlirBlockGetSuccessor(MlirBlock block, intptr_t pos)
void mlirModuleDestroy(MlirModule module)
MlirModule mlirModuleCreateEmpty(MlirLocation location)
void mlirOpPrintingFlagsPrintGenericOpForm(MlirOpPrintingFlags flags)
MlirOperation mlirOperationGetParentOperation(MlirOperation op)
void mlirValueSetType(MlirValue value, MlirType type)
intptr_t mlirOperationGetNumSuccessors(MlirOperation op)
MlirDialect mlirAttributeGetDialect(MlirAttribute attr)
void mlirLocationPrint(MlirLocation location, MlirStringCallback callback, void *userData)
void mlirOperationSetAttributeByName(MlirOperation op, MlirStringRef name, MlirAttribute attr)
void mlirOperationSetOperand(MlirOperation op, intptr_t pos, MlirValue newValue)
MlirOperation mlirOpResultGetOwner(MlirValue value)
MlirModule mlirModuleCreateParse(MlirContext context, MlirStringRef module)
size_t mlirOperationHashValue(MlirOperation op)
void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n, MlirType const *results)
MlirOperation mlirOperationClone(MlirOperation op)
MlirBlock mlirBlockArgumentGetOwner(MlirValue value)
void mlirBlockArgumentSetLocation(MlirValue value, MlirLocation loc)
MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos)
MlirOpOperand mlirOperationGetOpOperand(MlirOperation op, intptr_t pos)
MlirLocation mlirOperationGetLocation(MlirOperation op)
MlirAttribute mlirOperationGetAttributeByName(MlirOperation op, MlirStringRef name)
MlirTypeID mlirAttributeGetTypeID(MlirAttribute attr)
void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n, MlirRegion const *regions)
void mlirOperationSetLocation(MlirOperation op, MlirLocation loc)
MlirType mlirAttributeGetType(MlirAttribute attribute)
bool mlirOperationRemoveAttributeByName(MlirOperation op, MlirStringRef name)
bool mlirValueIsAOpResult(MlirValue value)
MlirBlock mlirBlockGetPredecessor(MlirBlock block, intptr_t pos)
size_t mlirOperationStructuralHashValue(MlirOperation op, uint32_t flags)
MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos)
MlirOperation mlirOperationCreate(MlirOperationState *state)
bool mlirOperationIsStructurallyEquivalent(MlirOperation lhs, MlirOperation rhs, uint32_t flags)
void mlirBytecodeWriterConfigDesiredEmitVersion(MlirBytecodeWriterConfig flags, int64_t version)
MlirAttribute mlirAttributeParseGet(MlirContext context, MlirStringRef attr)
void mlirOperationRemoveFromParent(MlirOperation op)
intptr_t mlirBlockGetNumSuccessors(MlirBlock block)
MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos)
void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags)
void mlirValueDump(MlirValue value)
void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData)
MlirBlock mlirModuleGetBody(MlirModule module)
MlirOperation mlirOperationCreateParse(MlirContext context, MlirStringRef sourceStr, MlirStringRef sourceName)
void mlirAsmStateDestroy(MlirAsmState state)
Destroys printing flags created with mlirAsmStateCreate.
MlirContext mlirOperationGetContext(MlirOperation op)
intptr_t mlirOpResultGetResultNumber(MlirValue value)
void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n, MlirBlock const *successors)
MlirBytecodeWriterConfig mlirBytecodeWriterConfigCreate()
void mlirOpPrintingFlagsPrintNameLocAsPrefix(MlirOpPrintingFlags flags)
void mlirOpPrintingFlagsSkipRegions(MlirOpPrintingFlags flags)
void mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n, MlirValue const *operands)
MlirOperationState mlirOperationStateGet(MlirStringRef name, MlirLocation loc)
intptr_t mlirOperationGetNumOperands(MlirOperation op)
void mlirTypeDump(MlirType type)
intptr_t mlirOperationGetNumAttributes(MlirOperation op)
static PyObject * mlirPythonTypeIDToCapsule(MlirTypeID typeID)
Creates a capsule object encapsulating the raw C-API MlirTypeID.
static PyObject * mlirPythonContextToCapsule(MlirContext context)
Creates a capsule object encapsulating the raw C-API MlirContext.
#define MLIR_PYTHON_MAYBE_DOWNCAST_ATTR
Attribute on MLIR Python objects that expose a function for downcasting the corresponding Python obje...
static MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule)
Extracts an MlirOperations from a capsule as produced from mlirPythonOperationToCapsule.
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
static MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule)
Extracts an MlirAttribute from a capsule as produced from mlirPythonAttributeToCapsule.
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
static PyObject * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
static MlirModule mlirPythonCapsuleToModule(PyObject *capsule)
Extracts an MlirModule from a capsule as produced from mlirPythonModuleToCapsule.
static MlirContext mlirPythonCapsuleToContext(PyObject *capsule)
Extracts a MlirContext from a capsule as produced from mlirPythonContextToCapsule.
static MlirTypeID mlirPythonCapsuleToTypeID(PyObject *capsule)
Extracts an MlirTypeID from a capsule as produced from mlirPythonTypeIDToCapsule.
#define MLIR_PYTHON_CAPI_VALUE_CASTER_REGISTER_ATTR
Attribute on main C extension module (_mlir) that corresponds to the value caster registration bindin...
static PyObject * mlirPythonBlockToCapsule(MlirBlock block)
Creates a capsule object encapsulating the raw C-API MlirBlock.
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
static MlirType mlirPythonCapsuleToType(PyObject *capsule)
Extracts an MlirType from a capsule as produced from mlirPythonTypeToCapsule.
static MlirValue mlirPythonCapsuleToValue(PyObject *capsule)
Extracts an MlirValue from a capsule as produced from mlirPythonValueToCapsule.
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
#define MLIR_PYTHON_CAPI_TYPE_CASTER_REGISTER_ATTR
Attribute on main C extension module (_mlir) that corresponds to the type caster registration binding...
static PyObject * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
static SmallVector< Value > slice(OpBuilder &b, Location loc, Value value, VectorType nativeType)
Accumulates into a file, either writing text (default) or binary.
A CRTP base class for pseudo-containers willing to support Python-type slicing access on top of index...
static void bind(nanobind::module_ &m)
Sliceable(intptr_t startIndex, intptr_t length, intptr_t step)
intptr_t wrapIndex(intptr_t index)
ReferrentTy * get() const
PyMlirContextRef & getContext()
Accesses the context reference.
BaseContextObject(PyMlirContextRef ref)
static PyLocation & resolve()
Used in function arguments when None should resolve to the current context manager set instance.
static PyMlirContext & resolve()
Wrapper around an MlirAsmState.
PyAsmState(MlirValue value, bool useLocalScope)
Wrapper around the generic MlirAttribute.
PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirAttribute.
MlirAttribute get() const
bool operator==(const PyAttribute &other) const
static PyAttribute createFromCapsule(const nanobind::object &capsule)
Creates a PyAttribute from the MlirAttribute wrapped by a capsule.
nanobind::typed< nanobind::object, PyAttribute > maybeDownCast()
A list of block arguments.
PyBlockArgumentList(PyOperationRef operation, MlirBlock block, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
static void bindDerived(ClassTy &c)
Python wrapper for MlirBlockArgument.
static void bindDerived(ClassTy &c)
PyBlockIterator & dunderIter()
nanobind::typed< nanobind::object, PyBlock > dunderNext()
static void bind(nanobind::module_ &m)
Blocks are exposed by the C-API as a forward-only linked list.
static void bind(nanobind::module_ &m)
PyBlockIterator dunderIter()
PyBlock appendBlock(const nanobind::args &pyArgTypes, const std::optional< nanobind::sequence > &pyArgLocs)
PyBlock dunderGetItem(intptr_t index)
A list of block predecessors.
PyBlockPredecessors(PyBlock block, PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
A list of block successors.
PyBlockSuccessors(PyBlock block, PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Wrapper around an MlirBlock.
PyOperationRef & getParentOperation()
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirBlock.
static void bindDerived(ClassTy &c)
static void bind(nanobind::module_ &m)
nanobind::class_< PyUnknownLocation, PyLocation > ClassTy
static void bind(nanobind::module_ &m)
Represents a diagnostic handler attached to the context.
void detach()
Detaches the handler. Does nothing if not attached.
nanobind::object contextEnter()
PyDiagnosticHandler(MlirContext context, nanobind::object callback)
void contextExit(const nanobind::object &excType, const nanobind::object &excVal, const nanobind::object &excTb)
Python class mirroring the C MlirDiagnostic struct.
PyDiagnostic(MlirDiagnostic diagnostic)
nanobind::typed< nanobind::object, PyLocation > getLocation()
nanobind::str getMessage()
PyDiagnosticSeverity getSeverity()
nanobind::typed< nanobind::tuple, PyDiagnostic > getNotes()
Wrapper around an MlirDialect.
Wrapper around an MlirDialectRegistry.
static PyDialectRegistry createFromCapsule(nanobind::object capsule)
nanobind::object getCapsule()
User-level dialect object.
User-level object for accessing dialects with dotted syntax such as: ctx.dialect.std.
MlirDialect getDialectForKey(const std::string &key, bool attrError)
static void bind(nanobind::module_ &m)
static const char * typeIDAttr
static bool attach(const nanobind::object &opName, const nanobind::object &target, PyMlirContext &context)
static bool attach(const nanobind::object &opName, PyMlirContext &context)
static void bind(nanobind::module_ &m)
static bool attach(const nanobind::object &opName, PyMlirContext &context)
static void bind(nanobind::module_ &m)
static void bind(nanobind::module_ &m)
static bool attach(const nanobind::object &opName, PyMlirContext &context)
static bool attach(const nanobind::object &opName, PyMlirContext &context)
static void bind(nanobind::module_ &m)
static void bindDerived(ClassTy &c)
static void bindDerived(ClassTy &c)
size_t locTracebackFramesLimit()
void setLocTracebackFramesLimit(size_t value)
void registerTracebackFileExclusion(const std::string &file)
void registerTracebackFileInclusion(const std::string &file)
OnExplicitAction tracebackActionOnExplicitLoc()
CurrentLocAction tracebackActionOnCurrentLoc()
static constexpr size_t kMaxFrames
void setLocTracebacksEnabled(bool value)
CurrentLocAction
Policy for composing Location.current with the computed location.
void setTracebackActionOnCurrentLoc(CurrentLocAction action)
OnExplicitAction
Policy for handling explicit loc= when loc_tracebacks() is active.
bool locTracebacksEnabled()
void setTracebackActionOnExplicitLoc(OnExplicitAction action)
Globals that are always accessible once the extension has been initialized.
void registerOpAdaptorImpl(const std::string &operationName, nanobind::object pyClass, bool replace=false)
Adds an operation adaptor class.
std::optional< nanobind::callable > lookupValueCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom value caster for MlirTypeID mlirTypeID.
bool loadDialectModule(std::string_view dialectNamespace)
Loads a python module corresponding to the given dialect namespace.
void addDialectSearchPrefix(std::string value)
void registerDialectImpl(const std::string &dialectNamespace, nanobind::object pyClass, bool replace=false)
Adds a concrete implementation dialect class.
static PyGlobals & get()
Most code should get the globals via this static accessor.
std::optional< nanobind::object > lookupOperationClass(std::string_view operationName)
Looks up a registered operation class (deriving from OpView) by operation name.
void registerTypeCaster(MlirTypeID mlirTypeID, nanobind::callable typeCaster, bool replace=false)
Adds a user-friendly type caster.
void registerOperationImpl(const std::string &operationName, nanobind::object pyClass, bool replace=false)
Adds a concrete implementation operation class.
void setDialectSearchPrefixes(std::vector< std::string > newValues)
std::optional< nanobind::callable > lookupTypeCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom type caster for MlirTypeID mlirTypeID.
void registerValueCaster(MlirTypeID mlirTypeID, nanobind::callable valueCaster, bool replace=false)
Adds a user-friendly value caster.
std::optional< nanobind::callable > lookupAttributeBuilder(const std::string &attributeKind)
Returns the custom Attribute builder for Attribute kind.
TracebackLoc & getTracebackLoc()
std::optional< nanobind::object > lookupDialectClass(const std::string &dialectNamespace)
Looks up a registered dialect class by namespace.
std::vector< std::string > getDialectSearchPrefixes()
Get and set the list of parent modules to search for dialect implementation classes.
void registerAttributeBuilder(const std::string &attributeKind, nanobind::callable pyFunc, bool replace=false, bool allow_existing=false)
Adds a user-friendly Attribute builder.
An insertion point maintains a pointer to a Block and a reference operation.
void insert(PyOperationBase &operationBase)
Inserts an operation.
void contextExit(const nanobind::object &excType, const nanobind::object &excVal, const nanobind::object &excTb)
static PyInsertionPoint atBlockTerminator(PyBlock &block)
Shortcut to create an insertion point before the block terminator.
static PyInsertionPoint after(PyOperationBase &op)
Shortcut to create an insertion point to the node after the specified operation.
static PyInsertionPoint atBlockBegin(PyBlock &block)
Shortcut to create an insertion point at the beginning of the block.
PyInsertionPoint(const PyBlock &block)
Creates an insertion point positioned after the last operation in the block, but still inside the blo...
static nanobind::object contextEnter(nanobind::object insertionPoint)
Enter and exit the context manager.
Wrapper around an MlirLocation.
static nanobind::object contextEnter(nanobind::object location)
Enter and exit the context manager.
static PyLocation createFromCapsule(nanobind::object capsule)
Creates a PyLocation from the MlirLocation wrapped by a capsule.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirLocation.
nanobind::typed< nanobind::object, PyLocation > maybeDownCast()
Returns the most-derived Location subclass registered for this TypeID, or self.
void contextExit(const nanobind::object &excType, const nanobind::object &excVal, const nanobind::object &excTb)
PyLocation(PyMlirContextRef contextRef, MlirLocation loc)
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
static size_t getLiveCount()
Gets the count of live context objects. Used for testing.
static nanobind::object createFromCapsule(nanobind::object capsule)
Creates a PyMlirContext from the MlirContext wrapped by a capsule.
bool getRemarksEnabled()
Whether a remark engine is enabled on the context.
void enableRemarks(PyRemarkPolicy policy, const std::optional< std::string > &outputFile, PyRemarkFormat format, const std::string &allFilter, const std::string &passedFilter, const std::string &missedFilter, const std::string &analysisFilter, const std::string &failedFilter, nanobind::object callback, std::optional< bool > printAsEmitRemarks)
Enables the optimization remark engine of the context, streaming to outputFile, to callback,...
nanobind::object attachDiagnosticHandler(nanobind::object callback)
Attaches a Python callback as a diagnostic handler, returning a registration object (internally a PyD...
void contextExit(const nanobind::object &excType, const nanobind::object &excVal, const nanobind::object &excTb)
MlirContext get()
Accesses the underlying MlirContext.
PyMlirContextRef getRef()
Gets a strong reference to this context, which will ensure it is kept alive for the life of the refer...
bool getEmitErrorDiagnostics()
void setEmitErrorDiagnostics(bool value)
Controls whether error diagnostics should be propagated to diagnostic handlers, instead of being capt...
static nanobind::object contextEnter(nanobind::object context)
Enter and exit the context manager.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirContext.
void finalizeRemarks()
Finalizes and removes the remark engine; no-op when none is enabled.
size_t getLiveModuleCount()
Gets the count of live modules associated with this context.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirModule.
PyModule(PyModule &)=delete
MlirModule get()
Gets the backing MlirModule.
static PyModuleRef forModule(MlirModule module)
Returns a PyModule reference for the given MlirModule.
static nanobind::object createFromCapsule(nanobind::object capsule)
Creates a PyModule from the MlirModule wrapped by a capsule.
static void bindDerived(ClassTy &c)
Represents a Python MlirNamedAttr, carrying an optional owned name.
PyNamedAttribute(MlirAttribute attr, std::string ownedName)
Constructs a PyNamedAttr that retains an owned name.
MlirNamedAttribute namedAttr
Template for a reference to a concrete type which captures a python reference to its underlying pytho...
nanobind::object releaseObject()
Releases the object held by this instance, returning it.
nanobind::object getObject()
Base class of operation adaptors.
static void bind(nanobind::module_ &m)
A list of operation attributes.
PyOpAttributeMap(PyOperationRef operation)
void dunderDelItem(const std::string &name)
static void bind(nanobind::module_ &m)
void dunderSetItem(const std::string &name, const PyAttribute &attr)
bool dunderContains(const std::string &name)
nanobind::typed< nanobind::object, PyAttribute > dunderGetItemNamed(const std::string &name)
nanobind::typed< nanobind::object, std::optional< PyAttribute > > get(const std::string &key, nanobind::object defaultValue)
static void forEachAttr(MlirOperation op, std::function< void(MlirStringRef, MlirAttribute)> fn)
PyNamedAttribute dunderGetItemIndexed(intptr_t index)
nanobind::typed< nanobind::object, PyOpOperand > dunderNext()
PyOpOperandIterator & dunderIter()
static void bind(nanobind::module_ &m)
A list of operation operands.
static void bindDerived(ClassTy &c)
PyOpOperandList(PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
void dunderSetItem(intptr_t index, PyValue value)
size_t getOperandNumber() const
static void bind(nanobind::module_ &m)
nanobind::typed< nanobind::object, PyOpView > getOwner() const
PyOpOperands(PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
static constexpr const char * pyClassName
Sliceable< PyOpOperandList, PyOpOperand > SliceableT
A list of operation results.
static void bindDerived(ClassTy &c)
PyOpResultList(PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
PyOperationRef & getOperation()
Python wrapper for MlirOpResult.
static void bindDerived(ClassTy &c)
A list of operation successors.
static void bindDerived(ClassTy &c)
PyOpSuccessors(PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
void dunderSetItem(intptr_t index, PyBlock block)
A PyOpView is equivalent to the C++ "Op" wrappers: these are the basis for providing more instance-sp...
PyOpView(const nanobind::object &operationObject)
static nanobind::typed< nanobind::object, PyOperation > buildGeneric(std::string_view name, std::tuple< int, bool > opRegionSpec, nanobind::object operandSegmentSpecObj, nanobind::object resultSegmentSpecObj, std::optional< nanobind::sequence > resultTypeList, nanobind::sequence operandList, std::optional< nanobind::dict > attributes, std::optional< std::vector< PyBlock * > > successors, std::optional< int > regions, PyLocation &location, const nanobind::object &maybeIp)
static nanobind::object constructDerived(const nanobind::object &cls, const nanobind::object &operation)
Construct an instance of a class deriving from OpView, bypassing its __init__ method.
Base class for PyOperation and PyOpView which exposes the primary, user visible methods for manipulat...
bool isBeforeInBlock(PyOperationBase &other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
nanobind::object getAsm(bool binary, std::optional< int64_t > largeElementsLimit, std::optional< int64_t > largeResourceLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool useNameLocAsPrefix, bool assumeVerified, bool skipRegions)
void print(std::optional< int64_t > largeElementsLimit, std::optional< int64_t > largeResourceLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool useNameLocAsPrefix, bool assumeVerified, nanobind::object fileObject, bool binary, bool skipRegions)
Implements the bound 'print' method and helps with others.
void writeBytecode(const nanobind::object &fileObject, std::optional< int64_t > bytecodeVersion)
bool verify()
Verify the operation.
virtual PyOperation & getOperation()=0
Each must provide access to the raw Operation.
void moveAfter(PyOperationBase &other)
Moves the operation before or after the other operation.
void moveBefore(PyOperationBase &other)
void walk(std::function< PyWalkResult(MlirOperation)> callback, PyWalkOrder walkOrder)
static void bind(nanobind::module_ &m)
PyOperationIterator & dunderIter()
nanobind::typed< nanobind::object, PyOpView > dunderNext()
Operations are exposed by the C-API as a forward-only linked list.
static void bind(nanobind::module_ &m)
nanobind::typed< nanobind::object, PyOpView > dunderGetItem(intptr_t index)
PyOperationIterator dunderIter()
MlirOperation get() const
static nanobind::object create(std::string_view name, std::optional< std::vector< PyType * > > results, const MlirValue *operands, size_t numOperands, std::optional< nanobind::dict > attributes, std::optional< std::vector< PyBlock * > > successors, int regions, PyLocation &location, const nanobind::object &ip, bool inferType)
Creates an operation. See corresponding python docstring.
void setInvalid()
Invalidate the operation.
PyOperation & getOperation() override
Each must provide access to the raw Operation.
static PyOperationRef parse(PyMlirContextRef contextRef, const std::string &sourceStr, const std::string &sourceName)
Parses a source string (either text assembly or bytecode), creating a detached operation.
nanobind::object clone(const nanobind::object &ip)
Clones this operation.
static nanobind::object createFromCapsule(const nanobind::object &capsule)
Creates a PyOperation from the MlirOperation wrapped by a capsule.
std::optional< PyOperationRef > getParentOperation()
Gets the parent operation or raises an exception if the operation has no parent.
nanobind::object createOpView()
Creates an OpView suitable for this operation.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirOperation.
static PyOperationRef forOperation(PyMlirContextRef contextRef, MlirOperation operation, nanobind::object parentKeepAlive=nanobind::object())
Returns a PyOperation for the given MlirOperation, optionally associating it with a parentKeepAlive.
void detachFromParent()
Detaches the operation from its parent block and updates its state accordingly.
void erase()
Erases the underlying MlirOperation, removes its pointer from the parent context's live operations ma...
PyBlock getBlock()
Gets the owning block or raises an exception if the operation has no owning block.
static PyOperationRef createDetached(PyMlirContextRef contextRef, MlirOperation operation, nanobind::object parentKeepAlive=nanobind::object())
Creates a detached operation.
PyOperation(PyMlirContextRef contextRef, MlirOperation operation)
void setAttached(const nanobind::object &parent=nanobind::object())
Regions of an op are fixed length and indexed numerically so are represented with a sequence-like con...
PyRegionList(PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Wrapper around an MlirRegion.
PyOperationRef & getParentOperation()
Bindings for MLIR symbol tables.
PyStringAttribute insert(PyOperationBase &symbol)
Inserts the given operation into the symbol table.
PySymbolTable(PyOperationBase &operation)
Constructs a symbol table for the given operation.
static PyStringAttribute getVisibility(PyOperationBase &symbol)
Gets and sets the visibility of a symbol op.
void erase(PyOperationBase &symbol)
Removes the given operation from the symbol table and erases it.
static void walkSymbolTables(PyOperationBase &from, bool allSymUsesVisible, nanobind::object callback)
Walks all symbol tables under and including 'from'.
nanobind::object dunderGetItem(const std::string &name)
Returns the symbol (opview) with the given name, throws if there is no such symbol in the table.
static void replaceAllSymbolUses(const std::string &oldSymbol, const std::string &newSymbol, PyOperationBase &from)
Replaces all symbol uses within an operation.
static PyStringAttribute getSymbolName(PyOperationBase &symbol)
Gets and sets the name of a symbol op.
void dunderDel(const std::string &name)
Removes the operation with the given name from the symbol table and erases it, throws if there is no ...
static void setSymbolName(PyOperationBase &symbol, const std::string &name)
static void setVisibility(PyOperationBase &symbol, const std::string &visibility)
Tracks an entry in the thread context stack.
static PyInsertionPoint * getDefaultInsertionPoint()
Gets the top of stack insertion point and return nullptr if not defined.
static nanobind::object pushInsertionPoint(nanobind::object insertionPoint)
PyLocation * getLocation()
static void popInsertionPoint(PyInsertionPoint &insertionPoint)
static PyLocation * getDefaultLocation()
Gets the top of stack location and returns nullptr if not defined.
static PyThreadContextEntry * getTopOfStack()
Stack management.
PyInsertionPoint * getInsertionPoint()
static nanobind::object pushLocation(nanobind::object location)
static void popLocation(PyLocation &location)
static nanobind::object pushContext(nanobind::object context)
PyMlirContext * getContext()
static void popContext(PyMlirContext &context)
static PyMlirContext * getDefaultContext()
Gets the top of stack context and return nullptr if not defined.
static std::vector< PyThreadContextEntry > & getStack()
Gets the thread local stack.
Wrapper around MlirLlvmThreadPool Python object owns the C++ thread pool.
int getMaxConcurrency() const
std::string _mlir_thread_pool_ptr() const
A TypeID provides an efficient and unique identifier for a specific C++ type.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirTypeID.
PyTypeID(MlirTypeID typeID)
bool operator==(const PyTypeID &other) const
static PyTypeID createFromCapsule(nanobind::object capsule)
Creates a PyTypeID from the MlirTypeID wrapped by a capsule.
Wrapper around the generic MlirType.
PyType(PyMlirContextRef contextRef, MlirType type)
bool operator==(const PyType &other) const
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirType.
static PyType createFromCapsule(nanobind::object capsule)
Creates a PyType from the MlirType wrapped by a capsule.
nanobind::typed< nanobind::object, PyType > maybeDownCast()
static void bindDerived(ClassTy &c)
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirValue.
PyOperationRef & getParentOperation()
PyValue(PyOperationRef parentOperation, MlirValue value)
nanobind::typed< nanobind::object, std::variant< PyBlockArgument, PyOpResult, PyValue > > maybeDownCast()
static PyValue createFromCapsule(nanobind::object capsule)
Creates a PyValue from the MlirValue wrapped by a capsule.
MLIR_CAPI_EXPORTED intptr_t mlirDiagnosticGetNumNotes(MlirDiagnostic diagnostic)
Returns the number of notes attached to the diagnostic.
MLIR_CAPI_EXPORTED MlirDiagnosticSeverity mlirDiagnosticGetSeverity(MlirDiagnostic diagnostic)
Returns the severity of the diagnostic.
MLIR_CAPI_EXPORTED void mlirDiagnosticPrint(MlirDiagnostic diagnostic, MlirStringCallback callback, void *userData)
Prints a diagnostic using the provided callback.
MLIR_CAPI_EXPORTED MlirDiagnostic mlirDiagnosticGetNote(MlirDiagnostic diagnostic, intptr_t pos)
Returns pos-th note attached to the diagnostic.
MLIR_CAPI_EXPORTED void mlirEmitError(MlirLocation location, const char *message)
Emits an error at the given location through the diagnostics engine.
MLIR_CAPI_EXPORTED MlirDiagnosticHandlerID mlirContextAttachDiagnosticHandler(MlirContext context, MlirDiagnosticHandler handler, void *userData, void(*deleteUserData)(void *))
Attaches the diagnostic handler to the context.
struct MlirDiagnostic MlirDiagnostic
MLIR_CAPI_EXPORTED void mlirContextDetachDiagnosticHandler(MlirContext context, MlirDiagnosticHandlerID id)
Detaches an attached diagnostic handler from the context given its identifier.
uint64_t MlirDiagnosticHandlerID
Opaque identifier of a diagnostic handler, useful to detach a handler.
MLIR_CAPI_EXPORTED MlirLocation mlirDiagnosticGetLocation(MlirDiagnostic diagnostic)
Returns the location at which the diagnostic is reported.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI32ArrayGet(MlirContext ctx, intptr_t size, int32_t const *values)
MLIR_CAPI_EXPORTED MlirAttribute mlirStringAttrGet(MlirContext ctx, MlirStringRef str)
Creates a string attribute in the given context containing the given string.
MLIR_CAPI_EXPORTED MlirDynamicOpTrait mlirDynamicOpTraitIsTerminatorCreate(void)
Get the dynamic op trait that indicates the operation is a terminator.
MLIR_CAPI_EXPORTED MlirDynamicOpTrait mlirDynamicOpTraitIsIsolatedFromAboveCreate(void)
Get the dynamic op trait that indicates regions are isolated from above.
MLIR_CAPI_EXPORTED MlirTypeID mlirDynamicOpTraitRecursiveMemoryEffectsGetTypeID(void)
Get the type ID of the dynamic op trait that indicates memory effects of an operation includes the ef...
MLIR_CAPI_EXPORTED MlirTypeID mlirDynamicOpTraitIsIsolatedFromAboveGetTypeID(void)
Get the type ID of the dynamic op trait that indicates regions are isolated from above.
MLIR_CAPI_EXPORTED MlirTypeID mlirDynamicOpTraitIsTerminatorGetTypeID(void)
Get the type ID of the dynamic op trait that indicates the operation is a terminator.
MLIR_CAPI_EXPORTED MlirDynamicOpTrait mlirDynamicOpTraitRecursiveMemoryEffectsCreate(void)
Get the dynamic op trait that indicates memory effects of an operation includes the effects of operat...
MLIR_CAPI_EXPORTED MlirDynamicOpTrait mlirDynamicOpTraitCreate(MlirTypeID typeID, MlirDynamicOpTraitCallbacks callbacks, void *userData)
Create a custom dynamic op trait with the given type ID and callbacks.
MLIR_CAPI_EXPORTED bool mlirDynamicOpTraitAttach(MlirDynamicOpTrait dynamicOpTrait, MlirStringRef opName, MlirContext context)
Attach a dynamic op trait to the given operation name.
MLIR_CAPI_EXPORTED MlirTypeID mlirDynamicOpTraitNoTerminatorGetTypeID(void)
Get the type ID of the dynamic op trait that indicates regions have no terminator.
MLIR_CAPI_EXPORTED MlirDynamicOpTrait mlirDynamicOpTraitNoTerminatorCreate(void)
Get the dynamic op trait that indicates regions have no terminator.
MLIR_CAPI_EXPORTED MlirAttribute mlirLocationGetAttribute(MlirLocation location)
Returns the underlying location attribute of this location.
MlirWalkResult(* MlirOperationWalkCallback)(MlirOperation, void *userData)
Operation walker type.
MLIR_CAPI_EXPORTED MlirLocation mlirValueGetLocation(MlirValue v)
Gets the location of the value.
MLIR_CAPI_EXPORTED unsigned mlirContextGetNumThreads(MlirContext context)
Gets the number of threads of the thread pool of the context when multithreading is enabled.
MLIR_CAPI_EXPORTED void mlirOperationWriteBytecode(MlirOperation op, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but writing the bytecode format.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFileLineColGet(MlirContext context, MlirStringRef filename, unsigned line, unsigned col)
Creates an File/Line/Column location owned by the given context.
MLIR_CAPI_EXPORTED void mlirSymbolTableWalkSymbolTables(MlirOperation from, bool allSymUsesVisible, void(*callback)(MlirOperation, bool, void *userData), void *userData)
Walks all symbol table operations nested within, and including, op.
MLIR_CAPI_EXPORTED MlirStringRef mlirDialectGetNamespace(MlirDialect dialect)
Returns the namespace of the given dialect.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetEndColumn(MlirLocation location)
Getter for end_column of FileLineColRange.
MLIR_CAPI_EXPORTED MlirAttribute mlirSymbolTableInsert(MlirSymbolTable symbolTable, MlirOperation operation)
Inserts the given operation into the given symbol table.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetDefaultVisibilityAttributeName(void)
Returns the name of the attribute used by default to store symbol visibility.
MlirWalkOrder
Traversal order for operation walk.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name, MlirAttribute attr)
Associates an attribute with the name. Takes ownership of neither.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGetChildLoc(MlirLocation location)
Getter for childLoc of Name.
MLIR_CAPI_EXPORTED void mlirSymbolTableErase(MlirSymbolTable symbolTable, MlirOperation operation)
Removes the given operation from the symbol table and erases it.
MLIR_CAPI_EXPORTED void mlirContextAppendDialectRegistry(MlirContext ctx, MlirDialectRegistry registry)
Append the contents of the given dialect registry to the registry associated with the context.
MLIR_CAPI_EXPORTED MlirStringRef mlirIdentifierStr(MlirIdentifier ident)
Gets the string value of the identifier.
MLIR_CAPI_EXPORTED MlirType mlirTypeParseGet(MlirContext context, MlirStringRef type)
Parses a type. The type is owned by the context.
MLIR_CAPI_EXPORTED MlirOpOperand mlirOpOperandGetNextUse(MlirOpOperand opOperand)
Returns an op operand representing the next use of the value, or a null op operand if there is no nex...
MLIR_CAPI_EXPORTED void mlirContextSetAllowUnregisteredDialects(MlirContext context, bool allow)
Sets whether unregistered dialects are allowed in this context.
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockBefore(MlirRegion region, MlirBlock reference, MlirBlock block)
Takes a block owned by the caller and inserts it before the (non-owned) reference block in the given ...
MLIR_CAPI_EXPORTED void mlirContextBeginTransientScope(MlirContext context)
Begins a transient scope on the context, freezing the base layer (loaded dialects,...
MLIR_CAPI_EXPORTED unsigned mlirLocationFusedGetNumLocations(MlirLocation location)
Getter for number of locations fused together.
MLIR_CAPI_EXPORTED void mlirValueReplaceAllUsesOfWith(MlirValue of, MlirValue with)
Replace all uses of 'of' value with the 'with' value, updating anything in the IR that uses 'of' to u...
MLIR_CAPI_EXPORTED void mlirValuePrintAsOperand(MlirValue value, MlirAsmState state, MlirStringCallback callback, void *userData)
Prints a value as an operand (i.e., the ValueID).
MLIR_CAPI_EXPORTED MlirLocation mlirLocationUnknownGet(MlirContext context)
Creates a location with unknown position owned by the given context.
MLIR_CAPI_EXPORTED MlirOperation mlirOpOperandGetOwner(MlirOpOperand opOperand)
Returns the owner operation of an op operand.
MLIR_CAPI_EXPORTED MlirIdentifier mlirLocationFileLineColRangeGetFilename(MlirLocation location)
Getter for filename of FileLineColRange.
MLIR_CAPI_EXPORTED void mlirLocationFusedGetLocations(MlirLocation location, MlirLocation *locationsCPtr)
Getter for locations of Fused.
MLIR_CAPI_EXPORTED void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData to callback`...
MLIR_CAPI_EXPORTED MlirRegion mlirBlockGetParentRegion(MlirBlock block)
Returns the region that contains this block.
MLIR_CAPI_EXPORTED void mlirOperationMoveBefore(MlirOperation op, MlirOperation other)
Moves the given operation immediately before the other operation in its parent block.
MLIR_CAPI_EXPORTED void mlirValueReplaceAllUsesExcept(MlirValue of, MlirValue with, intptr_t numExceptions, MlirOperation *exceptions)
Replace all uses of 'of' value with 'with' value, updating anything in the IR that uses 'of' to use '...
MLIR_CAPI_EXPORTED void mlirOperationPrintWithState(MlirOperation op, MlirAsmState state, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but accepts AsmState controlling the printing behavior as well as caching ...
MlirWalkResult
Operation walk result.
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos, MlirBlock block)
Takes a block owned by the caller and inserts it at pos to the given region.
static bool mlirTypeIsNull(MlirType type)
Checks whether a type is null.
MLIR_CAPI_EXPORTED bool mlirContextIsRegisteredOperation(MlirContext context, MlirStringRef name)
Returns whether the given fully-qualified operation (i.e.
MLIR_CAPI_EXPORTED intptr_t mlirBlockGetNumArguments(MlirBlock block)
Returns the number of arguments of the block.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetStartLine(MlirLocation location)
Getter for start_line of FileLineColRange.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFusedGet(MlirContext ctx, intptr_t nLocations, MlirLocation const *locations, MlirAttribute metadata)
Creates a fused location with an array of locations and metadata.
MLIR_CAPI_EXPORTED MlirDialect mlirContextGetLoadedDialect(MlirContext context, MlirStringRef name)
Gets the dialect instance owned by the given context using the dialect namespace to identify it.
MLIR_CAPI_EXPORTED void mlirBlockInsertOwnedOperationBefore(MlirBlock block, MlirOperation reference, MlirOperation operation)
Takes an operation owned by the caller and inserts it before the (non-owned) reference operation in t...
static bool mlirContextIsNull(MlirContext context)
Checks whether a context is null.
MLIR_CAPI_EXPORTED MlirDialect mlirContextGetOrLoadDialect(MlirContext context, MlirStringRef name)
Gets the dialect instance owned by the given context using the dialect namespace to identify it,...
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockAfter(MlirRegion region, MlirBlock reference, MlirBlock block)
Takes a block owned by the caller and inserts it after the (non-owned) reference block in the given r...
MLIR_CAPI_EXPORTED MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args, MlirLocation const *locs)
Creates a new empty block with the given argument types and transfers ownership to the caller.
static bool mlirBlockIsNull(MlirBlock block)
Checks whether a block is null.
MLIR_CAPI_EXPORTED void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation)
Takes an operation owned by the caller and appends it to the block.
MLIR_CAPI_EXPORTED MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos)
Returns pos-th argument of the block.
MLIR_CAPI_EXPORTED MlirOperation mlirSymbolTableLookup(MlirSymbolTable symbolTable, MlirStringRef name)
Looks up a symbol with the given name in the given symbol table and returns the operation that corres...
MLIR_CAPI_EXPORTED MlirContext mlirTypeGetContext(MlirType type)
Gets the context that a type was created with.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFileLineColRangeGet(MlirContext context, MlirStringRef filename, unsigned start_line, unsigned start_col, unsigned end_line, unsigned end_col)
Creates an File/Line/Column range location owned by the given context.
MLIR_CAPI_EXPORTED bool mlirOpOperandIsNull(MlirOpOperand opOperand)
Returns whether the op operand is null.
MLIR_CAPI_EXPORTED MlirSymbolTable mlirSymbolTableCreate(MlirOperation operation)
Creates a symbol table for the given operation.
MLIR_CAPI_EXPORTED bool mlirLocationEqual(MlirLocation l1, MlirLocation l2)
Checks if two locations are equal.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetStartColumn(MlirLocation location)
Getter for start_column of FileLineColRange.
MLIR_CAPI_EXPORTED bool mlirContextIsInTransientScope(MlirContext context)
Returns whether the context is currently in a transient scope.
MLIR_CAPI_EXPORTED bool mlirLocationIsAFused(MlirLocation location)
Checks whether the given location is an Fused.
static bool mlirLocationIsNull(MlirLocation location)
Checks if the location is null.
MLIR_CAPI_EXPORTED MlirValue mlirBlockAddArgument(MlirBlock block, MlirType type, MlirLocation loc)
Appends an argument of the specified type to the block.
MLIR_CAPI_EXPORTED void mlirOperationPrintWithFlags(MlirOperation op, MlirOpPrintingFlags flags, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but accepts flags controlling the printing behavior.
MLIR_CAPI_EXPORTED MlirOpOperand mlirValueGetFirstUse(MlirValue value)
Returns an op operand representing the first use of the value, or a null op operand if there are no u...
MLIR_CAPI_EXPORTED void mlirContextEndTransientScope(MlirContext context)
Ends the transient scope and resets the context to the base state, pruning transient types,...
MLIR_CAPI_EXPORTED void mlirContextSetThreadPool(MlirContext context, MlirLlvmThreadPool threadPool)
Sets the thread pool of the context explicitly, enabling multithreading in the process.
MLIR_CAPI_EXPORTED bool mlirOperationVerify(MlirOperation op)
Verify the operation and return true if it passes, false if it fails.
MLIR_CAPI_EXPORTED bool mlirTypeEqual(MlirType t1, MlirType t2)
Checks if two types are equal.
MLIR_CAPI_EXPORTED unsigned mlirOpOperandGetOperandNumber(MlirOpOperand opOperand)
Returns the operand number of an op operand.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGetCaller(MlirLocation location)
Getter for caller of CallSite.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetTerminator(MlirBlock block)
Returns the terminator operation in the block or null if no terminator.
MLIR_CAPI_EXPORTED MlirIdentifier mlirLocationNameGetName(MlirLocation location)
Getter for name of Name.
MLIR_CAPI_EXPORTED bool mlirOperationIsBeforeInBlock(MlirOperation op, MlirOperation other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFromAttribute(MlirAttribute attribute)
Creates a location from a location attribute.
MLIR_CAPI_EXPORTED MlirTypeID mlirTypeGetTypeID(MlirType type)
Gets the type ID of the type.
static bool mlirDialectIsNull(MlirDialect dialect)
Checks if the dialect is null.
MLIR_CAPI_EXPORTED MlirAttribute mlirLocationFusedGetMetadata(MlirLocation location)
Getter for metadata of Fused.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockGetNextInRegion(MlirBlock block)
Returns the block immediately following the given block in its parent region.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller)
Creates a call site location with a callee and a caller.
MLIR_CAPI_EXPORTED bool mlirLocationIsAName(MlirLocation location)
Checks whether the given location is an Name.
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
MLIR_CAPI_EXPORTED void mlirOperationWalk(MlirOperation op, MlirOperationWalkCallback callback, void *userData, MlirWalkOrder walkOrder)
Walks operation op in walkOrder and calls callback on that operation.
MLIR_CAPI_EXPORTED MlirContext mlirContextCreateWithThreading(bool threadingEnabled)
Creates an MLIR context with an explicit setting of the multithreading setting and transfers its owne...
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetParentOperation(MlirBlock)
Returns the closest surrounding operation that contains this block.
MLIR_CAPI_EXPORTED MlirContext mlirLocationGetContext(MlirLocation location)
Gets the context that a location was created with.
MLIR_CAPI_EXPORTED void mlirBlockEraseArgument(MlirBlock block, unsigned index)
Erase the argument at 'index' and remove it from the argument list.
MLIR_CAPI_EXPORTED void mlirAttributeDump(MlirAttribute attr)
Prints the attribute to the standard error stream.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirSymbolTableReplaceAllSymbolUses(MlirStringRef oldSymbol, MlirStringRef newSymbol, MlirOperation from)
Attempt to replace all uses that are nested within the given operation of the given symbol 'oldSymbol...
MLIR_CAPI_EXPORTED void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block)
Takes a block owned by the caller and appends it to the given region.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetFirstOperation(MlirBlock block)
Returns the first operation in the block.
static bool mlirRegionIsNull(MlirRegion region)
Checks whether a region is null.
MLIR_CAPI_EXPORTED MlirDialect mlirTypeGetDialect(MlirType type)
Gets the dialect a type belongs to.
MLIR_CAPI_EXPORTED MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
MLIR_CAPI_EXPORTED void mlirContextLoadAllAvailableDialects(MlirContext context)
Eagerly loads all available dialects registered with a context, making them available for use for IR ...
MLIR_CAPI_EXPORTED MlirLlvmThreadPool mlirContextGetThreadPool(MlirContext context)
Gets the thread pool of the context when enabled multithreading, otherwise an assertion is raised.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetEndLine(MlirLocation location)
Getter for end_line of FileLineColRange.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGet(MlirContext context, MlirStringRef name, MlirLocation childLoc)
Creates a name location owned by the given context.
MLIR_CAPI_EXPORTED void mlirContextEnableMultithreading(MlirContext context, bool enable)
Set threading mode (must be set to false to mlir-print-ir-after-all).
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGetCallee(MlirLocation location)
Getter for callee of CallSite.
MLIR_CAPI_EXPORTED MlirContext mlirValueGetContext(MlirValue v)
Gets the context that a value was created with.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetSymbolAttributeName(void)
Returns the name of the attribute used to store symbol names compatible with symbol tables.
MLIR_CAPI_EXPORTED MlirRegion mlirRegionCreate(void)
Creates a new empty region and transfers ownership to the caller.
MLIR_CAPI_EXPORTED void mlirBlockDetach(MlirBlock block)
Detach a block from the owning region and assume ownership.
MLIR_CAPI_EXPORTED void mlirOperationDump(MlirOperation op)
Prints an operation to stderr.
static bool mlirSymbolTableIsNull(MlirSymbolTable symbolTable)
Returns true if the symbol table is null.
MLIR_CAPI_EXPORTED bool mlirContextGetAllowUnregisteredDialects(MlirContext context)
Returns whether the context allows unregistered dialects.
MLIR_CAPI_EXPORTED void mlirOperationReplaceUsesOfWith(MlirOperation op, MlirValue of, MlirValue with)
Replace uses of 'of' value with the 'with' value inside the 'op' operation.
MLIR_CAPI_EXPORTED void mlirOperationMoveAfter(MlirOperation op, MlirOperation other)
Moves the given operation immediately after the other operation in its parent block.
MLIR_CAPI_EXPORTED void mlirValuePrint(MlirValue value, MlirStringCallback callback, void *userData)
Prints a block by sending chunks of the string representation and forwarding userData to callback`.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirOperationWriteBytecodeWithConfig(MlirOperation op, MlirBytecodeWriterConfig config, MlirStringCallback callback, void *userData)
Same as mlirOperationWriteBytecode but with writer config and returns failure only if desired bytecod...
MLIR_CAPI_EXPORTED void mlirContextDestroy(MlirContext context)
Takes an MLIR context owned by the caller and destroys it.
MLIR_CAPI_EXPORTED MlirBlock mlirRegionGetFirstBlock(MlirRegion region)
Gets the first block in the region.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
static MlirLogicalResult mlirLogicalResultFailure(void)
Creates a logical result representing a failure.
struct MlirLogicalResult MlirLogicalResult
MLIR_CAPI_EXPORTED int mlirLlvmThreadPoolGetMaxConcurrency(MlirLlvmThreadPool pool)
Returns the maximum number of threads in the thread pool.
MLIR_CAPI_EXPORTED void mlirLlvmThreadPoolDestroy(MlirLlvmThreadPool pool)
Destroy an LLVM thread pool.
MLIR_CAPI_EXPORTED MlirLlvmThreadPool mlirLlvmThreadPoolCreate(void)
Create an LLVM thread pool.
MLIR_CAPI_EXPORTED size_t mlirTypeIDHashValue(MlirTypeID typeID)
Returns the hash value of the type id.
static MlirLogicalResult mlirLogicalResultSuccess(void)
Creates a logical result representing a success.
struct MlirStringRef MlirStringRef
static bool mlirLogicalResultIsFailure(MlirLogicalResult res)
Checks if the given logical result represents a failure.
static bool mlirTypeIDIsNull(MlirTypeID typeID)
Checks whether a type id is null.
MLIR_CAPI_EXPORTED bool mlirTypeIDEqual(MlirTypeID typeID1, MlirTypeID typeID2)
Checks if two type ids are equal.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
InFlightDiagnostic & next(InFlightDiagnostic &diag)
Starts a new message part in an in-flight diagnostic.
MLIR_PYTHON_API_EXPORTED MlirValue getUniqueResult(MlirOperation operation)
static std::string formatMLIRError(const MLIRError &e)
PyOperationEquivalenceFlags
Flags controlling structural operation equivalence and hashing.
MLIR_PYTHON_API_EXPORTED void populateRoot(nanobind::module_ &m)
static void maybeInsertOperation(PyOperationRef &op, const nb::object &maybeIp)
static void populateResultTypes(std::string_view name, nb::sequence resultTypeList, const nb::object &resultSegmentSpecObj, std::vector< int32_t > &resultSegmentLengths, std::vector< PyType * > &resultTypes)
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
static MlirValue getOpResultOrValue(nb::handle operand)
PyObjectRef< PyOperation > PyOperationRef
MlirStringRef toMlirStringRef(const std::string &s)
PyRemarkKind
The kinds, emitting policies and file formats of the remark engine (mlir-c/Remarks....
static bool attachOpTrait(const nb::object &opName, MlirDynamicOpTrait trait, PyMlirContext &context)
PyObjectRef< PyModule > PyModuleRef
static MlirLogicalResult verifyTraitByMethod(MlirOperation op, void *userData, const char *methodName)
static PyOperationRef getValueOwnerRef(MlirValue value)
MlirBlock MLIR_PYTHON_API_EXPORTED createBlock(const nanobind::typed< nanobind::sequence, PyType > &pyArgTypes, const std::optional< nanobind::typed< nanobind::sequence, PyLocation > > &pyArgLocs)
Create a block, using the current location context if no locations are specified.
static std::vector< nb::typed< nb::object, PyType > > getValueTypes(Container &container, PyMlirContextRef &context)
Returns the list of types of the values held by container.
PyWalkOrder
Traversal order for operation walk.
MLIR_PYTHON_API_EXPORTED void populateIRCore(nanobind::module_ &m)
nanobind::object classmethod(Func f, Args... args)
Helper for creating an @classmethod.
Action
The actions performed by @newSparseTensor.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
std::string join(const Ts &...args)
Helper function to concatenate arguments into a std::string.
An opaque reference to a diagnostic, always owned by the diagnostics engine (context).
MlirLogicalResult(* verifyTrait)(MlirOperation op, void *userData)
The callback function to verify the operation.
void(* construct)(void *userData)
Optional constructor for the user data.
void(* destruct)(void *userData)
Optional destructor for the user data.
MlirLogicalResult(* verifyRegionTrait)(MlirOperation op, void *userData)
The callback function to verify the operation with access to regions.
A logical result value, essentially a boolean with named states.
A pointer to a sized fragment of a string, not necessarily null-terminated.
const char * data
Pointer to the first symbol.
size_t length
Length of the fragment.
Accumulates into a python string from a method that accepts an MlirStringCallback.
MlirStringCallback getCallback()
Custom exception that allows access to error diagnostic information.
MLIRError(std::string message, std::vector< PyDiagnostic::DiagnosticInfo > &&errorDiagnostics={})
std::vector< PyDiagnostic::DiagnosticInfo > errorDiagnostics
static void bind(nanobind::module_ &m)
Bind the MLIRError exception class to the given module.
static bool dunderContains(const std::string &attributeKind)
static nanobind::callable dunderGetItemNamed(const std::string &attributeKind)
static void bind(nanobind::module_ &m)
static void dunderSetItemNamed(const std::string &attributeKind, nanobind::callable func, bool replace, bool allow_existing)
Materialized diagnostic information.
std::vector< DiagnosticInfo > notes
PyDiagnosticSeverity severity
static void set(nanobind::object &o, bool enable)
static bool get(const nanobind::object &)
static void bind(nanobind::module_ &m)
RAII object that captures any error diagnostics emitted to the provided context.
std::vector< PyDiagnostic::DiagnosticInfo > take()
ErrorCapture(PyMlirContextRef ctx)