Commit Graph

24 Commits

Author SHA1 Message Date
7c10ae3e18 Rasterisation GPU du DTM (bin_mean_2d) + GPU fallback renforcé et workers mono-thread
Rastérisation des points sol via gpu.bin_mean_2d (bincount 2D CuPy, sémantique
identique au repli scipy binned_statistic_2d) : ~x7 plus rapide sur cette
étape, logs de durée par phase dans create_dtm_fast. safe_gpu_call retente en
CPU sur toute erreur GPU (pas seulement les messages CUDA) : un transfert
échoué en cours de run mélangeait types numpy/cupy et faisait échouer la
visualisation entière. Workers en mono-thread BLAS/OpenMP sur la machine de
traitement (plus de saturation des cœurs pendant les runs).
2026-09-21 23:42:55 +02:00
796e68c870 Supprimer le code mort (imports inutilisés, variable _xp, conseil GPU inatteignable) 2026-09-18 21:31:19 +02:00
f3708f8449 Journaliser les replis CPU du GPU et retirer une copie VRAM inutile 2026-09-18 21:23:39 +02:00
422f58d772 Split webapp for Raspberry Pi deployment, remote generation API and sync
La webapp (carte + vignettes) et la génération de tuiles se déploient sur
deux machines : image légère Dockerfile.webapp (FastAPI + Pillow AVIF
natif + pyproj) sur Raspberry Pi, pipeline complet sur la machine de
traitement. LIDAR_GENERATION_URL délègue /api/generate, /api/preview et
/api/status ; /api/sync ramène les tuiles par rsync puis régénère
vignettes et index localement. Token partagé optionnel
(LIDAR_API_TOKEN/LIDAR_REMOTE_TOKEN). Retire du dépôt les journaux
internes (.swival, audit-findings) et les données (data/, notebooks/).
Doc : docs/DEPLOY_WEBAPP.md.
2026-09-02 19:44:39 +02:00
c58ca3f477 Fix multi-GPU detection, VRAM leak on disable, and orphaned GPU array handling
_gpu_candidates was never populated (typo: _candidate_gpus), breaking
num_gpus()/available_gpu_ids() and the multi-GPU round-robin. available_gpu_ids
also indexed tuples with dict syntax (TypeError). disable_gpu() now frees the
memory pool before clearing refs (was leaking VRAM). to_cpu() and safe_gpu_call()
survive disable_gpu() via a persistent _cupy_ndarray type reference so orphaned
GPU arrays are recovered to CPU. log_gpu_status() now uses Device(0) instead of
the host index (CuPy renumbers to 0 after CUDA_VISIBLE_DEVICES).
2026-07-23 20:06:14 +02:00
8478106e51 Fix GPU bugs, restore aspect viz, fix anomaly mask, revert flow_acc to vectorized D8
GPU: num_gpus() returns real count via _gpu_candidates (was always 0/1),
available_gpu_ids() added. Pipeline: round-robin on real GPU host indices
instead of file enumerate index. _process_file_standalone signature simplified.

Restore generate_aspect using SharedDEM gradient (dy, dx). Colormap twilight
0-360 fixed range. VIZ_STEPS back to 16.

Flow accumulation: revert to vectorized numpy D8 direction + module-level
numba accumulator (cached, top-down sort) with Python fallback. Priority-flood
NaN-aware. Log1p transform.

