22#include "nanobind/nanobind.h"
23#include "nanobind/typing.h"
24#include "llvm/ADT/ArrayRef.h"
25#include "llvm/ADT/SmallVector.h"
30using namespace nb::literals;
38 R
"(Parses a module's assembly format from a string.
40Returns a new MlirModule or raises an MLIRError if the parsing fails.
42See also: https://mlir.llvm.org/docs/LangRef/
46 "Dumps a debug representation of the object to stderr.";
49 R
"(Replace all uses of this value with the `with` value, except for those
50in `exceptions`. `exceptions` can be either a single operation or a list of
59template <
class Func,
typename... Args>
61 nb::object
cf = nb::cpp_function(f, args...);
62 return nb::borrow<nb::object>((PyClassMethod_New(
cf.ptr())));
67 nb::object dialectDescriptor) {
74 std::move(dialectDescriptor)));
78 return (*dialectClass)(std::move(dialectDescriptor));
86 const std::optional<nb::sequence> &pyArgLocs) {
88 argTypes.reserve(nb::len(pyArgTypes));
89 for (
const auto &pyType : pyArgTypes)
91 nb::cast<python::MLIR_BINDINGS_PYTHON_DOMAIN::PyType &>(pyType));
95 argLocs.reserve(nb::len(*pyArgLocs));
96 for (
const auto &pyLoc : *pyArgLocs)
98 nb::cast<python::MLIR_BINDINGS_PYTHON_DOMAIN::PyLocation &>(pyLoc));
99 }
else if (!argTypes.empty()) {
105 if (argTypes.size() != argLocs.size())
106 throw nb::value_error((
"Expected " + Twine(argTypes.size()) +
107 " locations, got: " + Twine(argLocs.size()))
110 return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
114 nb::ft_lock_guard lock(mutex);
119 nb::ft_lock_guard lock(mutex);
125 nb::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug")
130 [](
const std::string &type) {
131 nb::ft_lock_guard lock(mutex);
134 "types"_a,
"Sets specific debug types to be produced by LLVM.")
137 [](
const std::vector<std::string> &types) {
138 std::vector<const char *> pointers;
139 pointers.reserve(types.size());
140 for (
const std::string &str : types)
141 pointers.push_back(str.c_str());
142 nb::ft_lock_guard lock(mutex);
146 "Sets multiple specific debug types to be produced by LLVM.");
149nb::ft_mutex PyGlobalDebugFlag::mutex;
159 throw nb::key_error(attributeKind.c_str());
164 nb::callable
func,
bool replace) {
170 nb::class_<PyAttrBuilderMap>(m,
"AttrBuilder")
173 "Checks whether an attribute builder is registered for the "
174 "given attribute kind.")
177 "Gets the registered attribute builder for the given "
180 "attribute_kind"_a,
"attr_builder"_a,
"replace"_a =
false,
181 "Register an attribute builder for building MLIR "
182 "attributes from Python values.");
200 throw nb::stop_iteration();
207 nb::class_<PyRegionIterator>(m,
"RegionIterator")
209 "Returns an iterator over the regions in the operation.")
211 "Returns the next region in the iteration.");
220 operation(std::move(operation)) {}
223 operation->checkValid();
229 "Returns an iterator over the regions in the sequence.");
232intptr_t PyRegionList::getRawNumElements() {
250 throw nb::stop_iteration();
253 PyBlock returnBlock(operation, next);
259 nb::class_<PyBlockIterator>(m,
"BlockIterator")
261 "Returns an iterator over the blocks in the operation's region.")
263 "Returns the next block in the iteration.");
267 operation->checkValid();
272 operation->checkValid();
288 throw nb::index_error(
"attempt to access out of bounds block");
293 return PyBlock(operation, block);
298 throw nb::index_error(
"attempt to access out of bounds block");
302 const std::optional<nb::sequence> &pyArgLocs) {
304 MlirBlock block =
createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
306 return PyBlock(operation, block);
310 nb::class_<PyBlockList>(m,
"BlockList")
312 "Returns the block at the specified index.")
314 "Returns an iterator over blocks in the operation's region.")
316 "Returns the number of blocks in the operation's region.")
319 Appends a new block, with argument types as positional args.
324 "args"_a, nb::kw_only(),
"arg_locs"_a = std::nullopt);
329 if (mlirOperationIsNull(next)) {
330 throw nb::stop_iteration();
340 nb::class_<PyOperationIterator>(m,
"OperationIterator")
342 "Returns an iterator over the operations in an operation's block.")
344 "Returns the next operation in the iteration.");
348 parentOperation->checkValid();
357 while (!mlirOperationIsNull(childOp)) {
370 throw nb::index_error(
"attempt to access out of bounds operation");
373 while (!mlirOperationIsNull(childOp)) {
381 throw nb::index_error(
"attempt to access out of bounds operation");
385 nb::class_<PyOperationList>(m,
"OperationList")
387 "Returns the operation at the specified index.")
389 "Returns an iterator over operations in the list.")
391 "Returns the number of operations in the list.");
406 nb::class_<PyOpOperand>(m,
"OpOperand")
408 "Returns the operation that owns this operand.")
410 "Returns the operand number in the owning operation.");
415 throw nb::stop_iteration();
419 return returnOpOperand;
423 nb::class_<PyOpOperandIterator>(m,
"OpOperandIterator")
425 "Returns an iterator over operands.")
427 "Returns the next operand in the iteration.");
435 ownedThreadPool = std::make_unique<llvm::DefaultThreadPool>();
439 std::stringstream ss;
440 ss << ownedThreadPool.get();
449 nb::gil_scoped_acquire acquire;
450 nb::ft_lock_guard lock(live_contexts_mutex);
451 auto &liveContexts = getLiveContexts();
452 liveContexts[context.ptr] =
this;
459 nb::gil_scoped_acquire acquire;
461 nb::ft_lock_guard lock(live_contexts_mutex);
462 getLiveContexts().erase(context.ptr);
478 throw nb::python_error();
483 nb::gil_scoped_acquire acquire;
484 nb::ft_lock_guard lock(live_contexts_mutex);
485 auto &liveContexts = getLiveContexts();
486 auto it = liveContexts.find(context.ptr);
487 if (it == liveContexts.end()) {
490 nb::object pyRef = nb::cast(unownedContextWrapper);
491 assert(pyRef &&
"cast to nb::object failed");
492 liveContexts[context.ptr] = unownedContextWrapper;
496 nb::object pyRef = nb::cast(it->second);
500nb::ft_mutex PyMlirContext::live_contexts_mutex;
502PyMlirContext::LiveContextMap &PyMlirContext::getLiveContexts() {
503 static LiveContextMap liveContexts;
508 nb::ft_lock_guard lock(live_contexts_mutex);
509 return getLiveContexts().size();
517 const nb::object &excVal,
518 const nb::object &excTb) {
527 nb::object pyHandlerObject =
528 nb::cast(pyHandler, nb::rv_policy::take_ownership);
529 (
void)pyHandlerObject.inc_ref();
533 auto handlerCallback =
536 nb::object pyDiagnosticObject =
537 nb::cast(pyDiagnostic, nb::rv_policy::take_ownership);
544 nb::gil_scoped_acquire gil;
546 result = nb::cast<bool>(pyHandler->callback(pyDiagnostic));
547 }
catch (std::exception &e) {
548 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
550 pyHandler->hadError =
true;
557 auto deleteCallback = +[](
void *userData) {
558 auto *pyHandler =
static_cast<PyDiagnosticHandler *
>(userData);
559 assert(pyHandler->registeredID &&
"handler is not registered");
560 pyHandler->registeredID.reset();
563 nb::object pyHandlerObject = nb::cast(pyHandler, nb::rv_policy::reference);
564 pyHandlerObject.dec_ref();
568 get(), handlerCallback,
static_cast<void *
>(pyHandler), deleteCallback);
569 return pyHandlerObject;
576 if (self->ctx->emitErrorDiagnostics)
580 MlirDiagnosticSeverity::MlirDiagnosticError)
590 throw std::runtime_error(
591 "An MLIR function requires a Context but none was provided in the call "
592 "or from the surrounding environment. Either pass to the function with "
593 "a 'context=' argument or establish a default using 'with Context():'");
603 static thread_local std::vector<PyThreadContextEntry> stack;
608 auto &stack = getStack();
611 return &stack.back();
614void PyThreadContextEntry::push(FrameKind frameKind, nb::object context,
615 nb::object insertionPoint,
616 nb::object location) {
617 auto &stack = getStack();
618 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
619 std::move(location));
623 if (stack.size() > 1) {
624 auto &prev = *(stack.rbegin() + 1);
625 auto ¤t = stack.back();
626 if (current.context.is(prev.context)) {
628 if (!current.insertionPoint)
629 current.insertionPoint = prev.insertionPoint;
630 if (!current.location)
631 current.location = prev.location;
639 return nb::cast<PyMlirContext *>(context);
645 return nb::cast<PyInsertionPoint *>(insertionPoint);
651 return nb::cast<PyLocation *>(location);
656 return tos ? tos->getContext() :
nullptr;
661 return tos ? tos->getInsertionPoint() :
nullptr;
666 return tos ? tos->getLocation() :
nullptr;
670 push(FrameKind::Context, context,
677 auto &stack = getStack();
679 throw std::runtime_error(
"Unbalanced Context enter/exit");
680 auto &tos = stack.back();
681 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
682 throw std::runtime_error(
"Unbalanced Context enter/exit");
689 nb::cast<PyInsertionPoint &>(insertionPointObj);
690 nb::object contextObj =
692 push(FrameKind::InsertionPoint,
696 return insertionPointObj;
700 auto &stack = getStack();
702 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
703 auto &tos = stack.back();
704 if (tos.frameKind != FrameKind::InsertionPoint &&
705 tos.getInsertionPoint() != &insertionPoint)
706 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
711 PyLocation &location = nb::cast<PyLocation &>(locationObj);
713 push(FrameKind::Location, contextObj,
720 auto &stack = getStack();
722 throw std::runtime_error(
"Unbalanced Location enter/exit");
723 auto &tos = stack.back();
724 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
725 throw std::runtime_error(
"Unbalanced Location enter/exit");
735 if (materializedNotes) {
736 for (nb::handle noteObject : *materializedNotes) {
737 PyDiagnostic *note = nb::cast<PyDiagnostic *>(noteObject);
745 : context(context), callback(std::move(callback)) {}
754 assert(!registeredID &&
"should have unregistered");
760void PyDiagnostic::checkValid() {
762 throw std::invalid_argument(
763 "Diagnostic is invalid (used outside of callback)");
782 nb::object fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
785 return nb::cast<nb::str>(fileObject.attr(
"getvalue")());
790 if (materializedNotes)
791 return *materializedNotes;
793 nb::tuple notes = nb::steal<nb::tuple>(PyTuple_New(numNotes));
794 for (
intptr_t i = 0; i < numNotes; ++i) {
796 nb::object diagnostic = nb::cast(
PyDiagnostic(noteDiag));
797 PyTuple_SET_ITEM(notes.ptr(), i, diagnostic.release().ptr());
799 materializedNotes = std::move(notes);
801 return *materializedNotes;
805 std::vector<DiagnosticInfo> notes;
807 notes.emplace_back(nb::cast<PyDiagnostic>(n).
getInfo());
819 {key.data(), key.size()});
821 std::string msg = (Twine(
"Dialect '") + key +
"' not found").str();
823 throw nb::attribute_error(msg.c_str());
824 throw nb::index_error(msg.c_str());
834 MlirDialectRegistry rawRegistry =
837 throw nb::python_error();
852 throw nb::python_error();
862 const nb::object &excVal,
863 const nb::object &excTb) {
870 throw std::runtime_error(
871 "An MLIR function requires a Location but none was provided in the "
872 "call or from the surrounding environment. Either pass to the function "
873 "with a 'loc=' argument or establish a default using 'with loc:'");
886 nb::gil_scoped_acquire acquire;
887 auto &liveModules =
getContext()->liveModules;
888 assert(liveModules.count(module.ptr) == 1 &&
889 "destroying module not in live map");
890 liveModules.erase(module.ptr);
898 nb::gil_scoped_acquire acquire;
899 auto &liveModules = contextRef->liveModules;
900 auto it = liveModules.find(module.ptr);
901 if (it == liveModules.end()) {
907 nb::object pyRef = nb::cast(unownedModule, nb::rv_policy::take_ownership);
908 unownedModule->handle = pyRef;
909 liveModules[module.ptr] =
910 std::make_pair(unownedModule->handle, unownedModule);
911 return PyModuleRef(unownedModule, std::move(pyRef));
915 nb::object pyRef = nb::borrow<nb::object>(it->second.first);
921 if (mlirModuleIsNull(rawModule))
922 throw nb::python_error();
954template <
typename T,
class... Args>
956 nb::handle type = nb::type<T>();
957 nb::object instance = nb::inst_alloc(type);
958 T *
ptr = nb::inst_ptr<T>(instance);
959 new (
ptr) T(std::forward<Args>(args)...);
960 nb::inst_mark_ready(instance);
967 MlirOperation operation,
968 nb::object parentKeepAlive) {
971 makeObjectRef<PyOperation>(std::move(contextRef), operation);
972 unownedOperation->handle = unownedOperation.
getObject();
973 if (parentKeepAlive) {
974 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
976 return unownedOperation;
980 MlirOperation operation,
981 nb::object parentKeepAlive) {
982 return createInstance(std::move(contextRef), operation,
983 std::move(parentKeepAlive));
987 MlirOperation operation,
988 nb::object parentKeepAlive) {
989 PyOperationRef created = createInstance(std::move(contextRef), operation,
990 std::move(parentKeepAlive));
991 created->attached =
false;
996 const std::string &sourceStr,
997 const std::string &sourceName) {
1002 if (mlirOperationIsNull(op))
1003 throw MLIRError(
"Unable to parse operation assembly", errors.take());
1010 parentKeepAlive = nb::object();
1023 assert(!attached &&
"operation already attached");
1028 assert(attached &&
"operation already detached");
1034 throw std::runtime_error(
"the operation has been invalidated");
1039 std::optional<int64_t> largeResourceLimit,
1040 bool enableDebugInfo,
bool prettyDebugInfo,
1041 bool printGenericOpForm,
bool useLocalScope,
1042 bool useNameLocAsPrefix,
bool assumeVerified,
1043 nb::object fileObject,
bool binary,
1047 if (fileObject.is_none())
1048 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1051 if (largeElementsLimit)
1053 if (largeResourceLimit)
1055 if (enableDebugInfo)
1058 if (printGenericOpForm)
1066 if (useNameLocAsPrefix)
1071 accum.getUserData());
1079 if (fileObject.is_none())
1080 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1083 accum.getUserData());
1087 std::optional<int64_t> bytecodeVersion) {
1092 if (!bytecodeVersion.has_value())
1094 accum.getUserData());
1099 operation,
config, accum.getCallback(), accum.getUserData());
1102 throw nb::value_error((Twine(
"Unable to honor desired bytecode version ") +
1103 Twine(*bytecodeVersion))
1115 std::string exceptionWhat;
1116 nb::object exceptionType;
1118 UserData userData{callback,
false, {}, {}};
1121 UserData *calleeUserData =
static_cast<UserData *
>(userData);
1123 return static_cast<MlirWalkResult>((calleeUserData->callback)(op));
1124 }
catch (nb::python_error &e) {
1125 calleeUserData->gotException =
true;
1126 calleeUserData->exceptionWhat = std::string(e.what());
1127 calleeUserData->exceptionType = nb::borrow(e.type());
1128 return MlirWalkResult::MlirWalkResultInterrupt;
1133 if (userData.gotException) {
1134 std::string message(
"Exception raised in callback: ");
1135 message.append(userData.exceptionWhat);
1136 throw std::runtime_error(message);
1141 std::optional<int64_t> largeElementsLimit,
1142 std::optional<int64_t> largeResourceLimit,
1143 bool enableDebugInfo,
bool prettyDebugInfo,
1144 bool printGenericOpForm,
bool useLocalScope,
1145 bool useNameLocAsPrefix,
bool assumeVerified,
1147 nb::object fileObject;
1149 fileObject = nb::module_::import_(
"io").attr(
"BytesIO")();
1151 fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
1153 print(largeElementsLimit,
1165 return fileObject.attr(
"getvalue")();
1174 operation.parentKeepAlive = otherOp.parentKeepAlive;
1183 operation.parentKeepAlive = otherOp.parentKeepAlive;
1198 throw MLIRError(
"Verification failed", errors.take());
1205 throw nb::value_error(
"Detached operations have no parent");
1207 if (mlirOperationIsNull(operation))
1217 assert(parentOperation &&
"Operation has no parent");
1218 return PyBlock{std::move(*parentOperation), block};
1228 if (mlirOperationIsNull(rawOperation))
1229 throw nb::python_error();
1236 const nb::object &maybeIp) {
1238 if (!maybeIp.is(nb::cast(
false))) {
1240 if (maybeIp.is_none()) {
1243 ip = nb::cast<PyInsertionPoint *>(maybeIp);
1251 std::optional<std::vector<PyType *>> results,
1253 std::optional<nb::dict> attributes,
1254 std::optional<std::vector<PyBlock *>> successors,
1256 const nb::object &maybeIp,
bool inferType) {
1263 throw nb::value_error(
"number of regions must be >= 0");
1267 mlirResults.reserve(results->size());
1271 throw nb::value_error(
"result type cannot be None");
1272 mlirResults.push_back(*
result);
1277 mlirAttributes.reserve(attributes->size());
1278 for (std::pair<nb::handle, nb::handle> it : *attributes) {
1281 key = nb::cast<std::string>(it.first);
1282 }
catch (nb::cast_error &err) {
1283 std::string msg =
"Invalid attribute key (not a string) when "
1284 "attempting to create the operation \"" +
1285 std::string(name) +
"\" (" + err.what() +
")";
1286 throw nb::type_error(msg.c_str());
1289 auto &attribute = nb::cast<PyAttribute &>(it.second);
1291 mlirAttributes.emplace_back(std::move(key), attribute);
1292 }
catch (nb::cast_error &err) {
1293 std::string msg =
"Invalid attribute value for the key \"" + key +
1294 "\" when attempting to create the operation \"" +
1295 std::string(name) +
"\" (" + err.what() +
")";
1296 throw nb::type_error(msg.c_str());
1297 }
catch (std::runtime_error &) {
1300 "Found an invalid (`None`?) attribute value for the key \"" + key +
1301 "\" when attempting to create the operation \"" +
1302 std::string(name) +
"\"";
1303 throw std::runtime_error(msg);
1309 mlirSuccessors.reserve(successors->size());
1310 for (
auto *successor : *successors) {
1313 throw nb::value_error(
"successor block cannot be None");
1314 mlirSuccessors.push_back(successor->get());
1320 MlirOperationState state =
1322 if (!operands.empty())
1324 state.enableResultTypeInference = inferType;
1325 if (!mlirResults.empty())
1327 mlirResults.data());
1328 if (!mlirAttributes.empty()) {
1332 llvm::SmallVector<MlirNamedAttribute, 4> mlirNamedAttributes;
1333 mlirNamedAttributes.reserve(mlirAttributes.size());
1334 for (
auto &it : mlirAttributes)
1340 mlirNamedAttributes.data());
1342 if (!mlirSuccessors.empty())
1344 mlirSuccessors.data());
1346 llvm::SmallVector<MlirRegion, 4> mlirRegions;
1347 mlirRegions.resize(regions);
1348 for (
int i = 0; i < regions; ++i)
1351 mlirRegions.data());
1355 PyMlirContext::ErrorCapture errors(location.
getContext());
1358 throw MLIRError(
"Operation creation failed", errors.take());
1395 [](
PyOpResult &self) -> nb::typed<nb::object, PyOpView> {
1398 "expected the owner of the value in Python to match that in "
1402 "Returns the operation that produces this result.");
1406 "Returns the position of this result in the operation's result list.");
1410template <
typename Container>
1411static std::vector<nb::typed<nb::object, PyType>>
1413 std::vector<nb::typed<nb::object, PyType>>
result;
1414 result.reserve(container.size());
1415 for (
int i = 0, e = container.size(); i < e; ++i) {
1429 operation(std::move(operation)) {}
1437 "Returns a list of types for all results in this result list.");
1443 "Returns the operation that owns this result list.");
1446intptr_t PyOpResultList::getRawNumElements() {
1447 operation->checkValid();
1451PyOpResult PyOpResultList::getRawElement(intptr_t index) {
1453 return PyOpResult(value);
1456PyOpResultList PyOpResultList::slice(intptr_t startIndex, intptr_t length,
1457 intptr_t step)
const {
1466 const nb::object &resultSegmentSpecObj,
1467 std::vector<int32_t> &resultSegmentLengths,
1468 std::vector<PyType *> &resultTypes) {
1469 resultTypes.reserve(resultTypeList.size());
1470 if (resultSegmentSpecObj.is_none()) {
1472 for (
const auto &it : llvm::enumerate(resultTypeList)) {
1474 resultTypes.push_back(nb::cast<PyType *>(it.value()));
1475 if (!resultTypes.back())
1476 throw nb::cast_error();
1477 }
catch (nb::cast_error &err) {
1478 throw nb::value_error((llvm::Twine(
"Result ") +
1479 llvm::Twine(it.index()) +
" of operation \"" +
1480 name +
"\" must be a Type (" + err.what() +
")")
1487 auto resultSegmentSpec = nb::cast<std::vector<int>>(resultSegmentSpecObj);
1488 if (resultSegmentSpec.size() != resultTypeList.size()) {
1489 throw nb::value_error((llvm::Twine(
"Operation \"") + name +
1491 llvm::Twine(resultSegmentSpec.size()) +
1492 " result segments but was provided " +
1493 llvm::Twine(resultTypeList.size()))
1497 resultSegmentLengths.reserve(resultTypeList.size());
1498 for (
const auto &it :
1499 llvm::enumerate(llvm::zip(resultTypeList, resultSegmentSpec))) {
1500 int segmentSpec = std::get<1>(it.value());
1501 if (segmentSpec == 1 || segmentSpec == 0) {
1504 auto *resultType = nb::cast<PyType *>(std::get<0>(it.value()));
1506 resultTypes.push_back(resultType);
1507 resultSegmentLengths.push_back(1);
1508 }
else if (segmentSpec == 0) {
1510 resultSegmentLengths.push_back(0);
1512 throw nb::value_error(
1513 (llvm::Twine(
"Result ") + llvm::Twine(it.index()) +
1514 " of operation \"" + name +
1515 "\" must be a Type (was None and result is not optional)")
1519 }
catch (nb::cast_error &err) {
1520 throw nb::value_error((llvm::Twine(
"Result ") +
1521 llvm::Twine(it.index()) +
" of operation \"" +
1522 name +
"\" must be a Type (" + err.what() +
1527 }
else if (segmentSpec == -1) {
1530 if (std::get<0>(it.value()).is_none()) {
1532 resultSegmentLengths.push_back(0);
1535 auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
1536 for (nb::handle segmentItem : segment) {
1537 resultTypes.push_back(nb::cast<PyType *>(segmentItem));
1538 if (!resultTypes.back()) {
1539 throw nb::type_error(
"contained a None item");
1542 resultSegmentLengths.push_back(nb::len(segment));
1544 }
catch (std::exception &err) {
1548 throw nb::value_error((llvm::Twine(
"Result ") +
1549 llvm::Twine(it.index()) +
" of operation \"" +
1550 name +
"\" must be a Sequence of Types (" +
1556 throw nb::value_error(
"Unexpected segment spec");
1564 if (numResults != 1) {
1566 throw nb::value_error((Twine(
"Cannot call .result on operation ") +
1567 StringRef(name.data, name.length) +
" which has " +
1569 " results (it is only valid for operations with a "
1578 if (operand.is_none()) {
1579 throw nb::value_error(
"contained a None item");
1582 if (nb::try_cast<PyOperationBase *>(operand, op)) {
1586 if (nb::try_cast<PyOpResultList *>(operand, opResultList)) {
1590 if (nb::try_cast<PyValue *>(operand, value)) {
1593 throw nb::value_error(
"is not a Value");
1597 std::string_view name, std::tuple<int, bool> opRegionSpec,
1598 nb::object operandSegmentSpecObj, nb::object resultSegmentSpecObj,
1599 std::optional<nb::list> resultTypeList, nb::list operandList,
1600 std::optional<nb::dict> attributes,
1601 std::optional<std::vector<PyBlock *>> successors,
1602 std::optional<int> regions,
PyLocation &location,
1603 const nb::object &maybeIp) {
1612 std::vector<int32_t> operandSegmentLengths;
1613 std::vector<int32_t> resultSegmentLengths;
1616 int opMinRegionCount = std::get<0>(opRegionSpec);
1617 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1619 regions = opMinRegionCount;
1621 if (*regions < opMinRegionCount) {
1622 throw nb::value_error(
1623 (llvm::Twine(
"Operation \"") + name +
"\" requires a minimum of " +
1624 llvm::Twine(opMinRegionCount) +
1625 " regions but was built with regions=" + llvm::Twine(*regions))
1629 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1630 throw nb::value_error(
1631 (llvm::Twine(
"Operation \"") + name +
"\" requires a maximum of " +
1632 llvm::Twine(opMinRegionCount) +
1633 " regions but was built with regions=" + llvm::Twine(*regions))
1639 std::vector<PyType *> resultTypes;
1640 if (resultTypeList.has_value()) {
1642 resultSegmentLengths, resultTypes);
1646 llvm::SmallVector<MlirValue, 4> operands;
1647 operands.reserve(operands.size());
1648 if (operandSegmentSpecObj.is_none()) {
1650 for (
const auto &it : llvm::enumerate(operandList)) {
1653 }
catch (nb::builtin_exception &err) {
1654 throw nb::value_error((llvm::Twine(
"Operand ") +
1655 llvm::Twine(it.index()) +
" of operation \"" +
1656 name +
"\" must be a Value (" + err.what() +
")")
1663 auto operandSegmentSpec = nb::cast<std::vector<int>>(operandSegmentSpecObj);
1664 if (operandSegmentSpec.size() != operandList.size()) {
1665 throw nb::value_error((llvm::Twine(
"Operation \"") + name +
1667 llvm::Twine(operandSegmentSpec.size()) +
1668 "operand segments but was provided " +
1669 llvm::Twine(operandList.size()))
1673 operandSegmentLengths.reserve(operandList.size());
1674 for (
const auto &it :
1675 llvm::enumerate(llvm::zip(operandList, operandSegmentSpec))) {
1676 int segmentSpec = std::get<1>(it.value());
1677 if (segmentSpec == 1 || segmentSpec == 0) {
1679 auto &operand = std::get<0>(it.value());
1680 if (!operand.is_none()) {
1684 }
catch (nb::builtin_exception &err) {
1685 throw nb::value_error((llvm::Twine(
"Operand ") +
1686 llvm::Twine(it.index()) +
1687 " of operation \"" + name +
1688 "\" must be a Value (" + err.what() +
")")
1693 operandSegmentLengths.push_back(1);
1694 }
else if (segmentSpec == 0) {
1696 operandSegmentLengths.push_back(0);
1698 throw nb::value_error(
1699 (llvm::Twine(
"Operand ") + llvm::Twine(it.index()) +
1700 " of operation \"" + name +
1701 "\" must be a Value (was None and operand is not optional)")
1705 }
else if (segmentSpec == -1) {
1708 if (std::get<0>(it.value()).is_none()) {
1710 operandSegmentLengths.push_back(0);
1713 auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
1714 for (nb::handle segmentItem : segment) {
1717 operandSegmentLengths.push_back(nb::len(segment));
1719 }
catch (std::exception &err) {
1723 throw nb::value_error((llvm::Twine(
"Operand ") +
1724 llvm::Twine(it.index()) +
" of operation \"" +
1725 name +
"\" must be a Sequence of Values (" +
1731 throw nb::value_error(
"Unexpected segment spec");
1737 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
1740 attributes = nb::dict(*attributes);
1742 attributes = nb::dict();
1744 if (attributes->contains(
"resultSegmentSizes") ||
1745 attributes->contains(
"operandSegmentSizes")) {
1746 throw nb::value_error(
"Manually setting a 'resultSegmentSizes' or "
1747 "'operandSegmentSizes' attribute is unsupported. "
1748 "Use Operation.create for such low-level access.");
1752 if (!resultSegmentLengths.empty()) {
1753 MlirAttribute segmentLengthAttr =
1755 resultSegmentLengths.data());
1756 (*attributes)[
"resultSegmentSizes"] =
1757 PyAttribute(context, segmentLengthAttr);
1761 if (!operandSegmentLengths.empty()) {
1762 MlirAttribute segmentLengthAttr =
1764 operandSegmentLengths.data());
1765 (*attributes)[
"operandSegmentSizes"] =
1766 PyAttribute(context, segmentLengthAttr);
1772 std::move(resultTypes),
1774 std::move(attributes),
1775 std::move(successors),
1776 *regions, location, maybeIp,
1781 const nb::object &operation) {
1782 nb::handle opViewType = nb::type<PyOpView>();
1783 nb::object instance = cls.attr(
"__new__")(cls);
1784 opViewType.attr(
"__init__")(instance, operation);
1792 operationObject(operation.getRef().getObject()) {}
1823 : refOperation(beforeOperationBase.getOperation().getRef()),
1827 : refOperation(beforeOperationRef), block((*refOperation)->getBlock()) {}
1832 throw nb::value_error(
1833 "Attempt to insert operation that is already attached");
1834 block.getParentOperation()->checkValid();
1835 MlirOperation beforeOp = {
nullptr};
1838 (*refOperation)->checkValid();
1839 beforeOp = (*refOperation)->get();
1845 throw nb::index_error(
"Cannot insert operation at the end of a block "
1846 "that already has a terminator. Did you mean to "
1847 "use 'InsertionPoint.at_block_terminator(block)' "
1848 "versus 'InsertionPoint(block)'?");
1857 if (mlirOperationIsNull(firstOp)) {
1864 block.getParentOperation()->getContext(), firstOp);
1870 if (mlirOperationIsNull(terminator))
1871 throw nb::value_error(
"Block has no terminator");
1873 block.getParentOperation()->getContext(), terminator);
1881 if (mlirOperationIsNull(nextOperation))
1895 const nb::object &excVal,
1896 const nb::object &excTb) {
1914 if (mlirAttributeIsNull(rawAttr))
1915 throw nb::python_error();
1923 "mlirTypeID was expected to be non-null.");
1928 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
1931 return typeCaster.value()(thisObj);
1939 : ownedName(new std::string(std::move(ownedName))) {
1961 throw nb::python_error();
1969 "mlirTypeID was expected to be non-null.");
1974 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
1977 return typeCaster.value()(thisObj);
1991 throw nb::python_error();
2010 "mlirTypeID was expected to be non-null.");
2011 std::optional<nb::callable> valueCaster =
2015 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
2018 return valueCaster.value()(thisObj);
2023 if (mlirValueIsNull(value))
2024 throw nb::python_error();
2025 MlirOperation owner;
2030 if (mlirOperationIsNull(owner))
2031 throw nb::python_error();
2035 return PyValue(ownerRef, value);
2043 : operation(operation.getOperation().getRef()) {
2046 throw nb::type_error(
"Operation is not a Symbol Table.");
2051 operation->checkValid();
2054 if (mlirOperationIsNull(symbol))
2055 throw nb::key_error(
2056 (
"Symbol '" + name +
"' not in the symbol table.").c_str());
2059 operation.getObject())
2064 operation->checkValid();
2075 erase(nb::cast<PyOperationBase &>(operation));
2079 operation->checkValid();
2083 if (mlirAttributeIsNull(symbolAttr))
2084 throw nb::value_error(
"Expected operation to have a symbol name.");
2095 MlirAttribute existingNameAttr =
2097 if (mlirAttributeIsNull(existingNameAttr))
2098 throw nb::value_error(
"Expected operation to have a symbol name.");
2104 const std::string &name) {
2109 MlirAttribute existingNameAttr =
2111 if (mlirAttributeIsNull(existingNameAttr))
2112 throw nb::value_error(
"Expected operation to have a symbol name.");
2113 MlirAttribute newNameAttr =
2122 MlirAttribute existingVisAttr =
2124 if (mlirAttributeIsNull(existingVisAttr))
2125 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2130 const std::string &visibility) {
2131 if (visibility !=
"public" && visibility !=
"private" &&
2132 visibility !=
"nested")
2133 throw nb::value_error(
2134 "Expected visibility to be 'public', 'private' or 'nested'");
2138 MlirAttribute existingVisAttr =
2140 if (mlirAttributeIsNull(existingVisAttr))
2141 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2148 const std::string &newSymbol,
2156 throw nb::value_error(
"Symbol rename failed");
2160 bool allSymUsesVisible,
2161 nb::object callback) {
2166 nb::object callback;
2168 std::string exceptionWhat;
2169 nb::object exceptionType;
2172 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
2174 fromOperation.
get(), allSymUsesVisible,
2175 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
2176 UserData *calleeUserData = static_cast<UserData *>(calleeUserDataVoid);
2178 PyOperation::forOperation(calleeUserData->context, foundOp);
2179 if (calleeUserData->gotException)
2182 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
2183 } catch (nb::python_error &e) {
2184 calleeUserData->gotException =
true;
2185 calleeUserData->exceptionWhat = e.what();
2186 calleeUserData->exceptionType = nb::borrow(e.type());
2189 static_cast<void *
>(&userData));
2190 if (userData.gotException) {
2191 std::string message(
"Exception raised in callback: ");
2192 message.append(userData.exceptionWhat);
2193 throw std::runtime_error(message);
2204 "Returns the block that owns this argument.");
2210 "Returns the position of this argument in the block's argument list.");
2216 "type"_a,
"Sets the type of this block argument.");
2219 [](PyBlockArgument &self, PyLocation loc) {
2222 "loc"_a,
"Sets the location of this block argument.");
2226 MlirBlock block,
intptr_t startIndex,
2230 operation(std::move(operation)), block(block) {}
2238 "Returns a list of types for all arguments in this argument list.");
2241intptr_t PyBlockArgumentList::getRawNumElements() {
2263 operation(operation) {}
2272 "Sets the operand at the specified index to a new value.");
2275intptr_t PyOpOperandList::getRawNumElements() {
2282 MlirOperation owner;
2288 assert(
false &&
"Value must be an block arg or op result.");
2291 return PyValue(pyOwner, operand);
2305 operation(operation) {}
2314 "Sets the successor block at the specified index.");
2317intptr_t PyOpSuccessors::getRawNumElements() {
2324 return PyBlock(operation, block);
2338 operation(operation), block(block) {}
2340intptr_t PyBlockSuccessors::getRawNumElements() {
2347 return PyBlock(operation, block);
2363 operation(operation), block(block) {}
2365intptr_t PyBlockPredecessors::getRawNumElements() {
2372 return PyBlock(operation, block);
2381nb::typed<nb::object, PyAttribute>
2383 MlirAttribute attr =
2385 if (mlirAttributeIsNull(attr)) {
2386 throw nb::key_error(
"attempt to access a non-existent attribute");
2395 if (index < 0 || index >=
dunderLen()) {
2396 throw nb::index_error(
"attempt to access out of bounds attribute");
2416 throw nb::key_error(
"attempt to delete a non-existent attribute");
2424 return !mlirAttributeIsNull(
2440 nb::class_<PyOpAttributeMap>(m,
"OpAttributeMap")
2442 "Checks if an attribute with the given name exists in the map.")
2444 "Returns the number of attributes in the map.")
2446 "Gets an attribute by name.")
2448 "Gets a named attribute by index.")
2450 "Sets an attribute with the given name.")
2452 "Deletes an attribute with the given name.")
2459 keys.append(nb::str(name.data, name.length));
2461 return nb::iter(keys);
2463 "Iterates over attribute names.")
2470 out.append(nb::str(name.data, name.length));
2474 "Returns a list of attribute names.")
2481 out.append(PyAttribute(self.operation->getContext(), attr)
2486 "Returns a list of attribute values.")
2492 self.operation->
get(),
2494 out.append(nb::make_tuple(
2495 nb::str(name.data, name.length),
2496 PyAttribute(self.operation->getContext(), attr)
2501 "Returns a list of `(name, attribute)` tuples.");
2513#define _Py_CAST(type, expr) ((type)(expr))
2520#if (defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L) || \
2521 (defined(__cplusplus) && __cplusplus >= 201103)
2522#define _Py_NULL nullptr
2524#define _Py_NULL NULL
2529#if PY_VERSION_HEX < 0x030A00A3
2532#if !defined(Py_XNewRef)
2533[[maybe_unused]] PyObject *_Py_XNewRef(PyObject *obj) {
2537#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
2541#if !defined(Py_NewRef)
2542[[maybe_unused]] PyObject *_Py_NewRef(PyObject *obj) {
2546#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
2552#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
2555PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate) {
2556 assert(tstate !=
_Py_NULL &&
"expected tstate != _Py_NULL");
2561PyFrameObject *PyFrame_GetBack(PyFrameObject *frame) {
2562 assert(frame !=
_Py_NULL &&
"expected frame != _Py_NULL");
2567PyCodeObject *PyFrame_GetCode(PyFrameObject *frame) {
2568 assert(frame !=
_Py_NULL &&
"expected frame != _Py_NULL");
2569 assert(frame->f_code !=
_Py_NULL &&
"expected frame->f_code != _Py_NULL");
2575using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
2577MlirLocation tracebackToLocation(MlirContext ctx) {
2578 size_t framesLimit =
2581 thread_local std::array<MlirLocation, PyGlobals::TracebackLoc::kMaxFrames>
2585 nb::gil_scoped_acquire acquire;
2586 PyThreadState *tstate = PyThreadState_GET();
2587 PyFrameObject *next;
2588 PyFrameObject *pyFrame = PyThreadState_GetFrame(tstate);
2594 for (; pyFrame !=
nullptr && count < framesLimit;
2595 next = PyFrame_GetBack(pyFrame), Py_XDECREF(pyFrame), pyFrame = next) {
2596 PyCodeObject *code = PyFrame_GetCode(pyFrame);
2598 nb::cast<std::string>(nb::borrow<nb::str>(code->co_filename));
2599 llvm::StringRef fileName(fileNameStr);
2600 if (!
PyGlobals::get().getTracebackLoc().isUserTracebackFilename(fileName))
2604#if PY_VERSION_HEX < 0x030B00F0
2606 nb::cast<std::string>(nb::borrow<nb::str>(code->co_name));
2607 llvm::StringRef funcName(name);
2608 int startLine = PyFrame_GetLineNumber(pyFrame);
2613 nb::cast<std::string>(nb::borrow<nb::str>(code->co_qualname));
2614 llvm::StringRef funcName(name);
2615 int startLine, startCol, endLine, endCol;
2616 int lasti = PyFrame_GetLasti(pyFrame);
2617 if (!PyCode_Addr2Location(code, lasti, &startLine, &startCol, &endLine,
2619 throw nb::python_error();
2622 ctx,
wrap(fileName), startLine, startCol, endLine, endCol);
2630 Py_XDECREF(pyFrame);
2635 MlirLocation callee = frames[0];
2640 MlirLocation caller = frames[count - 1];
2642 for (
int i = count - 2; i >= 1; i--)
2649maybeGetTracebackLocation(
const std::optional<PyLocation> &location) {
2650 if (location.has_value())
2651 return location.value();
2656 MlirLocation mlirLoc = tracebackToLocation(ctx.
get());
2658 return {ref, mlirLoc};
2667 m.attr(
"T") = nb::type_var(
"T");
2668 m.attr(
"U") = nb::type_var(
"U");
2670 nb::class_<PyGlobals>(m,
"_Globals")
2671 .def_prop_rw(
"dialect_search_modules",
2677 "_check_dialect_module_loaded",
2678 [](
PyGlobals &self,
const std::string &dialectNamespace) {
2681 "dialect_namespace"_a)
2683 "dialect_namespace"_a,
"dialect_class"_a,
2684 "Testing hook for directly registering a dialect")
2686 "operation_name"_a,
"operation_class"_a, nb::kw_only(),
2687 "replace"_a =
false,
2688 "Testing hook for directly registering an operation")
2689 .def(
"loc_tracebacks_enabled",
2693 .def(
"set_loc_tracebacks_enabled",
2697 .def(
"loc_tracebacks_frame_limit",
2701 .def(
"set_loc_tracebacks_frame_limit",
2702 [](
PyGlobals &self, std::optional<int> n) {
2706 .def(
"register_traceback_file_inclusion",
2707 [](
PyGlobals &self,
const std::string &filename) {
2710 .def(
"register_traceback_file_exclusion",
2711 [](
PyGlobals &self,
const std::string &filename) {
2718 m.attr(
"globals") = nb::cast(
new PyGlobals, nb::rv_policy::take_ownership);
2723 [](nb::type_object pyClass) {
2724 std::string dialectNamespace =
2725 nb::cast<std::string>(pyClass.attr(
"DIALECT_NAMESPACE"));
2730 "Class decorator for registering a custom Dialect wrapper");
2732 "register_operation",
2733 [](
const nb::type_object &dialectClass,
bool replace) -> nb::object {
2734 return nb::cpp_function(
2736 replace](nb::type_object opClass) -> nb::type_object {
2737 std::string operationName =
2738 nb::cast<std::string>(opClass.attr(
"OPERATION_NAME"));
2742 nb::object opClassName = opClass.attr(
"__name__");
2743 dialectClass.attr(opClassName) = opClass;
2748 nb::sig(
"def register_operation(dialect_class: type, *, replace: bool = False) "
2749 "-> typing.Callable[[type[T]], type[T]]"),
2751 "dialect_class"_a, nb::kw_only(),
"replace"_a =
false,
2752 "Produce a class decorator for registering an Operation class as part of "
2756 [](MlirTypeID mlirTypeID,
bool replace) -> nb::object {
2757 return nb::cpp_function([mlirTypeID, replace](
2758 nb::callable typeCaster) -> nb::object {
2764 nb::sig(
"def register_type_caster(typeid: _mlir.ir.TypeID, *, replace: bool = False) "
2765 "-> typing.Callable[[typing.Callable[[T], U]], typing.Callable[[T], U]]"),
2767 "typeid"_a, nb::kw_only(),
"replace"_a =
false,
2768 "Register a type caster for casting MLIR types to custom user types.");
2771 [](MlirTypeID mlirTypeID,
bool replace) -> nb::object {
2772 return nb::cpp_function(
2773 [mlirTypeID, replace](nb::callable valueCaster) -> nb::object {
2780 nb::sig(
"def register_value_caster(typeid: _mlir.ir.TypeID, *, replace: bool = False) "
2781 "-> typing.Callable[[typing.Callable[[T], U]], typing.Callable[[T], U]]"),
2783 "typeid"_a, nb::kw_only(),
"replace"_a =
false,
2784 "Register a value caster for casting MLIR values to custom user values.");
2794 nb::enum_<PyDiagnosticSeverity>(m,
"DiagnosticSeverity")
2800 nb::enum_<PyWalkOrder>(m,
"WalkOrder")
2803 nb::enum_<PyWalkResult>(m,
"WalkResult")
2811 nb::class_<PyDiagnostic>(m,
"Diagnostic")
2813 "Returns the severity of the diagnostic.")
2815 "Returns the location associated with the diagnostic.")
2817 "Returns the message text of the diagnostic.")
2819 "Returns a tuple of attached note diagnostics.")
2824 return nb::str(
"<Invalid Diagnostic>");
2827 "Returns the diagnostic message as a string.");
2829 nb::class_<PyDiagnostic::DiagnosticInfo>(m,
"DiagnosticInfo")
2835 "diag"_a,
"Creates a DiagnosticInfo from a Diagnostic.")
2837 "The severity level of the diagnostic.")
2839 "The location associated with the diagnostic.")
2841 "The message text of the diagnostic.")
2843 "List of attached note diagnostics.")
2847 "Returns the diagnostic message as a string.");
2849 nb::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler")
2851 "Detaches the diagnostic handler from the context.")
2853 "Returns True if the handler is attached to a context.")
2855 "Returns True if an error was encountered during diagnostic "
2858 "Enters the diagnostic handler as a context manager.")
2860 "exc_value"_a.none(),
"traceback"_a.none(),
2861 "Exits the diagnostic handler context manager.");
2864 nb::class_<PyThreadPool>(m,
"ThreadPool")
2867 "Creates a new thread pool with default concurrency.")
2869 "Returns the maximum number of threads in the pool.")
2871 "Returns the raw pointer to the LLVM thread pool as a string.");
2873 nb::class_<PyMlirContext>(m,
"Context")
2881 Creates a new MLIR context.
2883 The context is the top-level container for all MLIR objects. It owns the storage
2884 for types, attributes, locations, and other core IR objects. A context can be
2885 configured to allow or disallow unregistered dialects and can have dialects
2886 loaded on-demand.)")
2888 "Gets the number of live Context objects.")
2890 "_get_context_again",
2891 [](
PyMlirContext &self) -> nb::typed<nb::object, PyMlirContext> {
2895 "Gets another reference to the same context.")
2897 "Gets the number of live modules owned by this context.")
2899 "Gets a capsule wrapping the MlirContext.")
2902 "Creates a Context from a capsule wrapping MlirContext.")
2904 "Enters the context as a context manager.")
2906 "exc_value"_a.none(),
"traceback"_a.none(),
2907 "Exits the context manager.")
2908 .def_prop_ro_static(
2911 -> std::optional<nb::typed<nb::object, PyMlirContext>> {
2915 return nb::cast(context);
2917 nb::sig(
"def current(/) -> Context | None"),
2918 "Gets the Context bound to the current thread or returns None if no "
2923 "Gets a container for accessing dialects by name.")
2926 "Alias for `dialects`.")
2928 "get_dialect_descriptor",
2931 self.get(), {name.data(), name.size()});
2933 throw nb::value_error(
2934 (Twine(
"Dialect '") + name +
"' not found").str().c_str());
2939 "Gets or loads a dialect by name, returning its descriptor object.")
2941 "allow_unregistered_dialects",
2948 "Controls whether unregistered dialects are allowed in this context.")
2951 "Attaches a diagnostic handler that will receive callbacks.")
2953 "enable_multithreading",
2959 Enables or disables multi-threading support in the context.
2962 enable: Whether to enable (True) or disable (False) multi-threading.
2974 Sets a custom thread pool for the context to use.
2977 pool: A ThreadPool object to use for parallel operations.
2980 Multi-threading is automatically disabled before setting the thread pool.)")
2986 "Gets the number of threads in the context's thread pool.")
2988 "_mlir_thread_pool_ptr",
2991 std::stringstream ss;
2995 "Gets the raw pointer to the LLVM thread pool as a string.")
2997 "is_registered_operation",
3004 Checks whether an operation with the given name is registered.
3007 operation_name: The fully qualified name of the operation (e.g., `arith.addf`).
3010 True if the operation is registered, False otherwise.)")
3012 "append_dialect_registry",
3018 Appends the contents of a dialect registry to the context.
3021 registry: A DialectRegistry containing dialects to append.)")
3022 .def_prop_rw("emit_error_diagnostics",
3026 Controls whether error diagnostics are emitted to diagnostic handlers.
3028 By default, error diagnostics are captured and reported through MLIRError exceptions.)")
3030 "load_all_available_dialects",
3035 Loads all dialects available in the registry into the context.
3037 This eagerly loads all dialects that have been registered, making them
3038 immediately available for use.)");
3043 nb::class_<PyDialectDescriptor>(m,
"DialectDescriptor")
3050 "Returns the namespace of the dialect.")
3055 std::string repr(
"<DialectDescriptor ");
3060 nb::sig(
"def __repr__(self) -> str"),
3061 "Returns a string representation of the dialect descriptor.");
3066 nb::class_<PyDialects>(m,
"Dialects")
3070 MlirDialect dialect =
3071 self.getDialectForKey(keyName,
false);
3072 nb::object descriptor =
3076 "Gets a dialect by name using subscript notation.")
3079 [=](
PyDialects &self, std::string attrName) {
3080 MlirDialect dialect =
3081 self.getDialectForKey(attrName,
true);
3082 nb::object descriptor =
3086 "Gets a dialect by name using attribute notation.");
3091 nb::class_<PyDialect>(m,
"Dialect")
3092 .def(nb::init<nb::object>(),
"descriptor"_a,
3093 "Creates a Dialect from a DialectDescriptor.")
3095 "descriptor", [](
PyDialect &self) {
return self.getDescriptor(); },
3096 "Returns the DialectDescriptor for this dialect.")
3099 [](
const nb::object &self) {
3100 auto clazz = self.attr(
"__class__");
3101 return nb::str(
"<Dialect ") +
3102 self.attr(
"descriptor").attr(
"namespace") +
3103 nb::str(
" (class ") + clazz.attr(
"__module__") +
3104 nb::str(
".") + clazz.attr(
"__name__") + nb::str(
")>");
3106 nb::sig(
"def __repr__(self) -> str"),
3107 "Returns a string representation of the dialect.");
3112 nb::class_<PyDialectRegistry>(m,
"DialectRegistry")
3114 "Gets a capsule wrapping the MlirDialectRegistry.")
3117 "Creates a DialectRegistry from a capsule wrapping "
3118 "`MlirDialectRegistry`.")
3119 .def(nb::init<>(),
"Creates a new empty dialect registry.");
3124 nb::class_<PyLocation>(m,
"Location")
3126 "Gets a capsule wrapping the MlirLocation.")
3128 "Creates a Location from a capsule wrapping MlirLocation.")
3130 "Enters the location as a context manager.")
3132 "exc_value"_a.none(),
"traceback"_a.none(),
3133 "Exits the location context manager.")
3139 "Compares two locations for equality.")
3141 "__eq__", [](
PyLocation &self, nb::object other) {
return false; },
3142 "Compares location with non-location object (always returns False).")
3143 .def_prop_ro_static(
3145 [](nb::object & ) -> std::optional<PyLocation *> {
3148 return std::nullopt;
3152 nb::sig(
"def current(/) -> Location | None"),
3154 "Gets the Location bound to the current thread or raises ValueError.")
3161 "context"_a = nb::none(),
3162 "Gets a Location representing an unknown location.")
3165 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
3168 throw nb::value_error(
"No caller frames provided.");
3169 MlirLocation caller = frames.back().get();
3176 "callee"_a,
"frames"_a,
"context"_a = nb::none(),
3177 "Gets a Location representing a caller and callsite.")
3179 "Returns True if this location is a CallSiteLoc.")
3186 "Gets the callee location from a CallSiteLoc.")
3193 "Gets the caller location from a CallSiteLoc.")
3196 [](std::string filename,
int line,
int col,
3203 "filename"_a,
"line"_a,
"col"_a,
"context"_a = nb::none(),
3204 "Gets a Location representing a file, line and column.")
3207 [](std::string filename,
int startLine,
int startCol,
int endLine,
3212 startLine, startCol, endLine, endCol));
3214 "filename"_a,
"start_line"_a,
"start_col"_a,
"end_line"_a,
3215 "end_col"_a,
"context"_a = nb::none(),
3216 "Gets a Location representing a file, line and column range.")
3218 "Returns True if this location is a FileLineColLoc.")
3221 [](MlirLocation loc) {
3225 "Gets the filename from a FileLineColLoc.")
3227 "Gets the start line number from a `FileLineColLoc`.")
3229 "Gets the start column number from a `FileLineColLoc`.")
3231 "Gets the end line number from a `FileLineColLoc`.")
3233 "Gets the end column number from a `FileLineColLoc`.")
3236 [](
const std::vector<PyLocation> &pyLocations,
3237 std::optional<PyAttribute> metadata,
3240 locations.reserve(pyLocations.size());
3241 for (
auto &pyLocation : pyLocations)
3242 locations.push_back(pyLocation.get());
3244 context->
get(), locations.size(), locations.data(),
3245 metadata ? metadata->get() : MlirAttribute{0});
3246 return PyLocation(context->getRef(), location);
3248 "locations"_a,
"metadata"_a = nb::none(),
"context"_a = nb::none(),
3249 "Gets a Location representing a fused location with optional "
3252 "Returns True if this location is a `FusedLoc`.")
3257 std::vector<MlirLocation> locations(numLocations);
3260 std::vector<PyLocation> pyLocations{};
3261 pyLocations.reserve(numLocations);
3262 for (
unsigned i = 0; i < numLocations; ++i)
3263 pyLocations.emplace_back(self.getContext(), locations[i]);
3266 "Gets the list of locations from a `FusedLoc`.")
3269 [](std::string name, std::optional<PyLocation> childLoc,
3275 childLoc ? childLoc->get()
3278 "name"_a,
"childLoc"_a = nb::none(),
"context"_a = nb::none(),
3279 "Gets a Location representing a named location with optional child "
3282 "Returns True if this location is a `NameLoc`.")
3285 [](MlirLocation loc) {
3288 "Gets the name string from a `NameLoc`.")
3295 "Gets the child location from a `NameLoc`.")
3302 "attribute"_a,
"context"_a = nb::none(),
3303 "Gets a Location from a `LocationAttr`.")
3306 [](
PyLocation &self) -> nb::typed<nb::object, PyMlirContext> {
3307 return self.getContext().getObject();
3309 "Context that owns the `Location`.")
3316 "Get the underlying `LocationAttr`.")
3324 Emits an error diagnostic at this location.
3327 message: The error message to emit.)")
3334 return printAccum.
join();
3336 "Returns the assembly representation of the location.");
3341 nb::class_<PyModule>(m,
"Module", nb::is_weak_referenceable())
3343 "Gets a capsule wrapping the MlirModule.")
3346 Creates a Module from a `MlirModule` wrapped by a capsule (i.e. `module._CAPIPtr`).
3348 This returns a new object **BUT** `_clear_mlir_module(module)` must be called to
3349 prevent double-frees (of the underlying `mlir::Module`).)")
3352 Clears the internal MLIR module reference.
3354 This is used internally to prevent double-free when ownership is transferred
3355 via the C API capsule mechanism. Not intended for normal use.)")
3359 -> nb::typed<nb::object, PyModule> {
3363 if (mlirModuleIsNull(module))
3364 throw MLIRError(
"Unable to parse module assembly", errors.
take());
3371 -> nb::typed<nb::object, PyModule> {
3375 if (mlirModuleIsNull(module))
3376 throw MLIRError(
"Unable to parse module assembly", errors.
take());
3383 -> nb::typed<nb::object, PyModule> {
3387 if (mlirModuleIsNull(module))
3388 throw MLIRError(
"Unable to parse module assembly", errors.
take());
3394 [](
const std::optional<PyLocation> &loc)
3395 -> nb::typed<nb::object, PyModule> {
3396 PyLocation pyLoc = maybeGetTracebackLocation(loc);
3400 "loc"_a = nb::none(),
"Creates an empty module.")
3403 [](
PyModule &self) -> nb::typed<nb::object, PyMlirContext> {
3404 return self.getContext().getObject();
3406 "Context that created the `Module`.")
3409 [](
PyModule &self) -> nb::typed<nb::object, PyOperation> {
3412 self.getRef().releaseObject())
3415 "Accesses the module as an operation.")
3421 self.getRef().releaseObject());
3425 "Return the block for this module.")
3434 [](
const nb::object &self) {
3436 return self.attr(
"operation").attr(
"__str__")();
3438 nb::sig(
"def __str__(self) -> str"),
3440 Gets the assembly form of the operation with default options.
3442 If more advanced control over the assembly formatting or I/O options is needed,
3443 use the dedicated print or get_asm method, which supports keyword arguments to
3451 "other"_a,
"Compares two modules for equality.")
3455 "Returns the hash value of the module.");
3460 nb::class_<PyOperationBase>(m,
"_OperationBase")
3464 return self.getOperation().getCapsule();
3466 "Gets a capsule wrapping the `MlirOperation`.")
3471 other.getOperation().
get());
3473 "Compares two operations for equality.")
3477 "Compares operation with non-operation object (always returns "
3484 "Returns the hash value of the operation.")
3490 "Returns a dictionary-like map of operation attributes.")
3494 PyOperation &concreteOperation = self.getOperation();
3498 "Context that owns the operation.")
3502 auto &concreteOperation = self.getOperation();
3503 concreteOperation.checkValid();
3504 MlirOperation operation = concreteOperation.
get();
3507 "Returns the fully qualified name of the operation.")
3513 "Returns the list of operation operands.")
3519 "Returns the list of operation regions.")
3525 "Returns the list of Operation results.")
3529 auto &operation = self.getOperation();
3533 "Shortcut to get an op result if it has only one (throws an error "
3546 nb::for_getter(
"Returns the source location the operation was "
3547 "defined or derived from."),
3548 nb::for_setter(
"Sets the source location the operation was defined "
3549 "or derived from."))
3553 -> std::optional<nb::typed<nb::object, PyOperation>> {
3554 auto parent = self.getOperation().getParentOperation();
3556 return parent->getObject();
3559 "Returns the parent operation, or `None` if at top level.")
3563 return self.getAsm(
false,
3574 nb::sig(
"def __str__(self) -> str"),
3575 "Returns the assembly form of the operation.")
3577 nb::overload_cast<PyAsmState &, nb::object, bool>(
3579 "state"_a,
"file"_a = nb::none(),
"binary"_a =
false,
3581 Prints the assembly form of the operation to a file like object.
3584 state: `AsmState` capturing the operation numbering and flags.
3585 file: Optional file like object to write to. Defaults to sys.stdout.
3586 binary: Whether to write `bytes` (True) or `str` (False). Defaults to False.)")
3588 nb::overload_cast<std::optional<int64_t>, std::optional<int64_t>,
3589 bool,
bool,
bool,
bool,
bool,
bool, nb::object,
3592 "large_elements_limit"_a = nb::none(),
3593 "large_resource_limit"_a = nb::none(),
"enable_debug_info"_a =
false,
3594 "pretty_debug_info"_a =
false,
"print_generic_op_form"_a =
false,
3595 "use_local_scope"_a =
false,
"use_name_loc_as_prefix"_a =
false,
3596 "assume_verified"_a =
false,
"file"_a = nb::none(),
3597 "binary"_a =
false,
"skip_regions"_a =
false,
3599 Prints the assembly form of the operation to a file like object.
3602 large_elements_limit: Whether to elide elements attributes above this
3603 number of elements. Defaults to None (no limit).
3604 large_resource_limit: Whether to elide resource attributes above this
3605 number of characters. Defaults to None (no limit). If large_elements_limit
3606 is set and this is None, the behavior will be to use large_elements_limit
3607 as large_resource_limit.
3608 enable_debug_info: Whether to print debug/location information. Defaults
3610 pretty_debug_info: Whether to format debug information for easier reading
3611 by a human (warning: the result is unparseable). Defaults to False.
3612 print_generic_op_form: Whether to print the generic assembly forms of all
3613 ops. Defaults to False.
3614 use_local_scope: Whether to print in a way that is more optimized for
3615 multi-threaded access but may not be consistent with how the overall
3617 use_name_loc_as_prefix: Whether to use location attributes (NameLoc) as
3618 prefixes for the SSA identifiers. Defaults to False.
3619 assume_verified: By default, if not printing generic form, the verifier
3620 will be run and if it fails, generic form will be printed with a comment
3621 about failed verification. While a reasonable default for interactive use,
3622 for systematic use, it is often better for the caller to verify explicitly
3623 and report failures in a more robust fashion. Set this to True if doing this
3624 in order to avoid running a redundant verification. If the IR is actually
3625 invalid, behavior is undefined.
3626 file: The file like object to write to. Defaults to sys.stdout.
3627 binary: Whether to write bytes (True) or str (False). Defaults to False.
3628 skip_regions: Whether to skip printing regions. Defaults to False.)")
3630 "desired_version"_a = nb::none(),
3632 Write the bytecode form of the operation to a file like object.
3635 file: The file like object to write to.
3636 desired_version: Optional version of bytecode to emit.
3638 The bytecode writer status.)")
3641 "binary"_a =
false,
"large_elements_limit"_a = nb::none(),
3642 "large_resource_limit"_a = nb::none(),
"enable_debug_info"_a =
false,
3643 "pretty_debug_info"_a =
false,
"print_generic_op_form"_a =
false,
3644 "use_local_scope"_a =
false,
"use_name_loc_as_prefix"_a =
false,
3645 "assume_verified"_a =
false,
"skip_regions"_a =
false,
3647 Gets the assembly form of the operation with all options available.
3650 binary: Whether to return a bytes (True) or str (False) object. Defaults to
3652 ... others ...: See the print() method for common keyword arguments for
3653 configuring the printout.
3655 Either a bytes or str object, depending on the setting of the `binary`
3658 "Verify the operation. Raises MLIRError if verification fails, and "
3659 "returns true otherwise.")
3661 "Puts self immediately after the other operation in its parent "
3664 "Puts self immediately before the other operation in its parent "
3668 Checks if this operation is before another in the same block.
3671 other: Another operation in the same parent block.
3674 True if this operation is before `other` in the operation list of the parent block.)")
3678 const nb::object &ip) -> nb::typed<nb::object, PyOperation> {
3679 return self.getOperation().clone(ip);
3681 "ip"_a = nb::none(),
3683 Creates a deep copy of the operation.
3686 ip: Optional insertion point where the cloned operation should be inserted.
3687 If None, the current insertion point is used. If False, the operation
3691 A new Operation that is a clone of this operation.)")
3693 "detach_from_parent",
3698 throw nb::value_error(
"Detached operation has no parent.");
3703 "Detaches the operation from its parent block.")
3711 "Reports if the operation is attached to its parent block.")
3715 Erases the operation and frees its memory.
3718 After erasing, any Python references to the operation become invalid.)")
3722 nb::sig(
"def walk(self, callback: Callable[[Operation], WalkResult], walk_order: WalkOrder) -> None"),
3725 Walks the operation tree with a callback function.
3728 callback: A callable that takes an Operation and returns a WalkResult.
3729 walk_order: The order of traversal (PRE_ORDER or POST_ORDER).)");
3731 nb::class_<PyOperation, PyOperationBase>(m, "Operation")
3734 [](std::string_view name,
3735 std::optional<std::vector<PyType *>> results,
3736 std::optional<std::vector<PyValue *>> operands,
3737 std::optional<nb::dict> attributes,
3738 std::optional<std::vector<PyBlock *>> successors,
int regions,
3739 const std::optional<PyLocation> &location,
3740 const nb::object &maybeIp,
3741 bool inferType) -> nb::typed<nb::object, PyOperation> {
3745 mlirOperands.reserve(operands->size());
3746 for (
PyValue *operand : *operands) {
3748 throw nb::value_error(
"operand value cannot be None");
3749 mlirOperands.push_back(operand->get());
3753 PyLocation pyLoc = maybeGetTracebackLocation(location);
3755 successors, regions, pyLoc, maybeIp,
3758 "name"_a,
"results"_a = nb::none(),
"operands"_a = nb::none(),
3759 "attributes"_a = nb::none(),
"successors"_a = nb::none(),
3760 "regions"_a = 0,
"loc"_a = nb::none(),
"ip"_a = nb::none(),
3761 "infer_type"_a =
false,
3763 Creates a new operation.
3766 name: Operation name (e.g. `dialect.operation`).
3767 results: Optional sequence of Type representing op result types.
3768 operands: Optional operands of the operation.
3769 attributes: Optional Dict of {str: Attribute}.
3770 successors: Optional List of Block for the operation's successors.
3771 regions: Number of regions to create (default = 0).
3772 location: Optional Location object (defaults to resolve from context manager).
3773 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).
3774 infer_type: Whether to infer result types (default = False).
3776 A new detached Operation object. Detached operations can be added to blocks, which causes them to become attached.)")
3779 [](
const std::string &sourceStr,
const std::string &sourceName,
3781 -> nb::typed<nb::object, PyOpView> {
3785 "source"_a, nb::kw_only(),
"source_name"_a =
"",
3786 "context"_a = nb::none(),
3787 "Parses an operation. Supports both text assembly format and binary "
3790 "Gets a capsule wrapping the MlirOperation.")
3793 "Creates an Operation from a capsule wrapping MlirOperation.")
3796 [](nb::object self) -> nb::typed<nb::object, PyOperation> {
3799 "Returns self (the operation).")
3802 [](
PyOperation &self) -> nb::typed<nb::object, PyOpView> {
3803 return self.createOpView();
3806 Returns an OpView of this operation.
3809 If the operation has a registered and loaded dialect then this OpView will
3810 be concrete wrapper class.)")
3812 "Returns the block containing this operation.")
3818 "Returns the list of Operation successors.")
3820 "replace_uses_of_with",
3825 "Replaces uses of the 'of' value with the 'with' value inside the "
3828 "Invalidate the operation.");
3831 nb::class_<PyOpView, PyOperationBase>(m,
"OpView")
3832 .def(nb::init<nb::typed<nb::object, PyOperation>>(),
"operation"_a)
3835 [](
PyOpView *self, std::string_view name,
3836 std::tuple<int, bool> opRegionSpec,
3837 nb::object operandSegmentSpecObj,
3838 nb::object resultSegmentSpecObj,
3839 std::optional<nb::list> resultTypeList, nb::list operandList,
3840 std::optional<nb::dict> attributes,
3841 std::optional<std::vector<PyBlock *>> successors,
3842 std::optional<int> regions,
3843 const std::optional<PyLocation> &location,
3844 const nb::object &maybeIp) {
3845 PyLocation pyLoc = maybeGetTracebackLocation(location);
3847 name, opRegionSpec, operandSegmentSpecObj,
3848 resultSegmentSpecObj, resultTypeList, operandList,
3849 attributes, successors, regions, pyLoc, maybeIp));
3851 "name"_a,
"opRegionSpec"_a,
3852 "operandSegmentSpecObj"_a = nb::none(),
3853 "resultSegmentSpecObj"_a = nb::none(),
"results"_a = nb::none(),
3854 "operands"_a = nb::none(),
"attributes"_a = nb::none(),
3855 "successors"_a = nb::none(),
"regions"_a = nb::none(),
3856 "loc"_a = nb::none(),
"ip"_a = nb::none())
3859 [](
PyOpView &self) -> nb::typed<nb::object, PyOperation> {
3860 return self.getOperationObject();
3862 .def_prop_ro(
"opview",
3863 [](nb::object self) -> nb::typed<nb::object, PyOpView> {
3868 [](
PyOpView &self) {
return nb::str(self.getOperationObject()); })
3874 "Returns the list of Operation successors.")
3877 [](
PyOpView &self) { self.getOperation().setInvalid(); },
3878 "Invalidate the operation.");
3879 opViewClass.attr(
"_ODS_REGIONS") = nb::make_tuple(0,
true);
3880 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = nb::none();
3881 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = nb::none();
3886 [](nb::handle cls, std::optional<nb::list> resultTypeList,
3887 nb::list operandList, std::optional<nb::dict> attributes,
3888 std::optional<std::vector<PyBlock *>> successors,
3889 std::optional<int> regions, std::optional<PyLocation> location,
3890 const nb::object &maybeIp) {
3891 std::string name = nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
3892 std::tuple<int, bool> opRegionSpec =
3893 nb::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
3894 nb::object operandSegmentSpec = cls.attr(
"_ODS_OPERAND_SEGMENTS");
3895 nb::object resultSegmentSpec = cls.attr(
"_ODS_RESULT_SEGMENTS");
3896 PyLocation pyLoc = maybeGetTracebackLocation(location);
3898 resultSegmentSpec, resultTypeList,
3899 operandList, attributes, successors,
3900 regions, pyLoc, maybeIp);
3902 "cls"_a,
"results"_a = nb::none(),
"operands"_a = nb::none(),
3903 "attributes"_a = nb::none(),
"successors"_a = nb::none(),
3904 "regions"_a = nb::none(),
"loc"_a = nb::none(),
"ip"_a = nb::none(),
3905 "Builds a specific, generated OpView based on class level attributes.");
3907 [](
const nb::object &cls,
const std::string &sourceStr,
3908 const std::string &sourceName,
3918 std::string clsOpName =
3919 nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
3922 std::string_view parsedOpName(identifier.
data, identifier.
length);
3923 if (clsOpName != parsedOpName)
3924 throw MLIRError(Twine(
"Expected a '") + clsOpName +
"' op, got: '" +
3925 parsedOpName +
"'");
3928 "cls"_a,
"source"_a, nb::kw_only(),
"source_name"_a =
"",
3929 "context"_a = nb::none(),
3930 "Parses a specific, generated OpView based on class level attributes.");
3935 nb::class_<PyRegion>(m,
"Region")
3939 return PyBlockList(self.getParentOperation(), self.get());
3941 "Returns a forward-optimized sequence of blocks.")
3944 [](
PyRegion &self) -> nb::typed<nb::object, PyOpView> {
3945 return self.getParentOperation()->createOpView();
3947 "Returns the operation owning this region.")
3955 "Iterates over blocks in the region.")
3959 return self.get().ptr == other.
get().ptr;
3961 "Compares two regions for pointer equality.")
3963 "__eq__", [](
PyRegion &self, nb::object &other) {
return false; },
3964 "Compares region with non-region object (always returns False).");
3969 nb::class_<PyBlock>(m,
"Block")
3971 "Gets a capsule wrapping the MlirBlock.")
3974 [](
PyBlock &self) -> nb::typed<nb::object, PyOpView> {
3975 return self.getParentOperation()->createOpView();
3977 "Returns the owning operation of this block.")
3982 return PyRegion(self.getParentOperation(), region);
3984 "Returns the owning region of this block.")
3990 "Returns a list of block arguments.")
3999 Appends an argument of the specified type to the block.
4002 type: The type of the argument to add.
4003 loc: The source location for the argument.
4006 The newly added block argument.)")
4014 Erases the argument at the specified index.
4017 index: The index of the argument to erase.)")
4023 "Returns a forward-optimized sequence of operations.")
4026 [](
PyRegion &parent,
const nb::sequence &pyArgTypes,
4027 const std::optional<nb::sequence> &pyArgLocs) {
4029 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
4033 "parent"_a,
"arg_types"_a = nb::list(),
"arg_locs"_a = std::nullopt,
4034 "Creates and returns a new Block at the beginning of the given "
4035 "region (with given argument types and locations).")
4039 MlirBlock
b = self.get();
4046 Appends this block to a region.
4048 Transfers ownership if the block is currently owned by another region.
4051 region: The region to append the block to.)")
4054 [](
PyBlock &self,
const nb::args &pyArgTypes,
4055 const std::optional<nb::sequence> &pyArgLocs) {
4058 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
4061 return PyBlock(self.getParentOperation(), block);
4063 "arg_types"_a, nb::kw_only(),
"arg_locs"_a = std::nullopt,
4064 "Creates and returns a new Block before this block "
4065 "(with given argument types and locations).")
4068 [](
PyBlock &self,
const nb::args &pyArgTypes,
4069 const std::optional<nb::sequence> &pyArgLocs) {
4072 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
4075 return PyBlock(self.getParentOperation(), block);
4077 "arg_types"_a, nb::kw_only(),
"arg_locs"_a = std::nullopt,
4078 "Creates and returns a new Block after this block "
4079 "(with given argument types and locations).")
4084 MlirOperation firstOperation =
4089 "Iterates over operations in the block.")
4093 return self.get().ptr == other.
get().ptr;
4095 "Compares two blocks for pointer equality.")
4097 "__eq__", [](
PyBlock &self, nb::object &other) {
return false; },
4098 "Compares block with non-block object (always returns False).")
4102 return static_cast<size_t>(llvm::hash_value(self.get().ptr));
4104 "Returns the hash value of the block.")
4112 return printAccum.
join();
4114 "Returns the assembly form of the block.")
4124 self.getParentOperation().getObject());
4128 Appends an operation to this block.
4130 If the operation is currently in another block, it will be moved.
4133 operation: The operation to append to the block.)")
4139 "Returns the list of Block successors.")
4145 "Returns the list of Block predecessors.");
4151 nb::class_<PyInsertionPoint>(m,
"InsertionPoint")
4152 .def(nb::init<PyBlock &>(),
"block"_a,
4153 "Inserts after the last operation but still inside the block.")
4155 "Enters the insertion point as a context manager.")
4157 "exc_value"_a.none(),
"traceback"_a.none(),
4158 "Exits the insertion point context manager.")
4159 .def_prop_ro_static(
4164 throw nb::value_error(
"No current InsertionPoint");
4167 nb::sig(
"def current(/) -> InsertionPoint"),
4168 "Gets the InsertionPoint bound to the current thread or raises "
4169 "ValueError if none has been set.")
4170 .def(nb::init<PyOperationBase &>(),
"beforeOperation"_a,
4171 "Inserts before a referenced operation.")
4174 Creates an insertion point at the beginning of a block.
4177 block: The block at whose beginning operations should be inserted.
4180 An InsertionPoint at the block's beginning.)")
4184 Creates an insertion point before a block's terminator.
4187 block: The block whose terminator to insert before.
4190 An InsertionPoint before the terminator.
4193 ValueError: If the block has no terminator.)")
4196 Creates an insertion point immediately after an operation.
4199 operation: The operation after which to insert.
4202 An InsertionPoint after the operation.)")
4205 Inserts an operation at this insertion point.
4208 operation: The operation to insert.)")
4211 "Returns the block that this `InsertionPoint` points to.")
4215 -> std::optional<nb::typed<nb::object, PyOperation>> {
4216 auto refOperation = self.getRefOperation();
4218 return refOperation->getObject();
4221 "The reference operation before which new operations are "
4222 "inserted, or None if the insertion point is at the end of "
4228 nb::class_<PyAttribute>(m,
"Attribute")
4231 .def(nb::init<PyAttribute &>(),
"cast_from_type"_a,
4232 "Casts the passed attribute to the generic `Attribute`.")
4234 "Gets a capsule wrapping the MlirAttribute.")
4237 "Creates an Attribute from a capsule wrapping `MlirAttribute`.")
4241 -> nb::typed<nb::object, PyAttribute> {
4245 if (mlirAttributeIsNull(attr))
4246 throw MLIRError(
"Unable to parse attribute", errors.
take());
4249 "asm"_a,
"context"_a = nb::none(),
4250 "Parses an attribute from an assembly form. Raises an `MLIRError` on "
4254 [](
PyAttribute &self) -> nb::typed<nb::object, PyMlirContext> {
4255 return self.getContext().getObject();
4257 "Context that owns the `Attribute`.")
4260 [](
PyAttribute &self) -> nb::typed<nb::object, PyType> {
4264 "Returns the type of the `Attribute`.")
4270 nb::keep_alive<0, 1>(),
4272 Binds a name to the attribute, creating a `NamedAttribute`.
4275 name: The name to bind to the `Attribute`.
4278 A `NamedAttribute` with the given name and this attribute.)")
4282 "Compares two attributes for equality.")
4284 "__eq__", [](
PyAttribute &self, nb::object &other) {
return false; },
4285 "Compares attribute with non-attribute object (always returns "
4290 return static_cast<size_t>(llvm::hash_value(self.get().ptr));
4292 "Returns the hash value of the attribute.")
4302 return printAccum.
join();
4304 "Returns the assembly form of the Attribute.")
4314 printAccum.
parts.append(
"Attribute(");
4317 printAccum.
parts.append(
")");
4318 return printAccum.
join();
4320 "Returns a string representation of the attribute.")
4326 "mlirTypeID was expected to be non-null.");
4329 "Returns the `TypeID` of the attribute.")
4332 [](
PyAttribute &self) -> nb::typed<nb::object, PyAttribute> {
4333 return self.maybeDownCast();
4335 "Downcasts the attribute to a more specific attribute if possible.");
4340 nb::class_<PyNamedAttribute>(m,
"NamedAttribute")
4345 printAccum.
parts.append(
"NamedAttribute(");
4346 printAccum.
parts.append(
4349 printAccum.
parts.append(
"=");
4353 printAccum.
parts.append(
")");
4354 return printAccum.
join();
4356 "Returns a string representation of the named attribute.")
4362 "The name of the `NamedAttribute` binding.")
4366 nb::keep_alive<0, 1>(), nb::sig(
"def attr(self) -> Attribute"),
4367 "The underlying generic attribute of the `NamedAttribute` binding.");
4372 nb::class_<PyType>(m,
"Type")
4375 .def(nb::init<PyType &>(),
"cast_from_type"_a,
4376 "Casts the passed type to the generic `Type`.")
4378 "Gets a capsule wrapping the `MlirType`.")
4380 "Creates a Type from a capsule wrapping `MlirType`.")
4383 [](std::string typeSpec,
4392 "asm"_a,
"context"_a = nb::none(),
4394 Parses the assembly form of a type.
4396 Returns a Type object or raises an `MLIRError` if the type cannot be parsed.
4398 See also: https://mlir.llvm.org/docs/LangRef/#type-system)")
4401 [](
PyType &self) -> nb::typed<nb::object, PyMlirContext> {
4402 return self.getContext().getObject();
4404 "Context that owns the `Type`.")
4406 "__eq__", [](
PyType &self,
PyType &other) {
return self == other; },
4407 "Compares two types for equality.")
4409 "__eq__", [](
PyType &self, nb::object &other) {
return false; },
4411 "Compares type with non-type object (always returns False).")
4415 return static_cast<size_t>(llvm::hash_value(self.get().ptr));
4417 "Returns the hash value of the `Type`.")
4426 return printAccum.
join();
4428 "Returns the assembly form of the `Type`.")
4437 printAccum.
parts.append(
"Type(");
4440 printAccum.
parts.append(
")");
4441 return printAccum.
join();
4443 "Returns a string representation of the `Type`.")
4446 [](
PyType &self) -> nb::typed<nb::object, PyType> {
4447 return self.maybeDownCast();
4449 "Downcasts the Type to a more specific `Type` if possible.")
4456 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(self)));
4457 throw nb::value_error(
4458 (origRepr + llvm::Twine(
" has no typeid.")).str().c_str());
4460 "Returns the `TypeID` of the `Type`, or raises `ValueError` if "
4467 nb::class_<PyTypeID>(m,
"TypeID")
4469 "Gets a capsule wrapping the `MlirTypeID`.")
4471 "Creates a `TypeID` from a capsule wrapping `MlirTypeID`.")
4478 "Compares two `TypeID`s for equality.")
4481 [](
PyTypeID &self,
const nb::object &other) {
return false; },
4482 "Compares TypeID with non-TypeID object (always returns False).")
4491 "Returns the hash value of the `TypeID`.");
4496 m.attr(
"_T") = nb::type_var(
"_T",
"bound"_a = m.attr(
"Type"));
4498 nb::class_<PyValue>(m,
"Value", nb::is_generic(),
4499 nb::sig(
"class Value(Generic[_T])"))
4500 .def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(),
"value"_a,
4501 "Creates a Value reference from another `Value`.")
4503 "Gets a capsule wrapping the `MlirValue`.")
4505 "Creates a `Value` from a capsule wrapping `MlirValue`.")
4508 [](
PyValue &self) -> nb::typed<nb::object, PyMlirContext> {
4509 return self.getParentOperation()->getContext().getObject();
4511 "Context in which the value lives.")
4517 [](
PyValue &self) -> nb::typed<nb::object, PyOpView> {
4518 MlirValue v = self.get();
4522 "expected the owner of the value in Python to match "
4525 return self.getParentOperation()->createOpView();
4530 return nb::cast(
PyBlock(self.getParentOperation(), block));
4533 assert(
false &&
"Value must be a block argument or an op result");
4536 "Returns the owner of the value (`Operation` for results, `Block` "
4544 "Returns an iterator over uses of this value.")
4548 return self.get().ptr == other.
get().ptr;
4550 "Compares two values for pointer equality.")
4552 "__eq__", [](
PyValue &self, nb::object other) {
return false; },
4553 "Compares value with non-value object (always returns False).")
4557 return static_cast<size_t>(llvm::hash_value(self.get().ptr));
4559 "Returns the hash value of the value.")
4564 printAccum.
parts.append(
"Value(");
4567 printAccum.
parts.append(
")");
4568 return printAccum.
join();
4571 Returns the string form of the value.
4573 If the value is a block argument, this is the assembly form of its type and the
4574 position in the argument list. If the value is an operation result, this is
4575 equivalent to printing the operation that produced it.
4579 [](
PyValue &self,
bool useLocalScope,
bool useNameLocAsPrefix) {
4584 if (useNameLocAsPrefix)
4586 MlirAsmState valueState =
4593 return printAccum.
join();
4595 "use_local_scope"_a =
false,
"use_name_loc_as_prefix"_a =
false,
4597 Returns the string form of value as an operand.
4600 use_local_scope: Whether to use local scope for naming.
4601 use_name_loc_as_prefix: Whether to use the location attribute (NameLoc) as prefix.
4604 The value's name as it appears in IR (e.g., `%0`, `%arg0`).)")
4609 MlirAsmState valueState = state.
get();
4613 return printAccum.
join();
4616 "Returns the string form of value as an operand (i.e., the ValueID).")
4619 [](
PyValue &self) -> nb::typed<nb::object, PyType> {
4620 return PyType(self.getParentOperation()->getContext(),
4624 "Returns the type of the value.")
4630 "type"_a,
"Sets the type of the value.",
4631 nb::sig(
"def set_type(self, type: _T)"))
4633 "replace_all_uses_with",
4637 "Replace all uses of value with the new value, updating anything in "
4638 "the IR that uses `self` to use the other value instead.")
4640 "replace_all_uses_except",
4642 MlirOperation exceptedUser = exception.
get();
4647 "replace_all_uses_except",
4651 for (nb::handle exception : exceptions) {
4652 exceptionOps.push_back(nb::cast<PyOperation &>(exception).
get());
4656 self, with,
static_cast<intptr_t>(exceptionOps.size()),
4657 exceptionOps.data());
4661 "replace_all_uses_except",
4663 MlirOperation exceptedUser = exception.
get();
4668 "replace_all_uses_except",
4670 std::vector<PyOperation> &exceptions) {
4674 exceptionOps.push_back(exception);
4676 self, with,
static_cast<intptr_t>(exceptionOps.size()),
4677 exceptionOps.data());
4682 [](
PyValue &self) -> nb::typed<nb::object, PyValue> {
4683 return self.maybeDownCast();
4685 "Downcasts the `Value` to a more specific kind if possible.")
4688 [](MlirValue self) {
4693 "Returns the source location of the value.");
4699 nb::class_<PyAsmState>(m,
"AsmState")
4700 .def(nb::init<PyValue &, bool>(),
"value"_a,
"use_local_scope"_a =
false,
4702 Creates an `AsmState` for consistent SSA value naming.
4705 value: The value to create state for.
4706 use_local_scope: Whether to use local scope for naming.)")
4707 .def(nb::init<PyOperationBase &, bool>(), "op"_a,
4708 "use_local_scope"_a =
false,
4710 Creates an AsmState for consistent SSA value naming.
4713 op: The operation to create state for.
4714 use_local_scope: Whether to use local scope for naming.)");
4719 nb::class_<PySymbolTable>(m,
"SymbolTable")
4720 .def(nb::init<PyOperationBase &>(),
4722 Creates a symbol table for an operation.
4725 operation: The `Operation` that defines a symbol table (e.g., a `ModuleOp`).
4728 TypeError: If the operation is not a symbol table.)")
4732 const std::string &name) -> nb::typed<nb::object, PyOpView> {
4733 return self.dunderGetItem(name);
4736 Looks up a symbol by name in the symbol table.
4739 name: The name of the symbol to look up.
4742 The operation defining the symbol.
4745 KeyError: If the symbol is not found.)")
4748 Inserts a symbol operation into the symbol table.
4751 operation: An operation with a symbol name to insert.
4754 The symbol name attribute of the inserted operation.
4757 ValueError: If the operation does not have a symbol name.)")
4760 Erases a symbol operation from the symbol table.
4763 operation: The symbol operation to erase.
4766 The operation is also erased from the IR and invalidated.)")
4768 "Deletes a symbol by name from the symbol table.")
4775 "Checks if a symbol with the given name exists in the table.")
4778 "name"_a,
"Sets the symbol name for a symbol operation.")
4780 "Gets the symbol name from a symbol operation.")
4782 "Gets the visibility attribute of a symbol operation.")
4785 "Sets the visibility attribute of a symbol operation.")
4786 .def_static(
"replace_all_symbol_uses",
4788 "new_symbol"_a,
"from_op"_a,
4789 "Replaces all uses of a symbol with a new symbol name within "
4790 "the given operation.")
4792 "from_op"_a,
"all_sym_uses_visible"_a,
"callback"_a,
4793 "Walks symbol tables starting from an operation with a "
4794 "callback function.");
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 nb::object classmethod(Func f, Args... args)
Helper for creating an @classmethod.
#define _Py_CAST(type, expr)
static nb::object createCustomDialectWrapper(const std::string &dialectNamespace, nb::object dialectDescriptor)
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)
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)
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)
MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos)
MlirOperation mlirOperationCreate(MlirOperationState *state)
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 std::string diag(const llvm::Value &value)
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)
nanobind::class_< PyRegionList > ClassTy
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()
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 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::str getMessage()
PyDiagnosticSeverity getSeverity()
nanobind::tuple 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)
size_t locTracebackFramesLimit()
void setLocTracebackFramesLimit(size_t value)
void registerTracebackFileExclusion(const std::string &file)
void registerTracebackFileInclusion(const std::string &file)
static constexpr size_t kMaxFrames
void setLocTracebacksEnabled(bool value)
bool locTracebacksEnabled()
Globals that are always accessible once the extension has been initialized.
std::optional< nanobind::callable > lookupValueCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom value caster for MlirTypeID mlirTypeID.
bool loadDialectModule(llvm::StringRef dialectNamespace)
Loads a python module corresponding to the given dialect namespace.
void addDialectSearchPrefix(std::string value)
static PyGlobals & get()
Most code should get the globals via this static accessor.
void registerTypeCaster(MlirTypeID mlirTypeID, nanobind::callable typeCaster, bool replace=false)
Adds a user-friendly type caster.
void registerAttributeBuilder(const std::string &attributeKind, nanobind::callable pyFunc, bool replace=false)
Adds a user-friendly Attribute builder.
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::object > lookupOperationClass(llvm::StringRef operationName)
Looks up a registered operation class (deriving from OpView) by operation name.
std::optional< nanobind::callable > lookupAttributeBuilder(const std::string &attributeKind)
Returns the custom Attribute builder for Attribute kind.
void registerDialectImpl(const std::string &dialectNamespace, nanobind::object pyClass)
Adds a concrete implementation dialect class.
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.
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.
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.
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.
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.
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()
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)
static void forEachAttr(MlirOperation op, llvm::function_ref< void(MlirStringRef, MlirAttribute)> fn)
PyNamedAttribute dunderGetItemIndexed(intptr_t index)
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
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::object buildGeneric(std::string_view name, std::tuple< int, bool > opRegionSpec, nanobind::object operandSegmentSpecObj, nanobind::object resultSegmentSpecObj, std::optional< nanobind::list > resultTypeList, nanobind::list 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
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.
static nanobind::object create(std::string_view name, std::optional< std::vector< PyType * > > results, llvm::ArrayRef< MlirValue > operands, 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.
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())
PyRegionIterator & dunderIter()
static void bind(nanobind::module_ &m)
Regions of an op are fixed length and indexed numerically so are represented with a sequence-like con...
PyRegionIterator dunderIter()
PyRegionList(PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
static void bindDerived(ClassTy &c)
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()
Wrapper around the generic MlirValue.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirValue.
PyOperationRef & getParentOperation()
PyValue(PyOperationRef parentOperation, MlirValue value)
nanobind::typed< nanobind::object, 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.
MlirDiagnostic wrap(mlir::Diagnostic &diagnostic)
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 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.
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 bool mlirLocationIsAFileLineColRange(MlirLocation location)
Checks whether the given location is an FileLineColRange.
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 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 bool mlirLocationIsACallSite(MlirLocation location)
Checks whether the given location is an CallSite.
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 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 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.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetVisibilityAttributeName(void)
Returns the name of the attribute used to store symbol visibility.
static bool mlirDialectIsNull(MlirDialect dialect)
Checks if the dialect is null.
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 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.
MLIR_PYTHON_API_EXPORTED MlirValue getUniqueResult(MlirOperation operation)
MLIR_PYTHON_API_EXPORTED void populateRoot(nanobind::module_ &m)
static void maybeInsertOperation(PyOperationRef &op, const nb::object &maybeIp)
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
static MlirValue getOpResultOrValue(nb::handle operand)
PyObjectRef< PyOperation > PyOperationRef
MlirStringRef toMlirStringRef(const std::string &s)
PyObjectRef< PyModule > PyModuleRef
MlirBlock MLIR_PYTHON_API_EXPORTED createBlock(const nanobind::sequence &pyArgTypes, const std::optional< nanobind::sequence > &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)
static void populateResultTypes(StringRef name, nb::list resultTypeList, const nb::object &resultSegmentSpecObj, std::vector< int32_t > &resultSegmentLengths, std::vector< PyType * > &resultTypes)
Include the generated interface declarations.
const FrozenRewritePatternSet GreedyRewriteConfig config
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
An opaque reference to a diagnostic, always owned by the diagnostics engine (context).
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.
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)
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)