Во время счета многочасовых задач возникают ситуации, которые приводят к сбою одного или нескольких процессоров. При этом чаще всего, задача «вылетает». Это влечет за собой потерю результатов счета. Естественно, возникает желание сохранять результаты промежуточных итераций и организовать задачу с так называемым «продолжением» (т.е. при повторном запуске задачи счет начинать не с начала, а со следующей итерации). При этом для гарантии сохранения данных необходимо сначала записать данные в какой-то новый файл, а потом переименовать его, чтобы не потерять данные вследствие сбоя во время записи. Задача усложняется, если файлов исходных данных несколько. Для облегчения организации гарантированного сохранения промежуточных результатов создан комплекс подпрограмм. Он обеспечивает защиту целостности совокупности данных в итерационных задачах, использующих одни и те же файлы для чтения исходных данных и записи промежуточных результатов. При запуске после сбоя счет возобновляется с последнего целостного состояния файлов. Использование этих подпрограмм актуально только для многочасовых задач. Для организации работы в режиме защиты необходимо:
- Создать в текущем каталоге вспомогательный каталог olddata (обязательно маленькие буквы).
- Во вспомогательном каталоге olddata создать файл info, который должен содержать имена файлов данных, используемых в вашей программе для сохранения промежуточных данных. Знак ‘#’ в 1 позиции строки обозначает, что содержимое этой строки является комментарием. В каждой строке файла info должен быть либо комментарий, либо имя файла. Имя файла может быть относительным, если файл находится в рабочем каталоге, или полным, в таком случае он может находиться в другом каталоге. Имя файла должно быть размещено с 1 позиции.
- В программу на Си необходимо добавить #include <staydf.h> , а в программу на Фортране include ’staydf_f.h’
- Вставить вызовы описанных ниже процедур в текст программы.
- Для MPI транслировать программу с присоединением библиотеки -L/common/mpich/lib ?lmpidf.Например: mpicc -o test test.c -L/common/mpich/lib ?lmpidf
Комплекс состоит из следующих программ:
- iInitDF(int n_proc) –подпрограмма инициализации режима защиты. Всегда должна быть вызвана после rf_create или MPI_Init, но до вызова описанных ниже программ, n_proc – логический номер процесса, на котором будет производиться сохранение. Во всех остальных процессах все вызовы подпрограмм не будут производить никаких действий, выдавая код ответа 0 (ноль). Исключением является только iRestoreDF (), где для гарантии восстановления файлов до их чтения используется барьер — известный примитив синхронизации. Для ROUTER этот примитив пришлось реализовать с использованием блокировки файлов, чтобы не пересечься с посылками сообщений в программе. Для Фортрана call iinitdf( n_proc, cc) , где сс –код ответа .
- iRestoreDF () – проверяет целостность и при необходимости восстанавливает предыдущее состояние совокупности файлов с данными. Для Фортрана call irestoredf(cc) , где сс –код ответа.
- iHideDF () - переносит все файлы, указанные в файле olddata/info, в каталог olddata. При этом перенесенные файлы будут иметь имена от “00” до “99” по порядку их расположения в olddata/info. Для Фортрана call ihidedf(cc) , где сс –код ответа.
- iEOWDF() – завершает работу подпрограмм защиты от сбоев и переносит, при необходимости, файлы из временного хранилища на постоянное место. Вызов этой подпрограммы обязательно должен стоять перед каждым «нормальным» выходом из программы. Для Фортрана call ieowdf(cc) , где сс –код ответа.
Эти 4 подпрограммы выдают код ответа 0 (ноль) при нормальном завершении. В случае ошибки возвращается отрицательный код ответа. По умолчанию действуют следующие установки:
- при наличии ошибки выдавать информацию в файл вывода ошибок и прерывать работу процесса с логическим номером, указанным в качестве аргумента iInitDF;
- при удачном переносе файлов данных выдавать соответствующую информацию в стандартный файл вывода;
- не считать ошибкой отсутствие файла при переносе, т.е. предполагается, что на разных итерациях могут создаваться не все файлы, указанные в olddata/info .
- синхронизация отсутствует, т.е. каждый процесс работает со своей скоростью и может завершать итерацию независимо от других.
Для изменения этих установок используйте следующие подпрограммы:
- set_errors( 1 ) – не прерывать работу в случае ошибки. (В таком случае Вам в своей программе необходимо проверять возвращаемое значение). Для Фортрана call set_errors( 1 ).
- set_no_diag( 1 ) – не печатать информацию об удачном переносе файлов. Для Фортрана call set_no_diag( 1 ).
- set_error_no_file( 1 ) – файлы данных должны существовать всегда и их отсутствие надо считать ошибкой. Для Фортрана call set_error_no_file( 1 ).
- set_barrier( 1 ) – включена синхронизация, т.е. процессы согласуют свои действия (гарантированное сохранение-восстановление результатов итерации, в случае, если чтение-запись файлов, указанных в olddata/info осуществляется разными процессами). Для Фортрана call set_ barrier ( 1 ).
Использование этих программ с входным параметром 0 (ноль) включает установки по умолчанию. Установочные подпрограммы могут быть вызваны неоднократно (исключение — п\п set_ barrier), в том числе и до использования iInitDF. Пример одного из вариантов организации работы:Допустим, в программе используется 3 файла данных для чтения и записи fl, f2, f3. Файл olddata/info содержит:
#список файлов, содержащих данныеf1f2f3
Программа содержит:
#include <staydf.h>…int iInitDF (nproc);intiRestoreDF();<открытие файлов f1, f2, f3 на чтение><чтение f1><чтение f2><чтение f3><закрытие файлов f1, f2, f3><начало счетного цикла> iHideDF(); <счет> <открытие файлов f1, f2, f3 на запись> <запись f1> <запись f2> <запись f3> <закрытие файлов f1, f2, f3>
<конец счетного цикла>iEOWDF();
Примечание 1. Файлы, указанные в olddata/info, должны быть закрыты на момент вызова iHideDF(), иначе корректная работа невозможна (особенности файловой системы). Рекомендуется закрывать файлы с данными сразу же после чтения (записи). Примечание 2. Нельзя изменять файл info в течение работы всей программы. Примечание 3. Во время работы подпрограмм, в каталоге olddata, появится служебный файл timedf. Открытие, изменение или уничтожение этого файла в течение работы (т.е. пока ваша программа не просчиталась полностью, и не произошло вызова iEOWDF()) может привести к сбою или ошибочным действиям. Примечание 4. Все указания Примечания 3, справедливы и для файлов, перенесенных в olddata.После окончания работы вашей программы в этих файлах хранятся результаты предпоследней итерации. Примечание 5 . Напоминаем! Снятие одного из процессов, в том числе и по ошибке, обнаруженной описанными выше подпрограммами, не всегда приводит к снятию других параллельных процессов (особенности OC Router и MPI). Примечание 6 . В настоящий момент значение n_proc должно быть задано одно и то же на всех процессах. Если у кого-то существует потребность сохранять данные на разных процессах — обращайтесь к разработчикам.
Сергей Владимировия Шарф scharf@imm.uran.ru Светлана Владимировна Попова posvet@imm.uran.ru.