[Mlir-commits] [mlir] [MLIR][Python] Add python-side adaptor class codegen in mlir-tblgen (PR #176640)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Jan 19 07:54:25 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-core
Author: Twice (PragmaTwice)
<details>
<summary>Changes</summary>
In dialect conversion, the operation adaptor is a fairly important helper type. Before we introduce the dialect conversion API into the MLIR Python bindings, we first need to generate the corresponding adaptor class for each op type (i.e., opview subclasses). This PR is an attempt to add support for generating adaptor classes in mlir-tblgen’s Python op class generator.
---
Patch is 25.85 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/176640.diff
3 Files Affected:
- (modified) mlir/python/mlir/dialects/_ods_common.py (+6)
- (modified) mlir/test/mlir-tblgen/op-python-bindings.td (+74-39)
- (modified) mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp (+111-24)
``````````diff
diff --git a/mlir/python/mlir/dialects/_ods_common.py b/mlir/python/mlir/dialects/_ods_common.py
index 10abd06ff266e..e8b7aa81ef920 100644
--- a/mlir/python/mlir/dialects/_ods_common.py
+++ b/mlir/python/mlir/dialects/_ods_common.py
@@ -305,3 +305,9 @@ def _get_int_array_array_attr(
# Turn the outer list into an ArrayAttr.
return ArrayAttr.get(values)
+
+
+class OpAdaptor:
+ def __init__(self, operands, attributes) -> None:
+ self.operands = operands
+ self.attributes = attributes
diff --git a/mlir/test/mlir-tblgen/op-python-bindings.td b/mlir/test/mlir-tblgen/op-python-bindings.td
index 929851724ba71..2d44824c9d8fd 100644
--- a/mlir/test/mlir-tblgen/op-python-bindings.td
+++ b/mlir/test/mlir-tblgen/op-python-bindings.td
@@ -16,8 +16,8 @@ class TestOp<string mnemonic, list<Trait> traits = []> :
Op<Test_Dialect, mnemonic, traits>;
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class AttrSizedOperandsOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.attr_sized_operands"
+// CHECK-LABEL: class AttrSizedOperandsOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.attr_sized_operands"
// CHECK: _ODS_OPERAND_SEGMENTS = [-1,1,0,]
def AttrSizedOperandsOp : TestOp<"attr_sized_operands",
[AttrSizedOperandSegments]> {
@@ -64,8 +64,8 @@ def AttrSizedOperandsOp : TestOp<"attr_sized_operands",
// CHECK: return AttrSizedOperandsOp(variadic1=variadic1, non_variadic=non_variadic, variadic2=variadic2, loc=loc, ip=ip)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class AttrSizedResultsOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.attr_sized_results"
+// CHECK-LABEL: class AttrSizedResultsOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.attr_sized_results"
// CHECK: _ODS_RESULT_SEGMENTS = [0,1,-1,]
def AttrSizedResultsOp : TestOp<"attr_sized_results",
[AttrSizedResultSegments]> {
@@ -112,10 +112,26 @@ def AttrSizedResultsOp : TestOp<"attr_sized_results",
// CHECK: op = AttrSizedResultsOp(variadic1=variadic1, non_variadic=non_variadic, variadic2=variadic2, loc=loc, ip=ip); results = op.results
// CHECK: return results if len(results) > 1 else (results[0] if len(results) == 1 else op)
-
+// CHECK-LABEL: class AttributedOpAdaptor(_ods_OpAdaptor):
+// CHECK: OPERATION_NAME = "test.attributed_op"
+// CHECK: @builtins.property
+// CHECK: def i32attr(self) -> _ods_ir.IntegerAttr:
+// CHECK: return self.attributes["i32attr"]
+// CHECK: @builtins.property
+// CHECK: def optionalF32Attr(self) -> _Optional[_ods_ir.FloatAttr]:
+// CHECK: if "optionalF32Attr" not in self.attributes:
+// CHECK: return None
+// CHECK: return self.attributes["optionalF32Attr"]
+// CHECK: @builtins.property
+// CHECK: def unitAttr(self) -> bool:
+// CHECK: return "unitAttr" in self.attributes
+// CHECK: @builtins.property
+// CHECK: def in_(self) -> _ods_ir.IntegerAttr:
+// CHECK: return self.attributes["in"]
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class AttributedOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.attributed_op"
+// CHECK-LABEL: class AttributedOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.attributed_op"
+// CHECK: Adaptor = AttributedOpAdaptor
// CHECK-NOT: _ODS_OPERAND_SEGMENTS
// CHECK-NOT: _ODS_RESULT_SEGMENTS
def AttributedOp : TestOp<"attributed_op"> {
@@ -164,8 +180,8 @@ def AttributedOp : TestOp<"attributed_op"> {
// CHECK: return AttributedOp(i32attr=i32attr, in_=in_, optionalF32Attr=optional_f32_attr, unitAttr=unit_attr, loc=loc, ip=ip)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class AttributedOpWithOperands(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.attributed_op_with_operands"
+// CHECK-LABEL: class AttributedOpWithOperands(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.attributed_op_with_operands"
// CHECK-NOT: _ODS_OPERAND_SEGMENTS
// CHECK-NOT: _ODS_RESULT_SEGMENTS
def AttributedOpWithOperands : TestOp<"attributed_op_with_operands"> {
@@ -201,8 +217,8 @@ def AttributedOpWithOperands : TestOp<"attributed_op_with_operands"> {
// CHECK: return AttributedOpWithOperands(_gen_arg_0=_gen_arg_0, _gen_arg_2=_gen_arg_2, in_=in_, is_=is_, loc=loc, ip=ip)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class DefaultValuedAttrsOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.default_valued_attrs"
+// CHECK-LABEL: class DefaultValuedAttrsOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.default_valued_attrs"
def DefaultValuedAttrsOp : TestOp<"default_valued_attrs"> {
// CHECK: def __init__(self, *, arr=None, unsupported=None, loc=None, ip=None):
// CHECK: operands = []
@@ -283,8 +299,8 @@ def DescriptionOp : TestOp<"description"> {
}
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class EmptyOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.empty"
+// CHECK-LABEL: class EmptyOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.empty"
def EmptyOp : TestOp<"empty">;
// CHECK: def __init__(self, *, loc=None, ip=None):
// CHECK: operands = []
@@ -329,8 +345,8 @@ def InferResultTypesOp : TestOp<"infer_result_types_op", [InferTypeOpInterface]>
// CHECK: return InferResultTypesOp(results=results, loc=loc, ip=ip).results
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class MissingNamesOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.missing_names"
+// CHECK-LABEL: class MissingNamesOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.missing_names"
def MissingNamesOp : TestOp<"missing_names"> {
// CHECK: def __init__(self, i32, _gen_res_1, i64, _gen_arg_0, f32, _gen_arg_2, *, loc=None, ip=None):
// CHECK: operands = []
@@ -367,9 +383,18 @@ def MissingNamesOp : TestOp<"missing_names"> {
// CHECK: def missing_names(i32, _gen_res_1, i64, _gen_arg_0, f32, _gen_arg_2, *, loc=None, ip=None) -> _ods_ir.OpResultList:
// CHECK: return MissingNamesOp(i32=i32, _gen_res_1=_gen_res_1, i64=i64, _gen_arg_0=_gen_arg_0, f32=f32, _gen_arg_2=_gen_arg_2, loc=loc, ip=ip).results
+// CHECK-LABEL: class OneOptionalOperandOpAdaptor(_ods_OpAdaptor):
+// CHECK: OPERATION_NAME = "test.one_optional_operand"
+// CHECK: @builtins.property
+// CHECK: def non_optional(self) -> _ods_ir.Value:
+// CHECK: return self.operands[0]
+// CHECK: @builtins.property
+// CHECK: def optional(self) -> _Optional[_ods_ir.Value]:
+// CHECK: return None if len(self.operands) < 2 else self.operands[1]
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class OneOptionalOperandOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.one_optional_operand"
+// CHECK-LABEL: class OneOptionalOperandOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.one_optional_operand"
+// CHECK: Adaptor = OneOptionalOperandOpAdaptor
// CHECK-NOT: _ODS_OPERAND_SEGMENTS
// CHECK-NOT: _ODS_RESULT_SEGMENTS
def OneOptionalOperandOp : TestOp<"one_optional_operand"> {
@@ -399,9 +424,19 @@ def OneOptionalOperandOp : TestOp<"one_optional_operand"> {
// CHECK: def one_optional_operand(non_optional, *, optional=None, loc=None, ip=None) -> OneOptionalOperandOp:
// CHECK: return OneOptionalOperandOp(non_optional=non_optional, optional=optional, loc=loc, ip=ip)
+// CHECK-LABEL: class OneVariadicOperandOpAdaptor(_ods_OpAdaptor):
+// CHECK: OPERATION_NAME = "test.one_variadic_operand"
+// CHECK: @builtins.property
+// CHECK: def non_variadic(self) -> _ods_ir.Value:
+// CHECK: return self.operands[0]
+// CHECK: @builtins.property
+// CHECK: def variadic(self) -> _ods_ir.OpOperandList:
+// CHECK: _ods_variadic_group_length = len(self.operands) - 2 + 1
+// CHECK: return self.operands[1:1 + _ods_variadic_group_length]
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class OneVariadicOperandOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.one_variadic_operand"
+// CHECK-LABEL: class OneVariadicOperandOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.one_variadic_operand"
+// CHECK: Adaptor = OneVariadicOperandOpAdaptor
// CHECK-NOT: _ODS_OPERAND_SEGMENTS
// CHECK-NOT: _ODS_RESULT_SEGMENTS
def OneVariadicOperandOp : TestOp<"one_variadic_operand"> {
@@ -433,8 +468,8 @@ def OneVariadicOperandOp : TestOp<"one_variadic_operand"> {
// CHECK: return OneVariadicOperandOp(non_variadic=non_variadic, variadic=variadic, loc=loc, ip=ip)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class OneVariadicResultOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.one_variadic_result"
+// CHECK-LABEL: class OneVariadicResultOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.one_variadic_result"
// CHECK-NOT: _ODS_OPERAND_SEGMENTS
// CHECK-NOT: _ODS_RESULT_SEGMENTS
def OneVariadicResultOp : TestOp<"one_variadic_result"> {
@@ -468,8 +503,8 @@ def OneVariadicResultOp : TestOp<"one_variadic_result"> {
// CHECK: return results if len(results) > 1 else (results[0] if len(results) == 1 else op)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class PythonKeywordOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.python_keyword"
+// CHECK-LABEL: class PythonKeywordOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.python_keyword"
def PythonKeywordOp : TestOp<"python_keyword"> {
// CHECK: def __init__(self, in_, *, loc=None, ip=None):
// CHECK: operands = []
@@ -518,8 +553,8 @@ def SameResultsVariadicOp : TestOp<"same_results_variadic", [SameOperandsAndResu
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class SameVariadicOperandSizeOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.same_variadic_operand"
+// CHECK-LABEL: class SameVariadicOperandSizeOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.same_variadic_operand"
def SameVariadicOperandSizeOp : TestOp<"same_variadic_operand",
[SameVariadicOperandSize]> {
// CHECK: @builtins.property
@@ -544,8 +579,8 @@ def SameVariadicOperandSizeOp : TestOp<"same_variadic_operand",
// CHECK: return SameVariadicOperandSizeOp(variadic1=variadic1, non_variadic=non_variadic, variadic2=variadic2, loc=loc, ip=ip)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class SameVariadicResultSizeOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.same_variadic_result"
+// CHECK-LABEL: class SameVariadicResultSizeOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.same_variadic_result"
def SameVariadicResultSizeOp : TestOp<"same_variadic_result",
[SameVariadicResultSize]> {
// CHECK: @builtins.property
@@ -571,8 +606,8 @@ def SameVariadicResultSizeOp : TestOp<"same_variadic_result",
// CHECK: return results if len(results) > 1 else (results[0] if len(results) == 1 else op)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class SimpleOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.simple"
+// CHECK-LABEL: class SimpleOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.simple"
def SimpleOp : TestOp<"simple"> {
// CHECK: def __init__(self, i64, f64, i32, f32, *, loc=None, ip=None):
// CHECK: operands = []
@@ -611,8 +646,8 @@ def SimpleOp : TestOp<"simple"> {
// CHECK: def simple(i64, f64, i32, f32, *, loc=None, ip=None) -> _ods_ir.OpResultList:
// CHECK: return SimpleOp(i64=i64, f64=f64, i32=i32, f32=f32, loc=loc, ip=ip).results
-// CHECK: class VariadicAndNormalRegionOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.variadic_and_normal_region"
+// CHECK-LABEL: class VariadicAndNormalRegionOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.variadic_and_normal_region"
def VariadicAndNormalRegionOp : TestOp<"variadic_and_normal_region"> {
// CHECK: def __init__(self, num_variadic, *, loc=None, ip=None):
// CHECK: operands = []
@@ -639,8 +674,8 @@ def VariadicAndNormalRegionOp : TestOp<"variadic_and_normal_region"> {
// CHECK: def variadic_and_normal_region(num_variadic, *, loc=None, ip=None) -> VariadicAndNormalRegionOp:
// CHECK: return VariadicAndNormalRegionOp(num_variadic=num_variadic, loc=loc, ip=ip)
-// CHECK: class VariadicRegionOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.variadic_region"
+// CHECK-LABEL: class VariadicRegionOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.variadic_region"
def VariadicRegionOp : TestOp<"variadic_region"> {
// CHECK: def __init__(self, num_variadic, *, loc=None, ip=None):
// CHECK: operands = []
@@ -664,8 +699,8 @@ def VariadicRegionOp : TestOp<"variadic_region"> {
// CHECK: return VariadicRegionOp(num_variadic=num_variadic, loc=loc, ip=ip)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class WithSpecialCharactersOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.123with--special.characters"
+// CHECK-LABEL: class WithSpecialCharactersOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.123with--special.characters"
def WithSpecialCharactersOp : TestOp<"123with--special.characters"> {
}
@@ -673,8 +708,8 @@ def WithSpecialCharactersOp : TestOp<"123with--special.characters"> {
// CHECK: return WithSpecialCharactersOp(loc=loc, ip=ip)
// CHECK: @_ods_cext.register_operation(_Dialect)
-// CHECK: class WithSuccessorsOp(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.with_successors"
+// CHECK-LABEL: class WithSuccessorsOp(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.with_successors"
def WithSuccessorsOp : TestOp<"with_successors"> {
// CHECK-NOT: _ods_successors = None
// CHECK: _ods_successors = []
@@ -687,8 +722,8 @@ def WithSuccessorsOp : TestOp<"with_successors"> {
// CHECK: def with_successors(successor, successors, *, loc=None, ip=None) -> WithSuccessorsOp:
// CHECK: return WithSuccessorsOp(successor=successor, successors=successors, loc=loc, ip=ip)
-// CHECK: class snake_case(_ods_ir.OpView):
-// CHECK-LABEL: OPERATION_NAME = "test.snake_case"
+// CHECK-LABEL: class snake_case(_ods_ir.OpView):
+// CHECK: OPERATION_NAME = "test.snake_case"
def already_snake_case : TestOp<"snake_case"> {}
// CHECK: def snake_case_(*, loc=None, ip=None) -> snake_case:
// CHECK: return snake_case(loc=loc, ip=ip)
diff --git a/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp b/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp
index 6545559ff1b10..74f6d7edea4c2 100644
--- a/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp
@@ -40,6 +40,7 @@ from ._ods_common import (
get_default_loc_context as _ods_get_default_loc_context,
get_op_results_or_values as _get_op_results_or_values,
segmented_accessor as _ods_segmented_accessor,
+ OpAdaptor as _ods_OpAdaptor,
)
_ods_ir = _ods_cext.ir
_ods_cext.globals.register_traceback_file_exclusion(__file__)
@@ -69,6 +70,15 @@ constexpr const char *opClassTemplate = R"Py(
@_ods_cext.register_operation(_Dialect)
class {0}(_ods_ir.OpView):{2}
OPERATION_NAME = "{1}"
+ Adaptor = {0}Adaptor
+)Py";
+
+/// Template for operation class:
+/// {0} is the Python class name;
+/// {1} is the operation name。
+constexpr const char *opAdaptorClassTemplate = R"Py(
+class {0}Adaptor(_ods_OpAdaptor):
+ OPERATION_NAME = "{1}"
)Py";
/// Template for class level declarations of operand and result
@@ -99,7 +109,7 @@ constexpr const char *opClassRegionSpecTemplate = R"Py(
constexpr const char *opSingleTemplate = R"Py(
@builtins.property
def {0}(self) -> {3}:
- return self.operation.{1}s[{2}]
+ return self.{1}s[{2}]
)Py";
/// Template for single-element accessor after a variable-length group:
@@ -113,8 +123,8 @@ constexpr const char *opSingleTemplate = R"Py(
constexpr const char *opSingleAfterVariableTemplate = R"Py(
@builtins.property
def {0}(self) -> {4}:
- _ods_variadic_group_length = len(self.operation.{1}s) - {2} + 1
- return self.operation.{1}s[{3} + _ods_variadic_group_length - 1]
+ _ods_variadic_group_length = len(self.{1}s) - {2} + 1
+ return self.{1}s[{3} + _ods_variadic_group_length - 1]
)Py";
/// Template for an optional element accessor:
@@ -129,7 +139,7 @@ constexpr const char *opSingleAfterVariableTemplate = R"Py(
constexpr const char *opOneOptionalTemplate = R"Py(
@builtins.property
def {0}(self) -> _Optional[{4}]:
- return None if len(self.operation.{1}s) < {2} else self.operation.{1}s[{3}]
+ return None if len(self.{1}s) < {2} else self.{1}s[{3}]
)Py";
/// Template for the variadic group accessor in the single variadic group case:
@@ -141,8 +151,8 @@ constexpr const char *opOneOptionalTemplate = R"Py(
constexpr const char *opOneVariadicTemplate = R"Py(
@builtins.property
def {0}(self) -> {4}:
- _ods_variadic_group_length = len(self.operation.{1}s) - {2} + 1
- return self.operation.{1}s[{3}:{3} + _ods_variadic_group_length]
+ _ods_variadic_group_length = len(self.{1}s) - {2} + 1
+ return self.{1}s[{3}:{3} + _ods_variadic_group_length]
)Py";
/// First part of the template for equally-sized variadic group accessor:
@@ -156,20 +166,20 @@ constexpr const char *opOneVariadicTemplate = R"Py(
constexpr const char *opVariadicEqualPrefixTemplate = R"Py(
@builtins.property
def {0}(self) -> {6}:
- start, elements_per_group = _ods_equally_sized_accessor(self.operation.{1}s, {2}, {3}, {4}, {5}))Py";
+ start, elements_per_group = _ods_equally_sized_accessor(self.{1}s, {2}, {3}, {4}, {5}))Py";
/// Second part of the template for equally-sized case, accessing a single
/// element:
/// {0} is either 'operand' or 'result'.
constexpr const char *opVariadicEqualSimpleTemplate = R"Py(
- return self.operation.{0}s[start]
+ return self.{0}s[start]
)Py";
/// Second part of the template for equally-sized case, accessing a variadic
/// group:
/// {0} is either 'operand' or 'result'.
constexpr const char *opVariadicEqualVariadicTemplate = R"Py(
- return self.operation.{0}s[start:start + elements_per_group]
+ return self.{0}s[start:start + elements_per_group]
)Py";
/// Template for an attribute-sized group accessor:
@@ -177,14 +187,16 @@ constexpr const char *opVariadicEqualVariadicTemplate = R"Py(
/// {1} is either 'operand' or 'result';
/// {2} is the position of the group in the group list;
/// {3} is a return suffix (expected [0] for single-element, empty for
-/// variadic, and opVariadicSegmentOptionalTrailingTemplate for optional).
-/// {4} is the type hint.
+/// variadic, and opVariadicSegmentOptionalTrailingTemplate for optional);
+/// {4} is the type hint;
+/// {5} is the instance variable name in python;
+/// {6} is the instance variable name for attributes in python.
constexpr const char *opVariadicSegmentTemplate = R"Py(
@builtins.property
def {0}(self) -> {4}:
{1}_range = _ods_segmented_accessor(
- self.operation.{1}s,
- self.operation.attributes["{1}SegmentSizes"], {2})
+ self.{5}s,
+ self.{6}["{1}SegmentSizes"], {2})
return {1}_range{3}
)Py";
@@ -216,6 +228,28 @@ constexpr const char *optionalAttributeGetterTemplate = R"Py(
return self.operation.attributes["{1}"]
)Py";
+/// Template for an operation attribute getter for adaptors:
+/// {0} is the name of the attribute sanitized for Python;
+/// {1} is the original name of the attribute.
+/// {2} is the type hint.
+constexpr const char *adaptorAttributeGetterTemplate = R"Py(
+ @builtins.property
+ def {0}(self) -> {2}:
+ return self.attributes["{1}"]
+)Py";
+
+/// Template for an optional operation attribute getter for adaptors:
+/// {0} is the name of the attribute sanitized for Python;
+/// {1} is the original name of the attribute.
+/// {2} is the type hint.
+constexpr const char *adaptorOptionalAttributeGetterTemplate = R"Py(
+ @builtins.property
+ def {0}(self) -> _Optional[{2}]:
+ if "{1}" not in self.attributes:
+ return None
+ return self.attributes["{1}"]
+)Py";
+
/// Template for a getter of a unit operation attribute, returns True of the
/// unit attribute is present, False otherwise (unit attributes have meaning
/// by mere presence):
@@ -227,6 +261,17 @@ constexpr const char *unitAttributeGetterTemplate = R"Py(
return "{1}" in self.operation.attributes
)Py";
+/// Template for a getter of a unit operation attribute for adaptors, returns
+/// True of the unit attribute is present, False ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/176640
More information about the Mlir-commits
mailing list