def _tuple_range_reader(
    input_range: Union[Tensor, float, Tuple[Any, ...]],
    target_size: int,
    device: Optional[torch.device] = None,
    dtype: Optional[torch.dtype] = None,
) -> Tensor:
    """Given target_size, it will generate the corresponding (target_size, 2) range tensor for element-wise params.

    Example:
    >>> degree = tensor([0.2, 0.3])
    >>> _tuple_range_reader(degree, 3)  # read degree for yaw, pitch and roll.
    tensor([[0.2000, 0.3000],
            [0.2000, 0.3000],
            [0.2000, 0.3000]])

    """
    target_shape = torch.Size([target_size, 2])

    if isinstance(input_range, Tensor):
        if (len(input_range.shape) == 0) or (len(input_range.shape) == 1 and len(input_range) == 1):
            if input_range < 0:
                raise ValueError(f"If input_range is only one number it must be a positive number. Got{input_range}")
            input_range_tmp = input_range.repeat(2).to(device=device, dtype=dtype) * tensor(
                [-1, 1], device=device, dtype=dtype
            )
            input_range_tmp = input_range_tmp.repeat(target_shape[0], 1)

        elif len(input_range.shape) == 1 and len(input_range) == 2:
            input_range_tmp = input_range.repeat(target_shape[0], 1).to(device=device, dtype=dtype)

        elif len(input_range.shape) == 1 and len(input_range) == target_shape[0]:
            input_range_tmp = input_range.unsqueeze(1).repeat(1, 2).to(device=device, dtype=dtype) * tensor(
                [-1, 1], device=device, dtype=dtype
            )

        elif input_range.shape == target_shape:
            input_range_tmp = input_range.to(device=device, dtype=dtype)

        else:
            raise ValueError(
                f"Degrees must be a {list(target_shape)} tensor for the degree range for independent operation."
                f"Got {input_range}"
            )
    elif isinstance(input_range, (float, int)):
        if input_range < 0:
            raise ValueError(f"If input_range is only one number it must be a positive number. Got{input_range}")
        input_range_tmp = tensor([-input_range, input_range], device=device, dtype=dtype).repeat(target_shape[0], 1)

    elif (
        isinstance(input_range, (tuple, list))
        and len(input_range) == 2
        and isinstance(input_range[0], (float, int))
        and isinstance(input_range[1], (float, int))
    ):
        input_range_tmp = tensor(input_range, device=device, dtype=dtype).repeat(target_shape[0], 1)

    elif (
        isinstance(input_range, (tuple, list))
        and len(input_range) == target_shape[0]
        and all(isinstance(x, (float, int)) for x in input_range)
    ):
        input_range_tmp = tensor([(-s, s) for s in input_range], device=device, dtype=dtype)

    elif (
        isinstance(input_range, (tuple, list))
        and len(input_range) == target_shape[0]
        and all(isinstance(x, (tuple, list)) for x in input_range)
    ):
        input_range_tmp = tensor(input_range, device=device, dtype=dtype)

    else:
        raise TypeError(
            "If not pass a tensor, it must be float, (float, float) for isotropic operation or a tuple of "
            f"{target_size} floats or {target_size} (float, float) for independent operation. Got {input_range}."
        )

    return input_range_tmp
Given target_size, it will generate the corresponding (target_size, 2) range tensor for element-wise params.

    Example:
    >>> degree = tensor([0.2, 0.3])
    >>> _tuple_range_reader(degree, 3)  # read degree for yaw, pitch and roll.
    tensor([[0.2000, 0.3000],
            [0.2000, 0.3000],
            [0.2000, 0.3000]])

    
kornia/augmentation/utils/param_validation.py