cu3GPPChan Python Bindings
Python interface to the GPU-accelerated cu3gppchan C++/CUDA library via nanobind.
Prerequisites
| Component | Version |
|---|---|
| Python | 3.10+ |
| CUDA Toolkit | 12.x+ |
| GPU | SM 8.0+ (Ampere / Hopper) |
| numpy | any |
| h5py | any |
| pyyaml | any |
| cupy (optional) | cupy-cuda13x — required for StatisticalChannel and FadingChannel |
The wheel build invokes the repo CMake project and packages both
_cu3gppchan*.so and libchanModels.so into the wheel. The target machine must
still provide the CUDA driver/runtime and system libraries such as HDF5.
On Windows the layout differs: chanModels, HDF5, yaml-cpp and the CUDA
runtime are all linked statically into _cu3gppchan.pyd, so the wheel
contains a single self-contained extension module and no libchanModels
counterpart. The only DLL resolved at runtime is curand64_10.dll from the
nvidia-curand dependency. A CUDA Toolkit install is not required to build or
run; the toolchain comes from PyPI. See the Windows section of the top-level
README.
Build a Wheel
# From the repository root:
bash scripts/build_wheel.sh --clean
# Install the generated wheel
python3 -m pip install dist/cu3gppchan-*.whl
# Verify import and basic config construction
python3 scripts/use_python_wheel.py
Set CUDA architectures with:
CU3GPPCHAN_CUDA_ARCHS="80;90" bash scripts/build_wheel.sh --clean
For editable development:
bash scripts/build.sh --python
python3 -m pip install -e python/
On Windows, use the PowerShell counterpart instead. The system prerequisites are
Visual Studio Build Tools 2022 with the "Desktop development with C++" workload,
uv, git, and a PowerShell host — no CUDA Toolkit install:
pwsh -NoProfile -File scripts/build_wheel.ps1 -CudaArchs 89 -Clean
python -m pip install (Get-Item dist\cu3gppchan-*-win_amd64.whl)
It builds one version-specific wheel per invocation (default -PythonVersion
3.12). build_wheel.sh instead loops Python 3.10–3.14 and partitions them into
three wheels by default: one cp312-abi3 wheel covering the non-free-threaded
≥ 3.12 interpreters, plus a version-specific wheel each for 3.10 and 3.11, which
cannot use the stable ABI. HDF5 1.14.6 and yaml-cpp 0.8.0 are compiled from
source via CMake FetchContent on every Windows build, which adds several
minutes. Only cp312 on SM 8.9 has been built and tested on Windows; other
interpreter versions and CUDA architectures are unexercised there. See the
Windows section of the top-level README for the full
prerequisite list.
Verify:
import cu3gppchan
print(cu3gppchan.__version__) # 0.1.4
Wheel smoke tests
python/tests/test_wheel_smoke.py is tiered:
- Tier 1 (import + config construction) runs everywhere.
- Tier 2 (
FadingChannel/StatisticalChannelGPU runs) auto-skips when no cupy/CUDA device is present. test_windows_cuda_dlls_resolveis Windows-only and skips elsewhere. It asserts that a directory containingcurand64_10.dllwas registered viaos.add_dll_directory, and skips entirely if CUDA is not supplied by thenvidiapip packages in that environment.
How the build scripts use it differs by platform:
scripts/build_wheel.shsmoke-tests repaired wheels only. Repair is on by default (REPAIR=1), and the pre-repair smoke run is gated onREPAIR -eq 0, so it is skipped unless you pass--no-repair. Afterauditwheel repair, each wheel is installed into a fresh venv and verified with eitherpytest python/tests/test_wheel_smoke.py -v— whenpytestcan be installed into that venv — orscripts/use_python_wheel.pyas a fallback when it cannot. Never both.- With
--no-repair, that pre-repair path runs instead and usesscripts/use_python_wheel.pyonly; pytest is never involved on that path. scripts/build_wheel.ps1runsscripts/use_python_wheel.pyonly. pytest is never invoked by the Windows build script — run it yourself.
Run manually against an installed wheel:
pip install "cu3gppchan[test]"
pytest python/tests/test_wheel_smoke.py -v
Package Structure
python/
pyproject.toml
src/cu3gppchan/
__init__.py Public API re-exports
_cu3gppchan*.so nanobind C++ extension (built by CMake)
libchanModels.so bundled runtime library used by the extension
statistical_channel.py StatisticalChannel — system-level SLS wrapper
fading_channel.py FadingChannel — link-level TDL/CDL wrapper
channel_config.py TdlChannelConfig / CdlChannelConfig
channel_api_ref.py 3GPP TR 38.901 reference data
cuda_utils.py CUDA stream and array helpers
API Overview
Low-Level Bindings (no CuPy needed)
These are direct nanobind wrappers of C++ classes. Use when you manage GPU memory yourself or only need configuration objects.
| Class | Description |
|---|---|
SimConfig |
Simulation parameters (frequency, bandwidth, run mode) |
SystemLevelConfig |
Scenario, topology (sites, sectors, UTs) |
LinkLevelConfig |
Fading type, delay profile, mobility |
ExternalConfig |
External cell/UT/antenna configuration |
TdlConfig / TdlChan |
TDL channel config and engine |
CdlConfig / CdlChan |
CDL channel config and engine |
StatisChanModel |
System-level stochastic channel engine |
GauNoiseAdder |
AWGN noise on GPU |
OfdmModulate / OfdmDeModulate |
OFDM mod/demod |
Scenario |
Enum: UMa, UMi, RMa, etc. |
High-Level Wrappers (require CuPy)
These provide a Pythonic interface with CuPy array I/O and automatic GPU memory management.
StatisticalChannel — System-Level Channel
from cu3gppchan import (
StatisticalChannel, SimConfig, SystemLevelConfig,
LinkLevelConfig, ExternalConfig, Scenario,
)
sim_cfg = SimConfig(center_freq_hz=3.5e9, bandwidth_hz=100e6, run_mode=1)
sys_cfg = SystemLevelConfig(scenario=Scenario.UMa, n_site=1, n_ut=10)
link_cfg = LinkLevelConfig(fast_fading_type=2) # CDL
ext_cfg = ExternalConfig()
chan = StatisticalChannel(sim_cfg, sys_cfg, link_cfg, ext_cfg)
# Run one TTI
chan.run(ref_time=0.0)
FadingChannel — Link-Level TDL / CDL
from cu3gppchan import FadingChannel, TdlChannelConfig
config = TdlChannelConfig(
n_cell=1, n_ue=1,
n_bs_ant=4, n_ue_ant=4,
delay_profile='A',
delay_spread_ns=30,
max_doppler_hz=5,
sc_spacing_hz=30e3,
)
chan = FadingChannel(config)
rx_signal = chan.run(tx_signal, ref_time=0.0, snr_db=20.0)
Configuration Classes
| Class | Description |
|---|---|
TdlChannelConfig |
TDL channel parameters (profiles A–E, delay spread, Doppler) |
CdlChannelConfig |
CDL channel parameters (antenna arrays, spatial correlation) |
CellParam |
Per-cell parameters (position, antenna panel) |
UtParamCfg |
Per-UT parameters (position, velocity, type) |
AntPanelConfig |
Antenna panel geometry [M_g, N_g, M, N, P] per TR 38.901 |
Enums
| Enum | Values |
|---|---|
Scenario |
UMa, UMi, RMa, InH, InF |
SensingTargetType |
ISAC target types |
UeType |
UE mobility types |
Running Tests
# Static analysis (flake8 / pylint / mypy)
bash tests/run_static_tests.sh
# Python unit tests
bash tests/run_unit_tests.sh --python_only
Troubleshooting
Windows: ImportError: DLL load failed while importing _cu3gppchan
_cu3gppchan.pyd links chanModels, HDF5, yaml-cpp and the CUDA runtime
statically; the one CUDA DLL it still imports is curand64_10.dll, which ships
inside the nvidia-curand pip package under
site-packages/nvidia/cu13/bin/x86_64/. Since Python 3.8 Windows does not
search PATH when loading an extension module's dependencies, so
cu3gppchan/__init__.py registers that directory via os.add_dll_directory at
import time.
If the import fails, confirm nvidia-curand is installed in the same
environment as cu3gppchan and check which directories were registered:
python -c "import cu3gppchan; print(cu3gppchan._dll_directories_added)"
An empty list means no nvidia/cu13 tree was found — the package is missing or
installed into a different environment. A non-empty list that contains no
directory holding curand64_10.dll means the DLL itself is absent; reinstall
nvidia-curand. The list is always empty on Linux, where the mechanism does
not apply.
Also verify the Microsoft Visual C++ Redistributable is present. The extension
links the MSVC runtime dynamically, as every CPython extension does, and needs
both VCRUNTIME140.dll (C runtime) and MSVCP140.dll (C++ runtime — required
because chanModels, yaml-cpp and nanobind are C++; HDF5 is built as its C
library only, so it does not contribute). A working Python install does
not imply MSVCP140.dll: CPython is written in C and pulls in only the C
runtime. If that is the missing DLL, install the Visual C++ Redistributable.
Dependencies
Required (installed automatically by pip install):
numpyh5pypyyaml
Optional:
cupy-cuda13x— forStatisticalChannel,FadingChannel, and GPU array wrappers
License
Apache-2.0. See file headers for details.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cu3gppchan-0.1.4-cp312-abi3-win_amd64.whl.
File metadata
- Download URL: cu3gppchan-0.1.4-cp312-abi3-win_amd64.whl
- Upload date:
- Size: 73.7 MB
- Tags: CPython 3.12+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a95d60405cb2b2b2887d35ad484809b59a0a433d28c39214fcfd04cfef0b626d
|
|
| MD5 |
25a012a05717a14b2f1f062450b2ea2c
|
|
| BLAKE2b-256 |
9b8792fbf35fc0cc29d323c6c476d05185fa7cbe3df3a665246340a7ba980b84
|
File details
Details for the file cu3gppchan-0.1.4-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: cu3gppchan-0.1.4-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 73.7 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4830681f275c6f2428ca0675390e5b2b9fc06119521e33891e38f13eda59cb64
|
|
| MD5 |
c0c5719ad86043ca5809352eaa8a6478
|
|
| BLAKE2b-256 |
f33ca113178a235256f983601233a77a83f030556999e551bbb94c461a053283
|
File details
Details for the file cu3gppchan-0.1.4-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: cu3gppchan-0.1.4-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 73.7 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57d084c91814f8a99ec969ddc9ea20adeab8b8d5266fad97be1027e10094bb05
|
|
| MD5 |
7a1d77e3daa8f283d2cef15f10c39957
|
|
| BLAKE2b-256 |
ba81c00382c08a20a18cc3fee9480704cc0324589a3f7da61b620ee10c2f48f5
|