Zastanawiałem się, czy ktoś w tej społeczności próbował użyć przetwarzania wieloprocesorowego do analiz przestrzennych. Mianowicie próbuję iterować przez serię rastrów, utworzyć dla każdego zadanie wieloprocesowe i przeprowadzić je przez szereg etapów geoprzetwarzania w ramach jednej funkcji def. Coś w stylu
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)))
Teraz działa wiele procesów, zwykle dla pierwszej partii! Jednak ciągle napotykam kilka różnych błędów podczas próby kilku zestawów danych (więcej niż 4 pliki - tj. Czterordzeniowy proces wieloprocesowy), w tym:
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).
i
ERROR 999999: Error executing function.
Failed to copy raster dataset
Failed to execute (ProjectRaster)
Zauważ w pierwszym błędzie dziwny folder, który jest tworzony (w lokalizacji OutFolderDir) powiązany ze statystykami ogniskowymi, które prawie tworzą dokładną replikę końcowego wyniku.
Moje pytanie opiera się na twoim doświadczeniu. Czy niemożliwe jest utworzenie kilkuetapowego geoprzetwarzania w ramach jednej funkcji wieloprocesowej? Czy też muszę ułożyć te kroki w osobne etapy geoprzetwarzania?
AKTUALIZACJA
Wciąż szyfruję podobne błędy - pokazało to przeniesienie funkcji importowania do funkcji def
import arcpy
from arcpy.sa import *
nie można utworzyć wyniku z dodanym ostrzeżeniem o składni, że import * jest niedozwolony.
AKTUALIZACJA # 2
Wiem, że to późna odpowiedź, ale pomyślałem, że może to przydać się komuś innemu w przyszłości w odniesieniu do mojego obejścia, które pozwala na wieloprzetwarzanie do pracy z arcpy. Głównym problemem, który znalazłem po powrocie do tego problemu, nie jest rywalizacja modułów arcpy, ale raczej rywalizacja o scratchWorkspace, który ArcObjects wykorzystuje do zapisywania plików tymczasowych. Dlatego rozważ uruchomienie licznika w argumencie przetwarzania wieloprocesowego, aby utworzyć unikalny obszar roboczy scratch dla każdego procesu, tj
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
Następnie w głównej funkcji utwórz konkretny katalog tymczasowy i przypisz unikalny scratchWorkspace do każdego zadania wieloprocesowego.
def main(RasterImage,OutFolderDir,Counter)
TempFolder = os.path.join(os.path.dirname(OutFolderDir),'Temp_%s'% (Counter))
os.mkdir(TempFolder)
arcpy.scratchWorkspace = TempFolder
...
Mam nadzieję, że to pomaga i dziękuje Ragi za początkową sugestię korzystania z oddzielnych przestrzeni roboczych w temp. - nadal jest zaskoczony, dlaczego pierwotnie nie działał.
Dodatkowe zasoby
R
. Nie są to dobre sugestie do prac ogólnych, ponieważ mogą być bardziej kłopotliwe niż warte, ale gdy możesz zaoszczędzić wiele godzin, wysiłek może się opłacić.Odpowiedzi:
Każde połączenie IWorkspace (tj. Każde połączenie z bazą danych) ma powinowactwo do wątków. Dwa wątki nie mogą współdzielić tego samego obszaru roboczego. Możesz mieć jeden wątek będący właścicielem zasobu, a następnie zsynchronizować dostęp, ale jeśli zamierzasz używać prostych funkcji GP, nie jest to nawet możliwe.
Najłatwiejszym (lame) sposobem jest utworzenie osobnych procesów, a następnie synchronizacja wieloprocesowa (w przeciwieństwie do synchronizacji wielowątkowej). Nawet wtedy powinieneś być świadomy podstawowego typu obszaru roboczego. jeśli nie korzystasz z arcsde (źródło danych dla wielu użytkowników), prawdopodobnie użyjesz źródła danych dla jednego użytkownika (takiego jak personal lub filegdb). Pamiętaj, że oznacza to, że tylko jeden proces może pisać jednocześnie! Typowa (słaba) synchronizacja dla tych scenariuszy polega na tym, że każdy równoległy proces zapisuje w innym tymczasowym obszarze roboczym, a następnie łączy się wszystko z docelowym obszarem roboczym w jednym procesie.
źródło
Masz kilka wątków konkurujących o ten sam zasób.
Spróbuj przenieść instrukcję „arcpy importu” na cel procesu wieloprocesowego. Zapewnisz, że arcpy działa z własnym zestawem zmiennych środowiskowych i pamięci.
Brzmi to absurdalnie, ale nawet jeśli ustawiasz zmienne środowiskowe w metodzie docelowej Multiprocess, python nadal używa przestrzeni pamięci współużytkowanej do zarządzania modułem arcpy, a zatem dowolnymi ustawionymi zmiennymi.
Arcpy nie jest bezpieczne dla wątków. Zawsze miał być stosowany w jednym procesie. Ale są obejścia.
Moją sugestią było zaimportowanie arcpy w celu dla nowego procesu.
źródło