Anomaly mask: replace RMS+fixed 2sigma threshold (was blank) with weighted
sum of |z-score| + adaptive percentile threshold. Absolute z-score captures
both positive and negative deviations. 6% signal detected vs 0% before.
2026-06-01 23:03:19 +02:00
618cd620e3 Fix GPU auto-detection for RTX 5060 Ti (sm_120) — CUDA_VISIBLE_DEVICES via run.sh -e + warm-up in Python 2026-06-01 00:07:40 +02:00
67d024a64e Auto-detect best GPU with sm_120 skip: prefer RTX 5060 Ti, fall back to 4060 Ti when nvcc/CuPy does not support sm_120 yet 2026-05-31 23:14:23 +02:00
8490b5ddf0 Use CuPy Device API instead of CUDA_VISIBLE_DEVICES for JIT compatibility on sm_120 2026-05-31 22:14:18 +02:00
a5af50c043 Remove sm_120 filter: CuPy 13.4 JIT supports RTX 5060 Ti 2026-05-31 22:04:20 +02:00
04eac7eded Support RTX 5060 Ti: CuPy 13.4 JIT compiles kernels at runtime for sm_120 2026-05-31 22:01:08 +02:00
17fd96fdf5 Remove broken CuPy 13.x memory pool setup 2026-05-31 21:35:27 +02:00
5a9cdddcfb Auto-detect usable GPU (skip sm_120 RTX 5060, fallback to RTX 4060 Ti) 2026-05-31 21:32:34 +02:00
9119d63bc3 Auto-detect best GPU (RTX 5060 preferred) + build CuPy from source for sm_120 2026-05-31 20:55:06 +02:00
d2f382c94d Per-GPU warm-up with fallback CPU on NO_BINARY + memory pool limit per worker 2026-05-31 20:30:22 +02:00
a8fd8addb7 Limit GPU memory pool per worker to prevent OOM with multi-worker 2026-05-31 19:51:32 +02:00
b5b6787956 Add --gpu flag to select specific GPU(s) for processing 2026-05-31 16:06:58 +02:00
a3f7b44874 Fix multi-GPU with lazy CuPy init + rendering improvements
GPU fix:
- Revert to CUDA_VISIBLE_DEVICES approach but with lazy CuPy init
- gpu.py: CuPy is no longer imported at module level; _init_gpu()
  imports it lazily on first to_gpu() call. This allows workers to
  set CUDA_VISIBLE_DEVICES before CuPy creates a CUDA context.
- gpu.py: detect GPU count via nvidia-smi (no CUDA context needed)
- pipeline.py: each worker sets CUDA_VISIBLE_DEVICES=N before CuPy
  init, so each process uses only its assigned GPU

Rendering improvements:
- Title: split into bold title (14pt) + italic description (10pt)
  instead of single 15pt bold block
- North arrow: moved inside data area (top-right corner) with
  semi-transparent white background for readability over data
- Colorbar: full height (no gap for compass rose), added
  ScalarFormatter(useOffset=False) to avoid scientific notation
- Colorbar compass rose gap removed since north arrow is now
  inside the data area
2026-05-15 12:24:57 +02:00
5af53a390f Add multi-GPU support and fix scale bar / location map overlap
Multi-GPU:
- gpu.py: lazy CuPy initialization so CUDA_VISIBLE_DEVICES takes
  effect before context creation in worker processes
- gpu.py: detect GPU count via nvidia-smi (no CUDA import needed)
- gpu.py: add set_active_gpu() to assign workers to specific GPUs
- pipeline.py: distribute files across GPUs (file % num_gpus) in
  parallel mode so both GPUs are used simultaneously
- pipeline.py: log GPU count when multiple GPUs detected

Layout fixes:
- rendering.py: move scale bar left of location map to avoid overlap
  (scale bar ends at fig_x=0.78, map starts at 0.82)
- rendering.py: expand location map inset to 0.16x0.13 fig coords
- rendering.py: return bounds from _download_location_map so imshow
  extent matches the actual IGN tile coverage (80km context)
- ign.py: add min_zoom parameter to download_ign_tiles, fixing the
  location map that was broken (zoom 10 blocked by hardcoded min_zoom=15)
2026-05-15 12:00:34 +02:00
989bb71497 Add RRIM, Multi-Hillshade RGB, and Local Dominance visualizations
Three new visualizations complementing existing SVF/openness/LRM/MSRM:

- RRIM (Red Relief Image Map): RGB composite combining positive openness
  (R), inverted slope (G), negative openness (B). Uses ray-tracing
  to compute both openness values in a single pass.

