def _mark_always_affine_combination_ops_for_replacement(self, model: _fx.GraphModule):
        """
        This method follows the same reasoning as described in ``_mark_always_affine_layers_for_replacement``,
        but instead of replacing activation quantizers for stand-alone ops, it replaces them for
        ops which consume more than 1 tensor as input.

        For add or cat, if the qscheme of all tensors being combined together is
        affine, it also uses affine qscheme, otherwise, it uses symmetric qscheme.
        """
        for node in model.graph.nodes:
            if node.op == "call_function":
                combine_op_type = _combine_op_type(node)
                if combine_op_type is not None and combine_op_type != _CombinationOpType.AddReLU:
                    args = node.args
                    if combine_op_type == _CombinationOpType.Concat:
                        args = node.args[0]
                    arg_act_qschemes = []
                    for arg in args:
                        arg_mod = _find_module(model, arg)
                        if arg_mod is not None:
                            if (
                                type(arg_mod) in _always_affine_layers
                                or arg in self._modules_to_replace
                            ):
                                arg_act_qschemes.append(_QuantizationScheme.affine)
                            elif hasattr(arg_mod, "qscheme"):
                                if arg_mod.qscheme == _torch.per_tensor_affine:
                                    arg_act_qschemes.append(_QuantizationScheme.affine)
                                else:
                                    arg_act_qschemes.append(_QuantizationScheme.symmetric)
                            else:
                                arg_act_qschemes.append(_QuantizationScheme.symmetric)
                        else:
                            arg_act_qschemes.append(_QuantizationScheme.symmetric)
                    if all(x == _QuantizationScheme.affine for x in arg_act_qschemes):
                        # We have already marked cat op for replacement, when one of the
                        # tensors it combines was marked for replacement. So we don't need to
                        # add it here again.
                        if combine_op_type != _CombinationOpType.Concat:
                            self._mark_act_post_process_for_replacement(node, model)
                    else:
                        # If any of the tensor being cat-ed together need to use
                        # [-128, 127] range, we can't use affine quantization in
                        # symmetric mode for them, so we remove them from modules marked for replacement.
                        if combine_op_type == _CombinationOpType.Concat:
                            for arg in args:
                                if arg in self._modules_to_replace:
                                    self._modules_to_replace.pop(arg)
                                if arg in self._new_act_post_process:
                                    self._new_act_post_process.pop(arg)

        This method follows the same reasoning as described in ``_mark_always_affine_layers_for_replacement``,
        but instead of replacing activation quantizers for stand-alone ops, it replaces them for
        ops which consume more than 1 tensor as input.

        For add or cat, if the qscheme of all tensors being combined together is
        affine, it also uses affine qscheme, otherwise, it uses symmetric qscheme.
        
coremltools/optimize/torch/quantization/_configure.py