def _validate_tensor_args(sorted_graph: List[Tensor], output_tensors: List[Tensor]):
    """
    Validate the user's desired output name -> index ordering.

    Errors if:
    1) The given ordering has duplicates
    2) The given ordering has non-outputs
    3) The given ordering is missing outputs that are reachable

    Note that we have to do this before any optimizations. It is legal to replace output tensors
    with new Tensor objects of the same name, so the user-provided tensors might not be in
    the graph after optimizations (replacing a Tensor sets is_output=False).
    """
    seen_tensors = set()
    for tensor in output_tensors:
        name = tensor._attrs["name"]
        if not tensor._attrs["is_output"]:
            raise ValueError(f"Got non-output tensor in output_tensors list: {name}")
        if name in seen_tensors:
            raise ValueError(f"Got duplicate name {name} in output_tensors list.")
        seen_tensors.add(name)

    given_tensors = {tensor._attrs["name"] for tensor in output_tensors}
    for tensor in reversed(sorted_graph):
        name = tensor._attrs["name"]
        if tensor._attrs["is_output"] and name not in given_tensors:
            raise ValueError(f"Output {name} was not passed into output_tensors")

    Validate the user's desired output name -> index ordering.

    Errors if:
    1) The given ordering has duplicates
    2) The given ordering has non-outputs
    3) The given ordering is missing outputs that are reachable

    Note that we have to do this before any optimizations. It is legal to replace output tensors
    with new Tensor objects of the same name, so the user-provided tensors might not be in
    the graph after optimizations (replacing a Tensor sets is_output=False).
    
python/aitemplate/compiler/compiler.py