Files

47 lines
1.4 KiB
Python

"""Data-related utility functions used by the trainer main loop."""
from __future__ import annotations
from typing import Any
import torch
def move_batch_to_device(
batch: Any,
device: torch.device,
*,
non_blocking: bool = True,
) -> Any:
"""Move every tensor in ``batch`` to ``device``, recursing into dict/list.
Returns a new structure with the same shape; the input ``batch`` is not
mutated. dict / list containers are rebuilt; tensors are moved via
``.to(device, non_blocking=...)``; everything else is passed through
by reference.
Parameters
----------
batch : Any
Typically a dict produced by the dataloader, but recursion accepts
dict / list / tensor / arbitrary leaves.
device : torch.device
Target device, typically ``self.device`` on the trainer.
non_blocking : bool
Whether to use pinned-memory async copy. Default True because the
trainer uses pinned loaders; pass False if the dataloader hasn't
pinned memory.
"""
if isinstance(batch, dict):
return {
k: move_batch_to_device(v, device, non_blocking=non_blocking)
for k, v in batch.items()
}
if isinstance(batch, list):
return [
move_batch_to_device(v, device, non_blocking=non_blocking) for v in batch
]
if isinstance(batch, torch.Tensor):
return batch.to(device, non_blocking=non_blocking)
return batch