Metadata-Version: 2.4
Name: cu3gppchan
Version: 0.1.0
Summary: GPU-accelerated 3GPP channel models (TR 38.901)
License: Apache-2.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: numpy
Requires-Dist: h5py
Requires-Dist: pyyaml
Requires-Dist: nvidia-cuda-runtime>=13.0.88
Requires-Dist: nvidia-curand>=10.4.0
Provides-Extra: cuda
Requires-Dist: cupy-cuda13x; extra == "cuda"
Dynamic: requires-python

<!-- SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->

# 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.

## Build a Wheel

```bash
# 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:

```bash
CU3GPPCHAN_CUDA_ARCHS="80;90" bash scripts/build_wheel.sh --clean
```

For editable development:

```bash
bash scripts/build.sh --python
python3 -m pip install -e python/
```

Verify:

```python
import cu3gppchan
print(cu3gppchan.__version__)  # 0.1.0
```

## 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

```python
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

```python
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

```bash
# Static analysis (flake8 / pylint / mypy)
bash tests/run_static_tests.sh

# Python unit tests
bash tests/run_unit_tests.sh --python_only
```

## Dependencies

Required (installed automatically by `pip install`):

- `numpy`
- `h5py`
- `pyyaml`

Optional:

- `cupy-cuda13x` — for `StatisticalChannel`, `FadingChannel`, and GPU array wrappers

## License

Apache-2.0. See file headers for details.
