Vansh Chugh commited on
Commit
ee2c2c5
·
1 Parent(s): f06c181

move to zerogpu

Browse files
.gitignore CHANGED
@@ -1,2 +1,4 @@
1
  __pycache__/
2
  *.pyc
 
 
 
1
  __pycache__/
2
  *.pyc
3
+ .venv/
4
+ .gradio/
SOURCES.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Sources — BUDDy
2
+
3
+ - Source repo: https://github.com/sp-uhh/buddy.git
app.py CHANGED
@@ -1,23 +1,24 @@
1
  import sys
2
  sys.stdout.reconfigure(line_buffering=True) # real-time logs in HF Spaces
3
 
 
 
 
 
 
 
4
  import contextlib
5
  import tempfile
6
  import threading
7
  import traceback
8
 
 
9
  import torch
10
  import torchaudio
11
  from omegaconf import OmegaConf
12
  import gradio as gr
13
  from pyharp import ModelCard, build_endpoint
14
 
15
- try:
16
- import spaces
17
- def gpu_decorator(func): return spaces.GPU(func)
18
- except ImportError:
19
- def gpu_decorator(func): return func
20
-
21
  # ---- Paths and device ----
22
  CKPT_PATH = "pretrained/VCTK_16k_4s_time-190000.pt"
23
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
@@ -34,6 +35,7 @@ AUDIO_LEN = ARGS.exp.audio_len
34
  sampler = None
35
  model_loading = True
36
  model_error = None
 
37
 
38
  def load_model():
39
  global sampler, model_loading, model_error
@@ -50,11 +52,13 @@ def load_model():
50
  network_cfg = OmegaConf.load("config/network.yaml")
51
  # stft stays as OmegaConf — NCSNppTime uses dot access on it (stft_kwargs.n_fft)
52
  stft_cfg = network_cfg.pop("stft")
53
- network = NCSNppTime(stft=stft_cfg, **OmegaConf.to_container(network_cfg)).to(DEVICE)
 
 
54
 
55
  # load_state_dict tries multiple key strategies ('ema', 'model', etc.)
56
  # to handle checkpoints saved in different formats
57
- state_dict = torch.load(CKPT_PATH, map_location=DEVICE, weights_only=False)
58
  load_state_dict(state_dict, ema=network)
59
  network.eval()
60
 
@@ -88,17 +92,23 @@ model_card = ModelCard(
88
  # ---- Inference ----
89
  @gpu_decorator
90
  def process_fn(input_audio_path: str, num_steps: int):
 
91
  if model_loading:
92
  raise gr.Error("Model is still loading, please wait a moment and try again.")
93
  if sampler is None:
94
  raise gr.Error(f"Model failed to load: {model_error}")
 
 
 
95
 
96
  from testing.operators.subband_filtering import BlindSubbandFiltering
97
 
98
  # Update step count from slider — also update args so get_gamma() uses the right T
99
  sampler.T = num_steps
100
 
101
- waveform, sr = torchaudio.load(input_audio_path)
 
 
102
 
103
  # resampling to 16kHz
104
  if sr != SAMPLE_RATE:
@@ -130,12 +140,12 @@ def process_fn(input_audio_path: str, num_steps: int):
130
  pred = sampler.predict_conditional(y, operator, shape=(1, AUDIO_LEN), blind=True)
131
 
132
  pred = pred.detach().cpu()
133
- if pred.dim() == 1:
134
- pred = pred.unsqueeze(0)
135
 
136
  with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
137
  out_path = f.name
138
- torchaudio.save(out_path, pred, SAMPLE_RATE)
139
  return out_path
140
 
141
 
@@ -164,4 +174,5 @@ with gr.Blocks() as demo:
164
  process_fn=process_fn,
165
  )
166
 
167
- demo.queue().launch(share=True, show_error=True, pwa=True)
 
 
1
  import sys
2
  sys.stdout.reconfigure(line_buffering=True) # real-time logs in HF Spaces
3
 
4
+ try:
5
+ import spaces
6
+ def gpu_decorator(func): return spaces.GPU(func)
7
+ except ImportError:
8
+ def gpu_decorator(func): return func
9
+
10
  import contextlib
11
  import tempfile
12
  import threading
13
  import traceback
14
 
15
+ import soundfile as sf
16
  import torch
17
  import torchaudio
18
  from omegaconf import OmegaConf
19
  import gradio as gr
20
  from pyharp import ModelCard, build_endpoint
21
 
 
 
 
 
 
 
22
  # ---- Paths and device ----
23
  CKPT_PATH = "pretrained/VCTK_16k_4s_time-190000.pt"
