import torch


def to_gpu(data, device=None):
    """
        Transfer tensor in `data` to gpu recursively
        `data` can be dict, list or tuple
        """
    if isinstance(data, list) or isinstance(data, tuple):
        data = [to_gpu(x) for x in data]
    elif isinstance(data, dict):
        data = {key: to_gpu(_data) for key, _data in data.items()}
    elif isinstance(data, torch.Tensor):
        data = data.contiguous().cuda(non_blocking=True)
    return data