def convert_and_retrieve_op_mapping(
    model: Union["ExportedProgram", ScriptModule],
    **converter_kwargs,
) -> Tuple[MLModel, TorchNodeToMILOperationMapping]:
    """
    Converts a TorchScript model to a Core ML model and returns the
    mapping information mapping between the source TorchScript operations and their
    corresponding operations in the converted Core ML model.

    Parameters
    ----------
    model : ScriptModule or ExportedProgram
        The source model.

    **converter_kwargs:
        Additional keyword arguments to be passed to the Core ML conversion process.
        These can include options for optimization, input/output specifications, etc.

    Returns
    -------
    Tuple[MLModel, TorchNodeToMILOperationMapping]
        A tuple containing:
            - The converted Core ML model.
            - A dictionary-like object mapping each TorchScript node from the original model
              to a list of corresponding MIL operations in the Core ML model.
              This mapping helps trace the origin of operations in the converted
              model back to the source model for debugging and analysis

    Examples
    --------
    .. sourcecode:: python

        (
            target_model,
            mapping_info,
        ) = coremltools.models.ml_program.experimental.torch.convert_and_retrieve_op_mapping(
            model=traced_model,  # ScriptModule or ExportedProgram
            inputs=[
                coremltools.TensorType(
                    name="x", shape=example_inputs[0].shape, dtype=np.float16
                ),
                coremltools.TensorType(
                    name="y", shape=example_inputs[1].shape, dtype=np.float16
                ),
            ],
            minimum_deployment_target=coremltools.target.iOS16,
            compute_units=coremltools.ComputeUnit.CPU_ONLY,
            skip_model_load=True,
        )
    """

    def get_output_name_to_node_mapping(
        op_mapping: Dict[TorchNode, List[proto.MIL_pb2.Operation]]
    ) -> Dict[str, TorchNode]:
        result = {}
        for source_node, target_operations in op_mapping.items():
            for target_operation in target_operations:
                for output in target_operation.outputs:
                    result[output.name] = source_node

        return result

    converted_model = None
    node_to_operations_map = None
    if isinstance(model, ScriptModule):
        converted_model, module_mapping = _convert_and_retrieve_jit_module_mapping(
            model=model,
            **converter_kwargs,
        )
        node_to_operations_map = module_mapping[("", 0)].source_to_target_ops_mapping

    elif isinstance(model, ExportedProgram):
        converted_model, node_to_operations_map = _convert_and_retrieve_exported_program_op_mapping(
            model=model, **converter_kwargs
        )
    else:
        raise ValueError(
            f"Unsupported model type: {type(model)}. Expected either ScriptModule or ExportedProgram."
        )

    mapping = TorchNodeToMILOperationMapping(
        node_to_operations_map=node_to_operations_map,
        operation_output_name_to_node_map=get_output_name_to_node_mapping(node_to_operations_map),
    )

    return (converted_model, mapping)

    Converts a TorchScript model to a Core ML model and returns the
    mapping information mapping between the source TorchScript operations and their
    corresponding operations in the converted Core ML model.

    Parameters
    ----------
    model : ScriptModule or ExportedProgram
        The source model.

    **converter_kwargs:
        Additional keyword arguments to be passed to the Core ML conversion process.
        These can include options for optimization, input/output specifications, etc.

    Returns
    -------
    Tuple[MLModel, TorchNodeToMILOperationMapping]
        A tuple containing:
            - The converted Core ML model.
            - A dictionary-like object mapping each TorchScript node from the original model
              to a list of corresponding MIL operations in the Core ML model.
              This mapping helps trace the origin of operations in the converted
              model back to the source model for debugging and analysis

    Examples
    --------
    .. sourcecode:: python

        (
            target_model,
            mapping_info,
        ) = coremltools.models.ml_program.experimental.torch.convert_and_retrieve_op_mapping(
            model=traced_model,  # ScriptModule or ExportedProgram
            inputs=[
                coremltools.TensorType(
                    name="x", shape=example_inputs[0].shape, dtype=np.float16
                ),
                coremltools.TensorType(
                    name="y", shape=example_inputs[1].shape, dtype=np.float16
                ),
            ],
            minimum_deployment_target=coremltools.target.iOS16,
            compute_units=coremltools.ComputeUnit.CPU_ONLY,
            skip_model_load=True,
        )
    
coremltools/models/ml_program/experimental/torch/debugging_utils.py