Kesalahan Banyak Proses - Implementasi ArcGIS

13

Saya bertanya-tanya apakah ada orang lain di komunitas di sini yang telah mencoba menggunakan multi-pemrosesan untuk analisis spasial. Yaitu saya mencoba untuk mengulangi melalui serangkaian raster, membuat pekerjaan multiprosesing untuk masing-masing dan menjalankannya melalui sejumlah langkah geoprosesing dalam satu fungsi def. Sesuatu di sepanjang garis

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

Sekarang proses multiprosesing berjalan, biasanya untuk batch pertama! Namun, saya terus mengalami beberapa kesalahan yang berbeda ketika mencoba beberapa dataset (lebih dari 4 file - yaitu 4 core multiprocessing) termasuk:

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

dan

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

Perhatikan pada kesalahan pertama folder aneh yang dibuat (di lokasi OutFolderDir) yang terkait dengan statistik fokus yang hampir membuat replika yang tepat dari hasil akhir.

Pertanyaan saya didasarkan pada pengalaman Anda, apakah tidak mungkin membuat beberapa langkah geoprocessing dalam satu fungsi multiproses? Atau apakah saya perlu memasang langkah-langkah ini ke dalam langkah-langkah geoproses individu?

MEMPERBARUI

Masih mengatasi kesalahan serupa - memindahkan fungsi impor ke fungsi def telah menunjukkan hal itu

import arcpy 
from arcpy.sa import *

tidak dapat membuat output dengan sintaks tambahan yang menambahkan bahwa impor * tidak diperbolehkan.

PEMBARUAN # 2

Saya tahu ini adalah jawaban yang terlambat tapi saya pikir mungkin bermanfaat bagi orang lain untuk referensi di masa depan untuk solusi saya yang memungkinkan multiprosesor untuk bekerja dengan arcpy. Masalah utama yang saya temukan setelah kembali ke masalah ini bukan kompetisi modul arcpy melainkan kompetisi atas scratchWorkspace yang digunakan ArcObjects untuk menyimpan file sementara. Oleh karena itu pertimbangkan menjalankan penghitung ke argumen parsing multiprosesing untuk membuat scratchWorkspace unik untuk setiap proses yaitu

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

Kemudian pada fungsi utama buatlah direktori sementara spesifik dan berikan scratchWorkspace unik untuk setiap tugas multiprosesing.

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

Harapan yang membantu dan terima kasih kepada Ragi atas saran awal untuk menggunakan ruang kerja temp yang terpisah - masih bingung mengapa ini awalnya tidak berhasil.

Sumber daya tambahan

ESRI Multiprocessing Blog

Blog Python, Gis, dan Stuff

BJEBN
sumber
Saran ini sangat kasar sehingga saya tidak ingin memformalkannya dalam balasan, tetapi apakah Anda sudah mempertimbangkan menjalankan ArcGIS di beberapa mesin virtual secara bersamaan? (Anda mungkin memerlukan instalasi terpisah di masing-masing VM, masing-masing dengan struktur direktori sendiri.) Pemikiran radikal lainnya adalah mengeluarkan beberapa pemrosesan: misalnya, focalstats dapat dilakukan di R. Ini bukan saran yang bagus untuk pekerjaan tujuan umum, karena mungkin lebih banyak masalah daripada nilainya, tetapi ketika Anda dapat menghemat waktu, berulang kali, upaya itu dapat membuahkan hasil.
whuber

Jawaban:

7

Setiap koneksi IWorkspace (yaitu setiap koneksi basis data) memiliki afinitas utas. Dua utas tidak dapat berbagi ruang kerja yang sama. Anda dapat memiliki satu utas memiliki sumber daya lalu menyinkronkan akses, tetapi jika Anda akan menggunakan fungsi gp langsung, maka itu bahkan bukan pilihan.

