def get_default_recipe(nodes):
    r"""
    This function is about get default recipe which set where fake quant is inserted for the quantizable ops.
    """
    # step1: Quantization state init. Quantize inputs before quantizable node by setting their input's inf_dtype to
    # qconfig.activation().dtype, and also setting the weight's inf_dtype to
    # qconfig.weight().dtype if a module has a weight.
    _default_recipe_init(nodes)
    # step2: Optimization
    # 1. For conv, gemm, and LSTM,  we always quantize its' inputs and weight, so we keep them state.
    #    and for embedding_bag, which only has a weight, we always quantize it's weight to
    #    save memory space and bandwidth, we also keep it's state.
    # 2. For remaining quantizable ops (pooling, elt-wise op and add) which meet the following requirements, we will
    # update them inputs' quantization state.
    #   1. If it is a part of a quantized fusion pattern, don't need to quantize any inputs from inside the pattern.
    #   2. If any of its inputs outside the fusion pattern are from non-quantized op, don't quantize all inputs outside the pattern.
    #   3. If it is not part of a quantized fusion pattern, don't quantize all inputs if its one input from non-quantized op.
    # 3. For quantizable ops (pooling, relu, flatten, interation and embedding) forcing quantized output, need to \
    #    quantize its output if it is quantized.
    # 4. For interation and embedding, we only support s8->s8 symmetric quantization, so if doesn't meet the \
    #    requiresments, don't need to quantize its inputs.
    # Note: the fusion pattern we are supported is conv/gemm/add + elt-wise, conv/gemm + add, conv/gemm + add + elt-wise.
    # which means some ops can be combined with a single op to compute, but they are mathematically equivalent.
    embedding_bag_ops = [
        str(torch.embedding_bag),
        str(F.embedding_bag),
        str(torch.nn.EmbeddingBag),
        str(MergedEmbeddingBagWithCat),
        str(torch.ops.torch_ipex.merged_embeddingbag_cat_forward),
    ]
    for node in nodes:
        if isinstance(node, ParentNode):
            continue
        if node.qconfig is not None and node.type not in (
            conv_gemm_ops + rnn_ops + embedding_bag_ops
        ):
            if node.type in add_ops:
                # gemm+add fusion
                _add_recipe(node)
            elif node.type in elt_wise_q_ops:
                # don't have a pre_node, we can say it doesn't have a pre quantizable node.
                has_pre_quantized_node = True
                # If Has gemm(add) pre_op can be fused, not insert fake quant.
                if len(node.pre_nodes) > 0:
                    if (
                        _find_fused_node_with_cur_elt_wise(
                            node, conv_gemm_ops + add_ops + add_inplace_ops
                        )
                        is not None
                    ):
                        has_pre_quantized_node = False
                    else:
                        has_pre_quantized_node = (
                            _check_has_quantizable_node_before_node(node.pre_nodes[0])
                        )
                else:
                    has_pre_quantized_node = False
                if not has_pre_quantized_node:
                    node.input_tensor_infos[0].inf_dtype = node.input_tensor_infos[
                        0
                    ].orig_dtype
                    node.input_tensor_force_inf_dtype[0] = node.input_tensor_infos[
                        0
                    ].inf_dtype
            elif node.type == str(
                torch.Tensor.flatten
            ) and not _check_has_quantizable_node_after_node(node):
                # If the post op of flatten is not a quantizable node, force reset input's inf_dtype to orig_dtype
                node.input_tensor_infos[0].inf_dtype = node.input_tensor_infos[
                    0
                ].orig_dtype
                node.input_tensor_force_inf_dtype[0] = node.input_tensor_infos[
                    0
                ].inf_dtype
            else:
                # For other quantizable node, we don't need add fake quant before it if it's pre node is one none-quantizable op.
                # Now all other quantizable node only have one input info, so we can check the one pre input node info to check
                # whether has a pre quantizable node.
                has_pre_quantized_node = True
                if len(node.pre_nodes) == 1:
                    has_pre_quantized_node = _check_has_quantizable_node_before_node(
                        node.pre_nodes[0]
                    )
                elif len(node.pre_nodes) == 0:
                    has_pre_quantized_node = False
                # the node's pre node doesn't support int8 output.
                if not has_pre_quantized_node:
                    node.input_tensor_infos[0].inf_dtype = node.input_tensor_infos[
                        0
                    ].orig_dtype
                    node.input_tensor_force_inf_dtype[0] = node.input_tensor_infos[
                        0
                    ].inf_dtype

    set_node_output_quantized(nodes)

    This function is about get default recipe which set where fake quant is inserted for the quantizable ops.
    
intel_extension_for_pytorch/quantization/_recipe.py