← Blog
September 1, 2025

GPU geoespacial con RAPIDS cuSpatial: uniones espaciales y puntos en polígonos

Los conjuntos de puntos grandes contra polígonos grandes solían significar «vuelve mañana». Con CuSpatial, puede ejecutar esas uniones en cuestión de minutos, si su pila está bien configurada. Esta guía muestra una ruta limpia, además del código que puede pegar.

Qué cubriremos

  • Escogiendo un Plantilla preparada para CUDA (o una imagen de RAPIDS)
  • Conseguir CUDF/CU espacial listo sin afeitarse con yak
  • Dos patrones principales: punto en polígono y punto en polígono a escala (con filtrado espacial)
  • Un pequeño autoevaluación arnés
  • Dificultades en la VRAM, la E/S y la proyección

Start in seconds with the fastest, most affordable cloud GPU clusters.

Launch an instance in under a minute. Enjoy flexible pricing, powerful hardware, and 24/7 support. Scale as you grow—no long-term commitment needed.

Try Compute now

1) Elige tu imagen

En los alquileres de GPU, su trabajo se ejecuta dentro de una imagen. Dos buenas opciones:

A) Usa una imagen RAPIDS (la más rápida)

  • Registro (imagen): <24.xx>docker.io/rapidsai/rapidsai: -cuda12-runtime-ubuntu22.04-py3.10
  • Variables de entorno:
    • NVIDIA_VISIBLE_DEVICES=Todos
    • NVIDIA_DRIVER_CAPABILITIES=Computación, utilidad
  • CMD: mantenga su script de inicio o un shell interactivo.

B) Use una plantilla CUDA e instale RAPIDS con micromamba

# una vez en una instancia nueva
curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba
mkdir -p ~/micromamba &&. /bin/micromamba shell init -s bash -p ~/micromamba
fuente ~/.bashrc
micromamba create -y -n rapids -c rapidsai -c conda-forge rapids=24* python=3,10
micromamba activa rápidos
python -c «importar cudf, cuspatial; print (cudf). __versión__, cuspatial. __versión__)»

Cualquier camino te da brazalete + cuespacial con el espacio de usuario de CUDA listo. El controlador del host normalmente lo suministra el proveedor de servicios informáticos.

2) Formatos de datos que funcionan bien

  • GeoParquet para puntos y polígonos. Es columnar y compatible con CuDF.
  • Shapefile funciona, pero prefiero convertirla a GeoParquet una vez.
  • COCHES: reproyectar a un CRS métrico (p. ej., UTM) antes de realizar los cálculos de distancia/área. Guarda todo en el mismo CRS.

3) Punto en polígono (PIP): el patrón básico

Aquí se muestra la API en memoria con un polígono de juguete. Cambie datos reales más adelante.

importar cudf
importar cupy como copla
importar cuspacial

# Puntos (N x 2)
N = 1_000_000
puntos = cudf.DataFrame ({
«x»: cp.random.random (N),
«y»: cp.random.random (N),
})

# Un polígono cuadrado (anillo cerrado)
poly_offsets = cudf.Series ([0], dtype="int32")
ring_offsets = cudf.Series ([0], dtype="int32")
poly_x = cudf.Series ([0, 1, 0, 0], dtype="float64")
poly_y = cudf.Series ([0, 0, 1, 1, 0], dtype="float64")

máscara = cuspatial.point_in_polygon (
puntos ["x"], puntos ["y"],
poly_offsets, ring_offsets,
poly_x, poly_y,
)
# mask es un DataFrame bool (filas=puntos, cols=polígonos)
inside = puntos [mask.iloc [:, 0]]
imprimir (lente (interior))

Notas

  • Para polígonos múltiples, máscara tiene una columna por polígono. Usa .cualquiera (eje = 1) si solo te importa si un punto cayó ninguna polígono.
  • Utilice float64 para coordenadas de polígonos si tu dominio lo necesita; los puntos pueden ser float32/64.

4) PIP a escala: filtra y luego prueba

Las cargas de trabajo reales utilizan miles de polígonos y cientos de millones de puntos. Evalúe a menos candidatos filtrando primero con casillas delimitadoras y, a continuación, llame punto_in_polígono solo en esos.

importar cudf, ocupar como taza, cupatial

# Supongamos que los puntos y polígonos ya están cargados como cudf
# Ejemplo de estructura poligonal (múltiples polígonos, anillos):
# poly_offsets, ring_offsets, poly_points_x, poly_points_y

# 1) Construye cajas delimitadoras de polígonos (minx, maxx, miny, maxy)
boxes = cuspatial.polygon_bounding_boxes (
poly_offsets, ring_offsets, poly_x, poly_y
)
# cajas: DataFrame [min_x, min_y, max_x, max_y]

#2) Filtro rápido de candidatos: puntos dentro de cualquier casilla
cond = (
(puntos.x >= cajas.min_x.min ()) & (puntos.x <= cajas.max_x.max ()) &
(puntos.y >= boxes.min_y.min ()) & (points.y <= boxes.max_y.max ())
)
pts_cand = puntos [cond]

