I’m currently writing a rewrite pattern and struggling to access an element inside a MLIR Value instance.
func.func @main(%arg0: tensor<1x4x4x64xf32> {tf_saved_model.index_path = ["input_2"]}) -> (tensor<1x4x4x64xf32> {tf_saved_model.index_path = ["group_normalization"]}) attributes {tf.entry_function = {inputs = "serving_default_input_2:0", outputs = "StatefulPartitionedCall:0"}, tf_saved_model.exported_names = ["serving_default"]} {
%cst = arith.constant dense<[1, 4, 4, 64]> : tensor<4xi32>
%cst_0 = arith.constant dense<0.000000e+00> : tensor<32x2xf32>
%cst_1 = arith.constant dense<[1, 4, 4, 32, 2]> : tensor<5xi64>
%cst_2 = arith.constant dense<[1, 1, 1, 32, 2]> : tensor<5xi64>
%cst_3 = arith.constant dense<1.000000e-03> : tensor<1x1x1x32x1xf32>
%cst_4 = arith.constant dense<[1, 2, 4]> : tensor<3xi32>
%cst_5 = arith.constant dense<[1, 4, 4, 32, 2]> : tensor<5xi32>
%0 = call @func_0_CPU_FLOAT(%arg0, %cst_5, %cst_4, %cst_3, %cst_2, %cst_1, %cst_0, %cst) {tac.device = "CPU", tac.inference_type = "FLOAT", tac.interface_name = "func_0"} : (tensor<1x4x4x64xf32>, tensor<5xi32>, tensor<3xi32>, tensor<1x1x1x32x1xf32>, tensor<5xi64>, tensor<5xi64>, tensor<32x2xf32>, tensor<4xi32>) -> tensor<1x4x4x64xf32>
return %0 : tensor<1x4x4x64xf32>
}
func.func private @func_0_CPU_FLOAT(%arg0: tensor<1x4x4x64xf32>, %arg1: tensor<5xi32>, %arg2: tensor<3xi32>, %arg3: tensor<1x1x1x32x1xf32>, %arg4: tensor<5xi64>, %arg5: tensor<5xi64>, %arg6: tensor<32x2xf32>, %arg7: tensor<4xi32>) -> tensor<1x4x4x64xf32> attributes {tac.cost = 0x4B18A2E4 : f32, tac.device = "CPU", tac.inference_type = "FLOAT", tac.interface_name = "func_0"} {
%cst = arith.constant dense<[1, 4, 4, 32, 2]> : tensor<5xi32>
%cst_0 = arith.constant dense<[1, 2, 4]> : tensor<3xi32>
%cst_1 = arith.constant dense<[1, 1, 1, 32, 2]> : tensor<5xi64>
%cst_2 = arith.constant dense<[1, 4, 4, 32, 2]> : tensor<5xi64>
%cst_3 = arith.constant dense<[1, 4, 4, 64]> : tensor<4xi32>
%0 = "tfl.reshape"(%arg0, %cst) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x4x4x64xf32>, tensor<5xi32>) -> tensor<1x4x4x32x2xf32>
%1 = "tfl.mean"(%0, %cst_0) {keep_dims = true, tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x4x4x32x2xf32>, tensor<3xi32>) -> tensor<1x1x1x32x1xf32>
%2 = tfl.sub(%0, %1) {fused_activation_function = "NONE", tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x4x4x32x2xf32>, tensor<1x1x1x32x1xf32>) -> tensor<1x4x4x32x2xf32>
%3 = "tfl.square"(%2) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x4x4x32x2xf32>) -> tensor<1x4x4x32x2xf32>
%4 = "tfl.mean"(%3, %cst_0) {keep_dims = true, tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x4x4x32x2xf32>, tensor<3xi32>) -> tensor<1x1x1x32x1xf32>
%5 = tfl.add %4, %arg3 {fused_activation_function = "NONE", tac.device = "CPU", tac.inference_type = "FLOAT"} : tensor<1x1x1x32x1xf32>
%6 = "tfl.rsqrt"(%5) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x1x1x32x1xf32>) -> tensor<1x1x1x32x1xf32>
%7 = "tfl.broadcast_to"(%6, %cst_1) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x1x1x32x1xf32>, tensor<5xi64>) -> tensor<1x1x1x32x2xf32>
%8 = "tfl.broadcast_to"(%7, %cst_2) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x1x1x32x2xf32>, tensor<5xi64>) -> tensor<1x4x4x32x2xf32>
%9 = tfl.mul %0, %8 {fused_activation_function = "NONE", tac.device = "CPU", tac.inference_type = "FLOAT"} : tensor<1x4x4x32x2xf32>
%10 = "tfl.broadcast_to"(%1, %cst_1) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x1x1x32x1xf32>, tensor<5xi64>) -> tensor<1x1x1x32x2xf32>
%11 = tfl.mul %10, %7 {fused_activation_function = "NONE", tac.device = "CPU", tac.inference_type = "FLOAT"} : tensor<1x1x1x32x2xf32>
%12 = tfl.sub(%arg6, %11) {fused_activation_function = "NONE", tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<32x2xf32>, tensor<1x1x1x32x2xf32>) -> tensor<1x1x1x32x2xf32>
%13 = "tfl.broadcast_to"(%12, %cst_2) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x1x1x32x2xf32>, tensor<5xi64>) -> tensor<1x4x4x32x2xf32>
%14 = tfl.add %9, %13 {fused_activation_function = "NONE", tac.device = "CPU", tac.inference_type = "FLOAT"} : tensor<1x4x4x32x2xf32>
%15 = "tfl.reshape"(%14, %cst_3) {tac.device = "CPU", tac.inference_type = "FLOAT"} : (tensor<1x4x4x32x2xf32>, tensor<4xi32>) -> tensor<1x4x4x64xf32>
return %15 : tensor<1x4x4x64xf32>
}
This is an input graph(which is a GroupNormalization) and I’m trying to extract the epsilon value, which is 1.000000e-03
of %cst_3
from %5 = tfl.add
.
After getting the operand with mlir::Value epsilon = add_op.getRhs();
,
I believe there’s no direct method to access the elements inside. How can I get the value of the first element inside?
I’ve tried to cast it to a ConstantOp or DenseElementsAttr, but both approaches failed.
Fail Case 1)
DenseElementsAttr dense = epsilon.cast<DenseElementsAttr>();
// error: no viable conversion from 'mlir::Value' to 'mlir::Attribute'
Fail case 2)
auto op = epsilon.getDefiningOp();
auto const_op = llvm::dyn_cast<mlir::arith::ConstantOp>(op);
// op is a nullptr