Introduction to gr-cuda
Relevant source files
The following files were used as context for generating this wiki page:
gr-cuda is a GPU-accelerated Out-Of-Tree (OOT) module for GNU Radio 3.10+ designed to facilitate seamless, high-performance signal processing on NVIDIA GPUs. The module provides a specialized buffer system, cuda_buffer, which automates data movement between host memory and the device. This allows developers to receive device pointers directly in the work() function of their blocks, eliminating the need for manual cudaMemcpy operations and preventing unnecessary round-trips to the CPU.
The system supports creating GPU-accelerated blocks in both C++ and Python. Python developers can leverage CuPy for near-native performance, while C++ developers can inherit from specialized base classes to manage CUDA streams and kernel execution. Key architectural features include virtual memory management (VMM) for device-side circular buffers and a synchronization mechanism based on CUDA events to ensure data integrity across the GPU pipeline.
Sources: README.md:1-15, MANIFEST.md:1-25
Core Architecture and Features
The architecture of gr-cuda revolves around the cuda_buffer and a zero-copy pipeline that optimizes data flow through GPU kernels.
Key Architectural Components
| Feature | Description |
|---|---|
| Zero-copy GPU pipeline | cuda_buffer manages H2D/D2H transfers and synchronization, allowing kernels to run sequentially without CPU intervention. |
| CuPy Integration | Allows writing GPU blocks in Python by inheriting from cuda.sync_block, providing CuPy arrays directly to the user. |
| Virtual Memory Management | Implements circular buffers on the GPU using CUDA VMM, mirroring GNU Radio's CPU-side buffer behavior. |
| Managed CUDA Streams | Each cuda_block maintains a non-blocking stream (d_stream) for asynchronous execution. |
Sources: README.md:10-21, include/gnuradio/cuda/cuda_block.h:54-106
Data Flow and Synchronization
Synchronization is achieved through GPU-side events. The system uses two primary primitives: wait_for_work and mark_work_done. These ensure that a kernel does not read stale data or overwrite data currently in use by downstream consumers.
The flow above illustrates how GPU events manage the data hazards between blocks without blocking CPU execution.
Sources: include/gnuradio/cuda/cuda_block_helper.h:17-88, README.md:65-80
Development Framework
gr-cuda provides distinct paths for developing GPU blocks depending on the preferred language and complexity.
Python Development (CuPy)
Python blocks inherit from cuda.sync_block, cuda.decim_block, cuda.interp_block, or cuda.basic_block. The framework automatically presents input and output items as CuPy arrays.
- Classes:
cuda.sync_block,cuda.decim_block,cuda.interp_block,cuda.basic_block. - Logic: Users perform standard
cupy(e.g.,cp.multiply) operations within theworkmethod.
Sources: README.md:37-56, python/cuda/qa_cuda_block.py:20-150
C++ Development
C++ blocks typically use multiple inheritance, combining a standard GNU Radio block class (e.g., gr::sync_block) with gr::cuda::cuda_block.
- Member Variables:
d_stream(CUDA stream),d_min_grid_size,d_block_size. - Synchronization Helpers:
gr::cuda::wait_for_work(detail(), d_stream)andgr::cuda::mark_work_done(detail(), d_stream).
Sources: include/gnuradio/cuda/cuda_block.h:87-106, include/gnuradio/cuda/cuda_block_helper.h:35-88
System Integration and Build
The project uses CMake for configuration, requiring the CUDA Toolkit and GNU Radio development files.
Build Dependencies
- CUDA Toolkit: >= 10.2
- GNU Radio: >= 3.10
- CMake: >= 3.18
- CuPy: Required for Python-based GPU blocks.
Sources: README.md:25-32, CMakeLists.txt:14-25
Library Structure
The core logic is compiled into gnuradio-cuda, which links against the GNU Radio runtime and CUDA libraries.
Diagram shows the multiple inheritance pattern used for C++ GPU blocks.
Sources: lib/CMakeLists.txt:49-57, include/gnuradio/cuda/cuda_block.h:54-70
Included Blocks and Primitives
The module ships with several "batteries included" blocks for common operations:
| Category | Blocks |
|---|---|
| Math | add, multiply_const, complex_to_mag, nlog10 |
| Signal Processing | fft, fft_cupy |
| Flow Control | throttle, tee, nop |
| I/O | null_source, null_sink, load |
| Conversion | stream_to_vector, vector_to_stream |
Sources: lib/CMakeLists.txt:18-40, grc/CMakeLists.txt:11-34
Summary
gr-cuda provides a specialized infrastructure for GPU computing within GNU Radio, focusing on minimizing CPU-GPU synchronization overhead through its cuda_buffer implementation. By offering high-level Python abstractions via CuPy and structured C++ base classes, it enables efficient development of high-throughput signal processing applications that leverage modern NVIDIA hardware.