acids-cc 3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- acids_cc-3.0.dist-info/METADATA +220 -0
- acids_cc-3.0.dist-info/RECORD +11 -0
- acids_cc-3.0.dist-info/WHEEL +5 -0
- acids_cc-3.0.dist-info/top_level.txt +1 -0
- cached_conv/__init__.py +200 -0
- cached_conv/conv_1d.py +312 -0
- cached_conv/conv_2d.py +213 -0
- cached_conv/conv_3d.py +184 -0
- cached_conv/upsample.py +176 -0
- cached_conv/utils.py +133 -0
- cached_conv/variants.py +185 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: acids-cc
|
|
3
|
+
Version: 3.0
|
|
4
|
+
Summary: Cached convolution layers for real-time streaming inference with PyTorch (upgrade of Caillon's cached_conv 2021 package)
|
|
5
|
+
Author: Axel Chemla--Romeu-Santos, Nils Demerlé
|
|
6
|
+
Author-email: ACIDS <acids.paris@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Documentation, https://cached-conv.readthedocs.io
|
|
9
|
+
Project-URL: Repository, https://github.com/acids-ircam/acids-cc
|
|
10
|
+
Keywords: deep learning,pytorch,convolution,streaming,real-time
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: torch>1.8
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest; extra == "dev"
|
|
19
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
20
|
+
Provides-Extra: docs
|
|
21
|
+
Requires-Dist: sphinx>=7; extra == "docs"
|
|
22
|
+
Requires-Dist: furo; extra == "docs"
|
|
23
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
24
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
25
|
+
|
|
26
|
+
# cached_conv
|
|
27
|
+
|
|
28
|
+
[](https://acids-cc.readthedocs.io/en/latest/)
|
|
29
|
+
[](https://github.com/acids-ircam/acids-cc/actions/workflows/docs.yml)
|
|
30
|
+
|
|
31
|
+
**Cached convolutions for real-time streaming inference with PyTorch.**
|
|
32
|
+
|
|
33
|
+
`cached_conv` provides drop-in replacements for PyTorch convolutional layers
|
|
34
|
+
that process a signal **block by block** and give the same result as
|
|
35
|
+
processing it all at once. Each layer keeps the end of the previous block in
|
|
36
|
+
an internal cache, used instead of zero padding at block boundaries.
|
|
37
|
+
|
|
38
|
+
The same model definition can be built in two modes:
|
|
39
|
+
|
|
40
|
+
- **eager** (default): regular layers, for training on full signals;
|
|
41
|
+
- **cached**: streaming layers, for real-time inference, e.g. once exported
|
|
42
|
+
with TorchScript.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- 1D, 2D and 3D convolutions and transposed convolutions. Time is the last
|
|
47
|
+
axis, the only one that is streamed.
|
|
48
|
+
- `"same"`, `"causal"` and `"anticausal"` padding, computed from the kernel
|
|
49
|
+
size and dilation.
|
|
50
|
+
- Strides, dilation and groups.
|
|
51
|
+
- Latency tracking: every layer exposes its `cumulative_delay`, which
|
|
52
|
+
accumulates across a whole model.
|
|
53
|
+
- Windowed convolutions: the kernel is multiplied by a window before
|
|
54
|
+
convolving.
|
|
55
|
+
- StyleGAN 2-modulated convolutions. The style can change from one block to
|
|
56
|
+
the next.
|
|
57
|
+
- Streamable upsampling (nearest and linear), group normalization and
|
|
58
|
+
alignment of parallel branches.
|
|
59
|
+
- TorchScript export, on CPU, CUDA and MPS.
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install git+https://github.com/acids-ircam/acids-cc.git
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Requires Python ≥ 3.9 and PyTorch ≥ 1.9.
|
|
68
|
+
|
|
69
|
+
## Quick start
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import torch
|
|
73
|
+
import cached_conv as cc
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def build_model():
|
|
77
|
+
conv1 = cc.Conv1d(1, 16, 5, padding="same")
|
|
78
|
+
conv2 = cc.Conv1d(16, 1, 5, padding="same",
|
|
79
|
+
cumulative_delay=conv1.cumulative_delay)
|
|
80
|
+
return cc.CachedSequential(conv1, conv2)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# 1. train in eager mode (the default)
|
|
84
|
+
model = build_model()
|
|
85
|
+
|
|
86
|
+
# 2. build the same model with cached layers, and load the trained weights
|
|
87
|
+
cc.use_cached_conv(True)
|
|
88
|
+
streaming_model = build_model()
|
|
89
|
+
streaming_model.load_state_dict(model.state_dict())
|
|
90
|
+
|
|
91
|
+
# 3. process a stream block by block
|
|
92
|
+
stream = torch.randn(1, 1, 8192)
|
|
93
|
+
y = torch.cat([streaming_model(block) for block in stream.split(512, -1)], -1)
|
|
94
|
+
|
|
95
|
+
# the output is delayed by the model's latency, in samples. The edges differ:
|
|
96
|
+
# before the signal starts, eager layers see zero padding, cached layers see
|
|
97
|
+
# the previous layer's response to silence
|
|
98
|
+
delay = streaming_model.cumulative_delay
|
|
99
|
+
offline = model(stream)
|
|
100
|
+
assert torch.allclose(y[..., 2 * delay:], offline[..., delay:-delay],
|
|
101
|
+
atol=1e-5)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Cached layers can't look into the future: centered convolutions delay their
|
|
105
|
+
output instead. Pass each layer's `cumulative_delay` to the next one so that
|
|
106
|
+
the total latency is tracked correctly. With `padding="causal"` everywhere,
|
|
107
|
+
the latency only comes from strides.
|
|
108
|
+
|
|
109
|
+
## Layers
|
|
110
|
+
|
|
111
|
+
The layers exposed by the package (`cc.Conv1d`, `cc.Upsample2d`...) are
|
|
112
|
+
factories: they return a regular or a cached layer, depending on
|
|
113
|
+
`cc.use_cached_conv` at construction time.
|
|
114
|
+
|
|
115
|
+
| | 1D | 2D | 3D |
|
|
116
|
+
| --- | --- | --- | --- |
|
|
117
|
+
| Convolution | `Conv1d` | `Conv2d` | `Conv3d` |
|
|
118
|
+
| Transposed convolution | `ConvTranspose1d` | `ConvTranspose2d` | `ConvTranspose3d` |
|
|
119
|
+
| Windowed convolution | `WindowedConv1d` | `WindowedConv2d` | `WindowedConv3d` |
|
|
120
|
+
| Modulated convolution | `ModulatedConv1d` | `ModulatedConv2d` | `ModulatedConv3d` |
|
|
121
|
+
| Upsampling | `Upsample1d` | `Upsample2d` | `Upsample3d` |
|
|
122
|
+
| Branch alignment | `AlignBranches1d` | `AlignBranches2d` | `AlignBranches3d` |
|
|
123
|
+
| Group normalization | `CachedGroupNorm1d` | `CachedGroupNorm2d` | `CachedGroupNorm3d` |
|
|
124
|
+
|
|
125
|
+
Inputs are shaped `(batch, channels, time)`,
|
|
126
|
+
`(batch, channels, height, time)` and `(batch, channels, depth, height, time)`.
|
|
127
|
+
In 2D and 3D, `padding` sets the mode along time; the other axes are always
|
|
128
|
+
padded "same".
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# encoder / decoder; the transposed kernel size along time must be
|
|
132
|
+
# stride + 2 * padding
|
|
133
|
+
down = cc.Conv1d(16, 16, 4, stride=2, padding="same")
|
|
134
|
+
up = cc.ConvTranspose1d(16, 16, 4, stride=2, padding=1,
|
|
135
|
+
cumulative_delay=down.cumulative_delay)
|
|
136
|
+
|
|
137
|
+
# spectrogram convolution (frequency, time), windowed along time only
|
|
138
|
+
conv = cc.WindowedConv2d(1, 16, (3, 33), window=(None, "hann"))
|
|
139
|
+
|
|
140
|
+
# StyleGAN 2 modulation
|
|
141
|
+
mod = cc.ModulatedConv1d(16, 32, 3, padding="same", style_dim=64)
|
|
142
|
+
y = mod(torch.randn(2, 16, 512), torch.randn(2, 64))
|
|
143
|
+
|
|
144
|
+
# upsampling by an integer factor along time
|
|
145
|
+
upsample = cc.Upsample1d(2, mode="linear",
|
|
146
|
+
cumulative_delay=down.cumulative_delay)
|
|
147
|
+
|
|
148
|
+
# residual connection: delays the identity branch to match the convolution
|
|
149
|
+
conv = cc.Conv1d(16, 16, 3, padding="same")
|
|
150
|
+
residual = cc.AlignBranches1d(conv, torch.nn.Identity(),
|
|
151
|
+
delays=[conv.cumulative_delay, 0])
|
|
152
|
+
y_conv, y_identity = residual(torch.randn(1, 16, 512))
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Exporting with TorchScript
|
|
156
|
+
|
|
157
|
+
Caches are allocated on the first call. Run the cached model once before
|
|
158
|
+
scripting it:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
cc.use_cached_conv(True)
|
|
162
|
+
model = build_model().eval()
|
|
163
|
+
|
|
164
|
+
with torch.no_grad():
|
|
165
|
+
model(torch.zeros(1, 1, 512))
|
|
166
|
+
|
|
167
|
+
torch.jit.script(model).save("model.ts")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Caches have room for `max_batch_size` streams (a layer argument). Block
|
|
171
|
+
lengths must be divisible by the model's total stride.
|
|
172
|
+
|
|
173
|
+
## Testing
|
|
174
|
+
|
|
175
|
+
`cc.test_equal` checks that a model gives the same output when streamed as
|
|
176
|
+
when processed offline:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
assert cc.test_equal(build_model, torch.randn(1, 1, 4096))
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
To run the library's test suite, on all available devices:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pip install -e ".[dev]"
|
|
186
|
+
pytest tests
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
To run it against several Python / PyTorch versions with
|
|
190
|
+
[uv](https://docs.astral.sh/uv/):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
./test_versions.sh -p "3.9 3.12" -t "1.13 2.0 latest"
|
|
194
|
+
./test_versions.sh --lowest # oldest torch for each Python version
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`tests/test_audio.py` also writes audio examples to `tests/audio_outputs/`
|
|
198
|
+
(waveforms in 1D, spectrograms in 2D / 3D), in eager and streaming modes.
|
|
199
|
+
|
|
200
|
+
## Documentation
|
|
201
|
+
|
|
202
|
+
The full documentation is on
|
|
203
|
+
[cached-conv.readthedocs.io](https://cached-conv.readthedocs.io). To build it
|
|
204
|
+
locally:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pip install -r docs/requirements.txt
|
|
208
|
+
sphinx-build -b html docs docs/_build/html
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Credits
|
|
212
|
+
|
|
213
|
+
Developed at [ACIDS](https://acids.ircam.fr) (IRCAM) by Axel
|
|
214
|
+
Chemla--Romeu-Santos and Nils Demerlé. Upgrade of the original
|
|
215
|
+
[cached_conv](https://github.com/acids-ircam/cached_conv) package by Antoine
|
|
216
|
+
Caillon (2021).
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
cached_conv/__init__.py,sha256=ipXUyiMTOkIFXC1WZzAag2PDHM79hayQbW58ueiguR8,5548
|
|
2
|
+
cached_conv/conv_1d.py,sha256=cD1crJmtqDoJEiG3kR6_5naah8GUX22VTuAbyoAyGYg,9670
|
|
3
|
+
cached_conv/conv_2d.py,sha256=E5-7imoOXdGYMd_gDNaH3NycL_lA6g5_TWCh7k4kaDQ,6960
|
|
4
|
+
cached_conv/conv_3d.py,sha256=qJyfYpOyQGDpT1C5BkEGPBQClCNC-5rmSHZn0P4qQs8,6662
|
|
5
|
+
cached_conv/upsample.py,sha256=Wh6Ici3Rl16HdDq9rfW7Iw9ZVOBCR4Sh2N7JPpGkBdQ,5913
|
|
6
|
+
cached_conv/utils.py,sha256=IF_8yLADQJUem4609sr6DlQqbTeRxLGmwlfW25B0Vqk,3696
|
|
7
|
+
cached_conv/variants.py,sha256=13hhgctHuv7JLfABQZoZewcVGBSG5cu4VJQ-gt0KqQQ,6126
|
|
8
|
+
acids_cc-3.0.dist-info/METADATA,sha256=sT3H5X7sj2MCzdL1RwDR2Uzl0NtrtfXiEHSus1jD06Q,7641
|
|
9
|
+
acids_cc-3.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
10
|
+
acids_cc-3.0.dist-info/top_level.txt,sha256=eL4WC83WC3L5w7KL96_vqaOwAKWeoW3RgUgi7UhlRos,12
|
|
11
|
+
acids_cc-3.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cached_conv
|
cached_conv/__init__.py
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
|
|
3
|
+
USE_CACHED_CONV = False
|
|
4
|
+
MAX_BATCH_SIZE = 64 # Warning! added for retro-compatibility
|
|
5
|
+
|
|
6
|
+
def use_cached_conv(state: bool):
|
|
7
|
+
global USE_CACHED_CONV
|
|
8
|
+
USE_CACHED_CONV = state
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def is_cached():
|
|
12
|
+
global USE_CACHED_CONV
|
|
13
|
+
return USE_CACHED_CONV
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from .utils import Branches
|
|
17
|
+
from .conv_1d import (get_padding, CachedSequential, Sequential,
|
|
18
|
+
CachedPadding, CachedConv1d, CachedConvTranspose1d,
|
|
19
|
+
CachedGroupNorm, CachedGroupNorm1d)
|
|
20
|
+
from .conv_1d import Conv1d as _Conv1d
|
|
21
|
+
from .conv_1d import ConvTranspose1d as _ConvTranspose1d
|
|
22
|
+
from .conv_1d import AlignBranches1d as _AlignBranches1d
|
|
23
|
+
from .conv_2d import CachedConv2d, CachedConvTranspose2d, CachedGroupNorm2d
|
|
24
|
+
from .conv_2d import Conv2d as _Conv2d
|
|
25
|
+
from .conv_2d import ConvTranspose2d as _ConvTranspose2d
|
|
26
|
+
from .conv_2d import AlignBranches2d as _AlignBranches2d
|
|
27
|
+
from .conv_3d import CachedConv3d, CachedConvTranspose3d, CachedGroupNorm3d
|
|
28
|
+
from .conv_3d import Conv3d as _Conv3d
|
|
29
|
+
from .conv_3d import ConvTranspose3d as _ConvTranspose3d
|
|
30
|
+
from .conv_3d import AlignBranches3d as _AlignBranches3d
|
|
31
|
+
from .variants import (get_window, CachedWindowedConv1d,
|
|
32
|
+
CachedWindowedConv2d, CachedWindowedConv3d,
|
|
33
|
+
CachedModulatedConv1d, CachedModulatedConv2d,
|
|
34
|
+
CachedModulatedConv3d)
|
|
35
|
+
from . import variants as _variants
|
|
36
|
+
from .upsample import CachedUpsample1d, CachedUpsample2d, CachedUpsample3d
|
|
37
|
+
from . import upsample as _upsample
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def chunk_process(f, x, N):
|
|
41
|
+
x = torch.split(x, x.shape[-1] // N, -1)
|
|
42
|
+
y = torch.cat([f(_x) for _x in x], -1)
|
|
43
|
+
return y
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_equal(model_constructor, input_tensor, crop=True):
|
|
47
|
+
initial_state = USE_CACHED_CONV
|
|
48
|
+
|
|
49
|
+
use_cached_conv(False)
|
|
50
|
+
model = model_constructor().to(input_tensor.device)
|
|
51
|
+
use_cached_conv(True)
|
|
52
|
+
cmodel = model_constructor().to(input_tensor.device)
|
|
53
|
+
|
|
54
|
+
for p1, p2 in zip(model.parameters(), cmodel.parameters()):
|
|
55
|
+
p2.data.copy_(p1.data)
|
|
56
|
+
|
|
57
|
+
cd = cmodel.cumulative_delay
|
|
58
|
+
if cd > 0:
|
|
59
|
+
y = model(input_tensor)[..., :-cd]
|
|
60
|
+
else:
|
|
61
|
+
y = model(input_tensor)
|
|
62
|
+
cy = chunk_process(lambda x: cmodel(x), input_tensor, 4)[..., cd:]
|
|
63
|
+
|
|
64
|
+
if crop and cd > 0:
|
|
65
|
+
y = y[..., cd:-cd]
|
|
66
|
+
cy = cy[..., cd:-cd]
|
|
67
|
+
|
|
68
|
+
use_cached_conv(initial_state)
|
|
69
|
+
return torch.allclose(y, cy, 1e-4, 1e-4)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def Conv1d(*args, **kwargs):
|
|
73
|
+
if USE_CACHED_CONV:
|
|
74
|
+
return CachedConv1d(*args, **kwargs)
|
|
75
|
+
else:
|
|
76
|
+
return _Conv1d(*args, **kwargs)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def ConvTranspose1d(*args, **kwargs):
|
|
80
|
+
if USE_CACHED_CONV:
|
|
81
|
+
return CachedConvTranspose1d(*args, **kwargs)
|
|
82
|
+
else:
|
|
83
|
+
return _ConvTranspose1d(*args, **kwargs)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def AlignBranches1d(*args, **kwargs):
|
|
87
|
+
if USE_CACHED_CONV:
|
|
88
|
+
return _AlignBranches1d(*args, **kwargs)
|
|
89
|
+
else:
|
|
90
|
+
return Branches(*args, **kwargs)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# backward-compatible alias
|
|
94
|
+
def AlignBranches(*args, **kwargs):
|
|
95
|
+
return AlignBranches1d(*args, **kwargs)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def Conv2d(*args, **kwargs):
|
|
99
|
+
if USE_CACHED_CONV:
|
|
100
|
+
return CachedConv2d(*args, **kwargs)
|
|
101
|
+
else:
|
|
102
|
+
return _Conv2d(*args, **kwargs)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def ConvTranspose2d(*args, **kwargs):
|
|
106
|
+
if USE_CACHED_CONV:
|
|
107
|
+
return CachedConvTranspose2d(*args, **kwargs)
|
|
108
|
+
else:
|
|
109
|
+
return _ConvTranspose2d(*args, **kwargs)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def AlignBranches2d(*args, **kwargs):
|
|
113
|
+
if USE_CACHED_CONV:
|
|
114
|
+
return _AlignBranches2d(*args, **kwargs)
|
|
115
|
+
else:
|
|
116
|
+
return Branches(*args, **kwargs)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def Conv3d(*args, **kwargs):
|
|
120
|
+
if USE_CACHED_CONV:
|
|
121
|
+
return CachedConv3d(*args, **kwargs)
|
|
122
|
+
else:
|
|
123
|
+
return _Conv3d(*args, **kwargs)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def ConvTranspose3d(*args, **kwargs):
|
|
127
|
+
if USE_CACHED_CONV:
|
|
128
|
+
return CachedConvTranspose3d(*args, **kwargs)
|
|
129
|
+
else:
|
|
130
|
+
return _ConvTranspose3d(*args, **kwargs)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def AlignBranches3d(*args, **kwargs):
|
|
134
|
+
if USE_CACHED_CONV:
|
|
135
|
+
return _AlignBranches3d(*args, **kwargs)
|
|
136
|
+
else:
|
|
137
|
+
return Branches(*args, **kwargs)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def WindowedConv1d(*args, **kwargs):
|
|
141
|
+
if USE_CACHED_CONV:
|
|
142
|
+
return CachedWindowedConv1d(*args, **kwargs)
|
|
143
|
+
else:
|
|
144
|
+
return _variants.WindowedConv1d(*args, **kwargs)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def WindowedConv2d(*args, **kwargs):
|
|
148
|
+
if USE_CACHED_CONV:
|
|
149
|
+
return CachedWindowedConv2d(*args, **kwargs)
|
|
150
|
+
else:
|
|
151
|
+
return _variants.WindowedConv2d(*args, **kwargs)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def WindowedConv3d(*args, **kwargs):
|
|
155
|
+
if USE_CACHED_CONV:
|
|
156
|
+
return CachedWindowedConv3d(*args, **kwargs)
|
|
157
|
+
else:
|
|
158
|
+
return _variants.WindowedConv3d(*args, **kwargs)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def ModulatedConv1d(*args, **kwargs):
|
|
162
|
+
if USE_CACHED_CONV:
|
|
163
|
+
return CachedModulatedConv1d(*args, **kwargs)
|
|
164
|
+
else:
|
|
165
|
+
return _variants.ModulatedConv1d(*args, **kwargs)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def ModulatedConv2d(*args, **kwargs):
|
|
169
|
+
if USE_CACHED_CONV:
|
|
170
|
+
return CachedModulatedConv2d(*args, **kwargs)
|
|
171
|
+
else:
|
|
172
|
+
return _variants.ModulatedConv2d(*args, **kwargs)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def ModulatedConv3d(*args, **kwargs):
|
|
176
|
+
if USE_CACHED_CONV:
|
|
177
|
+
return CachedModulatedConv3d(*args, **kwargs)
|
|
178
|
+
else:
|
|
179
|
+
return _variants.ModulatedConv3d(*args, **kwargs)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def Upsample1d(*args, **kwargs):
|
|
183
|
+
if USE_CACHED_CONV:
|
|
184
|
+
return CachedUpsample1d(*args, **kwargs)
|
|
185
|
+
else:
|
|
186
|
+
return _upsample.Upsample1d(*args, **kwargs)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def Upsample2d(*args, **kwargs):
|
|
190
|
+
if USE_CACHED_CONV:
|
|
191
|
+
return CachedUpsample2d(*args, **kwargs)
|
|
192
|
+
else:
|
|
193
|
+
return _upsample.Upsample2d(*args, **kwargs)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def Upsample3d(*args, **kwargs):
|
|
197
|
+
if USE_CACHED_CONV:
|
|
198
|
+
return CachedUpsample3d(*args, **kwargs)
|
|
199
|
+
else:
|
|
200
|
+
return _upsample.Upsample3d(*args, **kwargs)
|