fortran: подождите, чтобы открыть файл, пока не закроется другое приложение

У меня есть код Fortran, который должен прочитать ряд файлов данных ASCII (которые вместе составляют около 25 ГБ). В основном код открывает заданный файл ascii, считывает информацию и использует ее для выполнения некоторых операций, а затем закрывает ее. Затем открывает другой файл, читает информацию, выполняет некоторые операции и снова закрывает его. И так далее с остальными файлами ascii.

В целом каждый полный цикл занимает около 10 часов. Обычно мне нужно выполнить несколько независимых вычислений с разными параметрами, и я должен последовательно выполнять каждый независимый расчет, чтобы в конце, если у меня было 10 независимых вычислений, общее время ЦП составляло 100 часов.

Более быстрый способ состоял бы в том, чтобы выполнить 10 независимых вычислений одновременно с использованием разных процессоров на компьютере кластера, но проблема в том, что если для данного вычисления необходимо открыть и прочитать данные из заданного файла ASCII, который уже открыт, и он используется другим вычислением, тогда код, очевидно, выдает ошибку.

Интересно, есть ли способ проверить, используется ли данный файл ascii для другого вычисления, и если да, попросить код подождать, пока файл ascii окончательно не будет закрыт.

Любая помощь будет очень полезна. Спасибо заранее.

Obamakoak.

2 ответа

Я знаю, что это старый поток, но я боролся с той же проблемой для моего собственного кода.

Моей первой попыткой было создание переменной в определенном процессе (например, ведущем) и доступ к этой переменной исключительно с использованием одностороннего пассивного MPI. Это модно и хорошо работает, но только с новыми версиями MPI.

Кроме того, мой код, кажется, счастлив открыть (с READWRITE статус) файлы, которые также были открыты в других процессах.

Поэтому самый простой обходной путь, если ваша программа имеет доступ к файлу, - это использовать внешний файл блокировки, как описано здесь. В вашем случае код может выглядеть примерно так:

  • Процесс проверяет, существует ли файл блокировки, используя NEW оператор, который не работает, если файл уже существует. Это будет выглядеть примерно так:

    file_exists = .true.
    do while (file_exists)
        open(STATUS='NEW',unit=11,file=lock_file_name,iostat=open_stat)
        if (open_stat.eq.0) then
            file_exists = .false.
            open(STATUS='OLD',ACTION=READWRITE',unit=12,file=data_file_name,iostat=ierr)
            if (ierr.ne.0) stop
        else
            call sleep(1)
        end if
    end do
    
  • Файл теперь открывается исключительно текущим процессом. Выполняйте необходимые операции, такие как чтение, письмо.

  • Когда вы закончите, закройте файл данных и, наконец, файл блокировки

    close(12,iostat=ierr)
    if (ierr.ne.0) stop
    close(11,status='DELETE',iostat=ierr)
    if (ierr.ne.0) stop
    
  • Файл данных теперь снова разблокирован для других процессов.

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

Два процесса должны иметь возможность читать один и тот же файл. возможно action="read" на открытом заявлении может помочь. Должны ли файлы быть удобочитаемыми для человека? Скорее всего, ввод / вывод будет намного быстрее с неформатированными (иногда вызываемыми двоичными) файлами.

PS Если ваша ОС не поддерживает множественный доступ для чтения, вам, возможно, придется создать собственную систему блокировки. Создайте главный файл, который открывается процессом, чтобы проверить, какие файлы используются или нет, и обновить указанный список. Немедленно закрытие после проверки или обновления. Для обработки коллизий в этом файле чтения / записи используйте iostat на операторе open и повторите попытку после задержки, если есть ошибка.

Другие вопросы по тегам