Je me demandais si quelqu'un d'autre dans la communauté ici avait tenté d'utiliser le multi-traitement pour les analyses spatiales. À savoir, j'essaie de parcourir une série de rasters, de créer un travail de multitraitement pour chacun et de les exécuter à travers un certain nombre d'étapes de géotraitement dans une fonction def. Quelque chose dans le sens 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)))
Maintenant, le multitraitement s'exécute, généralement pour le premier lot! Cependant, je continue à rencontrer plusieurs erreurs différentes lors de la tentative de plusieurs ensembles de données (plus de 4 fichiers - c'est-à-dire multiprocessing 4 cœurs), notamment:
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).
et
ERROR 999999: Error executing function.
Failed to copy raster dataset
Failed to execute (ProjectRaster)
Remarquez dans la première erreur l'étrange dossier créé (à l'emplacement OutFolderDir) associé aux statistiques focales qui crée presque une réplique exacte de la sortie finale.
Ma question est basée sur votre expérience, est-il impossible de créer un géotraitement en plusieurs étapes au sein d'une fonction multiprocesseur? Ou dois-je intégrer ces étapes dans leurs étapes de géotraitement individuelles?
MISE À JOUR
Toujours rencontrant des erreurs similaires - le déplacement des fonctions d'importation vers la fonction def a montré que
import arcpy
from arcpy.sa import *
ne peut pas créer une sortie avec une syntaxe ajoutée avertissant que l'importation * n'est pas autorisée.
MISE À JOUR # 2
Je sais que c'est une réponse tardive, mais j'ai pensé que cela pourrait bénéficier à quelqu'un d'autre pour une référence future à ma solution de contournement qui permet au multitraitement de fonctionner avec arcpy. Le problème principal que j'ai trouvé après être revenu à ce problème n'est pas la concurrence des modules arcpy mais plutôt la concurrence sur le scratchWorkspace que les ArcObjects utilisent pour enregistrer les fichiers temporaires. Par conséquent, envisagez d'exécuter un compteur dans l'argument d'analyse multiprocessing pour créer un scratchWorkspace unique pour chaque processus, c'est-à-dire
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
Ensuite, dans la fonction principale, créez un répertoire temporaire spécifique et affectez un scratchWorkspace unique à chaque tâche de multitraitement.
def main(RasterImage,OutFolderDir,Counter)
TempFolder = os.path.join(os.path.dirname(OutFolderDir),'Temp_%s'% (Counter))
os.mkdir(TempFolder)
arcpy.scratchWorkspace = TempFolder
...
J'espère que cela aide et merci à Ragi pour la suggestion initiale d'utiliser des espaces de travail temporaires séparés - toujours déconcerté par les raisons pour lesquelles cela ne fonctionnait pas à l'origine.
Ressources supplémentaires
R
. Ce ne sont pas de bonnes suggestions pour un travail à usage général, car elles peuvent être plus problématiques qu'elles n'en valent, mais lorsque vous pouvez économiser des heures à la fois, à plusieurs reprises, l'effort pourrait être payant.Réponses:
Chaque connexion IWorkspace (c'est-à-dire chaque connexion à la base de données) a une affinité de thread. Deux threads ne peuvent pas partager le même espace de travail. Vous pouvez avoir un thread propriétaire de la ressource, puis synchroniser l'accès, mais si vous allez utiliser des fonctions gp directes, ce n'est même pas une option.
Le moyen le plus simple (boiteux) consiste à créer des processus séparés, puis à effectuer une synchronisation multi-processus (par opposition à une synchronisation multithread). Même dans ce cas, vous devez connaître le type d'espace de travail sous-jacent. si vous n'utilisez pas arcsde (une source de données multi-utilisateurs), vous utiliserez probablement une seule source de données utilisateur (comme personal ou filegdb). N'oubliez pas que cela signifie qu'un seul processus peut écrire à la fois! La synchronisation typique (boiteuse) pour ces scénarios est que chaque processus parallèle écrit dans un espace de travail temporaire différent et que vous fusionnez tout cela dans votre espace de travail de destination en un seul processus.
la source
Vous avez plusieurs threads en compétition pour la même ressource.
Essayez de déplacer votre instruction «import arcpy» dans la cible du multitraitement. Vous vous assurerez qu'arcpy fonctionne avec son propre ensemble de variables d'environnement et de mémoire.
Cela semble absurde, mais même si vous définissez des variables d'environnement dans la méthode cible Multiprocess, python utilise toujours un espace mémoire partagé pour gérer le module arcpy et donc toutes les variables que vous définissez.
Arcpy n'est pas sûr pour les threads. Il a toujours été conçu pour être utilisé dans un seul processus. Mais il existe des solutions de contournement.
Ma suggestion était d'importer arcpy dans la cible pour un nouveau processus.
la source