7 votos

¿Trabajando alrededor de lenta tramitación en funciones de ArcGIS Spatial Analyst?

Yo soy el procesamiento por lotes de una gran cantidad de las funciones de la distancia (~50,000) el uso de ArcGIS 9.3. En esta versión, el uso de spatial analyst funciones, parece ser el caso de que los usuarios no se pueden paralelizar procesos a través de núcleos, o escribir a in_memory en lugar del disco duro de pasos intermedios, y hay una fuga de memoria inherente en el programa que causa el procesamiento a ser más lenta varios bucles. He visto un post del foro que muestra una cruda solución para la pérdida de memoria que se apaga la recolección de basura, pero que por sí sola probablemente no va a ayudar un montón. Ahora estoy mirando los tiempos de procesamiento en el orden de un par de semanas en el equipo que estoy usando para esto.

¿Alguien sabe de alguna fiable work-arounds que me permitiría escribir SA de salida a in_memory, paralelizar procesos, o en alguna otra forma de aumentar significativamente la velocidad de procesamiento? Estoy abierto a que con ERDAS si tengo que.

Secuencia de comandos:

# Import system modules
import sys, string, os, arcgisscripting, time, shutil

# Create the Geoprocessor object
gp = arcgisscripting.create(9.3)    

# Allow overwrites
gp.overwriteoutput = 1

# ----------------------------------------------------------
# Set changeable model parameters
# ----------------------------------------------------------

cell_sz = 90.04245658
Max_oid = 1 # Should be = 54567 for irrigated agriculture, in province sources - Range function starts at 0 and stops 1 before number in range - so this number should be = number of records in shapefile
Win_sz = 3100 # This is the minimum possible size, and should make it so that even the largest k results in values = 0.001 or less at boundary 

# Create a folder for this set of runs, designated by the current time, then copy the script being run to the folder and time stamp it
t = time.localtime()
timeholder = str(t[0]) + '_' + str(t[1]) + '_' + str(t[2]) + '_' + str(t[3]) + str(t[4]) + '_' + str(t[5])
folder_time_name = "M:\\Jess_GIS_NIDR\\" + timeholder
os.mkdir(folder_time_name)
filename=sys._getframe().f_code.co_filename
shutil.copyfile(filename, folder_time_name + '\\this_script_executed_' + timeholder + '.py') #shutil

# Check out any necessary licenses
gp.CheckOutExtension("spatial")


cell_sz_str = str(cell_sz) + " METERS"
gp.cellSize = cell_sz


# Set up loop to go through the data set, iteratively select cells out, and processs distance calculations

for i in range(Max_oid):
    pt = i
    print "Processing point number " + str(pt)

    # Load prepped dataset containing this point
    irragg = "M:\\Jess_GIS_NIDR\\Pts_irragg\\pt_int_" + str(pt) + ".shp"

    # Publish output to common folders - may add additional dists_proc style folders
    Dists_raw = "in_memory\\dists_raw"


    # Define local variables (files only associated with processing this source cell)
    DEM = "M:\\Jess_GIS_NIDR\\InputRasters_Globcover_Hydrosheds\\HydroSHEDS\\dem"
    Dir_hydro = "M:\\Jess_GIS_NIDR\\InputRasters_Globcover_Hydrosheds\\HydroSHEDS\\drain_dir"
    Dists_fin = folder_time_name + "\\Dists\\Dists_fin.shp"


    # Identify and set processing extent

    y = []
    x = []

    cur = gp.SearchCursor(irragg)
    row = cur.Next()

    while row:
        extent = row.Shape.Extent   
        y.append(extent.ymin)    
        x.append(extent.xmin)    
        row = cur.Next()

    del row    
    del cur

    ypt = y.pop(0)
    xpt = x.pop(0)

    def incmax(a): return (a + Win_sz)    
    def incmin(b): return (b - Win_sz)

    ymin = incmin(ypt)    
    ymax = incmax(ypt)    
    xmin = incmin(xpt)    
    xmax = incmax(xpt)

    del y    
    del x

    gp.extent = "%f %f %f %f" % (xmin, ymin, xmax, ymax) 


    # Path-distance function

    gp.PathDistance_sa(irragg, Dists_raw, "", DEM, Dir_hydro, "FORWARD 0.01 0.5", "", "", "", "")
    # Convert distance results to permanent shape file
    gp.RasterToPoint_conversion(Dists_raw, Dists_fin, "VALUE")



    # Further processing of original distance raster to get at first order ideas of distance

    # ---------------------------------------------------------------------------------------

    # Crudely correct for the fact that the original land-use data was originally at a coarser resolution than this dataset
    gp.AddField_management(Dists_fin, "Dcorr", "DOUBLE", "", "", "", "", "NULLABLE", "", "")

    gp.CalculateField_management(Dists_fin, "Dcorr", "[RASTERVALU] - 90.04245658", "", "")   

    # First order distance function
    gp.AddField_management(Dists_fin, "Dist_k", "DOUBLE", "", "", "", "", "NULLABLE", "", "")
    gp.CalculateField_management(Dists_fin, "Dist_k", "Exp([Dcorr]*-0.00231)", "", "")

