Skip to content

About

GPU-accelerated Network Digital Twin for AI-RAN experiments in Munich. Powered by NVIDIA Sionna RT and PyTorch for ray-traced RF simulation. Includes real-world Munich simulation, Mitsuba 3 backend, and finite-difference Adam optimization for antenna tuning. Automated KPI reporting (SINR/throughput) and coverage mapping for 6G R&D workflows

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

Copyright (c) 2026 Anubhab Banerjee (AnubhabBanerjee/kernel-critic) All rights reserved. No part of this repository may be used, redistributed, or modified in any form or by any means without the prior written permission of the author.


🚀 Sionna RT digital twin: Munich AI-RAN experiment

GPU-accelerated ray-traced RF simulation with Sionna RT—place cooperative gNodeBs in a Munich scene, solve planar radio maps, export KPIs and coverage PNGs, optionally tune antenna azimuth with finite-difference + Adam, and ship a Word baseline-vs-optimized comparison for reviews and demos.

This repo is a compact network digital twin slice: it pairs NVIDIA’s Sionna ray-tracing stack with a practical experiment driver and reporting path—useful for storytelling around O-RAN / AI-RAN, coverage optimization, and simulation-first R&D workflows.

🧠 System architecture

The pipeline is a linear experiment graph with an optional optimization loop—no separate services; everything runs from one Python entry point:

  1. Scene — Load the bundled Munich scene and attach two gNodeBs with positions, power, and aim from config.ini.
  2. Radio map (baseline) — Build a shared PlanarArray, configure RadioMapSolver on a planar grid, and produce a baseline PlanarRadioMap (GPU-backed Sionna RT solve).
  3. KPIs & figures — Derive SINR / throughput / outage-style metrics to CSV (and optional JSON), and render coverage PNGs for quick visual diffing.
  4. Optimization (optional) — Either a legacy stub sweep or an NN-style path: Adam on azimuth (α) offsets using central finite-difference gradients on a scalar loss (e.g. −P10 SINR), then re-export KPIs and maps.
  5. Report — Merge data/baseline/ and data/optimized/ KPI CSVs into a DOCX comparison suitable for write-ups and stakeholder decks.

🛠️ Stack & simulation backend

  • Sionna RT — Ray-traced propagation and RadioMapSolver on the Munich scene (see Sionna / NVIDIA ecosystem alignment).
  • Mitsuba 3 + Dr.Jit — Physically based rendering stack pulled in by Sionna’s RT path.
  • PyTorch — Tensor plumbing for the optional optimization loop (CUDA wheels recommended for parity with the reference requirements.txt pins).

The experiment is configuration-driven: tune grids, seeds, and KPI toggles without touching Python for many baseline-only studies.

✅ Prerequisites

  • Python 3.12+ (matches the pinned reference environment).
  • NVIDIA GPU recommended for interactive runs with CUDA PyTorch and responsive Sionna RT solves (CPU is possible but slower; adjust torch install—see below).
  • Enough disk for scene assets, data/ KPI bundles, and images/ PNGs (generated paths are gitignored by default).

⚙️ Installation

From the repository root (so import src.* resolves):

python3.12 -m venv ai_ran_env
source ai_ran_env/bin/activate   # Windows: ai_ran_env\Scripts\activate
pip install --upgrade pip
pip install -r requirements.txt

CPU-only PyTorch (skip CUDA index):

pip install torch==2.5.1 --index-url https://download.pytorch.org/whl/cpu
pip install -r requirements.txt --no-deps
pip install drjit lxml matplotlib mitsuba numpy python-docx sionna pytest

(Adjust so torch is not overwritten by the CUDA extra index if you need CPU wheels.)

Verify setup

After installing dependencies, smoke-check PyTorch, CUDA, and Sionna RT (including loading the bundled Munich scene):

python verify_setup.py

verify_setup() (in verify_setup.py) prints PyTorch version, whether CUDA is available and the active GPU name when present, then tries sionna.rt.load_scene on scene.munich so you catch missing mitsuba / wrong Python / broken installs before run_experiment.py.

📂 Configuration (config.ini)

