28 R
"(Given the arguments required to build an operation, attempts to infer
29its return types. Raises ValueError on failure.)";
32 R
"(Given the arguments required to build an operation, attempts to infer
33its return shaped type components. Raises ValueError on failure.)";
37MlirAttribute unwrapOptionalAttribute(
const nb::object &attribute) {
38 if (attribute.is_none())
42 if (!nb::try_cast<PyAttribute *>(attribute, pyAttribute) || !pyAttribute)
43 throw nb::type_error(
"parameters must be an Attribute or None");
44 return pyAttribute->
get();
50 const nb::object ¶meters,
int stage,
51 bool effectOnFullRegion,
53 MlirMemoryEffectInstancesList list = effects.
get();
54 MlirAttribute unwrappedParameters = unwrapOptionalAttribute(parameters);
56 MlirMemoryEffectInstance rawInstance{
nullptr};
60 effectOnFullRegion, resource.
get());
65 if (nb::try_cast<PyOpOperand *>(
target, opOperand) && opOperand) {
67 effect.
get(), *opOperand, unwrappedParameters, stage,
68 effectOnFullRegion, resource.
get());
69 }
else if (nb::try_cast<PyValue *>(
target, value) && value) {
70 MlirValue mlirValue = value->
get();
73 effect.
get(), mlirValue, unwrappedParameters, stage,
74 effectOnFullRegion, resource.
get());
77 effect.
get(), mlirValue, unwrappedParameters, stage,
78 effectOnFullRegion, resource.
get());
81 "target Value must be an OpResult or BlockArgument");
83 }
else if (nb::try_cast<PyAttribute *>(
target, attribute) && attribute) {
84 MlirAttribute symbol = attribute->
get();
86 throw nb::type_error(
"target Attribute must be a SymbolRefAttr");
88 effect.
get(), symbol, unwrappedParameters, stage, effectOnFullRegion,
92 "target must be an OpOperand, OpResult, BlockArgument, "
93 "SymbolRefAttr, or None");
103std::vector<MlirValue> wrapOperands(std::optional<nb::sequence> operandList) {
104 std::vector<MlirValue> mlirOperands;
106 if (!operandList || nb::len(*operandList) == 0) {
111 mlirOperands.reserve(nb::len(*operandList));
112 for (
size_t i = 0, e = nb::len(*operandList); i < e; ++i) {
113 nb::handle operand = (*operandList)[i];
115 if (operand.is_none())
120 val = nb::cast<PyValue *>(operand);
122 throw nb::cast_error();
123 mlirOperands.push_back(val->
get());
125 }
catch (nb::cast_error &err) {
131 auto vals = nb::cast<nb::sequence>(operand);
132 for (nb::handle v : vals) {
134 val = nb::cast<PyValue *>(v);
136 throw nb::cast_error();
137 mlirOperands.push_back(val->
get());
138 }
catch (nb::cast_error &err) {
139 throw nb::value_error(
141 " must be a Value or Sequence of Values (",
147 }
catch (nb::cast_error &err) {
148 throw nb::value_error(
150 " must be a Value or Sequence of Values (",
155 throw nb::cast_error();
163std::vector<MlirRegion>
164wrapRegions(std::optional<std::vector<PyRegion>> regions) {
165 std::vector<MlirRegion> mlirRegions;
168 mlirRegions.reserve(regions->size());
170 mlirRegions.push_back(region);
186 constexpr static const char *
pyClassName =
"InferTypeOpInterface";
201 data->
inferredTypes.reserve(data->inferredTypes.size() + nTypes);
202 for (
intptr_t i = 0; i < nTypes; ++i) {
203 data->inferredTypes.emplace_back(data->pyMlirContext.getRef(), types[i]);
211 std::optional<PyAttribute> attributes,
void *properties,
212 std::optional<std::vector<PyRegion>> regions,
215 std::vector<MlirValue> mlirOperands = wrapOperands(std::move(operandList));
216 std::vector<MlirRegion> mlirRegions = wrapRegions(std::move(regions));
218 std::vector<PyType> inferredTypes;
223 MlirAttribute attributeDict =
227 opNameRef, pyContext.
get(), location.
resolve(), mlirOperands.size(),
228 mlirOperands.data(), attributeDict, properties, mlirRegions.size(),
232 throw nb::value_error(
"Failed to infer result types");
235 return inferredTypes;
240 nb::arg(
"operands") = nb::none(),
241 nb::arg(
"attributes") = nb::none(),
242 nb::arg(
"properties") = nb::none(), nb::arg(
"regions") = nb::none(),
243 nb::arg(
"context") = nb::none(), nb::arg(
"loc") = nb::none(),
253 : shape(std::move(shape)), elementType(elementType), ranked(
true) {}
255 MlirAttribute attribute)
256 : shape(std::move(shape)), elementType(elementType), attribute(attribute),
260 : shape(other.shape), elementType(other.elementType),
261 attribute(other.attribute), ranked(other.ranked) {}
263 static void bind(nb::module_ &m) {
264 nb::class_<PyShapedTypeComponents>(m,
"ShapedTypeComponents")
268 nb::sig(
"def element_type(self) -> Type"),
269 "Returns the element type of the shaped type components.")
275 nb::arg(
"element_type"),
276 "Create an shaped type components object with only the element "
280 [](nb::typed<nb::list, nb::int_> shape,
PyType &elementType) {
283 nb::arg(
"shape"), nb::arg(
"element_type"),
284 "Create a ranked shaped type components object.")
287 [](nb::typed<nb::list, nb::int_> shape,
PyType &elementType,
292 nb::arg(
"shape"), nb::arg(
"element_type"), nb::arg(
"attribute"),
293 "Create a ranked shaped type components object with attribute.")
297 "Returns whether the given shaped type component is ranked.")
303 return nb::int_(self.shape.size());
305 "Returns the rank of the given ranked shaped type components. If "
306 "the shaped type components does not have a rank, None is "
313 return nb::list(self.shape);
315 "Returns the shape of the ranked shaped type components as a list "
316 "of integers. Returns none if the shaped type component does not "
325 MlirType elementType;
326 MlirAttribute attribute;
338 constexpr static const char *
pyClassName =
"InferShapedTypeOpInterface";
351 MlirAttribute attribute,
void *userData) {
354 data->inferredShapedTypeComponents.emplace_back(elementType);
357 for (
intptr_t i = 0; i < rank; ++i) {
358 shapeList.append(
shape[i]);
360 data->inferredShapedTypeComponents.emplace_back(shapeList, elementType,
368 std::optional<nb::sequence> operandList,
369 std::optional<PyAttribute> attributes,
void *properties,
370 std::optional<std::vector<PyRegion>> regions,
372 std::vector<MlirValue> mlirOperands = wrapOperands(std::move(operandList));
373 std::vector<MlirRegion> mlirRegions = wrapRegions(std::move(regions));
375 std::vector<PyShapedTypeComponents> inferredShapedTypeComponents;
380 MlirAttribute attributeDict =
384 opNameRef, pyContext.
get(), location.
resolve(), mlirOperands.size(),
385 mlirOperands.data(), attributeDict, properties, mlirRegions.size(),
389 throw nb::value_error(
"Failed to infer result shape type components");
392 return inferredShapedTypeComponents;
396 cls.def(
"inferReturnTypeComponents",
398 nb::arg(
"operands") = nb::none(),
399 nb::arg(
"attributes") = nb::none(), nb::arg(
"regions") = nb::none(),
400 nb::arg(
"properties") = nb::none(), nb::arg(
"context") = nb::none(),
412 constexpr static const char *
pyClassName =
"ConditionallySpeculatable";
423 nb::handle(
static_cast<PyObject *
>(callbacks.
userData)).inc_ref();
425 callbacks.
destruct = [](
void *userData) {
426 nb::handle(
static_cast<PyObject *
>(userData)).dec_ref();
429 nb::handle pyClass(
static_cast<PyObject *
>(userData));
431 auto pyGetSpeculatability =
432 nb::cast<nb::callable>(nb::getattr(pyClass,
"get_speculatability"));
438 return nb::cast<MlirSpeculatability>(pyGetSpeculatability(opview));
448 "getSpeculatability",
451 throw nb::type_error(
452 "Cannot query speculatability on a static interface");
454 auto *pyOperation = nb::cast<PyOperation *>(operation);
458 "Returns the speculatability of the given operation.");
460 [](
const nb::object &cls,
const nb::object &opName, nb::object
target,
464 return attach(
target, nb::cast<std::string>(opName), context);
466 nb::arg(
"cls"), nb::arg(
"op_name"), nb::kw_only(),
467 nb::arg(
"target").none() = nb::none(),
468 nb::arg(
"context").none() = nb::none(),
469 "Attach the interface subclass to the given operation name.");
480 constexpr static const char *
pyClassName =
"MemoryEffectsOpInterface";
491 nb::handle(
static_cast<PyObject *
>(callbacks.
userData)).inc_ref();
493 callbacks.
destruct = [](
void *userData) {
494 nb::handle(
static_cast<PyObject *
>(userData)).dec_ref();
497 MlirMemoryEffectInstancesList effects,
499 nb::handle pyClass(
static_cast<PyObject *
>(userData));
503 nb::cast<nb::callable>(nb::getattr(pyClass,
"get_effects"));
512 pyGetEffects(opview, effectsWrapper);
522 [](
const nb::object &cls,
const nb::object &opName, nb::object
target,
526 return attach(
target, nb::cast<std::string>(opName), context);
528 nb::arg(
"cls"), nb::arg(
"op_name"), nb::kw_only(),
529 nb::arg(
"target").none() = nb::none(),
530 nb::arg(
"context").none() = nb::none(),
531 "Attach the interface subclass to the given operation name.");
536 nb::enum_<MlirSpeculatability>(m,
"Speculatability")
539 .value(
"RecursivelySpeculatable",
541 nb::class_<PyMemoryEffect>(m,
"MemoryEffect",
"A memory effect.")
542 .def_prop_ro_static(
"Allocate",
547 .def_prop_ro_static(
"Free",
551 .def_prop_ro_static(
"Read",
555 .def_prop_ro_static(
"Write", [](nb::object & ) {
559 nb::class_<PySideEffectResource>(m,
"SideEffectResource",
560 "A side effect resource.")
561 .def_prop_ro_static(
"Default", [](nb::object & ) {
565 nb::class_<PyMemoryEffectsInstanceList>(
566 m,
"MemoryEffectInstancesList",
567 "A memory effect list that is valid only during get_effects.")
568 .def(
"append", &appendMemoryEffectInstance, nb::arg(
"effect"),
569 nb::arg(
"target").none() = nb::none(), nb::kw_only(),
570 nb::arg(
"parameters").none() = nb::none(), nb::arg(
"stage") = 0,
571 nb::arg(
"effect_on_full_region") =
false,
572 nb::arg(
"resource") =
574 nb::sig(
"def append(self, effect: MemoryEffect, target: OpOperand | "
575 "OpResult | BlockArgument | SymbolRefAttr | None = None, *, "
576 "parameters: Attribute | None = None, stage: int = 0, "
577 "effect_on_full_region: bool = False, resource: "
578 "SideEffectResource = ...) -> None"),
579 "Append a memory effect instance. The target may be an OpOperand, "
580 "OpResult, BlockArgument, SymbolRefAttr, or None.");
true
Given two iterators into the same block, return "true" if a is before `b.
bool mlirValueIsABlockArgument(MlirValue value)
bool mlirValueIsAOpResult(MlirValue value)
MlirContext mlirOperationGetContext(MlirOperation op)
ReferrentTy * get() const
Used in function arguments when None should resolve to the current context manager set instance.
static PyLocation & resolve()
Used in function arguments when None should resolve to the current context manager set instance.
static PyMlirContext & resolve()
Wrapper around the generic MlirAttribute.
MlirAttribute get() const
static void bind(nanobind::module_ &m)
MlirTypeID(*)() GetTypeIDFunctionTy
const std::string & getOpName()
PyConcreteOpInterface(nanobind::object object, DefaultingPyMlirContext context)
nanobind::typed< nanobind::object, PyOperation > getOperationObject()
Returns the operation instance from which this object was constructed.
nanobind::class_< PyInferTypeOpInterface > ClassTy
bool isStatic()
Returns true if this object was constructed from a subclass of OpView rather than from an operation i...
Wrapper around the ConditionallySpeculatable interface.
static constexpr GetTypeIDFunctionTy getInterfaceID
static constexpr const char * pyClassName
static void bindDerived(ClassTy &cls)
static void attach(nb::object &target, const std::string &opName, DefaultingPyMlirContext ctx)
Attach a new ConditionallySpeculatable FallbackModel to the named operation.
Python wrapper for InferShapedTypeOpInterface.
static constexpr GetTypeIDFunctionTy getInterfaceID
static void bindDerived(ClassTy &cls)
static constexpr const char * pyClassName
static void appendResultsCallback(bool hasRank, intptr_t rank, const int64_t *shape, MlirType elementType, MlirAttribute attribute, void *userData)
Appends the shaped type components provided as unpacked shape, element type, attribute to the user-da...
std::vector< PyShapedTypeComponents > inferReturnTypeComponents(std::optional< nb::sequence > operandList, std::optional< PyAttribute > attributes, void *properties, std::optional< std::vector< PyRegion > > regions, DefaultingPyMlirContext context, DefaultingPyLocation location)
Given the arguments required to build an operation, attempts to infer the shaped type components.
Python wrapper for InferTypeOpInterface.
std::vector< PyType > inferReturnTypes(std::optional< nb::sequence > operandList, std::optional< PyAttribute > attributes, void *properties, std::optional< std::vector< PyRegion > > regions, DefaultingPyMlirContext context, DefaultingPyLocation location)
Given the arguments required to build an operation, attempts to infer its return types.
static void bindDerived(ClassTy &cls)
static constexpr const char * pyClassName
static constexpr GetTypeIDFunctionTy getInterfaceID
static void appendResultsCallback(intptr_t nTypes, MlirType *types, void *userData)
Appends the types provided as the two first arguments to the user-data structure (expects AppendResul...
A memory effect instance.
MlirMemoryEffectInstance get() const
MlirMemoryEffect get() const
A callback-scoped view of a list of memory effect instances.
MlirMemoryEffectInstancesList get() const
Wrapper around the MemoryEffectsOpInterface.
static constexpr GetTypeIDFunctionTy getInterfaceID
static void attach(nb::object &target, const std::string &opName, DefaultingPyMlirContext ctx)
Attach a new MemoryEffectsOpInterface FallbackModel to the named operation.
static void bindDerived(ClassTy &cls)
static constexpr const char * pyClassName
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
MlirContext get()
Accesses the underlying MlirContext.
nanobind::object createOpView()
Creates an OpView suitable for this operation.
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.
Wrapper around an MlirRegion.
PyShapedTypeComponents(nb::list shape, MlirType elementType)
PyShapedTypeComponents(MlirType elementType)
PyShapedTypeComponents(nb::list shape, MlirType elementType, MlirAttribute attribute)
static PyShapedTypeComponents createFromCapsule(nb::object capsule)
PyShapedTypeComponents(PyShapedTypeComponents &)=delete
PyShapedTypeComponents(PyShapedTypeComponents &&other) noexcept
static void bind(nb::module_ &m)
MlirSideEffectResource get() const
Wrapper around the generic MlirType.
MLIR_CAPI_EXPORTED MlirAttribute mlirAttributeGetNull(void)
Returns an empty attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsASymbolRef(MlirAttribute attr)
Checks whether the given attribute is a symbol reference attribute.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirInferShapedTypeOpInterfaceInferReturnTypes(MlirStringRef opName, MlirContext context, MlirLocation location, intptr_t nOperands, MlirValue *operands, MlirAttribute attributes, void *properties, intptr_t nRegions, MlirRegion *regions, MlirShapedTypeComponentsCallback callback, void *userData)
Infers the return shaped type components of the operation.
MLIR_CAPI_EXPORTED MlirSpeculatability mlirConditionallySpeculatableOpInterfaceGetSpeculatability(MlirOperation operation)
Returns the speculatability of the given operation.
MLIR_CAPI_EXPORTED MlirTypeID mlirInferTypeOpInterfaceTypeID(void)
Returns the interface TypeID of the InferTypeOpInterface.
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForOpOperand(MlirMemoryEffect effect, MlirOpOperand opOperand, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with an operation operand.
MLIR_CAPI_EXPORTED MlirTypeID mlirConditionallySpeculatableOpInterfaceTypeID(void)
Returns the interface TypeID of the ConditionallySpeculatable interface.
MLIR_CAPI_EXPORTED void mlirConditionallySpeculatableOpInterfaceAttachFallbackModel(MlirContext ctx, MlirStringRef opName, MlirConditionallySpeculatableOpInterfaceCallbacks callbacks)
Attach a new FallbackModel for the ConditionallySpeculatable interface to the named operation.
@ MlirSpeculatabilityRecursivelySpeculatable
The operation is speculatable if all nested operations are speculatable.
@ MlirSpeculatabilitySpeculatable
The operation is speculatable.
@ MlirSpeculatabilityNotSpeculatable
The operation is not speculatable.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsReadGet(void)
Returns the borrowed singleton instance of the read memory effect.
MLIR_CAPI_EXPORTED MlirSideEffectResource mlirSideEffectsDefaultResourceGet(void)
Returns the borrowed singleton instance of the default side effect resource.
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreate(MlirMemoryEffect effect, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance without an associated IR entity.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirInferTypeOpInterfaceInferReturnTypes(MlirStringRef opName, MlirContext context, MlirLocation location, intptr_t nOperands, MlirValue *operands, MlirAttribute attributes, void *properties, intptr_t nRegions, MlirRegion *regions, MlirTypesCallback callback, void *userData)
Infers the return types of the operation identified by its canonical given the arguments that will be...
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForOpResult(MlirMemoryEffect effect, MlirValue result, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with an operation result.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsFreeGet(void)
Returns the borrowed singleton instance of the free memory effect.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsWriteGet(void)
Returns the borrowed singleton instance of the write memory effect.
MLIR_CAPI_EXPORTED MlirTypeID mlirMemoryEffectsOpInterfaceTypeID(void)
Returns the interface TypeID of the MemoryEffectsOpInterface.
MLIR_CAPI_EXPORTED MlirTypeID mlirInferShapedTypeOpInterfaceTypeID(void)
Returns the interface TypeID of the InferShapedTypeOpInterface.
MLIR_CAPI_EXPORTED void mlirMemoryEffectsOpInterfaceAttachFallbackModel(MlirContext ctx, MlirStringRef opName, MlirMemoryEffectsOpInterfaceCallbacks callbacks)
Attach a new FallbackModel for the MemoryEffectsOpInterface to the named operation.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsAllocateGet(void)
Returns the borrowed singleton instance of the allocate memory effect.
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForSymbol(MlirMemoryEffect effect, MlirAttribute symbol, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with a symbol.
MLIR_CAPI_EXPORTED void mlirMemoryEffectInstancesListAppend(MlirMemoryEffectInstancesList list, MlirMemoryEffectInstance instance)
Appends a copy of instance to the given list.
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForBlockArgument(MlirMemoryEffect effect, MlirValue blockArgument, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with a block argument.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
static bool mlirLogicalResultIsFailure(MlirLogicalResult res)
Checks if the given logical result represents a failure.
void populateIRInterfaces(nb::module_ &m)
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
static constexpr const char * inferReturnTypesDoc
static constexpr const char * inferReturnTypeComponentsDoc
nanobind::object classmethod(Func f, Args... args)
Helper for creating an @classmethod.
Include the generated interface declarations.
std::string join(const Ts &...args)
Helper function to concatenate arguments into a std::string.
Callbacks for implementing ConditionallySpeculatable from external code.
void(* destruct)(void *userData)
Optional destructor for user data. Set to nullptr to disable it.
void(* construct)(void *userData)
Optional constructor for user data. Set to nullptr to disable it.
MlirSpeculatability(* getSpeculatability)(MlirOperation op, void *userData)
Returns the speculatability of the given operation.
A logical result value, essentially a boolean with named states.
Callbacks for implementing MemoryEffectsOpInterface from external code.
void(* construct)(void *userData)
Optional constructor for user data. Set to nullptr to disable it.
void(* getEffects)(MlirOperation op, MlirMemoryEffectInstancesList effects, void *userData)
Get memory effects callback.
void(* destruct)(void *userData)
Optional destructor for user data. Set to nullptr to disable it.
A pointer to a sized fragment of a string, not necessarily null-terminated.
C-style user-data structure for type appending callback.
std::vector< PyShapedTypeComponents > & inferredShapedTypeComponents
C-style user-data structure for type appending callback.
PyMlirContext & pyMlirContext
std::vector< PyType > & inferredTypes