Is there a way to get the contents of the DefaultValueAttr in the MLIR Python binding?

Hi guys, I would like to ask a question about getting DefaultValueAttr in MLIR Python binding.
Currently I am working on an out of tree project and I need to get the default value of DefaultValueAttr in Python Binding for an OP that I have defined in tablegen file. But when I access the member via dot operator, it says “KeyError: attempt to access a non-existent attribute”.
The following example is a snippet from my tablegen file:

def BN : BaseOp<"BatchNormalization"> {
    let summary = "BatchNormalization OP";
    let description = [{}];
    let arguments = (ins
        AnyTensor:$X,
        AnyTensorOrNone:$scale,
        AnyTensorOrNone:$B,
        AnyTensor:$input_mean,
        AnyTensor:$input_var,
        DefaultValuedAttr<F64Attr, "1e-5">:$epsilon,
        DefaultValuedAttr<F64Attr, "0.9">:$momentum,
        DefaultValuedAttr<I64Attr, "1">:$training_mode
    );
    let results = (outs AnyTensor:$Y,AnyTensor:$running_mean,AnyTensor:$running_var); 
}

I tried to use xxx.epsilon in the MLIR Python binding, but encountered KeyError: attempt to access a non-existent attribute.
What should I use to access the default value of epsilon, please also guide me!

There is no way to query the default value programmatically, neither in Python nor in C++.

In C++, it should be possible to construct an instance of an op without providing the values for defaulted attributes, query the value of the attribute (which will be set to the default value in the op constructor), and immediately erase the op, but it is quite expensive. In Python, it will depend on how exactly the op constructor is exposed as that process is mostly manual.

1 Like

Thanks for the answer, I’ll think again if I can circumvent this need in my project

When you say you need to get the default value, why? Could you explain the flow? Python side you can also construct without providing default values, but it sounds like you are more interested in a op type static value.

I want to use the Dialect Conversion feature to convert deep learning model formats to each other, but in some cases, for example, the default attribute for ONNX may not be the default attribute for caffe, that’s why I need this feature, to make sure that I can get the value using the definition of DefaultAttrValue in tablegen without adding additional information。
Further, if I want to give professional users an easy-to-use feature for modifying model information (e.g., modifying some attribute of an OP without having to re-export the entire model), there is currently no way to modify the Location of an Operation in MLIR. So if I assume that the user will modify the information of an Operation via My Python API, I need to reconstruct the OP using the existing information, but the implementation of this function is complicated by the fact that the information related to the DefaultValueAttr is not available.
My specific idea was to provide a generic method, not a method specific to a particular Dialect, as there are multiple Dialects in my out of tree project. so I called xxx.__init__. __code__.co_varnames to get the python class construction method, used to get what attributes and operands I should get from the current OP when reconstructing the OP, but I was using this method with the problem I asked at the beginning, DefaultValueAttr in Python will prompt the Keyerror, resulting in no way to access the relevant attribute, which is why I came to the forum to ask if there is a solution for this!

Currently the parts related to Dialect conversion have been implemented in C++. The latter reconstruction of the OP is also implemented using an ugly approach

If you have existing op the calling the getter would return the value (default or not) and you’d set that in construction of the new. It would seem you don’t need to care if there is a default or different value set as in both cases you’d be querying using the same accessor on the source op and use the value to construct the destination.

Yes, I found this out when I was trying to figure out how to circumvent this requirement because I was using xxx.__init__. __code__.co_varnames to get the OP’s operands and attributes so I fell into a thinking trap.
Anyway thanks for the answers guys!