- Multi-Hillshade RGB: 3 azimuths (315°, 135°, 45°) mapped to R/G/B
  channels with slope blending. Color reveals structure orientation.

- Local Dominance: (dem - local_min) / (local_max - local_min) using
  min/max filters. Measures local height position — complements openness.

Also adds:
- _compute_openness_both() helper for shared ray-tracing (used by RRIM)
- xp_maximum_filter() in gpu.py (GPU/CPU abstraction)
- Entries in COLORMAPS, RGB_LEGENDS, VIZ_STEPS, and is_rgb detection
- All NaN handling follows existing patterns (nan_mask restoration)
2026-05-14 01:03:47 +02:00
a88e430f02 Audit: corrections de bugs identifiés
- rendering.py: colorbar cassée quand NaN mask actif — créer un
  ScalarMappable avec le cmap sauvegardé au lieu de rely sur
  l'image RGBA qui n'a plus de cmap
- rendering.py: nettoyage du PNG temporaire avec try/finally et
  missing_ok=True pour éviter les fichiers orphelins
- gpu.py: to_gpu() convertit en float32 au lieu de float64 pour
  réduire la consommation mémoire GPU
- dtm.py: utiliser _file_basename() de pipeline.py au lieu de
  dupliquer la logique d'extraction du basename
- pipeline.py: docstring corrigé (18 visualisations, pas 19)
- cli.py: --file supporte aussi les noms sans .copc
  (recherche .copc.laz et .copc.las en plus de .laz et .las)
2026-05-10 12:11:13 +02:00
e66a71d885 Fix CUDA fork: spawn multiprocessing + graceful GPU fallback
- multiprocessing.set_start_method('spawn') pour éviter la corruption
  du contexte CUDA dans les processus forkés
- to_gpu() et xp_*_filter() attrapent les erreurs CUDA et tombent
  sur CPU au lieu de crasher
- _gpu_available() vérifie que le GPU est utilisable avant chaque opération
- gpu_cleanup() attrape les exceptions au cas où le GPU serait indisponible
2026-05-10 01:04:02 +02:00
e734c9c472 Suppression éclairage solaire, GPU accéléré, --file multi, tests unitaires
- Suppression de generate_solar (éclairage solaire) des visualisations
- Accélération GPU de hillshade, slope, aspect, curvature, depressions,
  anomalies, roughness, texture GLCM, flow (sink filling)
- Nettoyage mémoire GPU entre visualisations (gpu_cleanup)
- Correction OOM texture GLCM: calcul entropie bin par bin au lieu d'un
  tableau 3D massif sur GPU
- Correction bug: xp_minimum_filter manquant dans imports visualizations
- Option --file accepte plusieurs noms complets sans extension
- run.sh affiche l'aide si appelé sans arguments
- Option --test pour exécuter les tests unitaires dans Docker
- Filtre ReturnNumber>=1 intégré dans le pipeline PDAL (plus d'erreur SMRF)
- 60 tests unitaires: GPU, visualisations, rendering, DTM, pipeline, CLI
- Ajout pytest au Dockerfile
2026-05-10 00:57:39 +02:00
405b0d20f8 Refactor pipeline en modules + logging verbose/debug + options CLI
- Découpage du monolithe process_lidar.py (~2750 lignes) en package
  lidar_pipeline/ avec 9 modules (gpu, dtm, visualizations, ign,
  rendering, pipeline, cli, __init__, __main__)
- Logging configurable: -v (verbose avec timestamps) et --debug
  (détails internes fichier:ligne)
- Option --force pour régénérer tous les fichiers (par défaut skip
  les WebP existants)
- Option --file NOM pour traiter un seul fichier LAZ (tests rapides)
- ProcessPoolExecutor avec répertoires temporaires uniques par worker
- Suppression du code mort (geomorphons, hillshade_ne, nodata_mask)
- Aucun fichier TIFF résiduel après conversion WebP
- setup.py pour installation pip, stub process_lidar.py compatible
2026-05-10 00:15:29 +02:00