How to construct custom attribute class in python

Hi all,

I am recently exploring MLIR python binding. I have some issues constructing a tosa.conv2d operator. My script is attached below.

I have two questions:

  1. How to construct a mlir::tosa::ConvOpQuantizationAttr for quantization_info? I did not find any constructor exposed in python.
  2. I keep getting error for pad attribute failed to satisfy constraint. The pad is in ir.DenseI64ArrayAttr and I was following the document here: Tensor Operator Set Architecture (TOSA) Dialect - MLIR which shows pad should be ::mlir::DenseI64ArrayAttr. Is there a bug here or is there some issues with my usage?

error: ‘tosa.conv2d’ op attribute ‘pad’ failed to satisfy constraint: 64-bit integer array attribute with exactly 4 elements

Thanks!

import mlir
from mlir import ir
import mlir.dialects.tosa as tosa
import mlir.dialects.func as func
from collections import OrderedDict
import numpy as np

with ir.Context() as ctx, ir.Location.unknown():
    m = ir.Module.create()
    ctx.load_all_available_dialects()
    f32Type = ir.F32Type.get()
    i64Type = ir.IntegerType.get_signless(64)

    inputs = OrderedDict()
    outputs =  OrderedDict()
    inputs['x1'] = ir.RankedTensorType.get((1, 3, 16, 16), f32Type)
    outputs['y'] = ir.RankedTensorType.get((1, 16, 16, 16), f32Type)

    with ir.InsertionPoint(m.body):
        foo = func.FuncOp("main", ([x for x in inputs.values()], [y for y in outputs.values()]))
        with ir.InsertionPoint(foo.add_entry_block()):
            inputs = foo.arguments
            mlir_outputs = OrderedDict()
            local_input_map = OrderedDict()

            kernel_data = np.random.random((16, 3, 3, 3)).astype(np.float32)
            kernel = tosa.ConstOp(ir.DenseElementsAttr.get(kernel_data))

            bias_data = np.random.random((16,)).astype(np.float32)
            bias = tosa.ConstOp(ir.DenseElementsAttr.get(bias_data))

            op_outputs = [ir.RankedTensorType.get((1, 16, 16, 16), f32Type)]
            cur_op_inputs = [inputs[0], kernel, bias]

            pad = ir.DenseI64ArrayAttr.get([1, 1, 1, 1])
            stride = ir.DenseI64ArrayAttr.get([1, 1])
            dilation = ir.DenseI64ArrayAttr.get([1, 1])
            # how to constrcute quantization_info?
            mlir_operator = tosa.Conv2DOp(*op_outputs, *cur_op_inputs, pad=pad, stride=stride, dilation=dilation)

            func.ReturnOp(mlir_operator)
print(m)

I don’t believe there is any facility to automatically generate type/attr bindings right now, but it use to be that type/attr were not generated by ODS at all. Now that they are it may be possible to do so.
In the meantime people have been getting around this by parsing strings from Python (and getting a Type/Attribute python objet back).

I would try to print the pad variable in python to see, as well as printing the mlir_operator (or does it fail during construction?)

Thanks for your information!
Here is the complete error message and printout for pad

pad:  array<i64: 1, 1, 1, 1>
error: 'tosa.conv2d' op attribute 'pad' failed to satisfy constraint: 64-bit integer array attribute with exactly 4 elements
mlir_operator:  // Verification failed, printing generic form
%2 = "tosa.conv2d"(%arg0, %0, %1) {dilation = array<i64: 1, 1>, pad = array<i64: 1, 1, 1, 1>, stride = array<i64: 1, 1>} : (tensor<1x3x16x16xf32>, tensor<16x3x3x3xf32>, tensor<16xf32>) -> tensor<1x16x16x16xf32>
error: 'tosa.conv2d' op attribute 'pad' failed to satisfy constraint: 64-bit integer array attribute with exactly 4 elements
// Verification failed, printing generic form

Is there any examples of how to get around this by parsing strings?

Thanks!

+1 that is the current state.

Besides this, I just wanted to point out that there is some machinery to declare the Types/Attributes in a dialect’s Python bindings manually.

For example, here’s an attribute declared in the sparse tensor dialect: llvm-project/DialectSparseTensor.cpp at 3712dd73a1d50b76624ee6a520be2b1ca94c02ee · llvm/llvm-project · GitHub

And it can be created like this from Python: llvm-project/dialect.py at 3712dd73a1d50b76624ee6a520be2b1ca94c02ee · llvm/llvm-project · GitHub

This doesn’t really help with the task at hand, but if the TOSA dialect did the same for ConvOpQuantizationAttr and its other attributes, it would be useful here. I guess for now the solution is to use Attribute.parse on a string representation of the attribute.

Here’s an example from the same test where the above sparse tensor attribute is parsed from string: llvm-project/dialect.py at 3712dd73a1d50b76624ee6a520be2b1ca94c02ee · llvm/llvm-project · GitHub

Seems like your mlir commit doesn’t match the latest tosa op definition. Previously it was using ArrayAttr instead of DenseI64ArrayAttr: [MLIR][TOSA] Switch Tosa_IntArrayAttr[N], Tosa_IntArrayAttrUpto[N] to… · llvm/llvm-project@11030c7 · GitHub

1 Like

Thanks! I just realize I am using an old branch.