Me preguntaba si alguien más en la comunidad aquí ha intentado usar multiprocesamiento para análisis espaciales. Es decir, estoy tratando de iterar a través de 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 en la línea 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, sigo encontrando varios errores diferentes cuando intento varios conjuntos de datos (más de 4 archivos, es decir, multiprocesamiento 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)
Observe en el primer error la carpeta extraña que se crea (en la ubicación OutFolderDir) asociada con las estadísticas focales que casi crean una réplica exacta de la salida final.
Mi pregunta se basa en su experiencia: ¿es imposible crear geoprocesamiento en varios pasos dentro de una función de multiprocesamiento? ¿O necesito agrupar estos pasos en sus pasos de geoprocesamiento individuales?
ACTUALIZAR
Todavía alentando errores similares: mover las funciones de importación a la función def ha demostrado que
import arcpy
from arcpy.sa import *
no se puede crear una salida con una advertencia de sintaxis agregada que no se permite la importación *.
ACTUALIZACIÓN # 2
Sé que esta es una respuesta tardía, pero pensé que podría beneficiar a alguien más para futuras referencias a mi solución alternativa que permite que el multiprocesamiento funcione con arcpy. El principal problema que encontré después de volver a este problema no es la competencia de los módulos arcpy, sino más bien la competencia sobre el scratchWorkspace 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 scratchWorkspace ú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, haga un directorio temporal específico y asigne un scratchWorkspace único a 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 eso ayude y gracias a Ragi por la sugerencia inicial de usar espacios de trabajo temporales separados, todavía desconcertado por qué originalmente no funcionó.
Recursos adicionales
R
. Estas no son buenas sugerencias para el trabajo de propósito general, porque pueden ser más problemáticas de lo que valen, pero cuando puede ahorrar horas a la vez, repetidamente, el esfuerzo podría dar sus frutos.Respuestas:
Cada conexión de IWorkspace (es decir, cada conexión de base de datos) tiene afinidad de hilos. Dos hilos no pueden compartir el mismo espacio de trabajo. Puede tener un subproceso propio del recurso y luego sincronizar el acceso, pero si va a usar funciones gp directas, entonces esa ni siquiera es una opción.
La forma más fácil (poco convincente) es crear procesos separados y luego realizar una sincronización multiproceso (en oposición a la sincronización multiproceso). Incluso entonces, debe tener en cuenta el tipo de espacio 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 (poco convincente) para estos escenarios es que cada proceso paralelo escribe en un espacio de trabajo temporal diferente y luego lo combina todo en su espacio de trabajo de destino en un solo proceso.
fuente
Tienes varios hilos que compiten por el mismo recurso.
Intente mover su declaración 'import arcpy' al objetivo del multiprocesamiento. Se asegurará de 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 destino Multiproceso, python todavía está utilizando un espacio de memoria compartida para administrar el módulo arcpy y, por lo tanto, cualquier variable que establezca.
Arcpy no es seguro para subprocesos. Siempre tuvo la intención de ser utilizado dentro de un solo proceso. Pero hay soluciones alternativas.
Mi sugerencia fue importar arcpy dentro del objetivo para un nuevo proceso.
fuente