Section Role
[nodeb_0], [nodeb_1] gNodeB positions (m) and power_dbm.
[look_at] Shared aim point when sites are created.
[planar_array] PlanarArray — num_rows, num_cols, spacing, pattern, polarization.
[radio_map_baseline] RadioMapSolver grid: center_*, orientation_*, size_*, cell_size_*, max_depth, samples_per_tx, seed.
[kpi] save_* toggles, sinr_outage_threshold_db, bandwidth_mhz.
[optimization] Stub loop: num_iterations, fixed α deltas (0 = skip).
[nn_optimization] use_nn_optimizer, num_epochs, learning_rate, finite_diff_epsilon_rad, optional torch_seed.

Defaults keep runs baseline-only (num_iterations = 0, use_nn_optimizer = false). Turn on use_nn_optimizer and set num_epochs for the NN-style loop.

🚀 Execution

End-to-end experiment:

python run_experiment.py

After data/baseline/ and data/optimized/ contain KPI CSVs, generate the Word report:

python -c "from src.report_generator import generate_kpi_comparison_docx; print(generate_kpi_comparison_docx())"

Smoke tests:

pytest

🎬 Example run

$ source ai_ran_env/bin/activate
$ python run_experiment.py
# Baseline radio map → data/baseline/baseline_kpis.csv, images/initial_radio_map.png
# If optimization enabled → data/optimized/optimized_kpis.csv, images/optimized_radio_map.png

Default output locations

Artifact Path
Baseline KPI CSV data/baseline/baseline_kpis.csv
Optimized KPI CSV data/optimized/optimized_kpis.csv
Baseline coverage PNG images/initial_radio_map.png
Optimized coverage PNG images/optimized_radio_map.png
KPI comparison DOCX data/kpi_comparison_report.docx

📁 Project layout

sionna-ndt/
├── verify_setup.py            # PyTorch/CUDA + Sionna RT Munich load smoke test
├── run_experiment.py          # Entry: baseline map → KPIs → PNGs → optional optimization
├── config.ini                 # Scene, arrays, radio map, KPI, optimization toggles
├── requirements.txt           # Pinned deps (CUDA PyTorch via extra index)
├── pyproject.toml
├── data/                      # Generated KPI bundles & reports (mostly gitignored)
│   ├── baseline/
│   └── optimized/
├── images/                    # Coverage PNGs (gitignored)
└── src/
    ├── scene_builder.py       # Munich + gNodeBs from INI
    ├── radiomap_builder.py    # PlanarRadioMap + RadioMapSolver
    ├── kpi_creator.py         # KPI CSV/JSON from PlanarRadioMap
    ├── image_creator.py       # PNG export
    ├── radio_optimization.py  # Stub sweep or NN optimizer dispatch
    ├── nn_optimizer.py        # Finite-difference Adam on α offsets
    └── report_generator.py    # Baseline vs optimized DOCX

🛣️ Roadmap

Active and planned hardening—this prototype is intentionally honest about where the stack can grow next:

  • Full autodiff through Sionna RT — Today’s loop uses finite-difference gradients on a scalar KPI, not end-to-end AD through RadioMapSolver / Mitsuba; exploring evaluated derivatives and tighter coupling where the stack allows.
  • Train elevation & polarization DoF — β / γ (and related orientation axes) locked in the current NN path; extend the optimizer to joint antenna pose search beyond α-only offsets.
  • Association-aware KPIs — Move from max-over-transmitter aggregate maps toward scheduler / association-style metrics where project goals require 3GPP-closer semantics.
  • CI & regression — Expand pytest coverage beyond CSV/DOCX smoke tests; optional headless baseline runs in CI with tight timeouts.

🙏 Acknowledgments

Built with Sionna (Sionna RT), Mitsuba 3, Dr.Jit, and the broader NVIDIA GPU computing ecosystem. Scene and solver behavior follow upstream library semantics—see project docs for license and attribution details.

About

GPU-accelerated Network Digital Twin for AI-RAN experiments in Munich. Powered by NVIDIA Sionna RT and PyTorch for ray-traced RF simulation. Includes real-world Munich simulation, Mitsuba 3 backend, and finite-difference Adam optimization for antenna tuning. Automated KPI reporting (SINR/throughput) and coverage mapping for 6G R&D workflows

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages