Errores de multiprocesamiento - implementación de ArcGIS

13

Me preguntaba si alguien más en la comunidad aquí ha intentado usar el multiprocesamiento para análisis espaciales. Es decir, estoy intentando recorrer una serie de rásteres, crear un trabajo de multiprocesamiento para cada uno y ejecutarlos a través de una serie de pasos de geoprocesamiento dentro de una función de definición. Algo a lo largo de las líneas de

def net(RasterImage, OutFolderDir):
    arcpy.env.overwriteOutput = True  
    arcpy.env.workspace = OutFolderDir 
    DEM_Prj = DEM_Prj.tif

    try:
        arcpy.ProjectRaster_management(RasterImage, DEM_Prj....
        FocalStatistics(DEM_prj....)
        ...

if __name__ == '__main__':  
    InputFolder = r'C:\test\somepath'  
    Output = r'C:\test\somepath2'  
    arcpy.env.workspace = InputFolder  
    arcpy.env.scratchWorkspace = r'C:\test.gdb'    

    fcs = arcpy.ListRasters('*')
    pool = multiprocessing.Pool(4)   
    jobs = []                 
    for fc in fcs:
        rIn = os.path.join(InputFolder,fc)
        rOut = os.path.join(Output,fc[:-4])
        jobs.append(pool.apply_async(net,(rIn, rOut)))    

¡Ahora se ejecuta el multiprocesamiento, generalmente para el primer lote! Sin embargo, me encuentro con varios errores diferentes al intentar varios conjuntos de datos (más de 4 archivos, es decir, multiproceso de 4 núcleos) que incluyen:

ERROR 010302: Unable to create the output raster: C:\somepath\sr6f8~1\FocalSt_srtm1
ERROR 010067: Error in executing grid expression.
Failed to execute (FocalStatistics).

y

ERROR 999999: Error executing function.
Failed to copy raster dataset
Failed to execute (ProjectRaster)

En el primer error, observe la extraña carpeta que se crea (en la ubicación de OutFolderDir) asociada con las estadísticas focales que casi crea una réplica exacta de la salida final.

Mi pregunta se basa en su experiencia: ¿es imposible crear geoprocesamiento de varios pasos dentro de una función de multiprocesamiento? ¿O necesito colocar estos pasos en sus pasos de geoprocesamiento individuales?

UPDATE

Sigue encontrando errores similares: mover las funciones de importación a la función def ha demostrado que

import arcpy 
from arcpy.sa import *

no puede crear una salida con una advertencia de sintaxis agregada que de importación * no está permitido.

UPDATE # 2

Sé que esta es una respuesta tardía, pero pensé que podría beneficiar a otra persona para futuras referencias a mi solución que permita que el multiprocesamiento funcione con arcpy. El principal problema que encontré después de regresar a este problema no es la competencia de los módulos arcpy, sino la competencia por el espacio de trabajo que los ArcObjects utilizan para guardar los archivos temporales. Por lo tanto, considere ejecutar un contador en el argumento de análisis de multiprocesamiento para crear un espacio de trabajo único para cada proceso, es decir,

Counter = 0 
for fc in fcs:              
    rIn = os.path.join(InputFolder,fc)              
    rOut = os.path.join(Output,fc[:-4])                    
    jobs.append(pool.apply_async(net,(rIn, rOut,Counter)))            
    Counter += 1

Luego, en la función principal, cree un directorio temporal específico y asigne un espacio de trabajo exclusivo para cada tarea de multiprocesamiento.

def main(RasterImage,OutFolderDir,Counter)      
    TempFolder = os.path.join(os.path.dirname(OutFolderDir),'Temp_%s'%  (Counter))      
    os.mkdir(TempFolder)      
    arcpy.scratchWorkspace = TempFolder      
    ... 

Espero que ayude y gracias a Ragi por la sugerencia inicial de usar espacios de trabajo temporales separados, todavía desconcertado por la razón por la que originalmente no funcionó.

Recursos adicionales

Blog de multiprocesamiento de ESRI

Blog de Python, Gis and Stuff

    
pregunta BJEBN 13.12.2011 - 09:51

2 respuestas

6

Cada conexión IWorkspace (es decir, cada conexión de base de datos) tiene afinidad de subprocesos. Dos hilos no pueden compartir el mismo espacio de trabajo. Puedes tener un subproceso propio del recurso y luego sincronizar el acceso, pero si vas a usar funciones gp directas, entonces eso no es una opción.

La forma más fácil (coja) es crear procesos separados y luego realizar la sincronización de múltiples procesos (a diferencia de la sincronización de múltiples hilos). Incluso en ese caso, debe tener en cuenta el tipo de área de trabajo subyacente. Si no está utilizando arcsde (una fuente de datos multiusuario) probablemente usará una fuente de datos de un solo usuario (como personal o filegdb). ¡Entonces recuerde que eso significa que solo un proceso puede escribir a la vez! La sincronización típica (lame) para estos escenarios es que cada proceso paralelo se escribe en un espacio de trabajo temporal diferente y luego se combina todo en el espacio de trabajo de destino en un solo proceso.

    
respondido por el Ragi Yaser Burhum 15.12.2011 - 08:47
5

Tienes varios hilos compitiendo por el mismo recurso.

Intente mover su declaración 'importar arcpy' al destino del multiprocesamiento. Asegurará que arcpy esté trabajando con su propio conjunto de variables de entorno y memoria.

Suena absurdo, pero a pesar de que está configurando variables de entorno en el método de objetivo de multiproceso, Python sigue utilizando un espacio de memoria compartido para administrar el módulo arcpy y, por lo tanto, cualquier variable que establezca.

Arcpy no es seguro para subprocesos. Siempre fue pensado para ser utilizado dentro de un solo proceso. Pero hay soluciones provisionales.

Mi sugerencia fue importar arcpy dentro del destino para el nuevo proceso.

def _multiprocessing_target(args):
    import arcpy
    ...code
    
respondido por el OptimizePrime 13.12.2011 - 19:47

Lea otras preguntas en las etiquetas