def _extract_outputs_from_exir_program(
    exported_program,  # torch.export.ExportedProgram
) -> Tuple[List[str], Dict[str, str],]:
    """
    Extract "outputs" from torch.export.ExportedProgram

    For easy delegation to different backends,
    EXIR lifts buffer mutations also as outputs,
    so we will extract all user outputs and buffer mutations

    Given:
        exported_program: torch.export.ExportedProgram
    Return:
        user_outputs: List[str]
            list of output names
        output_name_to_target_buffer_name: Dict[str, str]
            dictionary mapping output variable names to underlying mutable buffer names,
            i.e. these output variables are "written" to mutable buffer
    """
    user_outputs = []
    output_name_to_target_buffer_name = {}
    for output_spec in exported_program.graph_signature.output_specs:
        if output_spec.kind == torch.export.graph_signature.OutputKind.USER_OUTPUT:
            user_outputs.append(output_spec.arg.name)

        elif output_spec.kind == torch.export.graph_signature.OutputKind.BUFFER_MUTATION:
            output_name_to_target_buffer_name[output_spec.arg.name] = output_spec.target

        elif output_spec.kind == torch.export.graph_signature.OutputKind.USER_INPUT_MUTATION:
            raise ValueError(
                "Core ML cannot handle user input mutation, because Core ML distinguishes "
                "input (immutable) and state (mutable). You have 2 options:\n"
                "1. If mutation is intentional and necessary to carry over, then please "
                "replace input with buffer by your torch model.register_buffer then re-export\n"
                "2. If mutation is unnecessary, then please avoid it, e.g. by "
                "adding `input = input.clone()` at the 1st line of your torch model.forward method"
            )

        else:
            raise NotImplementedError(
                "Only 2 types of outputs handled yet: user output, buffer mutation. "
                f"But got {output_spec.kind}"
            )

    return user_outputs, output_name_to_target_buffer_name

    Extract "outputs" from torch.export.ExportedProgram

    For easy delegation to different backends,
    EXIR lifts buffer mutations also as outputs,
    so we will extract all user outputs and buffer mutations

    Given:
        exported_program: torch.export.ExportedProgram
    Return:
        user_outputs: List[str]
            list of output names
        output_name_to_target_buffer_name: Dict[str, str]
            dictionary mapping output variable names to underlying mutable buffer names,
            i.e. these output variables are "written" to mutable buffer
    
coremltools/converters/mil/frontend/torch/exir_utils.py