20voto

Nick Puntos 3115

Un par de generales trucos que he encontrado útiles en el pasado en esta situación:

  1. Ejecutar el script de Python como stand-alone (por ejemplo, a partir de INACTIVIDAD, PyWin, Eclipse o, preferiblemente, CMD) para eliminar la sobrecarga de ArcMap.
  2. El desove de los subprocesos es un viejo truco para la resolución de ArcGIS pérdidas de memoria, incluso si usted no desea parallize un proceso. Funciona porque la memoria se libera cada vez que el subproceso está cerrado, mientras que la memoria no es liberado correctamente en su actual código Python su proceso está abierto. Usted también puede 'paralellize' los procesos de desove de los subprocesos de esta manera (ver discusión más adelante). Se PUEDEN utilizar varios núcleos en ArcGIS 9.x de esta manera (yo lo he hecho en un 16 núcleo de la máquina y utiliza todos los 16 núcleos para una única secuencia de comandos).

Usted puede tener un control más complejos de su subprocesos fácilmente mediante el uso de concurrent.futures si se puede usar Python 3.x (se puede actualizar la versión de Python utilizado por Arco pero dadas las diferencias entre el Python 3.x y 2.x, que probablemente no es una opción para usted) o puede utilizar múltiples hilos en la versión anterior (Antes de que nadie se queja de que ArcGIS 9.x no es multiproceso, recuerde que no es de ArcGIS que se multithreading pero Python).

Sin embargo, usted NO desea multithread de la real tarea de geoprocesamiento a sí mismo como esto no va a ayudar a acelerar las cosas irónicamente. Python tiene el temido GIL (Bloqueo Global de Intérprete), que impide el uso de más de un núcleo, cuando el subprocesamiento múltiple. Para el geoprocesamiento esta es una mala noticia porque iba a meter un montón de uso intensivo de la CPU de las tareas de geoprocesamiento en un solo núcleo, porque todos están ejecutando a través de la misma intérprete. Yo lo que hago es multithread (o, preferiblemente, el uso concurrente.futuros, porque es más fácil) un poco de código que a su vez genera un subproceso. El subproceso no está limitado por el GIL (sólo los hilos). Esto suena complicado pero en realidad no lo es y se permite el uso de la agradable el proceso de cola y/o trabajadores de relación proporcionada por el multithreading, mientras que le da acceso completo para el total de la potencia de procesamiento de su PC.

Para mantener el control, puede utilizar subprocess.call en lugar de subprocces.popen a la fuerza de su hilo, para esperar en el subproceso de acabado. Puede que desee hacer esto si una posterior tarea se basa en la salida de un subproceso. Usted también quiere limitar el número de subprocesos porque un subproceso es independiente de la rosca a menos que usted tenga una devolución de llamada, por lo que un solo hilo se podría spawn cientos de subprocesos simultáneos si usted no es cuidadoso. PERO más paralelización no equivale necesariamente a más de velocidad para una máquina dada. Usted puede terminar de frenar las cosas! Si esta es una tarea que se repite mucho, entonces un poco de perfiles puede ir una manera larga. Las tareas de geoprocesamiento tienden a ser bastante CPU/memoria intensiva y que se han asentado en una regla de oro para limitar mi geoprocesamiento subprocesos a uno menos que el número de núcleos mi PC tiene (suponiendo que tengo un quad core o mejor - y cómo echo de menos a los 16-core bestia que tenía en una empresa). Esto permite un poco de espacio para el sistema operativo y el intérprete de Python en sí.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X