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)
This commit is contained in:
@ -63,7 +63,7 @@ from .visualizations import (
|
||||
generate_roughness, generate_wavelet,
|
||||
generate_svf, generate_aniso_open,
|
||||
)
|
||||
from .gpu import gpu_cleanup
|
||||
from .gpu import gpu_cleanup, num_gpus
|
||||
from .ign import generate_ign_overlay
|
||||
from .rendering import tif_to_png
|
||||
|
||||
@ -447,14 +447,20 @@ class LidarArchaeoPipeline:
|
||||
t_pipeline_start = time.time()
|
||||
|
||||
if self.workers > 1 and len(files) > 1:
|
||||
logger.info(f"Traitement parallèle avec {self.workers} workers...")
|
||||
n_gpus = num_gpus()
|
||||
if n_gpus > 1:
|
||||
logger.info(f"Traitement parallèle avec {self.workers} workers sur {n_gpus} GPUs...")
|
||||
else:
|
||||
logger.info(f"Traitement parallèle avec {self.workers} workers...")
|
||||
logger.info(f"Fichiers: {len(files)}")
|
||||
|
||||
with ProcessPoolExecutor(max_workers=self.workers) as executor:
|
||||
# Pass resolutions as comma-separated string for multiprocessing serialization
|
||||
resolutions_str = ','.join(str(r) for r in self.resolutions)
|
||||
n_gpus = num_gpus() or 1
|
||||
future_to_file = {
|
||||
executor.submit(_process_file_standalone, str(laz_file), str(self.input_dir), str(self.output_dir), resolutions_str, self.force, self.ground_method, self.force_classify, self.keep_tif, self.quality, self.only_viz, self.skip_viz, self.output_format): laz_file
|
||||
for laz_file in files
|
||||
executor.submit(_process_file_standalone, str(laz_file), str(self.input_dir), str(self.output_dir), resolutions_str, self.force, self.ground_method, self.force_classify, self.keep_tif, self.quality, self.only_viz, self.skip_viz, self.output_format, gpu_id % n_gpus): laz_file
|
||||
for gpu_id, laz_file in enumerate(files)
|
||||
}
|
||||
done = 0
|
||||
try:
|
||||
@ -526,11 +532,19 @@ class LidarArchaeoPipeline:
|
||||
logger.warning(f" Note: Impossible de supprimer les fichiers temporaires: {e}")
|
||||
|
||||
|
||||
def _process_file_standalone(laz_file_str, input_dir, output_dir, resolution, force=False, ground_method='auto', force_classify=False, keep_tif=False, quality=98, only_viz=None, skip_viz=None, output_format='avif'):
|
||||
def _process_file_standalone(laz_file_str, input_dir, output_dir, resolution, force=False, ground_method='auto', force_classify=False, keep_tif=False, quality=98, only_viz=None, skip_viz=None, output_format='avif', gpu_id=None):
|
||||
"""Standalone function for multiprocessing — creates its own pipeline instance.
|
||||
|
||||
Each worker gets its own temp directory to avoid file conflicts.
|
||||
When multiple GPUs are available, each worker is assigned a GPU via
|
||||
CUDA_VISIBLE_DEVICES to balance load across GPUs.
|
||||
"""
|
||||
# Assign GPU FIRST — before any CuPy import happens
|
||||
# This sets CUDA_VISIBLE_DEVICES and resets lazy CuPy init
|
||||
if gpu_id is not None and gpu_id >= 0:
|
||||
from .gpu import set_active_gpu
|
||||
set_active_gpu(gpu_id)
|
||||
|
||||
# Configure logging in worker process (spawn doesn't inherit parent config)
|
||||
import logging
|
||||
import sys
|
||||
|
||||
Reference in New Issue
Block a user