python.multiprocessing и «КАТАЛОГ ФАТАЛЬНЫХ ОШИБОК (INFADI)»

9

При попытке сделать многопроцессорную работу с Arcpy я иногда сталкиваюсь с этой ошибкой:

FATAL ERROR (INFADI)
MISSING DIRECTORY

Я понятия не имею, что вызывает эту ошибку, и она приводит к сбою процесса python, делая невозможным получение обратной трассировки. Это происходит при записи окончательного растрового выхода из длинной звуковой модели.

Иногда это сопровождается ошибкой

Unable to write BND file for %TEMP%\ras####

Где% Temp - анализируемая корректность, а #### - какое-то случайное четырехзначное число. Это необычно, потому что у каждого процесса есть свое собственное рабочее пространство, в которое должно быть записано большинство файлов.

Проблема не во входных данных ... Я могу перезапустить программу на неудачных входах, и она будет работать правильно.

blord-Castillo
источник
Я скоро вернусь к этому, но сейчас мне придется поработать над другой моделью.
blord-castillo

Ответы:

6

Вот несколько вещей для проверки:

Вы используете курсоры? Вы их выпускаете? Вы пытаетесь повторно использовать какие-либо объекты в разных процессах? Вы используете одно и то же временное местоположение? Вы занимаетесь обработкой памяти?

В общем, arcpy - это просто оболочка вокруг com-объектов, и любой тип многопроцессорной обработки будет сложным.

Джейми
источник
4

Я обнаружил, что эта проблема возникает, когда arcpy.env.workspace и arcpy.env.scratchWorkspace одинаковы для двух разных процессов. Arc записывает почти все промежуточные растры в рабочую область (или рабочую область с нуля) в формате ESRI GRID. Вы не можете записать два растра ESRI GRID в один и тот же каталог одновременно из-за псевдо-базы данных формата (в информационной папке хранятся уникальные ключи для каждого растра).

Я избежал этой ошибки, назначив уникальное рабочее пространство и scratchWorkspace для каждого процесса, используя временную папку tempfile.mkdtemp.

Иона
источник
Я уже использую уникальные рабочие пространства, но я еще раз проверю, что scratchWorkspace тоже уникально. Я предполагаю, что нет, поскольку он пишет в директорию% TEMP%.
blord-castillo
Иона прямо на. Я обрабатываю тысячи растров в одном каталоге в 5 одновременных потоках; установка уникального рабочего пространства для каждого - единственное решение, которое мне помогло. Вывод в уникальные папки, как некоторые рекомендовали, просто создает больше работы на потом ... в конце концов я хочу, чтобы они все были в одном каталоге.
Том
Какая боль в спине! Использование уникального рабочего пространства с работающей многопроцессорной обработкой, но, боже мой, управлять дополнительными папками, а затем пытаться удалить их с помощью дуговых блокировок, просто смешно!
D_C
3

Я также столкнулся с этим и пока не нашел исправления. Моя работа состоит в том, чтобы 1) убедиться, что многопроцессорная задача достаточно надежна, чтобы проверить, выполнены ли задачи, или нет, а затем создать новый список заданий. 2) запланируйте запуск двух скриптов каждые 10-15 минут. Один сценарий содержит команду для уничтожения выбранных запущенных процессов Python, а второй запускает требуемый многопроцессорный сценарий. По сути, это обновляет многопроцессорный пул. Сценарий уничтожения выглядит примерно так:

def read_pid():
    inFile = open("E:/temp/pid.csv")
    for line in inFile:
        pid = str(line)
    inFile.close()
    return pid

def kill():
    if os.path.exists("E:/temp/pid.csv")==True:
        pid = read_pid()
        PROCESS_TERMINATE=1
        handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE,False,pid)
        ctypes.windll.kernel32.TerminateProcess(handle,-1)
        ctypes.windll.kernel32.CloseHandle(handle)
    else:
        return

При каждом запуске нужного мне скрипта он записывает свой PID в CSV.

метасеквойя
источник
2

Я обнаружил, что получаю ошибку INFADI при попытке сохранить несколько потоков / ядер и изменить растры в одной папке. Назначение подпапки для каждой задачи для результатов, кажется, решает проблему. Я полагаю, что проблема была связана с несколькими операциями чтения / записи в периферийные файлы, связанные с растром (например, папка «info»). Теперь я также применяю следующие меры предосторожности:

import arcpy,multiprocessing,random

def run(foo,c):
    tempFolder = os.path.join("Z:/temp/",'temp_%s'%(str(c)))
    if not os.path.exists(tempFolder): os.mkdir(tempFolder)
    arcpy.env.scratchWorkspace = tempFolder
    arcpy.env.Workspace = tempFolder

    # create unique object in memory, run task, then delete unique object in memory
    tempMem = str(rnd)
    try:arcpy.Delete_management(tempMem)
    except:pass

    <tasks> #output to appropriate subfolder

    arcpy.Delete_management(tempMem)

if __name__ == '__main__':
    cores = 3
    pool = multiprocessing.Pool(cores)
    count = 0
    for foo in bar:
        pool.apply_async(run,(foo,c))
        count +=1
    pool.close()
    pool.join()
метасеквойя
источник
Кажется, я никогда не получаю ошибок от записи нескольких GRID в одну папку через несколько потоков. Единственная проблема, по-видимому, заключается в том, что это замедляет обработку и фактически лишает законной силы многопоточность, поскольку она записывает только один растр за раз.
Том