24
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
 
35
  sampler = None
36
  model_loading = True
37
  model_error = None
38
+ model_ready = False # has the network been moved onto the GPU yet?
39
 
40
  def load_model():
41
  global sampler, model_loading, model_error
 
52
  network_cfg = OmegaConf.load("config/network.yaml")
53
  # stft stays as OmegaConf — NCSNppTime uses dot access on it (stft_kwargs.n_fft)
54
  stft_cfg = network_cfg.pop("stft")
55
+ # built on CPU — ZeroGPU only intercepts CUDA calls inside an
56
+ # @spaces.GPU-decorated call, not from this background thread
57
+ network = NCSNppTime(stft=stft_cfg, **OmegaConf.to_container(network_cfg))
58
 
59
  # load_state_dict tries multiple key strategies ('ema', 'model', etc.)
60
  # to handle checkpoints saved in different formats
61
+ state_dict = torch.load(CKPT_PATH, map_location="cpu", weights_only=False)
62
  load_state_dict(state_dict, ema=network)
63
  network.eval()
64
 
 
92
  # ---- Inference ----
93
  @gpu_decorator
94
  def process_fn(input_audio_path: str, num_steps: int):
95
+ global model_ready
96
  if model_loading:
97
  raise gr.Error("Model is still loading, please wait a moment and try again.")
98
  if sampler is None:
99
  raise gr.Error(f"Model failed to load: {model_error}")
100
+ if not model_ready:
101
+ sampler.model.to(DEVICE) # only safe here, inside @spaces.GPU
102
+ model_ready = True
103
 
104
  from testing.operators.subband_filtering import BlindSubbandFiltering
105
 
106
  # Update step count from slider — also update args so get_gamma() uses the right T
107
  sampler.T = num_steps
108
 
109
+ # using soundfile directly — torchaudio.load/save need torchcodec, which isn't installed
110
+ data, sr = sf.read(input_audio_path)
111
+ waveform = torch.tensor(data.T if data.ndim > 1 else data[None]).float() # (channels, samples)
112
 
113
  # resampling to 16kHz
114
  if sr != SAMPLE_RATE:
 
140
  pred = sampler.predict_conditional(y, operator, shape=(1, AUDIO_LEN), blind=True)
141
 
142
  pred = pred.detach().cpu()
143
+ if pred.dim() > 1:
144
+ pred = pred.squeeze(0)
145
 
146
  with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
147
  out_path = f.name
148
+ sf.write(out_path, pred.numpy(), SAMPLE_RATE)
149
  return out_path
150
 
151
 
 
174
  process_fn=process_fn,
175
  )
176
 
177
+ if __name__ == "__main__":
178
+ demo.queue().launch(share=True, show_error=True, pwa=True)
model.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "BUDDy",
3
+ "local_smoke_threshold_gb": 5,
4
+ "package_dir": ".",
5
+ "entry_point": [
6
+ "networks.ncsnpp.NCSNppTime",
7
+ "diff_params.edm.EDM",
8
+ "utils.training_utils.load_state_dict",
9
+ "testing.EulerHeunSamplerDPS.EulerHeunSamplerDPS",
10
+ "testing.operators.subband_filtering.BlindSubbandFiltering"
11
+ ],
12
+ "checkpoint": {"location": "pretrained/VCTK_16k_4s_time-190000.pt", "size_mb": 424}
13
+ }
networks/ncsnpp_utils/op/__init__.py DELETED
@@ -1,2 +0,0 @@
1
- # from .fused_act import FusedLeakyReLU, fused_leaky_relu
2
- from .upfirdn2d import upfirdn2d, upfirdn1d
 
 
 
