Open tungld opened 1 year ago
I happened to see ONNXFlatten in Resnet50, and it is currently lowered into a loop in Krnl dialect:
func.func private @test_flatten0(%arg0 : tensor<2x3x4xf32>) -> tensor<*xf32> { %1 = "onnx.Flatten"(%arg0) {axis = 0 : si64} : (tensor<2x3x4xf32>) -> tensor<*xf32> "func.return"(%1) : (tensor<*xf32>) -> () // CHECK: [[MAP_FIRST:#.+]] = affine_map<() -> (0)> // CHECK: [[MAP_SECOND:#.+]] = affine_map<(d0, d1, d2)[s0, s1, s2] -> (d2 + d1 * s2 + d0 * (s1 * s2))> // CHECK-LABEL test_flatten0 // CHECK: [[ALLOC:%.+]] = memref.alloc() {{.*}}: memref<1x24xf32> // CHECK: [[LOOP:%.+]]:3 = krnl.define_loops 3 // CHECK: krnl.iterate([[LOOP]]#0, [[LOOP]]#1, [[LOOP]]#2) with ([[LOOP]]#0 -> [[LOOPARG1:%.+]] = 0 to 2, [[LOOP]]#1 -> [[LOOPARG2:%.+]] = 0 to 3, [[LOOP]]#2 -> [[LOOPARG3:%.+]] = 0 to 4){ // CHECK: [[LOAD:%.+]] = krnl.load %arg0{{\[}}[[LOOPARG1]], [[LOOPARG2]], [[LOOPARG3]]{{\]}} : memref<2x3x4xf32> // CHECK: [[FIRSTDIM:%.+]] = affine.apply [[MAP_FIRST]]() // CHECK: [[C0:%.+]] = arith.constant 0 : index // CHECK: [[R4:%.+]] = arith.constant 2 : index // CHECK: [[C1:%.+]] = arith.constant 1 : index // CHECK: [[R5:%.+]] = arith.constant 3 : index // CHECK: [[C2:%.+]] = arith.constant 2 : index // CHECK: [[R6:%.+]] = arith.constant 4 : index // CHECK: [[SECONDDIM:%.+]] = affine.apply [[MAP_SECOND]]([[LOOPARG1]], [[LOOPARG2]], [[LOOPARG3]]){{\[}}[[R4]], [[R5]], [[R6]]{{\]}} // CHECK: krnl.store [[LOAD]], [[ALLOC]]{{\[}}[[FIRSTDIM]], [[SECONDDIM]]{{\]}} : memref<1x24xf32> }
According to the onnx spec, Flatten can be replaced by a Reshape so that there is no data copy happened.
@tungld Is the intent to add a rule in the canonicalizer?
Is the intent to add a rule in the canonicalizer?
Yes, it can be done via the canoicalizer.
I happened to see ONNXFlatten in Resnet50, and it is currently lowered into a loop in Krnl dialect:
According to the onnx spec, Flatten can be replaced by a Reshape so that there is no data copy happened.