-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
executable file
·95 lines (70 loc) · 2.23 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import logging
from contextlib import contextmanager
from typing import Generator, Tuple
import numpy as np
from numpy.typing import ArrayLike
LOG = logging.getLogger(__name__)
try:
import cupy as cp
from cupy.cuda.memory import malloc_managed
LOG.info("cupy found.")
except (ModuleNotFoundError, ImportError):
LOG.info("cupy not found.")
cp = None
def center_crop(arr: ArrayLike, shape: Tuple[int, ...]) -> ArrayLike:
"""Crops the center of `arr`"""
assert arr.ndim == len(shape)
starts = ((cur_s - s) // 2 for cur_s, s in zip(arr.shape, shape))
assert all(s >= 0 for s in starts)
slicing = tuple(slice(s, s + d) for s, d in zip(starts, shape))
LOG.info(
f"center crop: input shape {arr.shape}, output shape {shape}, slicing {slicing}"
)
return arr[slicing]
def pad_to_shape(
arr: ArrayLike, shape: Tuple[int, ...], mode: str, **kwargs
) -> ArrayLike:
"""Pads array to shape.
Parameters
----------
arr : ArrayLike
Input array.
shape : Tuple[int]
Output shape.
mode : str
Padding mode (see np.pad).
Returns
-------
ArrayLike
Padded array.
"""
assert arr.ndim == len(shape)
dif = tuple(s - a for s, a in zip(shape, arr.shape))
assert all(d >= 0 for d in dif)
pad_width = [[s // 2, s - s // 2] for s in dif]
LOG.info(
f"padding: input shape {arr.shape}, output shape {shape}, padding {pad_width}"
)
return np.pad(arr, pad_width=pad_width, mode=mode, **kwargs)
def to_cpu(arr: ArrayLike) -> ArrayLike:
"""Moves array to cpu, if it's already there nothing is done."""
if hasattr(arr, "cpu"):
arr = arr.cpu()
elif hasattr(arr, "get"):
arr = arr.get()
return arr
@contextmanager
def unified_memory() -> Generator:
"""
Initializes cupy's unified memory allocation.
cupy's functions will run slower but it will spill memory memory into cpu without crashing.
"""
# starts unified memory
if cp is not None:
previous_allocator = cp.cuda.get_allocator()
cp.cuda.set_allocator(malloc_managed)
yield
# ends unified memory
if cp is not None:
cp.clear_memo()
cp.cuda.set_allocator(previous_allocator)