Question about Pass Pattern

Hi Sirs,

I’m trying to implement pass pattern to match the graph like below picture.

def qnn_conv2d_quant_pattern():
qnn_conv2d = is_op(“qnn.conv2d”)(
wildcard(), is_constant(), is_constant(), is_constant(), is_constant(), is_constant()
)
bias_add = is_op(“nn.bias_add”)(qnn_conv2d, is_constant())
req = is_op(“qnn.requantize”)(
qnn_conv2d | bias_add, is_constant(), is_constant(), is_constant(), is_constant()
)
clip_or_req = req.optional(is_op(“clip”))
clip_or_req = is_op(“qnn.requantize”)(
clip_or_req, is_constant(), is_constant(), is_constant(), is_constant()
)
return clip_or_req

But this pattern can only match #3 in the graph, #1 & #2 are not match.
Could you help~~

Thanks~

In most cases pattern match is to rewrite graph.

Yes, It can only match pattern #3.

Think about what will happen if you rewrite #1 success?

In origin graph, we the first conv generate two output has two branch.

Branch A’s output will be used for next conv, Branch B’s output will be used for Quantize.

So if you rewrite the conv and quantize, the rewrited conv still have two output, one for conv dtype float32, one for quantize int8.

In tvm, Batchnorm’s outputs is a Tuple, and the following op will use TupleGetItem to get correct index output.

It’s hard to figure out you rewrite conv will be used for following ops.

So in my opinio, change a quantize algorithm will be better for fuse.

 /**
 *             data
 *              | fp32
 *           quantize
 *              | int8
 *            conv
 *              | int32
 *           requantize
 *           /int8      \ int8
 *        conv        dequant
 *         | int32       | float32
 *     requantize        op1
 *     / int8     \ int8
 *  conv       dequant
 *   | int32       | float32
 * dequant       op2
 *   | float32
 *  op3
 *
 */

Hi chenugray,

thanks for your reply,
It seems I need to find another way to do the optimization.

Thanks~