マルチプロセッシングエラー-ArcGISの実装


13

ここのコミュニティの他の誰かが空間分析にマルチプロセッシングを使用しようとしたのではないかと思っていました。つまり、一連のラスターを反復処理し、それぞれに対してマルチプロセッシングジョブを作成し、1つのdef関数内で多数のジオプロセシングステップを実行しようとしています。の線に沿って何か

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

これで、通常は最初のバッチでマルチプロセッシングが実行されます!ただし、次のような複数のデータセット(4つ以上のファイル-4つのコアマルチプロセッシング)を試行すると、いくつかの異なるエラーが発生し続けます。

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

そして

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

最初のエラーでは、最終出力の正確なレプリカをほぼ作成するフォーカル統計に関連付けられた(OutFolderDirの場所に)作成された奇妙なフォルダーに注目してください。

私の質問は、1つのマルチプロセッシング機能内で複数のステップのジオプロセシングを作成することは不可能ですか?または、これらのステップを個々のジオプロセシングステップにタイル化する必要がありますか?

更新

まだ同様のエラーを引き起こしている-インポート関数をdef関数に移動すると、

import arcpy 
from arcpy.sa import *

import *が許可されていないことを示す警告が追加された出力を作成できません。

更新#2

これは返信が遅いことは知っていますが、将来的にはマルチプロセッシングがarcpyで動作できるようにする私の回避策を参照するために、他の誰かに役立つかもしれないと思いました。この問題に戻って私が見つけた主な問題は、arcpyモジュールの競合ではなく、ArcObjectsが一時ファイルを保存するために利用するscratchWorkspaceの競合です。したがって、マルチプロセス解析引数にカウンターを実行して、各プロセスに一意のscratchWorkspaceを作成することを検討してください。

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

次に、メイン関数で特定の一時ディレクトリを作成し、各マルチプロセッシングタスクに一意のscratchWorkspaceを割り当てます。

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

Ragiが個別の一時ワークスペースを使用するという最初の提案を助けてくれたことに感謝します-それが元々機能しなかった理由にまだ困惑しています。

追加資料

ESRIマルチプロセッシングブログ

Python、Gis and Stuffブログ


この提案は非常に粗雑なので、返信で正式にしたくありませんが、複数の仮想マシンで同時にArcGISを実行することを検討しましたか?(各VMに個別のインストールが必要になる場合があります。各VMには独自のディレクトリ構造があります。)別の急進的な考えは、処理の一部をファームアウトすることですR。これらは価値のあるものよりも面倒な場合があるため、これらは汎用作業には適していませんが、一度に何時間も節約できる場合、努力は報われる可能性があります。
whuber

回答:


7

各IWorkspace接続(つまり、各データベース接続)にはスレッドアフィニティがあります。2つのスレッドが同じワークスペースを共有することはできません。1つのスレッドにリソースを所有させてからアクセスを同期させることができますが、ストレートgp関数を使用する場合は、それもオプションではありません。

最も簡単な(ラメの)方法は、個別のプロセスを作成してから、マルチプロセス同期(マルチスレッド同期ではなく)を実行することです。その場合でも、基礎となるワークスペースの種類に注意する必要があります。arcsde(マルチユーザーデータソース)を使用していない場合は、おそらく個人ユーザーまたはfilegdbなどの単一ユーザーデータソースを使用します。その後、一度に1つのプロセスしか書き込むことができないことを忘れないでください!これらのシナリオの典型的な(ラメ)同期は、各並列プロセスが異なる一時ワークスペースに書き込み、それを単一のプロセスで宛先ワークスペースにすべてマージすることです。


良い提案...実際、この投稿に追加していませんが、ラスターイメージ名に基づいて新しいフォルダーを作成し、各プロセスのワークスペースをその特定のディレクトリに設定しています。これらは各ラスターイメージの個別のファイルディレクトリであり、個別のジオデータベースではありません(必要ですか?)。その後、単純なos.walk関数を使用して、必要なすべてのファイルを見つけて、目的のファイルジオデータベースに移動することを計画していました。
BJEBN

ラスター操作のみを行っていますか?同じジオデータベースに対して同時に読み取り/書き込みを行うスレッドまたはプロセスはありますか?
ラギヤセルバーフム

こんにちは、申し訳ありませんが、前の声明では少し不明瞭でした。ラスター操作(再投影、フォーカルスタット、再分類など)とそれらのすべてのジオプロセシングステップのみが、各ラスターイメージに対して順次実行されます(または実行する必要があります)。これらのラスターイメージは、一意のフォルダーワークスペースに保存されます。すべての元のラスターは、送信される個々のジョブを作成するのと同じディレクトリ(ただし、同じ画像ではない)から読み取っています。
BJEBN

少し考え直した後、各画像に対して特定のスクラッチワークスペースも指定しようとしました。DEMは正しく投影されていますが、フォーカルスタットの段階で「タイプ<ラスター>はサポートされていません」という新しいエラーが発生しています。ディレクトリアドレス全体を指定しようとしましたが、運がありません。投影されたラスターを問題なくarcgisにロードしました。
BJEBN

まあ、それはあなたが前進していることを意味します。フォーカルスタットの場合、内部での実装方法に依存します。新しい実装の場合、スクラッチワークスペース(ジオデータベース)を使用できます。ただし、まだアップグレードされていない(!?!?!)関数の1つである場合、許可されるワークスペースはフォルダーのみです。その特定のGP機能については、フォルダーのみを指定し(残りはスクラッチワークスペースを保持)、何が起こるかを確認します。
ラギヤセルバーフム

5

同じリソースに対して競合する複数のスレッドがあります。

「import arcpy」ステートメントをマルチプロセッシングのターゲットに移動してみてください。arcpyが環境変数とメモリの独自のセットで動作することを確認します。

馬鹿げているように聞こえますが、マルチプロセスターゲットメソッドで環境変数を設定している場合でも、pythonは共有メモリスペースを使用してarcpyモジュールと設定する変数を管理しています。

Arcpyはスレッドセーフではありません。常に単一のプロセス内で使用することを目的としていました。しかし、回避策があります。


私の提案は、新しいプロセスのターゲット内にarcpyをインポートすることでした。

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

こんにちは、アドバイスありがとうございます...まだ問題があるようです。「arcpyをマルチプロセッシングのターゲットにインポートする」という場合、if__name ...ステートメントの下にあるのか、実際にはdef関数内にあるのかを意味します。def関数でのインポートは無効だと思っていました。
BJEBN
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.