Skip to content

GPU Quick Start

Syota Sasaki edited this page May 5, 2026 · 1 revision

GPU Quick Start

End-to-end recipe for verifying that a brand-new environment can run the full smallbaselineApp.py workflow on the FernandinaSenDT128 tutorial dataset with the opt-in GPU solver. Every command is reproducible from a clean checkout — this page intentionally duplicates fragments of docs/installation.md and docs/gpu.md so a reviewer or new contributor can follow it without context-switching.

This is not a performance guide. For benchmarks see Performance Benchmarks.

What this verifies

  • The [gpu] extras install path (CUDA-enabled torch wheel + base deps in one uv pip install invocation).
  • mintpy.networkInversion.solver = torch runs the invert_network step on the GPU.
  • The whole 18-step smallbaselineApp.py pipeline completes end-to-end with GPU enabled (i.e. the GPU solver does not break any downstream step).

Out of scope: numerical equivalence vs. CPU, per-step timing, VRAM tuning. Those live in the mintpy-benchmark sibling repo.

Prerequisites

  • An NVIDIA GPU with a working CUDA driver (this fork is developed on RTX 5080 / Blackwell sm_120, CUDA driver ≥13.0).
  • This fork checked out, with the FernandinaSenDT128 tutorial dataset extracted at <repo>/FernandinaSenDT128/ (the tarball ships in this repo as FernandinaSenDT128.tar.xz; both are listed in .git/info/exclude).
  • uv ≥0.9.

All commands below are run from the repo root.

1. Create a fresh venv and install the [gpu] extras

The [gpu] extras pull a CUDA-enabled PyTorch wheel and all base dependencies (via the pyproject.toml dynamic-deps + requirements.txt chain), so a single uv pip install is enough — no separate requirements.txt step is needed.

uv venv --python 3.12 /tmp/issue5-venv

VIRTUAL_ENV=/tmp/issue5-venv uv pip install -e ".[gpu]" \
    --extra-index-url https://download.pytorch.org/whl/cu128 \
    --index-strategy unsafe-best-match

Both flags matter: pick the cuXXX wheel index that matches your CUDA toolkit (e.g. cu128 for Blackwell / RTX 50-series), and --index-strategy unsafe-best-match works around a stale setuptools pin in the PyTorch wheel index.

2. Verify CUDA visibility

/tmp/issue5-venv/bin/python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"
# expected: True / NVIDIA GeForce RTX 5080

If this prints False, stop here — selecting solver = torch on a host without a visible CUDA device raises immediately rather than silently falling back to CPU (design decision in #2).

3. Stage a fresh work directory

Run the verification in a sibling directory of the existing FernandinaSenDT128/mintpy/ so prior outputs do not interfere with update_mode. Copying the cached ERA5.h5 skips the CDS API download in the correct_troposphere step.

mkdir -p FernandinaSenDT128/mintpy-issue5/inputs
cp FernandinaSenDT128/mintpy/inputs/ERA5.h5 FernandinaSenDT128/mintpy-issue5/inputs/

4. Write the template

The template basename must be FernandinaSenDT128.cfgsmallbaselineApp.py infers the project name from the cfg basename and load_data infers the SAR sensor (and therefore the PLATFORM metadata key) by string-matching the project name against the known sensor list. A basename without a recognised sensor substring (Sen, Env, Alos, ...) leaves PLATFORM unset, which crashes the later correct_LOD step with KeyError: 'PLATFORM'. See smallbaselineApp.py:478 and objects/sensor.py:project_name2sensor_name. This is upstream MintPy behaviour, unrelated to the GPU solver.

cat > FernandinaSenDT128/mintpy-issue5/FernandinaSenDT128.cfg <<'EOF'
# vim: set filetype=cfg:
mintpy.load.processor        = isce
mintpy.load.metaFile         = ../reference/IW*.xml
mintpy.load.baselineDir      = ../baselines
mintpy.load.unwFile          = ../merged/interferograms/*/filt_*.unw
mintpy.load.corFile          = ../merged/interferograms/*/filt_*.cor
mintpy.load.connCompFile     = ../merged/interferograms/*/filt_*.unw.conncomp
mintpy.load.demFile          = ../merged/geom_reference/hgt.rdr
mintpy.load.lookupYFile      = ../merged/geom_reference/lat.rdr
mintpy.load.lookupXFile      = ../merged/geom_reference/lon.rdr
mintpy.load.incAngleFile     = ../merged/geom_reference/los.rdr
mintpy.load.azAngleFile      = ../merged/geom_reference/los.rdr
mintpy.load.shadowMaskFile   = ../merged/geom_reference/shadowMask.rdr
mintpy.load.waterMaskFile    = None

mintpy.reference.lalo                   = -0.30,-91.43
mintpy.topographicResidual.stepDate     = 20170910,20180613  #eruption dates
mintpy.deramp                           = linear

mintpy.networkInversion.solver          = torch
EOF

5. Run end-to-end

cd FernandinaSenDT128/mintpy-issue5
/tmp/issue5-venv/bin/smallbaselineApp.py FernandinaSenDT128.cfg | tee run.log

Expected wall time on RTX 5080 + NAS-backed data: ~7-8 min.

6. Confirm completion

grep -E "Normal end|torch solver|GPU auto chunk_size|Time used: 0" run.log | tail

Expected output:

estimating time-series via torch solver (batched, GPU)
GPU auto chunk_size = 19403 pixels (free VRAM 15.1 GiB)
   Normal end of smallbaselineApp processing!
Time used: 07 mins XX.X secs

The two lines from the invert_network step are the proof that the GPU path actually executed. The chunk count and exact pixel count vary with available VRAM; the auto-sizing formula is described in docs/gpu.md §3.

Cleanup

rm -rf /tmp/issue5-venv FernandinaSenDT128/mintpy-issue5

The fork's existing .venv/ and FernandinaSenDT128/mintpy/ are untouched by the procedure above.

Related

Clone this wiki locally