networks/ncsnpp_utils/op/upfirdn2d.cpp DELETED
@@ -1,23 +0,0 @@
1
- #include <torch/extension.h>
2
-
3
-
4
- torch::Tensor upfirdn2d_op(const torch::Tensor& input, const torch::Tensor& kernel,
5
- int up_x, int up_y, int down_x, int down_y,
6
- int pad_x0, int pad_x1, int pad_y0, int pad_y1);
7
-
8
- #define CHECK_CUDA(x) TORCH_CHECK(x.type().is_cuda(), #x " must be a CUDA tensor")
9
- #define CHECK_CONTIGUOUS(x) TORCH_CHECK(x.is_contiguous(), #x " must be contiguous")
10
- #define CHECK_INPUT(x) CHECK_CUDA(x); CHECK_CONTIGUOUS(x)
11
-
12
- torch::Tensor upfirdn2d(const torch::Tensor& input, const torch::Tensor& kernel,
13
- int up_x, int up_y, int down_x, int down_y,
14
- int pad_x0, int pad_x1, int pad_y0, int pad_y1) {
15
- CHECK_CUDA(input);
16
- CHECK_CUDA(kernel);
17
-
18
- return upfirdn2d_op(input, kernel, up_x, up_y, down_x, down_y, pad_x0, pad_x1, pad_y0, pad_y1);
19
- }
20
-
21
- PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
22
- m.def("upfirdn2d", &upfirdn2d, "upfirdn2d (CUDA)");
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
networks/ncsnpp_utils/op/upfirdn2d.py DELETED
@@ -1,212 +0,0 @@
1
- import os
2
-
3
- import torch
4
- from torch.nn import functional as F
5
- from torch.autograd import Function
6
- from torch.utils.cpp_extension import load
7
-
8
-
9
- module_path = os.path.dirname(__file__)
10
- upfirdn2d_op = load(
11
- "upfirdn2d",
12
- sources=[
13
- os.path.join(module_path, "upfirdn2d.cpp"),
14
- os.path.join(module_path, "upfirdn2d_kernel.cu"),
15
- ],
16
- )
17
-
18
-
19
- class UpFirDn2dBackward(Function):
20
- @staticmethod
21
- def forward(
22
- ctx, grad_output, kernel, grad_kernel, up, down, pad, g_pad, in_size, out_size
23
- ):
24
-
25
- up_x, up_y = up
26
- down_x, down_y = down
27
- g_pad_x0, g_pad_x1, g_pad_y0, g_pad_y1 = g_pad
28
-
29
- grad_output = grad_output.reshape(-1, out_size[0], out_size[1], 1)
30
-
31
- grad_input = upfirdn2d_op.upfirdn2d(
32
- grad_output,
33
- grad_kernel,
34
- down_x,
35
- down_y,
36
- up_x,
37
- up_y,
38
- g_pad_x0,
39
- g_pad_x1,
40
- g_pad_y0,
41
- g_pad_y1,
42
- )
43
- grad_input = grad_input.view(in_size[0], in_size[1], in_size[2], in_size[3])
44
-
45
- ctx.save_for_backward(kernel)
46
-
47
- pad_x0, pad_x1, pad_y0, pad_y1 = pad
48
-
49
- ctx.up_x = up_x
50
- ctx.up_y = up_y
51
- ctx.down_x = down_x
52
- ctx.down_y = down_y
53
- ctx.pad_x0 = pad_x0
54
- ctx.pad_x1 = pad_x1
55
- ctx.pad_y0 = pad_y0
56
- ctx.pad_y1 = pad_y1
57
- ctx.in_size = in_size
58
- ctx.out_size = out_size
59
-
60
- return grad_input
61
-
62
- @staticmethod
63
- def backward(ctx, gradgrad_input):
64
- kernel, = ctx.saved_tensors
65
-
66
- gradgrad_input = gradgrad_input.reshape(-1, ctx.in_size[2], ctx.in_size[3], 1)
67
-
68
- gradgrad_out = upfirdn2d_op.upfirdn2d(
69
- gradgrad_input,
70
- kernel,
71
- ctx.up_x,
72
- ctx.up_y,
73
- ctx.down_x,
74
- ctx.down_y,
75
- ctx.pad_x0,
76
- ctx.pad_x1,
77
- ctx.pad_y0,
78
- ctx.pad_y1,
79
- )
80
- # gradgrad_out = gradgrad_out.view(ctx.in_size[0], ctx.out_size[0], ctx.out_size[1], ctx.in_size[3])
81
- gradgrad_out = gradgrad_out.view(
82
- ctx.in_size[0], ctx.in_size[1], ctx.out_size[0], ctx.out_size[1]
83
- )
84
-
85
- return gradgrad_out, None, None, None, None, None, None, None, None
86
-
87
-
88
- class UpFirDn2d(Function):
89
- @staticmethod
90
- def forward(ctx, input, kernel, up, down, pad):
91
- up_x, up_y = up
92
- down_x, down_y = down
93
- pad_x0, pad_x1, pad_y0, pad_y1 = pad
94
-
95
- kernel_h, kernel_w = kernel.shape
96
- batch, channel, in_h, in_w = input.shape
97
- ctx.in_size = input.shape
98
-
99
- input = input.reshape(-1, in_h, in_w, 1)
100
-
101
- ctx.save_for_backward(kernel, torch.flip(kernel, [0, 1]))
102
-
103
- out_h = (in_h * up_y + pad_y0 + pad_y1 - kernel_h) // down_y + 1
104
- out_w = (in_w * up_x + pad_x0 + pad_x1 - kernel_w) // down_x + 1
105
- ctx.out_size = (out_h, out_w)
106
-
107
- ctx.up = (up_x, up_y)
108
- ctx.down = (down_x, down_y)
109
- ctx.pad = (pad_x0, pad_x1, pad_y0, pad_y1)
110
-
111
- g_pad_x0 = kernel_w - pad_x0 - 1
112
- g_pad_y0 = kernel_h - pad_y0 - 1
113
- g_pad_x1 = in_w * up_x - out_w * down_x + pad_x0 - up_x + 1
114
- g_pad_y1 = in_h * up_y - out_h * down_y + pad_y0 - up_y + 1
115
-
116
- ctx.g_pad = (g_pad_x0, g_pad_x1, g_pad_y0, g_pad_y1)
117
-
118
- out = upfirdn2d_op.upfirdn2d(
119
- input, kernel, up_x, up_y, down_x, down_y, pad_x0, pad_x1, pad_y0, pad_y1
120
- )
121
- # out = out.view(major, out_h, out_w, minor)
122
- out = out.view(-1, channel, out_h, out_w)
123
-
124
- return out
125
-
126
- @staticmethod
127
- def backward(ctx, grad_output):
128
- kernel, grad_kernel = ctx.saved_tensors
129
-
130
- grad_input = UpFirDn2dBackward.apply(
131
- grad_output,
132
- kernel,
133
- grad_kernel,
134
- ctx.up,
135
- ctx.down,
136
- ctx.pad,
137
- ctx.g_pad,
138
- ctx.in_size,
139
- ctx.out_size,
140
- )
141
-
142
- return grad_input, None, None, None, None
143
-
144
-
145
- def upfirdn2d(input, kernel, up=1, down=1, pad=(0, 0)):
146
- if input.device.type == "cpu":
147
- out = upfirdn2d_native(
148
- input, kernel, up, up, down, down, pad[0], pad[1], pad[0], pad[1]
149
- )
150
-
151
- else:
152
- out = UpFirDn2d.apply(
153
- input, kernel, (up, up), (down, down), (pad[0], pad[1], pad[0], pad[1])
154
- )
155
-
156
- return out
157
-
158
- def upfirdn1d(input, kernel, up_x=1, up_y=1, down_x=1, down_y=1, pad_x0=0, pad_x1=0, pad_y0=0, pad_y1=0):
159
- if input.device.type == "cpu":
160
- out = upfirdn2d_native(
161
- input, kernel, up_x, up_y, down_x, down_y, pad_x0, pad_x1, pad_y0, pad_y1
162
- )
163
-
164
- else:
165
- out = UpFirDn2d.apply(
166
- input, kernel, (up_x, up_y), (down_x, down_y), (pad_x0, pad_x1, pad_y0, pad_y1)
167
- )
168
-
169
- return out
170
-
171
- def upfirdn2d_native(
172
- input, kernel, up_x, up_y, down_x, down_y, pad_x0, pad_x1, pad_y0, pad_y1
173
- ):
174
- _, channel, in_h, in_w = input.shape
175
- input = input.reshape(-1, in_h, in_w, 1)
176
-
177
- _, in_h, in_w, minor = input.shape
178
- kernel_h, kernel_w = kernel.shape
179
-
180
- out = input.view(-1, in_h, 1, in_w, 1, minor)
181
- out = F.pad(out, [0, 0, 0, up_x - 1, 0, 0, 0, up_y - 1])
182
- out = out.view(-1, in_h * up_y, in_w * up_x, minor)
183
-
184
- out = F.pad(
185
- out, [0, 0, max(pad_x0, 0), max(pad_x1, 0), max(pad_y0, 0), max(pad_y1, 0)]
186
- )
187
- out = out[
188
- :,
189
- max(-pad_y0, 0) : out.shape[1] - max(-pad_y1, 0),
190
- max(-pad_x0, 0) : out.shape[2] - max(-pad_x1, 0),
191
- :,
192
- ]
193
-
194
- out = out.permute(0, 3, 1, 2)
195
- out = out.reshape(
196
- [-1, 1, in_h * up_y + pad_y0 + pad_y1, in_w * up_x + pad_x0 + pad_x1]
197
- )
198
- w = torch.flip(kernel, [0, 1]).view(1, 1, kernel_h, kernel_w)
199
- out = F.conv2d(out, w)
200
- out = out.reshape(
201
- -1,
202
- minor,
203
- in_h * up_y + pad_y0 + pad_y1 - kernel_h + 1,
204
- in_w * up_x + pad_x0 + pad_x1 - kernel_w + 1,
205
- )
206
- out = out.permute(0, 2, 3, 1)
207
- out = out[:, ::down_y, ::down_x, :]
208
-
209
- out_h = (in_h * up_y + pad_y0 + pad_y1 - kernel_h) // down_y + 1
210
- out_w = (in_w * up_x + pad_x0 + pad_x1 - kernel_w) // down_x + 1
211
-
212
- return out.view(-1, channel, out_h, out_w)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
networks/ncsnpp_utils/op/upfirdn2d_kernel.cu DELETED
@@ -1,369 +0,0 @@
1
- // Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
2
- //
3
- // This work is made available under the Nvidia Source Code License-NC.
4
- // To view a copy of this license, visit
5
- // https://nvlabs.github.io/stylegan2/license.html
6
-
7
- #include <torch/types.h>
8
-
9
- #include <ATen/ATen.h>
10
- #include <ATen/AccumulateType.h>
11
- #include <ATen/cuda/CUDAApplyUtils.cuh>
12
- #include <ATen/cuda/CUDAContext.h>
13
-
14
- #include <cuda.h>
15
- #include <cuda_runtime.h>
16
-
17
- static __host__ __device__ __forceinline__ int floor_div(int a, int b) {
18
- int c = a / b;
19
-
20
- if (c * b > a) {
21
- c--;
22
- }
23
-
24
- return c;
25
- }
26
-
27
- struct UpFirDn2DKernelParams {
28
- int up_x;
29
- int up_y;
30
- int down_x;
31
- int down_y;
32
- int pad_x0;
33
- int pad_x1;
34
- int pad_y0;
35
- int pad_y1;
36
-
37
- int major_dim;
38
- int in_h;
39
- int in_w;
40
- int minor_dim;
41
- int kernel_h;
42
- int kernel_w;
43
- int out_h;
44
- int out_w;
45
- int loop_major;
46
- int loop_x;
47
- };
48
-
49
- template <typename scalar_t>
50
- __global__ void upfirdn2d_kernel_large(scalar_t *out, const scalar_t *input,
51
- const scalar_t *kernel,
52
- const UpFirDn2DKernelParams p) {
53
- int minor_idx = blockIdx.x * blockDim.x + threadIdx.x;
54
- int out_y = minor_idx / p.minor_dim;
55
- minor_idx -= out_y * p.minor_dim;
56
- int out_x_base = blockIdx.y * p.loop_x * blockDim.y + threadIdx.y;
57
- int major_idx_base = blockIdx.z * p.loop_major;
58
-
59
- if (out_x_base >= p.out_w || out_y >= p.out_h ||
60
- major_idx_base >= p.major_dim) {
61
- return;
62
- }
63
-
64
- int mid_y = out_y * p.down_y + p.up_y - 1 - p.pad_y0;
65
- int in_y = min(max(floor_div(mid_y, p.up_y), 0), p.in_h);
66
- int h = min(max(floor_div(mid_y + p.kernel_h, p.up_y), 0), p.in_h) - in_y;
67
- int kernel_y = mid_y + p.kernel_h - (in_y + 1) * p.up_y;
68
-
69
- for (int loop_major = 0, major_idx = major_idx_base;
70
- loop_major < p.loop_major && major_idx < p.major_dim;
71
- loop_major++, major_idx++) {
72
- for (int loop_x = 0, out_x = out_x_base;
73
- loop_x < p.loop_x && out_x < p.out_w; loop_x++, out_x += blockDim.y) {
74
- int mid_x = out_x * p.down_x + p.up_x - 1 - p.pad_x0;
75
- int in_x = min(max(floor_div(mid_x, p.up_x), 0), p.in_w);
76
- int w = min(max(floor_div(mid_x + p.kernel_w, p.up_x), 0), p.in_w) - in_x;
77
- int kernel_x = mid_x + p.kernel_w - (in_x + 1) * p.up_x;
78
-
79
- const scalar_t *x_p =
80
- &input[((major_idx * p.in_h + in_y) * p.in_w + in_x) * p.minor_dim +
81
- minor_idx];
82
- const scalar_t *k_p = &kernel[kernel_y * p.kernel_w + kernel_x];
83
- int x_px = p.minor_dim;
84
- int k_px = -p.up_x;
85
- int x_py = p.in_w * p.minor_dim;
86
- int k_py = -p.up_y * p.kernel_w;
87
-
88
- scalar_t v = 0.0f;
89
-
90
- for (int y = 0; y < h; y++) {
91
- for (int x = 0; x < w; x++) {
92
- v += static_cast<scalar_t>(*x_p) * static_cast<scalar_t>(*k_p);
93
- x_p += x_px;
94
- k_p += k_px;
95
- }
96
-
97
- x_p += x_py - w * x_px;
98
- k_p += k_py - w * k_px;
99
- }
100
-
101
- out[((major_idx * p.out_h + out_y) * p.out_w + out_x) * p.minor_dim +
102
- minor_idx] = v;
103
- }
104
- }
105
- }
106
-
107
- template <typename scalar_t, int up_x, int up_y, int down_x, int down_y,
108
- int kernel_h, int kernel_w, int tile_out_h, int tile_out_w>
109
- __global__ void upfirdn2d_kernel(scalar_t *out, const scalar_t *input,
110
- const scalar_t *kernel,
111
- const UpFirDn2DKernelParams p) {
112
- const int tile_in_h = ((tile_out_h - 1) * down_y + kernel_h - 1) / up_y + 1;
113
- const int tile_in_w = ((tile_out_w - 1) * down_x + kernel_w - 1) / up_x + 1;
114
-
115
- __shared__ volatile float sk[kernel_h][kernel_w];
116
- __shared__ volatile float sx[tile_in_h][tile_in_w];
117
-
118
- int minor_idx = blockIdx.x;
119
- int tile_out_y = minor_idx / p.minor_dim;
120
- minor_idx -= tile_out_y * p.minor_dim;
121
- tile_out_y *= tile_out_h;
122
- int tile_out_x_base = blockIdx.y * p.loop_x * tile_out_w;
123
- int major_idx_base = blockIdx.z * p.loop_major;
124
-
125
- if (tile_out_x_base >= p.out_w | tile_out_y >= p.out_h |
126
- major_idx_base >= p.major_dim) {
127
- return;
128
- }
129
-
130
- for (int tap_idx = threadIdx.x; tap_idx < kernel_h * kernel_w;
131
- tap_idx += blockDim.x) {
132
- int ky = tap_idx / kernel_w;
133
- int kx = tap_idx - ky * kernel_w;
134
- scalar_t v = 0.0;
135
-
136
- if (kx < p.kernel_w & ky < p.kernel_h) {
137
- v = kernel[(p.kernel_h - 1 - ky) * p.kernel_w + (p.kernel_w - 1 - kx)];
138
- }
139
-
140
- sk[ky][kx] = v;
141
- }
142
-
143
- for (int loop_major = 0, major_idx = major_idx_base;
144
- loop_major < p.loop_major & major_idx < p.major_dim;
145
- loop_major++, major_idx++) {
146
- for (int loop_x = 0, tile_out_x = tile_out_x_base;
147
- loop_x < p.loop_x & tile_out_x < p.out_w;
148
- loop_x++, tile_out_x += tile_out_w) {
149
- int tile_mid_x = tile_out_x * down_x + up_x - 1 - p.pad_x0;
150
- int tile_mid_y = tile_out_y * down_y + up_y - 1 - p.pad_y0;
151
- int tile_in_x = floor_div(tile_mid_x, up_x);
152
- int tile_in_y = floor_div(tile_mid_y, up_y);
153
-
154
- __syncthreads();
155
-
156
- for (int in_idx = threadIdx.x; in_idx < tile_in_h * tile_in_w;
157
- in_idx += blockDim.x) {
158
- int rel_in_y = in_idx / tile_in_w;
159
- int rel_in_x = in_idx - rel_in_y * tile_in_w;
160
- int in_x = rel_in_x + tile_in_x;
161
- int in_y = rel_in_y + tile_in_y;
162
-
163
- scalar_t v = 0.0;
164
-
165
- if (in_x >= 0 & in_y >= 0 & in_x < p.in_w & in_y < p.in_h) {
166
- v = input[((major_idx * p.in_h + in_y) * p.in_w + in_x) *
167
- p.minor_dim +
168
- minor_idx];
169
- }
170
-
171
- sx[rel_in_y][rel_in_x] = v;
172
- }
173
-
174
- __syncthreads();
175
- for (int out_idx = threadIdx.x; out_idx < tile_out_h * tile_out_w;
176
- out_idx += blockDim.x) {
177
- int rel_out_y = out_idx / tile_out_w;
178
- int rel_out_x = out_idx - rel_out_y * tile_out_w;
179
- int out_x = rel_out_x + tile_out_x;
180
- int out_y = rel_out_y + tile_out_y;
181
-
182
- int mid_x = tile_mid_x + rel_out_x * down_x;
183
- int mid_y = tile_mid_y + rel_out_y * down_y;
184
- int in_x = floor_div(mid_x, up_x);
185
- int in_y = floor_div(mid_y, up_y);
186
- int rel_in_x = in_x - tile_in_x;
187
- int rel_in_y = in_y - tile_in_y;
188
- int kernel_x = (in_x + 1) * up_x - mid_x - 1;
189
- int kernel_y = (in_y + 1) * up_y - mid_y - 1;
190
-
191
- scalar_t v = 0.0;
192
-
193
- #pragma unroll
194
- for (int y = 0; y < kernel_h / up_y; y++)
195
- #pragma unroll
196
- for (int x = 0; x < kernel_w / up_x; x++)
197
- v += sx[rel_in_y + y][rel_in_x + x] *
198
- sk[kernel_y + y * up_y][kernel_x + x * up_x];
199
-
200
- if (out_x < p.out_w & out_y < p.out_h) {
201
- out[((major_idx * p.out_h + out_y) * p.out_w + out_x) * p.minor_dim +
202
- minor_idx] = v;
203
- }
204
- }
205
- }
206
- }
207
- }
208
-
209
- torch::Tensor upfirdn2d_op(const torch::Tensor &input,
210
- const torch::Tensor &kernel, int up_x, int up_y,
211
- int down_x, int down_y, int pad_x0, int pad_x1,
212
- int pad_y0, int pad_y1) {
213
- int curDevice = -1;
214
- cudaGetDevice(&curDevice);
215
- cudaStream_t stream = at::cuda::getCurrentCUDAStream(curDevice);
216
-
217
- UpFirDn2DKernelParams p;
218
-
219
- auto x = input.contiguous();
220
- auto k = kernel.contiguous();
221
-
222
- p.major_dim = x.size(0);
223
- p.in_h = x.size(1);
224
- p.in_w = x.size(2);
225
- p.minor_dim = x.size(3);
226
- p.kernel_h = k.size(0);
227
- p.kernel_w = k.size(1);
228
- p.up_x = up_x;
229
- p.up_y = up_y;
230
- p.down_x = down_x;
231
- p.down_y = down_y;
232
- p.pad_x0 = pad_x0;
233
- p.pad_x1 = pad_x1;
234
- p.pad_y0 = pad_y0;
235
- p.pad_y1 = pad_y1;
236
-
237
- p.out_h = (p.in_h * p.up_y + p.pad_y0 + p.pad_y1 - p.kernel_h + p.down_y) /
238
- p.down_y;
239
- p.out_w = (p.in_w * p.up_x + p.pad_x0 + p.pad_x1 - p.kernel_w + p.down_x) /
240
- p.down_x;
241
-
242
- auto out =
243
- at::empty({p.major_dim, p.out_h, p.out_w, p.minor_dim}, x.options());
244
-
245
- int mode = -1;
246
-
247
- int tile_out_h = -1;
248
- int tile_out_w = -1;
249
-
250
- if (p.up_x == 1 && p.up_y == 1 && p.down_x == 1 && p.down_y == 1 &&
251
- p.kernel_h <= 4 && p.kernel_w <= 4) {
252
- mode = 1;
253
- tile_out_h = 16;
254
- tile_out_w = 64;
255
- }
256
-
257
- if (p.up_x == 1 && p.up_y == 1 && p.down_x == 1 && p.down_y == 1 &&
258
- p.kernel_h <= 3 && p.kernel_w <= 3) {
259
- mode = 2;
260
- tile_out_h = 16;
261
- tile_out_w = 64;
262
- }
263
-
264
- if (p.up_x == 2 && p.up_y == 2 && p.down_x == 1 && p.down_y == 1 &&
265
- p.kernel_h <= 4 && p.kernel_w <= 4) {
266
- mode = 3;
267
- tile_out_h = 16;
268
- tile_out_w = 64;
269
- }
270
-
271
- if (p.up_x == 2 && p.up_y == 2 && p.down_x == 1 && p.down_y == 1 &&
272
- p.kernel_h <= 2 && p.kernel_w <= 2) {
273
- mode = 4;
274
- tile_out_h = 16;
275
- tile_out_w = 64;
276
- }
277
-
278
- if (p.up_x == 1 && p.up_y == 1 && p.down_x == 2 && p.down_y == 2 &&
279
- p.kernel_h <= 4 && p.kernel_w <= 4) {
280
- mode = 5;
281
- tile_out_h = 8;
282
- tile_out_w = 32;
283
- }
284
-
285
- if (p.up_x == 1 && p.up_y == 1 && p.down_x == 2 && p.down_y == 2 &&
286
- p.kernel_h <= 2 && p.kernel_w <= 2) {
287
- mode = 6;
288
- tile_out_h = 8;
289
- tile_out_w = 32;
290
- }
291
-
292
- dim3 block_size;
293
- dim3 grid_size;
294
-
295
- if (tile_out_h > 0 && tile_out_w > 0) {
296
- p.loop_major = (p.major_dim - 1) / 16384 + 1;
297
- p.loop_x = 1;
298
- block_size = dim3(32 * 8, 1, 1);
299
- grid_size = dim3(((p.out_h - 1) / tile_out_h + 1) * p.minor_dim,
300
- (p.out_w - 1) / (p.loop_x * tile_out_w) + 1,
301
- (p.major_dim - 1) / p.loop_major + 1);
302
- } else {
303
- p.loop_major = (p.major_dim - 1) / 16384 + 1;
304
- p.loop_x = 4;
305
- block_size = dim3(4, 32, 1);
306
- grid_size = dim3((p.out_h * p.minor_dim - 1) / block_size.x + 1,
307
- (p.out_w - 1) / (p.loop_x * block_size.y) + 1,
308
- (p.major_dim - 1) / p.loop_major + 1);
309
- }
310
-
311
- AT_DISPATCH_FLOATING_TYPES_AND_HALF(x.scalar_type(), "upfirdn2d_cuda", [&] {
312
- switch (mode) {
313
- case 1:
314
- upfirdn2d_kernel<scalar_t, 1, 1, 1, 1, 4, 4, 16, 64>
315
- <<<grid_size, block_size, 0, stream>>>(out.data_ptr<scalar_t>(),
316
- x.data_ptr<scalar_t>(),
317
- k.data_ptr<scalar_t>(), p);
318
-
319
- break;
320
-
321
- case 2:
322
- upfirdn2d_kernel<scalar_t, 1, 1, 1, 1, 3, 3, 16, 64>
323
- <<<grid_size, block_size, 0, stream>>>(out.data_ptr<scalar_t>(),
324
- x.data_ptr<scalar_t>(),
325
- k.data_ptr<scalar_t>(), p);
326
-
327
- break;
328
-
329
- case 3:
330
- upfirdn2d_kernel<scalar_t, 2, 2, 1, 1, 4, 4, 16, 64>
331
- <<<grid_size, block_size, 0, stream>>>(out.data_ptr<scalar_t>(),
332
- x.data_ptr<scalar_t>(),
333
- k.data_ptr<scalar_t>(), p);
334
-
335
- break;
336
-
337
- case 4:
338
- upfirdn2d_kernel<scalar_t, 2, 2, 1, 1, 2, 2, 16, 64>
339
- <<<grid_size, block_size, 0, stream>>>(out.data_ptr<scalar_t>(),
340
- x.data_ptr<scalar_t>(),
341
- k.data_ptr<scalar_t>(), p);
342
-
343
- break;
344
-
345
- case 5:
346
- upfirdn2d_kernel<scalar_t, 1, 1, 2, 2, 4, 4, 8, 32>
347
- <<<grid_size, block_size, 0, stream>>>(out.data_ptr<scalar_t>(),
348
- x.data_ptr<scalar_t>(),
349
- k.data_ptr<scalar_t>(), p);
350
-
351
- break;
352
-
353
- case 6:
354
- upfirdn2d_kernel<scalar_t, 1, 1, 2, 2, 4, 4, 8, 32>
355
- <<<grid_size, block_size, 0, stream>>>(out.data_ptr<scalar_t>(),
356
- x.data_ptr<scalar_t>(),
357
- k.data_ptr<scalar_t>(), p);
358
-
359
- break;
360
-
361
- default:
362
- upfirdn2d_kernel_large<scalar_t><<<grid_size, block_size, 0, stream>>>(
363
- out.data_ptr<scalar_t>(), x.data_ptr<scalar_t>(),
364
- k.data_ptr<scalar_t>(), p);
365
- }
366
- });
367
-
368
- return out;
369
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,7 +1,6 @@
1
- git+https://github.com/TEAMuP-dev/pyharp.git@v0.3.0
2
- torch
3
- torchaudio
4
- torchcodec
5
  nara_wpe
6
  torchcde
7
  soundfile
 
1
+ git+https://github.com/TEAMuP-dev/pyharp.git@develop
2
+ torch==2.11.0
3
+ torchaudio==2.11.0
 
4
  nara_wpe
5
  torchcde
6
  soundfile