@mytec: 3.8.0 start, stable w/0 ref+
This commit is contained in:
@@ -62,6 +62,9 @@ from app.services.parallel_coverage_service import (
|
||||
calculate_coverage_parallel, get_cpu_count, get_parallel_backend,
|
||||
CancellationToken,
|
||||
)
|
||||
# NOTE: gpu_manager and gpu_service are imported INSIDE functions that need them,
|
||||
# NOT at module level. This prevents worker processes from initializing CuPy/CUDA
|
||||
# which causes cudaErrorInsufficientDriver errors in child processes.
|
||||
|
||||
# ── New propagation models (Phase 3.0) ──
|
||||
from app.propagation.base import PropagationModel, PropagationInput, PropagationOutput
|
||||
@@ -546,8 +549,11 @@ class CoverageService:
|
||||
from app.services.gpu_service import gpu_service
|
||||
|
||||
t_gpu = time.time()
|
||||
grid_lats = np.array([lat for lat, lon in grid])
|
||||
grid_lons = np.array([lon for lat, lon in grid])
|
||||
# Import GPU modules here (main process only) to avoid CUDA context issues in workers
|
||||
from app.services.gpu_backend import gpu_manager
|
||||
xp = gpu_manager.get_array_module()
|
||||
grid_lats = xp.array([lat for lat, lon in grid], dtype=xp.float64)
|
||||
grid_lons = xp.array([lon for lat, lon in grid], dtype=xp.float64)
|
||||
|
||||
pre_distances = gpu_service.precompute_distances(
|
||||
grid_lats, grid_lons, site.lat, site.lon
|
||||
@@ -556,6 +562,9 @@ class CoverageService:
|
||||
pre_distances, site.frequency, site.height,
|
||||
environment=getattr(settings, 'environment', 'urban'),
|
||||
)
|
||||
gpu_time = time.time() - t_gpu
|
||||
backend_name = "GPU (CUDA)" if gpu_manager.gpu_available else "CPU (NumPy)"
|
||||
_clog(f"Precomputed {len(grid)} distances+path_loss on {backend_name} in {gpu_time:.2f}s")
|
||||
|
||||
# Build lookup dict for point loop
|
||||
precomputed = {}
|
||||
@@ -918,9 +927,12 @@ class CoverageService:
|
||||
await asyncio.sleep(0)
|
||||
|
||||
from app.services.gpu_service import gpu_service
|
||||
from app.services.gpu_backend import gpu_manager
|
||||
|
||||
grid_lats = np.array([lat for lat, _lon in tile_grid])
|
||||
grid_lons = np.array([_lon for _lat, _lon in tile_grid])
|
||||
t_gpu = time.time()
|
||||
xp = gpu_manager.get_array_module()
|
||||
grid_lats = xp.array([lat for lat, _lon in tile_grid], dtype=xp.float64)
|
||||
grid_lons = xp.array([_lon for _lat, _lon in tile_grid], dtype=xp.float64)
|
||||
|
||||
pre_distances = gpu_service.precompute_distances(
|
||||
grid_lats, grid_lons, site.lat, site.lon,
|
||||
@@ -929,6 +941,9 @@ class CoverageService:
|
||||
pre_distances, site.frequency, site.height,
|
||||
environment=getattr(settings, 'environment', 'urban'),
|
||||
)
|
||||
gpu_time = time.time() - t_gpu
|
||||
backend_name = "GPU (CUDA)" if gpu_manager.gpu_available else "CPU (NumPy)"
|
||||
_clog(f"Tile {tile_idx+1}: precomputed {len(tile_grid)} pts on {backend_name} in {gpu_time:.2f}s")
|
||||
|
||||
precomputed = {}
|
||||
for i, (lat, lon) in enumerate(tile_grid):
|
||||
@@ -1405,14 +1420,18 @@ class CoverageService:
|
||||
lat2: float, lon2: float
|
||||
) -> float:
|
||||
"""Calculate bearing from point 1 to point 2 (degrees)"""
|
||||
lat1, lon1, lat2, lon2 = map(np.radians, [lat1, lon1, lat2, lon2])
|
||||
# Use math for scalar operations (faster than numpy/cupy for single values)
|
||||
lat1_r = math.radians(lat1)
|
||||
lon1_r = math.radians(lon1)
|
||||
lat2_r = math.radians(lat2)
|
||||
lon2_r = math.radians(lon2)
|
||||
|
||||
dlon = lon2 - lon1
|
||||
dlon = lon2_r - lon1_r
|
||||
|
||||
x = np.sin(dlon) * np.cos(lat2)
|
||||
y = np.cos(lat1) * np.sin(lat2) - np.sin(lat1) * np.cos(lat2) * np.cos(dlon)
|
||||
x = math.sin(dlon) * math.cos(lat2_r)
|
||||
y = math.cos(lat1_r) * math.sin(lat2_r) - math.sin(lat1_r) * math.cos(lat2_r) * math.cos(dlon)
|
||||
|
||||
bearing = np.degrees(np.arctan2(x, y))
|
||||
bearing = math.degrees(math.atan2(x, y))
|
||||
|
||||
return (bearing + 360) % 360
|
||||
|
||||
|
||||
Reference in New Issue
Block a user