cuSignal - RAPIDS Signal Processing Library
RAPIDS v23.08 is the last formal release for cuSignal. Starting in 2019, cuSignal strived to provide a simple to use and highly performant library for signal processing developers working in Python. With over 400,000 total Anaconda downloads, we built an incredible community together. We are pleased to announce that much of the cuSignal codebase is moving to CuPy and is highly aligned with CuPy's goal to GPU-accelerate the NumPy and SciPy ecosystems. By moving our work to CuPy, we allow developers to use a single library for signal processing (and more!) while also reducing software dependencies.
To continue your journey with GPUs, Python, and Signal Processing, please:
cupyx.scipy.signal source codesignal module documentationThe offical deprecation announcement can be found here
cuSignal is a GPU-accelerated signal processing library in Python that is both based on and extends the SciPy Signal API. Notably, cuSignal:
If you're interested in the above concepts but prefer to program in C++ rather than Python, please consider MatX. MatX is an efficient C++17 GPU Numerical Computing library with a Pythonic Syntax.
A polyphase resampler changes the sample rate of an incoming signal while using polyphase filter banks to preserve the overall shape of the original signal. The following example shows how cuSignal serves as a drop-in replacement for SciPy Signal's polyphase resampler and how cuSignal interacts with data generated on GPU with CuPy, a drop-in replacement for the numerical computing library NumPy.
Scipy Signal and NumPy (CPU)
import numpy as np
from scipy import signal
start = 0
stop = 10
num_samps = int(1e8)
resample_up = 2
resample_down = 3
cx = np.linspace(start, stop, num_samps, endpoint=False)
cy = np.cos(-cx**2/6.0)
%%timeit
cf = signal.resample_poly(cy, resample_up, resample_down, window=('kaiser', 0.5))This code executes on 2x Xeon E5-2600 in 2.36 sec.
cuSignal and CuPy (GPU)
import cupy as cp
import cusignal
start = 0
stop = 10
num_samps = int(1e8)
resample_up = 2
resample_down = 3
gx = cp.linspace(start, stop, num_samps, endpoint=False)
gy = cp.cos(-gx**2/6.0)
%%timeit
gf = cusignal.resample_poly(gy, resample_up, resample_down, window=('kaiser', 0.5))This code executes on an NVIDIA V100 in 13.8 ms, a 170x increase over SciPy Signal. On an A100, this same code completes in 4.69 ms; 500x faster than CPU.
Next, we'll show that cuSignal can be used to access data that isn't explicitly generated on GPU. In this case, we use cusignal.get_shared_mem to allocate a buffer of memory that's been addressed by both the GPU and CPU. This process allows cuSignal to process data online.
cuSignal with Data Generated on the CPU with Mapped, Pinned (zero-copy) Memory
import cupy as cp
import numpy as np
import cusignal
start = 0
stop = 10
num_samps = int(1e8)
resample_up = 2
resample_down = 3
# Generate Data on CPU with NumPy
cx = np.linspace(start, stop, num_samps, endpoint=False)
cy = np.cos(-cx**2/6.0)
# Create shared memory between CPU and GPU and load with CPU signal (cy)
gpu_signal = cusignal.get_shared_mem(num_samps, dtype=np.float64)
%%time
# Move data to GPU/CPU shared buffer and run polyphase resampler
gpu_signal[:] = cy
gf = cusignal.resample_poly(gpu_signal, resample_up, resample_down, window=('kaiser', 0.5))This code executes on an NVIDIA V100 in 174 ms.
Finally, the example below shows that cuSignal can access data that's been generated elsewhere and moved to the GPU via cp.asarray. While this approach is fine for prototyping and algorithm development, it should be avoided for online signal processing.
cuSignal with Data Generated on the CPU and Copied to GPU
import cupy as cp
import numpy as np
import cusignal
start = 0
stop = 10
num_samps = int(1e8)
resample_up = 2
resample_down = 3
# Generate Data on CPU
cx = np.linspace(start, stop, num_samps, endpoint=False)
cy = np.cos(-cx**2/6.0)
%%time
gf = cusignal.resample_poly(cp.asarray(cy), resample_up, resample_down, window=('kaiser', 0.5))This code executes on an NVIDIA V100 in 637 ms.
cuSignal has been tested on and supports all modern GPUs - from Maxwell to Ampere. While Anaconda is the preferred installation mechanism for cuSignal, developers and Jetson users should follow the source build instructions below; there isn't presently a conda aarch64 package for cuSignal.
cuSignal can be installed with (Miniconda or the full Anaconda distribution) from the rapidsai channel. If you're using a Jetson GPU, please follow the build instructions below
conda install -c rapidsai -c conda-forge -c nvidia \
cusignal
# To specify a certain CUDA or Python version (e.g. 11.8 and 3.9, respectively)
conda install -c rapidsai -c conda-forge -c nvidia \
cusignal python=3.9 cudatoolkit=11.8For the nightly verison of cusignal, which includes pre-release features:
conda install -c rapidsai-nightly -c conda-forge -c nvidia \
cusignal
# To specify a certain CUDA or Python version (e.g. 11.8 and 3.9, respectively)
conda install -c rapidsai-nightly -c conda-forge -c nvidia \
cusignal python=3.9 cudatoolkit=11.8While only CUDA versions >= 11.2 are officially supported, cuSignal has been confirmed to work with CUDA version 10.2 and above. If you run into any issues with the conda install, please follow the source installation instructions, below.
For more OS and version information, please visit the RAPIDS version picker.
Since the Jetson platform is based on the arm chipset, we need to use an aarch64 supported Anaconda environment. While there are multiple options here, we recommend miniforge. Further, it's assumed that your Jetson device is running a current (>= 4.3) edition of JetPack and contains the CUDA Toolkit.
Please note, prior to installing cuSignal, ensure that your PATH environment variables are set to find the CUDA Toolkit. This can be done with:
export PATH=/usr/local/cuda/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}Clone the cuSignal repository
# Set the location to cuSignal in an environment variable CUSIGNAL_HOME
export CUSIGNAL_HOME=$(pwd)/cusignal
# Download the cuSignal repo
git clone https://github.com/rapidsai/cusignal.git $CUSIGNAL_HOMEInstall miniforge and create the cuSignal conda environment:
cd $CUSIGNAL_HOME
conda env create -f conda/environments/cusignal_jetson_base.yml Note: Compilation and installation of CuPy can be quite lengthy (~30+ mins), particularly on the Jetson Nano. Please consider setting the CUPY_NVCC_GENERATE_CODE environment variable to decrease the CuPy dependency install time:
export CUPY_NVCC_GENERATE_CODE="arch=compute_XX,code=sm_XX" where XX is your GPU's compute capability. If you'd like to compile to multiple architectures (e.g Nano and Xavier), concatenate the arch=... string with semicolins.
Activate created conda environment
conda activate cusignal-dev
Install cuSignal module
cd $CUSIGNAL_HOME
./build.sh # install cuSignal to $PREFIX if set, otherwise $CONDA_PREFIX
# run ./build.sh -h to print the supported command line options.Once installed, periodically update environment
cd $CUSIGNAL_HOME
conda env update -f conda/environments/cusignal_jetson_base.ymlOptional: Confirm unit testing via PyTest
cd $CUSIGNAL_HOME/python
pytest -v # for verbose mode
pytest -v -k # for more select testingClone the cuSignal repository
# Set the location to cuSignal in an environment variable CUSIGNAL_HOME
export CUSIGNAL_HOME=$(pwd)/cusignal
# Download the cuSignal repo
git clone https://github.com/rapidsai/cusignal.git $CUSIGNAL_HOMEDownload and install Anaconda or Miniconda then create the cuSignal conda environment:
Base environment (core dependencies for cuSignal)
cd $CUSIGNAL_HOME
conda env create -f conda/environments/cusignal_base.ymlFull environment (including RAPIDS's cuDF, cuML, cuGraph, and PyTorch)
cd $CUSIGNAL_HOME
conda env create -f conda/environments/cusignal_full.ymlActivate created conda environment
conda activate cusignal-dev
Install cuSignal module
cd $CUSIGNAL_HOME
./build.sh # install cuSignal to $PREFIX if set, otherwise $CONDA_PREFIX
# run ./build.sh -h to print the supported command line options.Once installed, periodically update environment
cd $CUSIGNAL_HOME
conda env update -f conda/environments/cusignal_base.ymlOptional: Confirm unit testing via PyTest
cd $CUSIGNAL_HOME/python
pytest -v # for verbose mode
pytest -v -k # for more select testingWe have confirmed that cuSignal successfully builds and runs on Windows by using CUDA on WSL. Please follow the instructions in the link to install WSL 2 and the associated CUDA drivers. You can then proceed to follow the cuSignal source build instructions, below.
Download and install Anaconda for Windows. In an Anaconda Prompt, navigate to your checkout of cuSignal.
Create c
No open issues yet, or sync has not completed.