Cara termudah (lumpuh) adalah membuat proses terpisah dan kemudian melakukan sinkronisasi multi proses (sebagai lawan dari sinkronisasi multithread). Bahkan kemudian Anda harus menyadari jenis ruang kerja yang mendasarinya. jika Anda tidak menggunakan arcsde (sumber data multi-pengguna) Anda mungkin akan menggunakan sumber data pengguna tunggal (seperti pribadi atau filegdb). Kemudian ingat itu berarti hanya satu proses yang dapat menulis sekaligus! Sinkronisasi (lumpuh) khas untuk skenario ini adalah bahwa setiap proses paralel menulis ke ruang kerja temp yang berbeda dan kemudian Anda menggabungkan semuanya ke ruang kerja tujuan Anda dalam satu proses tunggal.

Ragi Yaser Burhum
sumber
Saran yang bagus ... Sebenarnya, meskipun saya belum menambahkannya ke posting ini, saya membuat folder baru berdasarkan nama gambar raster dan mengatur ruang kerja untuk setiap proses ke direktori tertentu. Ini adalah direktori file terpisah untuk setiap gambar raster dan tidak memisahkan geodatabases (apakah saya memerlukannya?). Saya kemudian berencana untuk menggunakan fungsi os.walk sederhana untuk menemukan semua file yang saya butuhkan memindahkannya ke file geodatabase yang saya inginkan.
BJEBN
Apakah Anda hanya melakukan operasi raster? Apakah ada utas atau proses membaca / menulis ke geodatabase yang sama pada saat yang sama?
Ragi Yaser Burhum
Hai, maaf saya mungkin agak tidak jelas dengan pernyataan sebelumnya. Hanya operasi raster (proyeksi ulang, fokus, reklasifikasi, dll ...) dan semua langkah geoproses tersebut dilakukan secara berurutan (atau perlu) untuk setiap gambar raster. Gambar raster ini disimpan ke ruang kerja folder yang unik. Semua raster asli membaca dari direktori yang sama (bukan gambar yang sama) karena itu menciptakan pekerjaan individu untuk dikirim.
BJEBN
Setelah memikirkan kembali agak saya mencoba untuk menentukan ruang kerja awal yang spesifik juga untuk setiap gambar. DEM sedang diproyeksikan dengan benar namun ini telah menghasilkan kesalahan baru pada tahap fokus - "ketik <Raster> tidak didukung". Saya sudah mencoba menentukan seluruh alamat direktori tetapi tidak berhasil. Saya telah memuat raster yang diproyeksikan ke arcgis tanpa masalah.
BJEBN
Nah, itu berarti Anda bergerak maju. Untuk focalstats, itu tergantung bagaimana itu diterapkan secara internal. Jika ini merupakan implementasi baru, ini dapat menggunakan scratchworkspace (yaitu Geodatabase). Namun, jika itu adalah salah satu dari fungsi-fungsi yang belum diupgrade (!?!?!) Ruang kerja yang memungkinkannya mungkin hanya folder. Untuk fungsi GP tertentu, tentukan hanya folder (simpan ruang kerja awal untuk sisanya) dan lihat apa yang terjadi.
Ragi Yaser Burhum
5

Anda memiliki beberapa utas yang bersaing untuk sumber daya yang sama.

Coba pindahkan pernyataan 'impor arcpy' ke target multiprosesing. Anda akan memastikan arcpy bekerja dengan set variabel lingkungan dan memori itu sendiri.

Kedengarannya tidak masuk akal, tetapi meskipun Anda mengatur variabel lingkungan dalam metode target MultiProses, python masih menggunakan ruang memori bersama untuk mengelola modul arcpy dan karenanya setiap variabel yang Anda tetapkan.

Arcpy tidak aman untuk thread. Itu selalu dimaksudkan untuk digunakan dalam satu proses tunggal. Tetapi ada beberapa solusi.


Saran saya adalah mengimpor arcpy dalam target untuk proses baru.

def _multiprocessing_target(args):
    import arcpy
    ...code
OptimizePrime
sumber
Hai, terima kasih atas saran Anda ... meskipun saya tampaknya masih memiliki masalah. Ketika Anda merujuk ke 'impor arcpy ke dalam target multiprocessing' apakah Anda menyiratkan di bawah pernyataan if__name ... atau benar-benar dalam fungsi def. Karena saya pikir mengimpor dalam fungsi def tidak valid.
BJEBN