auvux-dsp 0.1.0.dev0__tar.gz → 0.1.0.dev2__tar.gz
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.
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/.gitignore +5 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/CMakeLists.txt +20 -3
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/PKG-INFO +11 -5
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/README.md +8 -4
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/benchmarks/benchmark.py +57 -58
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/pyproject.toml +9 -1
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/__init__.py +39 -1
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/_dispatch.py +39 -20
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/_functional.py +188 -1
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/_torch.py +22 -20
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/_transforms.py +282 -0
- auvux_dsp-0.1.0.dev2/python/auvux/dsp/_version.py +1 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/abi.hpp +1 -1
- auvux_dsp-0.1.0.dev2/src/bindings/bind_features.cpp +475 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/bind_stft.cpp +4 -5
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/module.cpp +2 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/pooled_array.hpp +3 -3
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/common/dlpack_bridge.hpp +3 -3
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/cuda/cuda_common.cu +2 -2
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/cuda/cuda_common.cuh +4 -2
- auvux_dsp-0.1.0.dev2/src/gpu/cuda/cuda_features.cu +1080 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/cuda/cuda_stft.cu +2 -1
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/gpu.hpp +28 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/gpu_stub.cpp +5 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/kernels/common.metal +14 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/kernels/flux.metal +108 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/kernels/moments.metal +219 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/kernels/onset.metal +67 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/kernels/rms.metal +92 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/kernels/tempogram.metal +116 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/metal_common.h +8 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/metal_common.mm +21 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/metal_flux.mm +187 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/metal_moments.mm +176 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/metal_onset.mm +158 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/metal_rms.mm +158 -0
- auvux_dsp-0.1.0.dev2/src/gpu/metal/metal_tempogram.mm +169 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/chroma/chroma_cpu.cpp +19 -6
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/cqt/cqt.hpp +6 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/cqt/cqt_cpu.cpp +102 -7
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/cqt/cqt_filterbank.cpp +1 -1
- auvux_dsp-0.1.0.dev2/src/ops/db.hpp +119 -0
- auvux_dsp-0.1.0.dev2/src/ops/flux/flux.hpp +30 -0
- auvux_dsp-0.1.0.dev2/src/ops/flux/flux_cpu.cpp +141 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/mel/mel_cpu.cpp +12 -3
- auvux_dsp-0.1.0.dev2/src/ops/moments/moments.hpp +58 -0
- auvux_dsp-0.1.0.dev2/src/ops/moments/moments_cpu.cpp +276 -0
- auvux_dsp-0.1.0.dev2/src/ops/onset/onset.hpp +30 -0
- auvux_dsp-0.1.0.dev2/src/ops/onset/onset_cpu.cpp +77 -0
- auvux_dsp-0.1.0.dev2/src/ops/rms/rms.hpp +36 -0
- auvux_dsp-0.1.0.dev2/src/ops/rms/rms_cpu.cpp +77 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/stft/stft_cpu.cpp +7 -5
- auvux_dsp-0.1.0.dev2/src/ops/tempogram/tempogram.hpp +41 -0
- auvux_dsp-0.1.0.dev2/src/ops/tempogram/tempogram_cpu.cpp +147 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/window.hpp +1 -1
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_adjoint.py +52 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_api.py +91 -0
- auvux_dsp-0.1.0.dev2/tests/test_dynamics.py +88 -0
- auvux_dsp-0.1.0.dev2/tests/test_gpu_features.py +248 -0
- auvux_dsp-0.1.0.dev2/tests/test_moments.py +87 -0
- auvux_dsp-0.1.0.dev2/tests/test_onset_tempo.py +100 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_vqt.py +8 -1
- auvux_dsp-0.1.0.dev2/tests/torch_refs.py +236 -0
- auvux_dsp-0.1.0.dev0/.env +0 -1
- auvux_dsp-0.1.0.dev0/python/auvux/dsp/_version.py +0 -1
- auvux_dsp-0.1.0.dev0/tests/torch_refs.py +0 -110
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/.clang-format +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/.clangd +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/.github/workflows/ci.yml +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/.github/workflows/wheels.yml +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/LICENSE +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/THIRD_PARTY_LICENSES +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/cmake/embed_text.cmake +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/_convert.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/_filters.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/_transform.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/python/auvux/dsp/py.typed +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/scripts/dev-build.ps1 +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/scripts/dev-build.sh +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/bind_cqt.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/bind_fft.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/bind_mel.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/bindings/bind_util.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/common/host_pool.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/common/host_pool.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/common/threadpool.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/common/threadpool.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/fft/fft.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/fft/fft.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/fft/fft_impl.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/fft/fft_pffft.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/fft/fft_vdsp.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/cqt_plan.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/cqt_plan.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/cuda/cuda_cqt.cu +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/cuda/cuda_mel.cu +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/gpu_common.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/kernels/cqt.metal +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/kernels/mel.metal +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/kernels/stft.metal +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/metal_cqt.mm +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/metal_mel.mm +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/gpu/metal/metal_stft.mm +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/chroma/chroma.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/cqt/cqt_filterbank.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/frame.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/istft/istft.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/istft/istft_cpu.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/mel/mel.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/mel/mel_filterbank.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/ola.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/ola.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/stft/stft.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/types.hpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/ops/window.cpp +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/third_party/dlpack.h +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/third_party/pffft.c +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/src/third_party/pffft.h +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_chroma.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_cqt.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_fft.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_gpu.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_grad.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_istft.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_mel.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_mfcc.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_namespace.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_resident.py +0 -0
- {auvux_dsp-0.1.0.dev0 → auvux_dsp-0.1.0.dev2}/tests/test_stft.py +0 -0
|
@@ -49,6 +49,11 @@ pybind11_add_module(_native
|
|
|
49
49
|
src/ops/cqt/cqt_filterbank.cpp
|
|
50
50
|
src/ops/cqt/cqt_cpu.cpp
|
|
51
51
|
src/ops/chroma/chroma_cpu.cpp
|
|
52
|
+
src/ops/moments/moments_cpu.cpp
|
|
53
|
+
src/ops/rms/rms_cpu.cpp
|
|
54
|
+
src/ops/flux/flux_cpu.cpp
|
|
55
|
+
src/ops/onset/onset_cpu.cpp
|
|
56
|
+
src/ops/tempogram/tempogram_cpu.cpp
|
|
52
57
|
src/gpu/gpu_stub.cpp
|
|
53
58
|
src/gpu/cqt_plan.cpp
|
|
54
59
|
src/third_party/pffft.c
|
|
@@ -57,6 +62,7 @@ pybind11_add_module(_native
|
|
|
57
62
|
src/bindings/bind_stft.cpp
|
|
58
63
|
src/bindings/bind_mel.cpp
|
|
59
64
|
src/bindings/bind_cqt.cpp
|
|
65
|
+
src/bindings/bind_features.cpp
|
|
60
66
|
src/bindings/bind_util.cpp)
|
|
61
67
|
target_include_directories(_native PRIVATE src src/third_party)
|
|
62
68
|
target_link_libraries(_native PRIVATE Threads::Threads)
|
|
@@ -90,7 +96,12 @@ if(AUVUX_GPU STREQUAL "metal")
|
|
|
90
96
|
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/common.metal
|
|
91
97
|
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/stft.metal
|
|
92
98
|
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/mel.metal
|
|
93
|
-
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/cqt.metal
|
|
99
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/cqt.metal
|
|
100
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/rms.metal
|
|
101
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/moments.metal
|
|
102
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/flux.metal
|
|
103
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/onset.metal
|
|
104
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/metal/kernels/tempogram.metal)
|
|
94
105
|
set(auvux_metal_gen ${CMAKE_CURRENT_BINARY_DIR}/generated/auvux_metal_kernels.h)
|
|
95
106
|
string(JOIN "," auvux_metal_kernels_arg ${auvux_metal_kernels})
|
|
96
107
|
add_custom_command(
|
|
@@ -104,7 +115,12 @@ if(AUVUX_GPU STREQUAL "metal")
|
|
|
104
115
|
src/gpu/metal/metal_common.mm
|
|
105
116
|
src/gpu/metal/metal_stft.mm
|
|
106
117
|
src/gpu/metal/metal_mel.mm
|
|
107
|
-
src/gpu/metal/metal_cqt.mm
|
|
118
|
+
src/gpu/metal/metal_cqt.mm
|
|
119
|
+
src/gpu/metal/metal_rms.mm
|
|
120
|
+
src/gpu/metal/metal_moments.mm
|
|
121
|
+
src/gpu/metal/metal_flux.mm
|
|
122
|
+
src/gpu/metal/metal_onset.mm
|
|
123
|
+
src/gpu/metal/metal_tempogram.mm)
|
|
108
124
|
target_sources(_native PRIVATE ${auvux_metal_srcs} ${auvux_metal_gen})
|
|
109
125
|
set_source_files_properties(${auvux_metal_srcs} PROPERTIES COMPILE_OPTIONS "-fobjc-arc")
|
|
110
126
|
target_include_directories(_native PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
|
@@ -125,7 +141,8 @@ elseif(AUVUX_GPU STREQUAL "cuda")
|
|
|
125
141
|
src/gpu/cuda/cuda_common.cu
|
|
126
142
|
src/gpu/cuda/cuda_stft.cu
|
|
127
143
|
src/gpu/cuda/cuda_mel.cu
|
|
128
|
-
src/gpu/cuda/cuda_cqt.cu
|
|
144
|
+
src/gpu/cuda/cuda_cqt.cu
|
|
145
|
+
src/gpu/cuda/cuda_features.cu)
|
|
129
146
|
target_compile_definitions(_native PRIVATE AUVUX_CUDA=1)
|
|
130
147
|
if(NOT auvux_user_archs)
|
|
131
148
|
# Distributable fatbin: SASS per supported generation plus PTX (the plain
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: auvux-dsp
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev2
|
|
4
4
|
Summary: Fast differentiable audio transforms (STFT, mel, MFCC, CQT, chroma) on CPU and GPU
|
|
5
5
|
Keywords: audio,dsp,stft,mel,mfcc,cqt,chroma,spectrogram,gpu
|
|
6
6
|
Author-Email: Peter Kiers <pkiers.1983@gmail.com>
|
|
@@ -17,15 +17,18 @@ Requires-Dist: pytest; extra == "test"
|
|
|
17
17
|
Requires-Dist: librosa; extra == "test"
|
|
18
18
|
Requires-Dist: soxr; extra == "test"
|
|
19
19
|
Requires-Dist: torch; extra == "test"
|
|
20
|
+
Provides-Extra: wheeltest
|
|
21
|
+
Requires-Dist: pytest; extra == "wheeltest"
|
|
20
22
|
Description-Content-Type: text/markdown
|
|
21
23
|
|
|
22
24
|
# auvux-dsp
|
|
23
25
|
|
|
24
26
|
Fast differentiable audio transforms (STFT, iSTFT, mel, MFCC, CQT/VQT, chroma)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
plus differentiable scalar/temporal features (spectral moments & flatness, RMS,
|
|
28
|
+
spectral flux, onset strength, tempogram) with native CPU backends (vDSP on
|
|
29
|
+
macOS, PFFFT elsewhere) and GPU support (Metal, CUDA). Forward *and* backward
|
|
30
|
+
passes run in native kernels; PyTorch autograd plugs in when you pass a torch
|
|
31
|
+
tensor, and torch is never required otherwise.
|
|
29
32
|
|
|
30
33
|
```python
|
|
31
34
|
import auvux.dsp as dsp
|
|
@@ -69,6 +72,9 @@ outputs (power/db/mel/...) are ordinary C-contiguous arrays.
|
|
|
69
72
|
Status: under construction.
|
|
70
73
|
- CPU (vDSP/PFFFT): STFT, ISTFT, MelSpectrogram, MFCC, CQT, VQT, Chroma —
|
|
71
74
|
forward and native backward, librosa-parity tested, torch autograd built in.
|
|
75
|
+
- Differentiable features: SpectralMoments (centroid, bandwidth, skewness,
|
|
76
|
+
kurtosis, flatness), RMS, SpectralFlux, OnsetStrength, Tempogram — native
|
|
77
|
+
forward + analytic adjoint, librosa-parity / torch-grad tested.
|
|
72
78
|
- Metal: all of the above on GPU (n_fft <= 4096), forward + backward,
|
|
73
79
|
parity-tested against the CPU path. torch MPS tensors stay on the GPU end to
|
|
74
80
|
end (DLPack), and backend="auto" routes them there — no flags needed.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# auvux-dsp
|
|
2
2
|
|
|
3
3
|
Fast differentiable audio transforms (STFT, iSTFT, mel, MFCC, CQT/VQT, chroma)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
plus differentiable scalar/temporal features (spectral moments & flatness, RMS,
|
|
5
|
+
spectral flux, onset strength, tempogram) with native CPU backends (vDSP on
|
|
6
|
+
macOS, PFFFT elsewhere) and GPU support (Metal, CUDA). Forward *and* backward
|
|
7
|
+
passes run in native kernels; PyTorch autograd plugs in when you pass a torch
|
|
8
|
+
tensor, and torch is never required otherwise.
|
|
8
9
|
|
|
9
10
|
```python
|
|
10
11
|
import auvux.dsp as dsp
|
|
@@ -48,6 +49,9 @@ outputs (power/db/mel/...) are ordinary C-contiguous arrays.
|
|
|
48
49
|
Status: under construction.
|
|
49
50
|
- CPU (vDSP/PFFFT): STFT, ISTFT, MelSpectrogram, MFCC, CQT, VQT, Chroma —
|
|
50
51
|
forward and native backward, librosa-parity tested, torch autograd built in.
|
|
52
|
+
- Differentiable features: SpectralMoments (centroid, bandwidth, skewness,
|
|
53
|
+
kurtosis, flatness), RMS, SpectralFlux, OnsetStrength, Tempogram — native
|
|
54
|
+
forward + analytic adjoint, librosa-parity / torch-grad tested.
|
|
51
55
|
- Metal: all of the above on GPU (n_fft <= 4096), forward + backward,
|
|
52
56
|
parity-tested against the CPU path. torch MPS tensors stay on the GPU end to
|
|
53
57
|
end (DLPack), and backend="auto" routes them there — no flags needed.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""Benchmark auvux-dsp against librosa
|
|
1
|
+
"""Benchmark auvux-dsp against librosa and torchaudio.
|
|
2
2
|
|
|
3
3
|
Forward passes and torch training steps (forward + sum().backward()) per
|
|
4
4
|
transform, implementation, and signal length. auvux runs on cpu, host-staged
|
|
5
|
-
gpu, and gpu-resident torch tensors; torchaudio
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
gpu, and gpu-resident torch tensors; torchaudio also runs on the torch device
|
|
6
|
+
when one is available. Progress prints as it runs; the summary tables are
|
|
7
|
+
markdown, ready for the README.
|
|
8
8
|
|
|
9
9
|
python benchmarks/benchmark.py # everything available
|
|
10
10
|
python benchmarks/benchmark.py --quick # 1 repeat, short signals
|
|
@@ -95,16 +95,33 @@ def build_cases(y, sec, torch, device, gpu, resident):
|
|
|
95
95
|
("vqt", vqt_t),
|
|
96
96
|
("chroma", chroma_t),
|
|
97
97
|
]
|
|
98
|
+
# CPU-only differentiable features (no GPU kernels yet). librosa comparisons
|
|
99
|
+
# are registered below only for the 1:1-matching definitions.
|
|
100
|
+
feat = [
|
|
101
|
+
("spectral_moments", dsp.SpectralMoments(sr=SR, n_fft=2048, hop_length=512)),
|
|
102
|
+
("spectral_centroid",
|
|
103
|
+
dsp.SpectralMoments(sr=SR, features=("centroid",), n_fft=2048, hop_length=512)),
|
|
104
|
+
("spectral_bandwidth",
|
|
105
|
+
dsp.SpectralMoments(sr=SR, features=("bandwidth",), n_fft=2048, hop_length=512)),
|
|
106
|
+
("spectral_flatness",
|
|
107
|
+
dsp.SpectralMoments(sr=SR, features=("flatness",), n_fft=2048, hop_length=512)),
|
|
108
|
+
("rms", dsp.RMS(sr=SR, frame_length=2048, hop_length=512)),
|
|
109
|
+
("spectral_flux", dsp.SpectralFlux(sr=SR, n_fft=2048, hop_length=512)),
|
|
110
|
+
("onset_strength", dsp.OnsetStrength(sr=SR, n_fft=2048, hop_length=512, n_mels=128)),
|
|
111
|
+
("tempogram", dsp.Tempogram(sr=SR, n_fft=2048, hop_length=512, n_mels=128)),
|
|
112
|
+
]
|
|
98
113
|
|
|
99
114
|
for name, t in fwd:
|
|
100
115
|
add("forward", name, "auvux cpu", lambda t=t: t(y))
|
|
116
|
+
for name, t in feat:
|
|
117
|
+
add("forward", name, "auvux cpu", lambda t=t: t(y))
|
|
101
118
|
if gpu:
|
|
102
|
-
for name, t in fwd:
|
|
119
|
+
for name, t in fwd + feat:
|
|
103
120
|
add("forward", name, f"auvux {gpu} staged", lambda t=t: t(y, backend="gpu"))
|
|
104
121
|
if resident:
|
|
105
122
|
sync = syncer(torch, device)
|
|
106
123
|
ytd = torch.from_numpy(y).to(device)
|
|
107
|
-
for name, t in fwd:
|
|
124
|
+
for name, t in fwd + feat:
|
|
108
125
|
add(
|
|
109
126
|
"forward",
|
|
110
127
|
name,
|
|
@@ -168,6 +185,25 @@ def build_cases(y, sec, torch, device, gpu, resident):
|
|
|
168
185
|
"librosa",
|
|
169
186
|
lambda: librosa.istft(Z, n_fft=2048, hop_length=512, length=n_out),
|
|
170
187
|
)
|
|
188
|
+
# Features whose definitions match librosa 1:1, so the diff column is a
|
|
189
|
+
# real correctness check.
|
|
190
|
+
add("forward", "spectral_centroid", "librosa",
|
|
191
|
+
lambda: librosa.feature.spectral_centroid(y=y, sr=SR, n_fft=2048, hop_length=512))
|
|
192
|
+
add("forward", "spectral_bandwidth", "librosa",
|
|
193
|
+
lambda: librosa.feature.spectral_bandwidth(y=y, sr=SR, n_fft=2048, hop_length=512))
|
|
194
|
+
add("forward", "spectral_flatness", "librosa",
|
|
195
|
+
lambda: librosa.feature.spectral_flatness(y=y, n_fft=2048, hop_length=512))
|
|
196
|
+
add("forward", "rms", "librosa",
|
|
197
|
+
lambda: librosa.feature.rms(y=y, frame_length=2048, hop_length=512))
|
|
198
|
+
# Speed-only: our onset/tempogram match librosa's values but not its
|
|
199
|
+
# `center=True` envelope lag-shift (n_fft//(2*hop) frames), so the diff
|
|
200
|
+
# is suppressed (see _NO_DIFF) — correctness lives in the test suite.
|
|
201
|
+
# librosa has no standalone spectral_flux.
|
|
202
|
+
add("forward", "onset_strength", "librosa",
|
|
203
|
+
lambda: librosa.onset.onset_strength(
|
|
204
|
+
y=y, sr=SR, n_fft=2048, hop_length=512, n_mels=128))
|
|
205
|
+
add("forward", "tempogram", "librosa",
|
|
206
|
+
lambda: librosa.feature.tempogram(y=y, sr=SR, hop_length=512, win_length=384))
|
|
171
207
|
|
|
172
208
|
if torch is not None and try_import("torchaudio"):
|
|
173
209
|
import torchaudio.transforms as T
|
|
@@ -233,34 +269,6 @@ def build_cases(y, sec, torch, device, gpu, resident):
|
|
|
233
269
|
lambda td=td: (td(ytd), sync()),
|
|
234
270
|
)
|
|
235
271
|
|
|
236
|
-
if torch is not None and try_import("nnAudio"):
|
|
237
|
-
from nnAudio import features
|
|
238
|
-
|
|
239
|
-
def nn_make():
|
|
240
|
-
return {
|
|
241
|
-
"mel_spectrogram": features.MelSpectrogram(
|
|
242
|
-
sr=SR,
|
|
243
|
-
n_fft=2048,
|
|
244
|
-
hop_length=512,
|
|
245
|
-
n_mels=128,
|
|
246
|
-
pad_mode="constant",
|
|
247
|
-
verbose=False,
|
|
248
|
-
),
|
|
249
|
-
"cqt": features.CQT(
|
|
250
|
-
sr=SR, hop_length=512, n_bins=84, pad_mode="constant", verbose=False
|
|
251
|
-
),
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
yt1 = torch.from_numpy(y)[None]
|
|
255
|
-
for name, t in nn_make().items():
|
|
256
|
-
add("forward", name, "nnAudio cpu", lambda t=t: t(yt1))
|
|
257
|
-
if device:
|
|
258
|
-
sync = syncer(torch, device)
|
|
259
|
-
ytd1 = yt1.to(device)
|
|
260
|
-
for name, t in nn_make().items():
|
|
261
|
-
td = t.to(device)
|
|
262
|
-
add("forward", name, f"nnAudio {device} resident", lambda td=td: (td(ytd1), sync()))
|
|
263
|
-
|
|
264
272
|
if torch is None:
|
|
265
273
|
return cases
|
|
266
274
|
|
|
@@ -287,16 +295,16 @@ def build_cases(y, sec, torch, device, gpu, resident):
|
|
|
287
295
|
("chroma", chroma_t),
|
|
288
296
|
]
|
|
289
297
|
|
|
290
|
-
for name, t in train:
|
|
298
|
+
for name, t in train + feat:
|
|
291
299
|
add("training step", name, "auvux cpu", step(t, yt, no_sync))
|
|
292
300
|
if gpu:
|
|
293
|
-
for name, t in train:
|
|
301
|
+
for name, t in train + feat:
|
|
294
302
|
staged = step(lambda x, t=t: t(x, backend="gpu"), yt, no_sync)
|
|
295
303
|
add("training step", name, f"auvux {gpu} staged", staged)
|
|
296
304
|
if resident:
|
|
297
305
|
sync = syncer(torch, device)
|
|
298
306
|
ytd = torch.from_numpy(y).to(device)
|
|
299
|
-
for name, t in train:
|
|
307
|
+
for name, t in train + feat:
|
|
300
308
|
add(
|
|
301
309
|
"training step",
|
|
302
310
|
name,
|
|
@@ -384,25 +392,13 @@ def build_cases(y, sec, torch, device, gpu, resident):
|
|
|
384
392
|
step(lambda x: inv_td(x, length=n_out), Ztd_ta, sync),
|
|
385
393
|
)
|
|
386
394
|
|
|
387
|
-
|
|
388
|
-
from nnAudio import features
|
|
395
|
+
return cases
|
|
389
396
|
|
|
390
|
-
ncqt = features.CQT(sr=SR, hop_length=512, n_bins=84, pad_mode="constant", verbose=False)
|
|
391
|
-
add("training step", "cqt", "nnAudio cpu", step(lambda x: ncqt(x[None]), yt, no_sync))
|
|
392
|
-
if device:
|
|
393
|
-
sync = syncer(torch, device)
|
|
394
|
-
ncqt_d = features.CQT(
|
|
395
|
-
sr=SR, hop_length=512, n_bins=84, pad_mode="constant", verbose=False
|
|
396
|
-
).to(device)
|
|
397
|
-
ytd = torch.from_numpy(y).to(device)
|
|
398
|
-
add(
|
|
399
|
-
"training step",
|
|
400
|
-
"cqt",
|
|
401
|
-
f"nnAudio {device} resident",
|
|
402
|
-
step(lambda x: ncqt_d(x[None]), ytd, sync),
|
|
403
|
-
)
|
|
404
397
|
|
|
405
|
-
|
|
398
|
+
# Transforms compared against librosa for speed only: their definitions match
|
|
399
|
+
# librosa's values but not its envelope lag-shift convention, so a relerr "diff"
|
|
400
|
+
# would read as a (misleading) failure rather than a correctness check.
|
|
401
|
+
_NO_DIFF = frozenset({"onset_strength", "tempogram"})
|
|
406
402
|
|
|
407
403
|
|
|
408
404
|
def run_cases(cases, repeats, warmup):
|
|
@@ -440,7 +436,10 @@ def run_cases(cases, repeats, warmup):
|
|
|
440
436
|
ts.append(time.perf_counter() - t0)
|
|
441
437
|
if rep == repeats - 1:
|
|
442
438
|
outs[id(c)] = r
|
|
443
|
-
|
|
439
|
+
grp_tr = live[0][0].transform if live else ""
|
|
440
|
+
ref = None
|
|
441
|
+
if grp_tr not in _NO_DIFF:
|
|
442
|
+
ref = next((to_numpy(outs[id(c)]) for c, _, _ in live if c.impl == "librosa"), None)
|
|
444
443
|
if ref is not None:
|
|
445
444
|
for c, _, _ in live:
|
|
446
445
|
if c.impl == "librosa":
|
|
@@ -466,7 +465,7 @@ def to_numpy(out):
|
|
|
466
465
|
if hasattr(out, "detach"):
|
|
467
466
|
out = out.detach().cpu().numpy()
|
|
468
467
|
out = np.asarray(out)
|
|
469
|
-
while out.ndim > 2 and out.shape[0] == 1: #
|
|
468
|
+
while out.ndim > 2 and out.shape[0] == 1: # drop a leading singleton batch dim
|
|
470
469
|
out = out[0]
|
|
471
470
|
return out
|
|
472
471
|
|
|
@@ -521,7 +520,7 @@ def print_table(title, col_names, rows):
|
|
|
521
520
|
print(line(r))
|
|
522
521
|
|
|
523
522
|
|
|
524
|
-
_LIB_ORDER = ("auvux", "librosa", "torchaudio"
|
|
523
|
+
_LIB_ORDER = ("auvux", "librosa", "torchaudio")
|
|
525
524
|
_PATH_ORDER = ("cpu", "gpu staged", "gpu resident")
|
|
526
525
|
|
|
527
526
|
|
|
@@ -629,7 +628,7 @@ def main():
|
|
|
629
628
|
|
|
630
629
|
torch, device, gpu, resident = detect_env()
|
|
631
630
|
gpu_s = f"{gpu} ({dsp.backend_info(gpu)['device_name']})" if gpu else "none"
|
|
632
|
-
rivals = ("librosa", "torchaudio"
|
|
631
|
+
rivals = ("librosa", "torchaudio")
|
|
633
632
|
libs = ", ".join(f"{n} {version_of(n)}" for n in rivals if try_import(n))
|
|
634
633
|
print(f"auvux-dsp {dsp.__version__} benchmark")
|
|
635
634
|
threads = dsp.get_num_threads() or "auto"
|
|
@@ -20,13 +20,21 @@ classifiers = [
|
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
[project.optional-dependencies]
|
|
23
|
+
# Full parity/grad suite: librosa is the forward oracle, torch the autograd
|
|
24
|
+
# oracle. Used in dev and native-arch CI.
|
|
23
25
|
test = ["pytest", "librosa", "soxr", "torch"]
|
|
26
|
+
# Lean smoke test for the per-wheel cibuildwheel run: just confirm the compiled
|
|
27
|
+
# extension loads and the native paths run. The librosa/torch oracle tests
|
|
28
|
+
# importorskip and skip cleanly without those (heavy, and unbuildable on some
|
|
29
|
+
# wheel targets — numba/llvmlite and torch have no x86_64-macOS wheels).
|
|
30
|
+
wheeltest = ["pytest"]
|
|
24
31
|
|
|
25
32
|
[tool.scikit-build]
|
|
26
33
|
minimum-version = "build-system.requires"
|
|
27
34
|
wheel.packages = ["python/auvux"]
|
|
28
35
|
cmake.version = ">=3.18"
|
|
29
36
|
build-dir = "build/{wheel_tag}"
|
|
37
|
+
sdist.exclude = [".env", ".env.*", "*.env", ".pypirc", "*.pem", "wheelhouse", "dist"]
|
|
30
38
|
|
|
31
39
|
[tool.scikit-build.metadata.version]
|
|
32
40
|
provider = "scikit_build_core.metadata.regex"
|
|
@@ -35,7 +43,7 @@ input = "python/auvux/dsp/_version.py"
|
|
|
35
43
|
[tool.cibuildwheel]
|
|
36
44
|
build = "cp310-* cp311-* cp312-* cp313-*"
|
|
37
45
|
skip = "*-musllinux* *_i686 *-win32"
|
|
38
|
-
test-
|
|
46
|
+
test-extras = ["wheeltest"]
|
|
39
47
|
test-command = "pytest {project}/tests -q"
|
|
40
48
|
|
|
41
49
|
[tool.cibuildwheel.macos]
|
|
@@ -26,22 +26,50 @@ from auvux.dsp._functional import (
|
|
|
26
26
|
istft,
|
|
27
27
|
mel_spectrogram,
|
|
28
28
|
mfcc,
|
|
29
|
+
onset_strength,
|
|
30
|
+
rms,
|
|
31
|
+
spectral_bandwidth,
|
|
32
|
+
spectral_centroid,
|
|
33
|
+
spectral_flatness,
|
|
34
|
+
spectral_flux,
|
|
35
|
+
spectral_kurtosis,
|
|
36
|
+
spectral_moments,
|
|
37
|
+
spectral_skewness,
|
|
29
38
|
stft,
|
|
39
|
+
tempogram,
|
|
30
40
|
vqt,
|
|
31
41
|
)
|
|
32
42
|
from auvux.dsp._transform import Transform
|
|
33
|
-
from auvux.dsp._transforms import
|
|
43
|
+
from auvux.dsp._transforms import (
|
|
44
|
+
CQT,
|
|
45
|
+
ISTFT,
|
|
46
|
+
MFCC,
|
|
47
|
+
RMS,
|
|
48
|
+
STFT,
|
|
49
|
+
VQT,
|
|
50
|
+
Chroma,
|
|
51
|
+
MelSpectrogram,
|
|
52
|
+
OnsetStrength,
|
|
53
|
+
SpectralFlux,
|
|
54
|
+
SpectralMoments,
|
|
55
|
+
Tempogram,
|
|
56
|
+
)
|
|
34
57
|
from auvux.dsp._version import __version__
|
|
35
58
|
|
|
36
59
|
__all__ = [
|
|
37
60
|
"CQT",
|
|
38
61
|
"ISTFT",
|
|
39
62
|
"MFCC",
|
|
63
|
+
"RMS",
|
|
40
64
|
"STFT",
|
|
41
65
|
"VQT",
|
|
42
66
|
"BackendError",
|
|
43
67
|
"Chroma",
|
|
44
68
|
"MelSpectrogram",
|
|
69
|
+
"OnsetStrength",
|
|
70
|
+
"SpectralFlux",
|
|
71
|
+
"SpectralMoments",
|
|
72
|
+
"Tempogram",
|
|
45
73
|
"Transform",
|
|
46
74
|
"__version__",
|
|
47
75
|
"amplitude_to_db",
|
|
@@ -65,8 +93,18 @@ __all__ = [
|
|
|
65
93
|
"mel_spectrogram",
|
|
66
94
|
"mel_to_hz",
|
|
67
95
|
"mfcc",
|
|
96
|
+
"onset_strength",
|
|
68
97
|
"power_to_db",
|
|
98
|
+
"rms",
|
|
69
99
|
"set_num_threads",
|
|
100
|
+
"spectral_bandwidth",
|
|
101
|
+
"spectral_centroid",
|
|
102
|
+
"spectral_flatness",
|
|
103
|
+
"spectral_flux",
|
|
104
|
+
"spectral_kurtosis",
|
|
105
|
+
"spectral_moments",
|
|
106
|
+
"spectral_skewness",
|
|
70
107
|
"stft",
|
|
108
|
+
"tempogram",
|
|
71
109
|
"vqt",
|
|
72
110
|
]
|
|
@@ -17,7 +17,7 @@ class BackendError(RuntimeError):
|
|
|
17
17
|
# Refuse to run against a compiled core older than these Python sources;
|
|
18
18
|
# editable installs do not rebuild the extension on source changes.
|
|
19
19
|
# Keep in lockstep with kAbiVersion in src/bindings/abi.hpp.
|
|
20
|
-
_EXPECTED_ABI =
|
|
20
|
+
_EXPECTED_ABI = 12
|
|
21
21
|
if getattr(_native, "abi_version", lambda: 0)() != _EXPECTED_ABI:
|
|
22
22
|
raise ImportError(
|
|
23
23
|
"auvux.dsp's compiled core is out of date with its Python sources; "
|
|
@@ -102,7 +102,10 @@ def backend_info(name: str) -> dict[str, Any]:
|
|
|
102
102
|
"available": True,
|
|
103
103
|
"device_name": "",
|
|
104
104
|
"supports": {
|
|
105
|
-
"transforms": [
|
|
105
|
+
"transforms": [
|
|
106
|
+
"stft", "istft", "mel_spectrogram", "mfcc", "cqt", "vqt", "chroma",
|
|
107
|
+
"spectral_moments", "rms", "spectral_flux", "onset_strength", "tempogram",
|
|
108
|
+
],
|
|
106
109
|
"n_fft": "any power of two >= 32",
|
|
107
110
|
},
|
|
108
111
|
}
|
|
@@ -115,7 +118,10 @@ def backend_info(name: str) -> dict[str, Any]:
|
|
|
115
118
|
"supports": {
|
|
116
119
|
# MFCC rides on the GPU mel; istft is resident-only (device
|
|
117
120
|
# tensors in, device tensors out).
|
|
118
|
-
"transforms": [
|
|
121
|
+
"transforms": [
|
|
122
|
+
"stft", "istft", "mel_spectrogram", "mfcc", "cqt", "vqt", "chroma", "rms",
|
|
123
|
+
"spectral_moments", "spectral_flux", "onset_strength", "tempogram",
|
|
124
|
+
],
|
|
119
125
|
"n_fft": "powers of two in [64, 4096]",
|
|
120
126
|
"cqt": "hop_length divisible by 2**(n_octaves - 1)",
|
|
121
127
|
},
|
|
@@ -198,12 +204,22 @@ def rewrap(out: np.ndarray, lead: tuple[int, ...], mod: str, device: Any = None)
|
|
|
198
204
|
return out
|
|
199
205
|
|
|
200
206
|
|
|
201
|
-
def _stream_for(kind: str) -> int:
|
|
202
|
-
if kind
|
|
207
|
+
def _stream_for(t: Any, kind: str) -> int:
|
|
208
|
+
if kind != "cuda":
|
|
209
|
+
return 0
|
|
210
|
+
if array_module(t) == "torch":
|
|
203
211
|
import torch
|
|
204
212
|
|
|
205
|
-
return int(torch.cuda.current_stream().cuda_stream) or 1
|
|
206
|
-
|
|
213
|
+
return int(torch.cuda.current_stream(getattr(t, "device", None)).cuda_stream) or 1
|
|
214
|
+
import cupy
|
|
215
|
+
|
|
216
|
+
return int(cupy.cuda.get_current_stream().ptr) or 1
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _dlpack_capsule(t: Any, kind: str, stream: int) -> Any:
|
|
220
|
+
if kind == "cuda":
|
|
221
|
+
return t.__dlpack__(stream=stream)
|
|
222
|
+
return t.__dlpack__()
|
|
207
223
|
|
|
208
224
|
|
|
209
225
|
def _frame_major(strides: tuple[int, ...], shape: tuple[int, ...], elem: int) -> bool:
|
|
@@ -225,13 +241,14 @@ def export_dlpack(
|
|
|
225
241
|
cplx: bool = False,
|
|
226
242
|
sync: bool = True,
|
|
227
243
|
frame_major: bool = False,
|
|
244
|
+
stream: int | None = None,
|
|
228
245
|
) -> Any:
|
|
229
|
-
"""GPU array (..., tail) -> (capsule, lead shape, keepalive) or
|
|
230
|
-
the array library cannot export DLPack here (then callers stage
|
|
231
|
-
sync=False skips the device sync when an immediately preceding
|
|
232
|
-
already drained the queue. frame_major=True normalizes a (...,
|
|
233
|
-
frames) spectrum to the STFT/ISTFT engines' frame-major contract;
|
|
234
|
-
engines (CQT complex included) take compact tensors."""
|
|
246
|
+
"""GPU array (..., tail) -> (capsule, lead shape, keepalive, stream) or
|
|
247
|
+
None when the array library cannot export DLPack here (then callers stage
|
|
248
|
+
to host). sync=False skips the device sync when an immediately preceding
|
|
249
|
+
export already drained the queue. frame_major=True normalizes a (...,
|
|
250
|
+
bins, frames) spectrum to the STFT/ISTFT engines' frame-major contract;
|
|
251
|
+
other engines (CQT complex included) take compact tensors."""
|
|
235
252
|
m = array_module(t)
|
|
236
253
|
lead = tuple(t.shape[:-trailing])
|
|
237
254
|
tail = tuple(t.shape[-trailing:])
|
|
@@ -252,8 +269,9 @@ def export_dlpack(
|
|
|
252
269
|
t2 = t2.contiguous()
|
|
253
270
|
if kind == "metal" and sync:
|
|
254
271
|
torch.mps.synchronize()
|
|
272
|
+
stream = _stream_for(t2, kind) if stream is None else stream
|
|
255
273
|
try:
|
|
256
|
-
return t2
|
|
274
|
+
return _dlpack_capsule(t2, kind, stream), lead, t2, stream
|
|
257
275
|
except Exception:
|
|
258
276
|
return None
|
|
259
277
|
import cupy
|
|
@@ -265,8 +283,9 @@ def export_dlpack(
|
|
|
265
283
|
t2 = cupy.ascontiguousarray(t2.transpose(0, 2, 1)).transpose(0, 2, 1)
|
|
266
284
|
else:
|
|
267
285
|
t2 = cupy.ascontiguousarray(t2)
|
|
286
|
+
stream = _stream_for(t2, kind) if stream is None else stream
|
|
268
287
|
try:
|
|
269
|
-
return t2
|
|
288
|
+
return _dlpack_capsule(t2, kind, stream), lead, t2, stream
|
|
270
289
|
except Exception:
|
|
271
290
|
return None
|
|
272
291
|
|
|
@@ -289,8 +308,8 @@ def resident_istft(engine: Any, Z: Any, length: int, kind: str) -> Any:
|
|
|
289
308
|
exp = export_dlpack(Z, kind, trailing=2, cplx=True, frame_major=True)
|
|
290
309
|
if exp is None:
|
|
291
310
|
return None
|
|
292
|
-
cap, lead, _keep = exp
|
|
293
|
-
out_cap = engine.forward_dlpack(cap, length,
|
|
311
|
+
cap, lead, _keep, stream = exp
|
|
312
|
+
out_cap = engine.forward_dlpack(cap, length, stream)
|
|
294
313
|
out = import_dlpack(out_cap, array_module(Z))
|
|
295
314
|
return out.reshape(lead + tuple(out.shape[1:]))
|
|
296
315
|
|
|
@@ -300,10 +319,10 @@ def resident_forward(engine: Any, y: Any, output: str | None, kind: str) -> Any:
|
|
|
300
319
|
exp = export_dlpack(y, kind, trailing=1)
|
|
301
320
|
if exp is None:
|
|
302
321
|
return None
|
|
303
|
-
cap, lead, _keep = exp
|
|
322
|
+
cap, lead, _keep, stream = exp
|
|
304
323
|
if output is None:
|
|
305
|
-
out_cap = engine.forward_dlpack(cap,
|
|
324
|
+
out_cap = engine.forward_dlpack(cap, stream)
|
|
306
325
|
else:
|
|
307
|
-
out_cap = engine.forward_dlpack(cap, output,
|
|
326
|
+
out_cap = engine.forward_dlpack(cap, output, stream)
|
|
308
327
|
out = import_dlpack(out_cap, array_module(y))
|
|
309
328
|
return out.reshape(lead + tuple(out.shape[1:]))
|