def transform_op(self, op) -> None:
        """Transform the input(s)/output(s) dtypes of the op."""
        block = op.enclosing_block
        casted_inputs = {}
        inputs_modified = False

        for param, inputs in op.inputs.items():
            if not self.should_cast_parameter(op, param):
                continue

            is_list_input = isinstance(inputs, (list, tuple))
            if not is_list_input:
                inputs = [inputs]

            casted_inputs[param] = list(inputs[:])
            for i, var in enumerate(inputs):
                if var.dtype == types.str and var.val == "int32":
                    # input may be a string that specifies the dtype, so simply replace with "int16"
                    inputs_modified = True
                    if op.op_type in {"topk"}:
                        # these ops can use uint16
                        casted_inputs[param][i] = "uint16"
                    else:
                        casted_inputs[param][i] = "int16"
                else:
                    # otherwise only int32 tensor / scalar should get cast to int16
                    if not var.is_tensor_or_scalar_of(dtype=self.origin_dtype):
                        continue

                    inputs_modified = True
                    casted_var_name = f"{var.name}_to_{self.target_dtype}"
                    if len(var._child_ops) > 1 and casted_var_name in self.current_cache_vars():
                        if self.current_cache_vars()[casted_var_name].op.x != var:
                            logger.warning(
                                "The cached cast Var doesn't match the original Var. It's due to duplicated Var "
                                f"names in the graph for {casted_var_name}."
                            )
                        casted_inputs[param][i] = self.current_cache_vars()[casted_var_name]
                    else:
                        x = mb.cast(
                            x=var,
                            dtype=self.target_dtype,
                            name=casted_var_name,
                            before_op=op,
                        )
                        if self.target_dtype == "fp16":
                            self._check_underflow_to_zero(x, var)
                        Block._copy_metadata(var, x)

                        casted_inputs[param][i] = x
                        if len(var._child_ops) > 1:
                            self.current_cache_vars()[casted_var_name] = casted_inputs[param][i]

            if not is_list_input:
                casted_inputs[param] = casted_inputs[param][0]

        if inputs_modified:
            casted_inputs.update({k: v for k, v in op.inputs.items() if k not in casted_inputs})
            casted_inputs["name"] = f"{op.name}_cast_{self.target_dtype}"
            casted_inputs["before_op"] = op
            quant_output = self._get_casted_outputs(op, casted_inputs)

            if not isinstance(quant_output, (list, tuple)):
                quant_output = [quant_output]

            for old_output_var, new_output_var in zip(op.outputs, quant_output):
                if old_output_var.is_tensor_or_scalar_of(dtype=self.origin_dtype) and (
                    not new_output_var.is_tensor_or_scalar_of(dtype=self.origin_dtype)
                ):
                    x = mb.cast(
                        x=new_output_var,
                        dtype=self.origin_dtype,
                        name=f"{new_output_var.name}_to_{self.origin_dtype}",
                        before_op=op,
                    )
                    op.enclosing_block.replace_uses_of_var_after_op(
                        anchor_op=op,
                        old_var=old_output_var,
                        new_var=x,
                        force_replace=True,
                    )
                else:

                    op.enclosing_block.replace_uses_of_var_after_op(
                        anchor_op=op,
                        old_var=old_output_var,
                        new_var=new_output_var,
                        force_replace=True,
                    )

            block.remove_ops([op])
Transform the input(s)/output(s) dtypes of the op.
coremltools/converters/mil/mil/passes/defs/quantization.py