Errori di elaborazione multipla: implementazione di ArcGIS


13

Mi chiedevo se qualcun altro nella comunità qui ha tentato di utilizzare la multi-elaborazione per analisi spaziali. Vale a dire che sto cercando di scorrere una serie di raster, creare un lavoro multiprocessore per ciascuno ed eseguirli attraverso una serie di passaggi di geoprocesso all'interno di una funzione def. Qualcosa del genere

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)))    

Ora viene eseguito il multiprocessing, di solito per il primo batch! Tuttavia, continuo a imbattermi in diversi errori quando provo diversi set di dati (più di 4 file - ovvero 4 core multiprocessing) tra cui:

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).

e

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

Si noti nel primo errore la strana cartella che viene creata (nella posizione OutFolderDir) associata alle statistiche focali che quasi crea una replica esatta dell'output finale.

La mia domanda si basa sulla tua esperienza: è impossibile creare una geoprocessing in più passaggi all'interno di una funzione multiprocessing? O devo affiancare questi passaggi ai loro singoli passaggi di geoprocessing?

AGGIORNARE

Riscontro ancora errori simili: lo spostamento delle funzioni di importazione nella funzione def ha dimostrato che

import arcpy 
from arcpy.sa import *

impossibile creare un output con un avviso di sintassi aggiunto che l'importazione * non è consentita.

AGGIORNAMENTO # 2

So che questa è una risposta tardiva, ma ho pensato che potrebbe essere utile a qualcun altro per riferimento futuro alla mia soluzione alternativa che consente al multiprocessore di funzionare con arcpy. Il problema principale che ho riscontrato dopo essere tornato a questo problema non è la concorrenza dei moduli arcpy, ma piuttosto la competizione su scratchWorkspace che ArcObjects utilizza per salvare i file temporanei. Pertanto, considerare di eseguire un contatore nell'argomento di analisi multiprocessing per creare un unico scratchWorkspace per ciascun processo, ad es

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

Quindi, nella funzione principale, creare una directory temporanea specifica e assegnare un unico scratchWorkspace a ciascuna attività multiprocessore.

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

Spero che sia d'aiuto e grazie a Ragi per il suggerimento iniziale di utilizzare spazi di lavoro temporanei separati, ancora sconcertati dal motivo per cui in origine non funzionava.

Risorse addizionali

Blog multiprocesso ESRI

Blog di Python, Gis e Stuff


Questo suggerimento è così rozzo che non voglio formalizzarlo in una risposta, ma hai mai pensato di eseguire ArcGIS su più macchine virtuali contemporaneamente? (Potrebbe essere necessaria un'installazione separata in ciascuna VM, ognuna con la propria struttura di directory.) Un altro pensiero radicale è quello di elaborare parte dell'elaborazione: ad esempio, potrebbe essere eseguito focalstats R. Questi non sono buoni suggerimenti per il lavoro per scopi generali, perché potrebbero essere più problemi di quanto valgono, ma quando puoi risparmiare ore alla volta, ripetutamente, lo sforzo potrebbe ripagare.
whuber

Risposte:


7

Ogni connessione IWorkspace (ovvero ogni connessione al database) ha affinità di thread. Due thread non possono condividere lo stesso spazio di lavoro. Puoi avere un thread proprietario della risorsa e quindi sincronizzare l'accesso, ma se stai per utilizzare le funzioni gp straight, allora questa non è nemmeno un'opzione.

Il modo più semplice (zoppo) è creare processi separati e quindi eseguire la sincronizzazione multi-processo (al contrario della sincronizzazione multithread). Anche allora dovresti essere consapevole del tipo di area di lavoro sottostante. se non si utilizza arcsde (un'origine dati multiutente) probabilmente si utilizzerà un'origine dati utente singolo (come personale o filegdb). Quindi ricorda che significa che solo un processo può scrivere alla volta! La sincronizzazione tipica (lame) per questi scenari è che ogni processo parallelo scrive in uno spazio di lavoro temporaneo diverso e quindi si fonde tutto nello spazio di lavoro di destinazione in un singolo processo.


Buoni suggerimenti ... In realtà, anche se non l'ho aggiunto a questo post, sto creando una nuova cartella basata sul nome dell'immagine raster e impostando l'area di lavoro per ciascun processo su quella directory specifica. Si tratta di directory di file separate per ogni immagine raster e non di geodatabase separati (ne ho bisogno?). Avevo quindi pianificato di utilizzare una semplice funzione os.walk per trovare tutti quei file di cui avevo bisogno per spostarli nel file di geodatabase desiderato.
BJEBN,

Stai solo facendo operazioni raster? Esistono thread o processi di lettura / scrittura nello stesso geodatabase contemporaneamente?
Ragi Yaser Burhum,

Ciao, mi dispiace che avrei potuto essere un po 'poco chiaro con la precedente dichiarazione. Solo le operazioni raster (riproiettare, focalstats, riclassificare ecc ...) e tutte quelle fasi di geoprocessing vengono eseguite in un ordine sequenziale (o devono essere) per ogni immagine raster. Queste immagini raster vengono salvate in un'area di lavoro della cartella univoca. Tutti i raster originali stanno leggendo dalla stessa directory (non la stessa immagine) in quanto crea i singoli lavori da inviare.
BJEBN,

Dopo aver ripensato un po ', ho provato a specificare uno spazio di lavoro specifico per ogni immagine. I DEM vengono proiettati correttamente, tuttavia questo ha prodotto un nuovo errore nella fase focalstats: "il tipo <Raster> non è supportato". Ho provato a specificare l'intero indirizzo della directory ma senza fortuna. Ho caricato i raster proiettati in arcgis senza alcun problema.
BJEBN,

Bene, questo significa che stai andando avanti. Per i focalstat, dipende da come viene implementato internamente. Se si tratta di una nuova implementazione, può richiedere uno spazio di lavoro (ad esempio un geodatabase). Tuttavia, se si tratta di una di quelle funzioni che non sono ancora state aggiornate (!?!?!) Lo spazio di lavoro che consente potrebbe essere solo una cartella. Per quella particolare funzione GP, specifica solo una cartella (mantieni lo spazio di lavoro per il resto) e guarda cosa succede.
Ragi Yaser Burhum,

5

Hai diversi thread in competizione per la stessa risorsa.

Prova a spostare la tua istruzione "import arcpy" nel target del multiprocessing. Assicurerai che arcpy stia funzionando con il proprio set di variabili d'ambiente e memoria.

Sembra assurdo, ma anche se si stanno impostando variabili d'ambiente nel metodo target Multiprocess, python sta ancora usando uno spazio di memoria condivisa per gestire il modulo arcpy e quindi qualsiasi variabile impostata.

Arcpy non è thread-safe. È stato sempre pensato per essere utilizzato all'interno di un singolo processo. Ma ci sono soluzioni alternative.


Il mio suggerimento era di importare arcpy all'interno del target per un nuovo processo.

def _multiprocessing_target(args):
    import arcpy
    ...code

Ciao, grazie per il tuo consiglio ... anche se sembra che abbia ancora problemi. Quando ti riferisci a 'import arcpy nel target del multiprocessing', intendi sotto l'istruzione if__name ... o effettivamente all'interno della funzione def. Come pensavo che l'importazione nella funzione def non fosse valida.
BJEBN,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.