Muestreo ráster eficiente de miles de millones de polígonos (cuadros delimitadores)

8

¿Cómo se puede calcular un ráster de manera eficiente (en Python), dado un conjunto que consiste en miles de millones de cuadros delimitadores (leídos secuencialmente de un archivo), y dado que los valores de ráster para cada celda deben dar el número de cuadros delimitadores superpuestos?

Para una trama 4000 * 4000

He cronometrado la creación de matriz numpy:

$ python -m timeit 'import numpy' 'a = numpy.zeros(shape=(4000,4000))'
10 loops, best of 3: 51.7 msec per loop

Creación de matriz de python estándar:

$ python -m timeit 'a = 4000*[0]' 'for i in range(4000):' ' a[i]=4000*[0]'
10 loops, best of 3: 218 msec per loop

Así que numpy es más rápido, pero aún 50 ms por ciclo, con mil millones de iteraciones, produce un tiempo de ejecución igual a aproximadamente un año (0.05 ms * 1000000000/60/60/24/365 = 1.5 años)

Por lo tanto, no es una opción probar cada polígono. ¿Cuál es un enfoque típico para este problema?

Pimin Konstantin Kefaloukos
fuente
Quiero resolverlo en una sola computadora, así que no hay soluciones de mapa / reducción, por favor :-)
Pimin Konstantin Kefaloukos
2
No entiendo la importancia de sincronizar las operaciones de creación de ráster. Este proceso necesita crear el ráster subyacente exactamente una vez. Dominar el tiempo de ejecución será cuestión de incrementar los recuentos dentro de los cuadros delimitadores. Todo lo que tienes que hacer es optimizar este bucle interno. Se puede hacer que vaya extremadamente rápido en un lenguaje compilado como C o Fortran.
whuber
Crear una trama cero es mi aproximación aproximada de cuánto tiempo tomaría incrementar los recuentos en un mal caso. Es un límite inferior de cuánto tiempo lleva el peor de los casos, donde el polígono es tan grande como el ráster, lenguaje compilado o no. La verdadera pregunta es, dado un ráster de 4000x4000, ¿qué tan rápido se puede incrementar todo el ráster en C o Fortran en una computadora portátil de nivel medio, detrás del sobre?
Pimin Konstantin Kefaloukos
2
Un BB determina un rango de filas indexadas por i0..i1 y un rango de columnas j0..j1. En el almacenamiento fila por fila, puede incrementar X (i, j0..j1) muy rápidamente (es almacenamiento contiguo). Eso probablemente se puede hacer en incrementos de 3E9 / seg e incluso vectorizado si lo desea para una operación mucho más rápida. Loop i desde i0 hasta i1: eso se encarga de una sola BB. Para cada BB, debe convertir sus coordenadas de límite en (i0, i1, j0, j1), pero eso no es demasiado elevado: puede hacerse más rápido de lo que puede leer las coordenadas.
whuber
1
Existe un blog interesante en el sitio de ESRI que habla sobre el uso de python y el procesamiento multinúcleo, ¿puede ser de ayuda? blogs.esri.com/esri/arcgis/2011/08/29/multiprocessing
Hornbydd

Respuestas:

2

Su timeitincluye la importación numpy, que agregaría algo de sobrecarga. Entonces, ¿por qué no escribe el código para un subconjunto de los cuadros delimitadores y cronometra ese ciclo, luego lo multiplica para estimar el tiempo total de ejecución?

Resolverlo en una sola computadora es, por naturaleza, serial, y con una operación relativamente simple, es posible que no obtenga una optimización significativa de un algoritmo ya simple. Podría intentar dividirlo en una especie de operación manual de reducción de mapas (sé que tiene una advertencia de "no reducción de mapas") y ejecutar tantas instancias como núcleos. Hacer mosaicos / fusionar n rásteres (el paso de reducción) es una operación trivialmente rápida. Probablemente será menos doloroso codificar que una solución multiproceso.

Alternativamente (o adicionalmente), podría escribir un programa para combinar ciertos cuadros delimitadores, como los superpuestos o anidados; esto requeriría un índice espacial. Si no tiene uno, puede ser beneficioso crear uno, especialmente si termina paralelizando localmente el algoritmo principal.

Además, no descarte la paralelización de varias computadoras de la mano. Si su mejor estimación es más de un año, entonces necesita sumar cuánto dinero costará su tiempo en la ejecución de la versión para una sola computadora, y compararlo con la contratación de un tiempo de computación en la nube. Como dice @whuber, 1024 GPU mordirán los datos tan rápido que te costará casi nada, incluso si pasas una semana dando vueltas a CUDA. Si es su jefe quien le prohíbe probarlo en más de una computadora, haga el análisis de costos y entréguele algunos números concretos; luego sopesará el valor de los datos con el valor de su tiempo.

MerseyViking
fuente
1

Si entendí correctamente, lo que quieres es como representar tu conjunto de miles de millones de cuadros delimitadores en una imagen. Excepto que en lugar de "pintar" cada polígono sobre una celda (píxel), los cuenta (o acumula).

Puede usar un código (relativamente) simple (en OpenGL, Vulcan, Direct3D) para representar los polígonos y acumular el recuento en el búfer de la plantilla. Tenga cuidado para que los polígonos caigan exactamente en los límites de los píxeles y elija un tipo de datos para el búfer de la plantilla para que el recuento no se desborde. Esperaría que se ejecute en unos segundos en una sola GPU ...

Pablo H
fuente