def deep_to(batch, device, dtype):
    """ Static method to call :func:`to` on tensors or tuples. All items in tuple will have :func:`deep_to` called

    Args:
        batch (tuple / list / :class:`torch.Tensor`): The mini-batch which requires a :func:`to` call
        device (:class:`torch.device`): The desired device of the batch
        dtype (:class:`torch.dtype`): The desired datatype of the batch

    Returns:
        tuple / list / :class:`torch.Tensor`: The moved or casted batch
    """
    is_tuple = isinstance(batch, tuple)

    if isinstance(batch, list) or isinstance(batch, tuple):
        batch = list(batch)
        for i in range(len(batch)):
            batch[i] = deep_to(batch[i], device, dtype)
        batch = tuple(batch) if is_tuple else batch
    elif isinstance(batch, dict):
        for key in batch:
            batch[key] = deep_to(batch[key], device, dtype)
    else:
        if batch.dtype.is_floating_point:
            batch = batch.to(device, dtype)
        else:
            batch = batch.to(device)

    return batch