Yeah, my IR after Fuse is like this now:
def @main(%xx: Tensor[(64, 64), int8], %ww: Tensor[(64), int8], %bb: Tensor[(64), int8], %y: Tensor[(64, 64), int8]) -> Tensor[(64, 64), int8] {
%0 = fn (%x: Tensor[(64, 64), int8], %w: Tensor[(64), int8], %b: Tensor[(64), int8], Primitive=1) -> Tensor[(64, 64), int8] {
qnn.aie.layer_norm(%x, %w, %b, epsilon=1.52588e-05f, ln_shift=7, affine_shift=8) /* ty=Tensor[(64, 64), int8] */
};
%1 = %0(%xx, %ww, %bb) /* ty=Tensor[(64, 64), int8] */;
%2 = fn (%p0: Tensor[(64, 64), int8], %p1: Tensor[(64, 64), int8], Primitive=1) -> Tensor[(64, 64), int8] {
nn.dense(%p0, %p1, units=64, out_dtype="int8") /* ty=Tensor[(64, 64), int8] */
};
%2(%1, %y) /* ty=Tensor[(64, 64), int8] */
}
after Partition pass looks like this:
#[version = "0.0.5"]
def @main(%xx: Tensor[(64, 64), int8], %ww: Tensor[(64), int8], %bb: Tensor[(64), int8], %y: Tensor[(64, 64), int8]) -> Tensor[(64, 64), int8] {
%0 = fn (%x: Tensor[(64, 64), int8], %w: Tensor[(64), int8], %b: Tensor[(64), int8], Primitive=1) -> Tensor[(64, 64), int8] {
@tvmgen_default_versal_aie_main_2(%x, %w, %b) /* ty=Tensor[(64, 64), int8] */
};
%1 = %0(%xx, %ww, %bb) /* ty=Tensor[(64, 64), int8] */;
%2 = fn (%p0: Tensor[(64, 64), int8], %p1: Tensor[(64, 64), int8], Primitive=1) -> Tensor[(64, 64), int8] {
@tvmgen_default_versal_aie_main_0(%p0, %p1) /* ty=Tensor[(64, 64), int8] */
};
%2(%1, %y) /* ty=Tensor[(64, 64), int8] */
}
def @tvmgen_default_versal_aie_main_0(%versal_aie_0_i0: Tensor[(64, 64), int8], %versal_aie_0_i1: Tensor[(64, 64), int8], Inline=1, Compiler="versal_aie", global_symbol="tvmgen_default_versal_aie_main_0", Primitive=1) -> Tensor[(64, 64), int8] {
nn.dense(%versal_aie_0_i0, %versal_aie_0_i1, units=64, out_dtype="int8") /* ty=Tensor[(64, 64), int8] */
}
def @tvmgen_default_versal_aie_main_2(%versal_aie_2_i0: Tensor[(64, 64), int8], %versal_aie_2_i1: Tensor[(64), int8], %versal_aie_2_i2: Tensor[(64), int8], Inline=1, Compiler="versal_aie", global_symbol="tvmgen_default_versal_aie_main_2", Primitive=1) -> Tensor[(64, 64), int8] {
qnn.aie.layer_norm(%versal_aie_2_i0, %versal_aie_2_i1, %versal_aie_2_i2, epsilon=1.52588e-05f, ln_shift=7, affine_shift=8) /* ty=Tensor[(64, 64), int8] */
}
But still can’t pass the checkings when building,
it seems that the checking there only accept an Op as Call.op, not accept a Function as Call.op for the IR fragment:
%2 = fn (%p0: Tensor[(64, 64), int8], %p1: Tensor[(64, 64), int8], Primitive=1) -> Tensor[(64, 64), int8] {
@tvmgen_default_versal_aie_main_0(%p0, %p1) /* ty=Tensor[(64, 64), int8] */
};
Is there anything I miss?