Ошибки многопроцессорной обработки - реализация ArcGIS

13

Мне было интересно, пытался ли кто-нибудь еще в сообществе использовать мультиобработку для пространственного анализа. А именно, я пытаюсь перебрать серию растров, создать многопроцессорное задание для каждого и выполнить их через ряд шагов геообработки в рамках одной функции 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), связанную с фокусной статистикой, которая почти создает точную копию окончательного вывода.

Мой вопрос основан на вашем опыте: нельзя ли создать несколько этапов геообработки в рамках одной многопроцессорной функции? Или мне нужно объединить эти шаги в отдельные этапы геообработки?

ОБНОВИТЬ

По-прежнему возникают похожие ошибки - перемещение функций импорта в функцию def показало, что

import arcpy 
from arcpy.sa import *

не может создать вывод с добавленным синтаксическим предупреждением, что импорт * не разрешен.

ОБНОВЛЕНИЕ № 2

Я знаю, что это поздний ответ, но я подумал, что кому-то может пригодиться дальнейшая ссылка на мой обходной путь, который позволяет многопроцессорной обработке работать с arcpy. Основная проблема, которую я обнаружил после возвращения к этой проблеме, - это не конкуренция модулей arcpy, а скорее конкуренция за пространство scratchWorkspace, которое ArcObjects использует для сохранения временных файлов. Поэтому рассмотрите возможность использования счетчика в аргументе разбора многопроцессорности, чтобы создать уникальное пространство для рабочего процесса, т.е.

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 Multiprocessing Blog

Блог Python, Gis и Stuff

BJEBN
источник
Это грубое предложение, я не хочу формализовать его в ответе, но рассматривали ли вы возможность запуска ArcGIS на нескольких виртуальных машинах одновременно? (Вам может потребоваться отдельная установка в каждой виртуальной машине, каждая из которых имеет свою собственную структуру каталогов.) Еще одна радикальная идея состоит в том, чтобы отобрать часть обработки: например, можно выполнить focalstats R. Это не очень хорошие предложения для работы общего назначения, потому что они могут доставлять больше хлопот, чем они того стоят, но если вы можете сэкономить часы за раз, усилия могут окупиться.
whuber

Ответы:

7

Каждое соединение IWorkspace (то есть каждое соединение с базой данных) имеет сходство потоков. Два потока не могут использовать одно и то же рабочее пространство. Вы можете иметь один поток, владеющий ресурсом, и затем синхронизировать доступ, но если вы собираетесь использовать прямые функции gp, то это даже не вариант.

Самый простой (неэффективный) способ - создать отдельные процессы, а затем выполнить многопроцессную синхронизацию (в отличие от многопоточной синхронизации). Даже тогда вы должны знать о базовом типе рабочего пространства. если вы не используете arcsde (многопользовательский источник данных), вы, вероятно, будете использовать однопользовательский источник данных (например, personal или filegdb). Тогда помните, что это означает, что только один процесс может писать одновременно! Типичная (хромая) синхронизация для этих сценариев состоит в том, что каждый параллельный процесс записывает в отдельное временное рабочее пространство, а затем вы объединяете все это в целевое рабочее пространство в одном процессе.

Раги Язер Бурхум
источник
Хорошие предложения ... На самом деле, хотя я не добавил его в этот пост, я создаю новую папку на основе имени растрового изображения и задаю рабочую область для каждого процесса в этом конкретном каталоге. Это отдельные каталоги файлов для каждого растрового изображения, а не отдельные базы геоданных (мне это нужно?). Затем я планировал использовать простую функцию os.walk, чтобы найти все те файлы, которые мне нужны, и переместить их в желаемую файловую базу геоданных.
BJEBN
Вы делаете только растровые операции? Существуют ли какие-либо потоки или процессы, читающие / записывающие данные в одну и ту же базу геоданных одновременно?
Раги Язер Бурхум
Привет, извините, я мог быть немного неясен с предыдущим заявлением. Только растровые операции (перепроектирование, фокусное состояние, переклассификация и т. Д.) И все эти шаги геообработки выполняются в последовательном порядке (или должны быть) для каждого растрового изображения. Эти растровые изображения сохраняются в уникальной рабочей области папки. Все исходные растры читают из того же каталога (но не с одного и того же изображения), поскольку это создает отдельные задания для отправки.
BJEBN
После некоторого переосмысления я попытался указать конкретное рабочее пространство для каждого изображения. ЦМР правильно проецируется, однако это вызвало новую ошибку на этапе focalstats - «тип <Растр> не поддерживается». Я попытался указать полный адрес каталога, но безуспешно. Я загрузил спроектированные растры в arcgis без проблем.
BJEBN
Ну, это означает, что вы движетесь вперед. Для координационных центров это зависит от того, как это реализовано внутри. Если это новая реализация, она может занять рабочее пространство (то есть базу геоданных). Однако, если это одна из тех функций, которые еще не были обновлены (!?!?!), То рабочим пространством, которое она разрешает, может быть только папка. Для этой конкретной функции GP укажите только папку (оставьте пространство для рабочего места для остальных) и посмотрите, что произойдет.
Раги Язер Бурхум
5

У вас есть несколько потоков, конкурирующих за один и тот же ресурс.

Попробуйте переместить ваш оператор import arcpy в цель многопроцессорной обработки. Вы убедитесь, что arcpy работает со своим собственным набором переменных окружения и памяти.

Это звучит абсурдно, но даже если вы устанавливаете переменные среды в целевом методе Multiprocess, python по-прежнему использует пространство общей памяти для управления модулем arcpy и, следовательно, любыми переменными, которые вы устанавливаете.

Arcpy не является потокобезопасным. Он всегда был предназначен для использования в одном процессе. Но есть обходные пути.


Мое предложение состояло в том, чтобы импортировать arcpy в пределах цели для нового процесса.

def _multiprocessing_target(args):
    import arcpy
    ...code
OptimizePrime
источник
Привет, спасибо за ваш совет ... хотя у меня все еще есть проблемы. Когда вы ссылаетесь на «импортировать arcpy в цель многопроцессорной обработки», вы подразумеваете под оператором if__name ... или фактически внутри функции def. Как я и думал, импорт в функцию def был неверным.
BJEBN