Source code for interpretune.utils.data_movement
from typing import Any
import torch
################################################################################
# A few useful utility functions for data movement. Originally copied and/or
# adpated from: https://bit.ly/lightning_core_utils and
# https://bit.ly/lightning_fabric_utils
################################################################################
################################################################################
# Data movement utils
################################################################################
_DEVICE = torch.device | str | int
[docs]
def to_device(device: _DEVICE, obj: torch.nn.Module | torch.Tensor | Any) -> torch.nn.Module | torch.Tensor | Any:
r"""Move a :class:`torch.nn.Module` or a collection of tensors to the current device, if it is not already on
that device.
Args:
obj: An object to move to the device. Can be an instance of :class:`torch.nn.Module`, a tensor, or a
(nested) collection of tensors (e.g., a dictionary).
Returns:
A reference to the object that was moved to the new device.
"""
if isinstance(obj, torch.nn.Module):
obj.to(device)
return obj
return move_data_to_device(obj, device=device)
[docs]
def move_data_to_device(batch: Any, device: _DEVICE) -> Any:
"""Transfers a collection of data to the given device. Any object that defines a method ``to(device)`` will be
moved and all other objects in the collection will be left untouched.
Args:
batch: A tensor or collection of tensors or anything that has a method ``.to(...)``.
See :func:`apply_to_collection` for a list of supported collection types.
device: The device to which the data should be moved
Return:
the same collection but with all contained tensors residing on the new device.
See Also:
- :meth:`torch.Tensor.to`
- :class:`torch.device`
"""
if isinstance(device, str):
device = torch.device(device)
def batch_to(data: Any) -> Any:
kwargs = {}
# Don't issue non-blocking transfers to CPU
if isinstance(data, torch.Tensor) and isinstance(device, torch.device) and device.type not in "cpu":
kwargs["non_blocking"] = True
data_output = data.to(device, **kwargs)
if data_output is not None:
return data_output
# user wrongly implemented the `_TransferableDataType` and forgot to return `self`.
return data
return batch_to(data=batch)