# 3) Prueba exacta solo para candidatos
máscara = cuspatial.point_in_polygon (
pts_cand.x, pts_cand.y,
poly_offsets, ring_offsets, poly_x, poly_y
)
any_hit = mask.any (eje = 1)
unido = pts_cand [any_hit]

Por qué esto ayuda
El filtrado de cajas delimitadoras reduce la cantidad de costosas pruebas de PIP. Para escalas extremas, consulte las utilidades de árbol cuádruple de CuSpatial para reducir aún más a los candidatos.

5) Lectura de datos reales (GeoParquet)

importar cudf

points = cudf.read_parquet («sensors_utm.parquet») # columnas: x, y, id
poly = cudf.read_parquet («zones_utm.parquet») # almacenados como anillos explotados

# Construya las matrices de polígonos esperadas por CUSpatial
poly_offsets = poli ["poly_offset"] .astype («int32")
ring_offsets = poli ["ring_offset"] .astype («int32")
poly_x = poli ["x"] .astype («float64")
poly_y = poli ["y"] .astype («float64")

Si los polígonos se encuentran en shapefiles, conviértelos una vez a GeoParquet (sin GPU está bien) para acelerar las cargas futuras.

6) Dask para trabajos más grandes que la GPU (opcional)

Para los conjuntos de datos que no caben en una GPU, usa Dask para particionar el trabajo. Patrón:

  • Divida puntos entre trabajadores/GPU.
  • Transmita polígonos (normalmente más pequeños) a los trabajadores.
  • Filtre los candidatos por partición y, a continuación, PIP.

El código refleja la versión de una sola GPU, pero envuelve los DataFrames de cuDF en Dask cuDF.

7) Arnés de autoevaluación

Manténgalo aburrido y comparable.

entradas: N_points, N_polygons, vértices de polígonos, CRS, precisión
hardware: modelo de GPU/VRAM, CUDA, controlador
código: versión cuSpatial, ruta exacta del código (con/sin filtro)
métricas: segundos para carga → filtro → PIP, pico de VRAM

Calcular coste por millón de puntos:

cost_por_millón = (precio_por_hora × pared_segundos/ 3600)/(N_puntos/ 1e6)

8) Consejos sobre VRAM y rendimiento

  • VRAM: vigila nvidia-smi. Si está cerca de estar llena, divida la tabla de puntos.
  • COCHES: reproyecte una vez en un CRS métrico antes de las operaciones de distancia/área; almacénelo en GeoParquet.
  • I/O: lee Parquet desde la NVMe local. Para los cubos en la nube, usa grupos de filas más grandes y snappy/zstd.
  • Precisión: float32 es más rápido y más pequeño. Use float64 solo si la validación lo requiere.
  • Explotación: cronometra cada etapa (carga, filtro, PIP) por separado; te ayuda a detectar los cuellos de botella.

9) Solución de problemas

Error de CUDA/sin GPU
Comprobar nvidia-smi dentro del contenedor. Asegúrate de que la imagen esté preparada para CUDA y de configurar las variables de entorno de NVIDIA.

MemoryError o OOM
Divida la tabla de puntos; filtre antes con bboxes; reduzca el conjunto de columnas.

Resultados incorrectos
CRS no coincidente. Reproyectar y volver a realizar la prueba. Confirme la orientación del anillo y los polígonos cerrados.

Cargas lentas
Mueva los datos a una NVMe local, cambie a GeoParquet y aumente el tamaño de los grupos de filas de Parquet.

Fragmento de métodos (copiar y pegar)

hardware:
gpu: "<model>(<VRAM>GB)»
conductor: "<NVIDIA driver>»
<CUDA version>cuda: "»
software:
<24.xx>imagen: «rapidsai/rapidsai: -cuda12-runtime-ubuntu22.04-py3.10"
pitón: «3.10"
bibliotecas:
<version>- brazalete:»
<version>- cuspacial: «»
entradas:
puntos: "s3://…/sensors_utm.parquet (N=<... >)»
polígonos: "s3://…/zones_utm.parquet (polys=<... >)»
correr:
script: "pip_join.py»
notas: «filtro bbox → PIP; CRS=EPSG:32633"
salidas:
wall_seconds: «<... >»
cost_por_millón: «<... >»

Lectura relacionada

Prueba Compute hoy

Inicia una instancia de GPU con una plantilla preparada para CUDA (p. ej., Ubuntu 24.04 LTS/CUDA 12.6) o tu propia imagen de GROMACS. Disfrute de una facturación flexible por segundo con plantillas personalizadas y la posibilidad de iniciar, detener y reanudar las sesiones en cualquier momento. ¿No está seguro de los requisitos de FP64? Póngase en contacto con el servicio de asistencia para que le ayuden a seleccionar el perfil de hardware ideal para sus necesidades informáticas.