from concurrent.futures import CancelledError import torch from torch.nn import functional as F import typing as tp import math import os from contextlib import contextmanager import tempfile def unfold(a, kernel_size, stride): *shape, length = a.shape n_frames = math.ceil(length / stride) tgt_length = (n_frames - 1) * stride + kernel_size a = F.pad(a, (0, tgt_length - length)) strides = list(a.stride()) assert strides[-1] == 1, 'data should be contiguous' strides = strides[:-1] + [stride, 1] return a.as_strided([*shape, n_frames, kernel_size], strides) def center_trim(tensor: torch.Tensor, reference: tp.Union[torch.Tensor, int]): ref_size: int if isinstance(reference, torch.Tensor): ref_size = reference.size(-1) else: ref_size = reference delta = tensor.size(-1) - ref_size if delta < 0: raise ValueError("tensor must be larger than reference. " f"Delta is {delta}.") if delta: tensor = tensor[..., delta // 2:-(delta - delta // 2)] return tensor @contextmanager def temp_filenames(count: int, delete=True): names = [] try: for _ in range(count): names.append(tempfile.NamedTemporaryFile(delete=False).name) yield names finally: if delete: for name in names: os.unlink(name) class DummyPoolExecutor: class DummyResult: def __init__(self, func, _dict, *args, **kwargs): self.func = func self._dict = _dict self.args = args self.kwargs = kwargs def result(self): if self._dict["run"]: return self.func(*self.args, **self.kwargs) else: raise CancelledError() def __init__(self, workers=0): self._dict = {"run": True} def submit(self, func, *args, **kwargs): return DummyPoolExecutor.DummyResult(func, self._dict, *args, **kwargs) def shutdown(self, *_, **__): self._dict["run"] = False def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_tb): return