Библиотека интерфейсных вызовов (API) для организации контрольных точек (КТ)

В.А. Абрамова, А.В. Баранов, М.Ю. Храмцов

Содержание

1. Общие понятия.

Для облегчения работы пользователя при сохранении и восстановлении расчетов с помощью КТ предлагается использовать специальную библиотеку интерфейсных вызовов (далее - API). Рассмотрим модель вычислений, на которую рассчитана предлагаемая разработка.

Пусть для решения некоторой задачи необходимо выполнить N итераций и после очередного выполнения K итераций сохранить результаты счета ("сбросить" контрольную точку). При первоначальном запуске задачи выполняется чтение исходных данных из файлов, инициализация переменных и далее начинается циклическое выполнение итераций. Перед выходом из итерации проверяется, исчерпался ли квант времени или выполнились K итераций. При возникновении любого из этих событий формируется контрольная точка.

При повторных вызовах задачи выполняется чтение исходных данных из сохраненных контрольных точек и вход в циклическое выполнение.

Контрольная точка - объект, состоящий из одного или нескольких файлов, хранящих информацию для возобновления счета. Структура файла произвольная и может состоять из нескольких записей (для возможности запоминания несмежных частей одного или нескольких массивов или отдельных переменных). Контрольные точки хранятся в указанной пользователем директории. Возможно хранение как одной (последней) контрольной точки, так и нескольких контрольных точек. Обычно несколько контрольных точек хранятся, если для продолжения расчета недостаточно данных только последнего шага вычислений. После завершения выполнения задачи все накопленные контрольные точки удаляются.

Порядок работы с файлами контрольной точки следующий. Вначале производится открытие контрольной точки на чтение или запись, затем происходит чтение или запись в файлы контрольной точки, после чего осуществляется закрытие контрольной точки. Последняя успешно записанная контрольная точка считается текущей. Любая контрольная точка определяется своим номером (число от 1 до 9999) и идентификатором (тип целое). Номер задается при открытии контрольной точки, идентификатор возвращает функция открытия. При достижении номера 9999 выполняется сброс на значение номера, равное 1.

При записи контрольной точки используется сжатие информации ( библиотека libz.a). Одновременно могут быть открыты несколько контрольных точек на чтение или одна контрольная точка на запись.

2. Программный интерфейс для использования механизма контрольных точек из языков Си и Фортран.

Механизм контрольных точек реализуется вызовом функций библиотеки libcp.a.

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

При открытии контрольной точки на запись формируется временная контрольная точка (1-й этап), которая преобразуется в рабочую контрольную точку (2-й этап) после закрытия контрольной точки на запись. Далее выполняется (если нужно) удаление ранее созданной контрольной точки в соответствии с параметром cp_save функции cp_init. После удаления рабочая контрольная точка становится текущей. Если удаление не завершилось (закончился выделенный квант времени), 2-й этап (удаление и преобразование рабочей контрольной точки в текущую) выполняется функцией cp_init при следующем запуске задачи. Если выполнение задачи было прервано на 1 этапе, временная контрольная точка удаляется, и выполнение задачи возобновляется с текущей контрольной точки.

2.1 Описание функций библиотеки libcp для языка Си.

Ициализация библиотеки libcp.

int cp_init ( int cp_save, char * cp_direct, int cp_sy)

Параметры:

  • cp_save - сколько контрольных точек хранить. Если переменная cp_save равна 0, то хранятся все контрольные точки. Обычно несколько контрольных точек хранятся, если для продолжения расчета недостаточно данных только последнего шага вычислений.
  • cp_direct - имя директории, куда будут записываться контрольные точки.
  • cp_sy - режим записи (чтения). Синхронный (cp_sy не нуль) режим означает синхронизацию формирования контрольной точки средствами MPI. В этом случае в программе до вызова cp_init необходимо инициализировать MPI.
    Синхронизация необходима для того, чтобы при записи информации во всех узлах, участвующих в выполнении задачи, была сформирована контрольная точка, относящаяся к одному и тому же шагу вычислений, чтобы после cp_init всем процессам был выдан один и тот же номер контрольной точки и т.д.
    Асинхронный режим (cp_sy равен нулю) не синхронизирует формирование контрольной точки.
    После cp_init формируется текущая контрольная точка на запись и чтение.

Возвращаемое значение - текущий номер контрольной точки на чтение (нуль - первый запуск программы, меньше нуля - ошибка инициализации библиотеки libcp.

Пример:

cp_init(1,"/store/home/test",1);

Данный вызов предполагает хранение только одной (последней) контрольной точки в директории "/store/home/test" и формирование контрольных точек синхронизируется.

Открытие контрольной точки.

int cp_open ( int cp_num,int cp_nfiles,char* mode,int cp_level)

Параметры:

  • cp_num - номер открываемой контрольной точки. Если cp_num больше нуля - открывается контрольная точка, соответствующая абсолютному значению cp_num. Если cp_num равно нулю - открывается текущая контрольная точка. Если cp_num меньше нуля - открывается контрольная точка, соответствующая разнице текущей контрольной точки и значения cp_num.
  • cp_nfiles - количество отдельных файлов, которые входят в контрольную точку ( от 1 до 99).
  • mode - открытие контрольной точки на чтение ("r"), на запись без сжатия ("w"), на запись с сжатием ("w[0-9]"). При записи со сжатием задается уровень сжатия (значение от "w0" до "w9"), соответствующий уровню сжатия, обеспечиваемому библиотекой libz. Если задается значение "w0" - информация записывается без сжатия (эквивалентно "w").
    Изменение уровня сжатия распространяется на запись всех последующих контрольных точек. Уровень сжатия при чтении определяется автоматически. Если при открытии контрольной точки на чтение уровень сжатия задается, то его значение будет использовано при последующих записях контрольных точек.
  • cp_level - уровень сжатия информации при записи в файл (значение от 0 до 9). Значение параметра соответствует уровню сжатия, обеспечиваемому библиотекой libz. По умолчанию параметру cp_level присваивается значение 0 - информация записывается без сжатия.

Возвращаемое значение - идентификатор контрольной точки или код ошибки.

Пример:

cp_id = cp_open ( 3, 2, "r");

Открывается контрольная точка номер 3, состоящая из двух файлов на чтение.

cp_id = cp_open ( -1, 1, "r");

Открывается контрольная точка, номер которой равен текущему значению контрольной точки минус 1, состоящая из одного файла на чтение.

Для открытия контрольной точки на запись наиболее типичен случай задания текущего значения контрольной точки:

cp_id = cp_open ( 0, 1, "w6").

Следующие две функции cp_ropen ( открытие контрольной точки на чтение) и cp_wopen (открытие текущей контрольной точки на запись) можно использовать вместо cp_open для упрощения интерфейса.

int cp_ropen ( int cp_num,int cp_nfiles)
- открытие контрольной точки на чтение.

Параметры:

  • cp_num - номер открываемой контрольной точки. Если cp_num больше нуля - открывается контрольная точка, соответствующая абсолютному значению. Если cp_num равно нулю - открывается текущая контрольная точка. Если cp_num меньше нуля - открывается контрольная точка, соответствующая разнице текущей контрольной точки и значения cp_num.
  • cp_nfiles - количество отдельных файлов, которые входят в контрольную точку ( от 1 до 99).

Возвращаемое значение - идентификатор контрольной точки или код ошибки.

Пример:

cp_id = cp_ropen ( 3, 2);

Открывается контрольная точка номер 3, состоящая из двух файлов на чтение.

cp_id = cp_ropen ( -1, 1);

Открывается контрольная точка, номер которой равен текущему значению контрольной точки минус 1, состоящая из одного файла на чтение.

int cp_wopen ( int cp_nfiles,int cp_level)
- открытие текущей контрольной точки на запись.

Параметры:

  • cp_nfiles - количество отдельных файлов, которые входят в контрольную точку ( от 1 до 99).
  • cp_level - уровень сжатия информации при записи в файл (значение от 0 до 9). Значение параметра соответствует уровню сжатия, обеспечиваемому библиотекой libz. По умолчанию параметру cp_level присваивается значение 0 - информация записывается без сжатия.

Возвращаемое значение - идентификатор контрольной точки или код ошибки.

Пример:

cp_id = cp_wopen (1,5);

Открывается контрольная точка, номер которой равен текущему значению контрольной точки, состоящая из одного файла на запись. При этом уровень сжатия устанавливается равным 5.

Чтение контрольной точки из файла

int cp_read (int cp_id,int cp_nfile, void* cp_buf, int cp_len)
- чтение из файла cp_nfile контрольной точки, определяемой идентификатором cp_id.

Параметры:

  • cp_id - идентификатор контрольной точки (возвращает cp_open или cp_ropen).
  • cp_nfile - номер файла в контрольной точке, определяемой идентификатором cp_id.
  • cp_buf - адрес буфера.
  • cp_len - длина буфера.

Возвращаемое значение - длина прочитанной информации или код ошибки.

Запись контрольной точки в файл

int cp_write (int cp_id ,int cp_nfile, void* cp_buf, int cp_len)
- запись в файл cp_nfile контрольной точки, определяемой идентификатором cp_id.

Параметры:

  • cp_id - идентификатор контрольной точки (возвращает cp_open и cp_wopen).
  • cp_nfile - номер файла в контрольной точке, определяемой идентификатором cp_id.
  • cp_buf - адрес буфера.
  • cp_len - длина буфера.

Возвращаемое значение - длина записанной информации или код ошибки.

Закрытие контрольной точки

int cp_close (int cp_id )
- закрытие контрольной точки, определяемой идентификатором cp_id

Возвращаемое значение нуль или код ошибки.

Получение номера текущей контрольной точки

int cp_current_num ( int cp_mode)

Параметры:

  • cp_mode - получение контрольной точки на чтение (0) или на запись (1).

Опрос флага завершения очередного запуска задачи

int cp_signal (void)
- опрос флага завершения очередного запуска задачи.

При первоначальном запуске задачи вводится дополнительный параметр, определяющий время (в минутах) предупреждения задачи о завершении (например за 5 минут до завершения), что позволяет сформировать контрольную точку до выброса задачи из счета. При достижении соответствующего времени устанавливается флаг. Завершение очередного запуска задачи может возникнуть в результате истечения кванта времени, выдаче mkill и т.д.

Определение дополнительного параметра: время формирования контрольной точки плюс промежуток между двумя cp_signal.

2.2 Описание подпрограмм для работы с контрольными точками из языка Фортран.

Все функции библиотеки libcp вызываются из Фортрана через соответствующие подпрограммы.

Ициализация библиотеки libcp

cpf_init (cp_save, cp_direct,cp_sy,cp_num)

Параметры:

  • cp_save - сколько контрольных точек хранить (тип INTEGER).
    Если переменная cp_save равна 0, то хранятся все контрольные точки.
    Обычно несколько контрольных точек хранятся, если для продолжения расчета недостаточно данных только последнего шага вычислений.
  • cp_direct - имя директории, куда будут записываться контрольные точки.
  • cp_sy - режим записи (чтения). Синхронный (cp_sy не нуль) режим означает синхронизацию формирования контрольной точки средствами MPI. В этом случае в программе до вызова cpf_init необходимо инициализировать MPI.
    Синхронизация необходима для того, чтобы при записи на локальные диски всех узлов, участвующих в выполнении задачи, была сформирована контрольная точка, относящаяся к одному и тому же шагу вычислений, чтобы после cpf_init всем процессам был выдан один и тот же номер контрольной точки и т.д.
    Асинхронный режим (cp_sy равен нулю) не синхронизирует формирование контрольной точки.
    После cpf_init формируется текущая контрольная точка на запись и чтение.
  • cp_num (тип INTEGER) - возвращаемое значение - текущий номер контрольной точки на чтение (нуль - первый запуск программы, меньше нуля - ошибка инициализации библиотеки libcp.

Пример:

call cpf_init(1,'/store/home/test',1,cpnum)

Данный вызов предполагает хранение только одной (последней) контрольной точки в директории '/store/home/test', формирование контрольных точек синхронизируется, текущая контрольная точка на чтение записывается в переменную cpnum.

Открытие контрольной точки.

cpf_open ( cp_num,cp_nfiles, mode, cp_id)

Параметры:

  • cp_num (тип INTEGER) - номер открываемой нонтрольной точки. Если cp_num больше нуля - открывается контрольная точка, соответствующая абсолютному значению cp_num. Если cp_num равно нулю - открывается текущая контрольная точка. Если cp_num меньше нуля - открывается контрольная точка, соответствующая разнице текущей контрольной точки и значения cp_num.
  • cp_nfiles (тип INTEGER) - количество отдельных файлов, которые входят в контрольную точку ( от 1 до 99).
  • mode - открытие контрольной точки на чтение ('r'), на запись без сжатия ('w'), на запись с сжатием ('w[0-9]'). При записи со сжатием задается уровень сжатия (значение от 'w0' до 'w9'), соответствующий уровню сжатия, обеспечиваемому библиотекой libz. Если задается значение 'w0' - информация записывается без сжатия (эквивалентно 'w').
    Изменение уровня сжатия распространяется на запись всех последующих контрольных точек. Уровень сжатия при чтении определяется автоматически. Если при открытии контрольной точки на чтение уровень сжатия задается, то его значение будет использовано при последующих записях контрольных точек.
  • cp_id (тип INTEGER ) - записывается идентификатор контрольной точки или код ошибки.

Пример:

call cpf_open ( 3, 2, 'r',cp_id)

Открывается контрольная точка номер 3, состоящая из двух файлов на чтение. При этом формируется идентификатор контрольной точки и присваивается переменной cp_id.

call cpf_open ( -1, 1, 'r',cp_id)

Открывается контрольная точка, номер которой равен текущему значению контрольной точки минус 1, состоящая из одного файла на чтение. При этом формируется идентификатор контрольной точки и присваивается переменной cp_id.

Для открытия контрольной точки на запись наиболее типичен случай задания текущего значения контрольной точки:

call cpf_open ( 0, 1, 'w',cp_id)

Следующие две подпрограммы cpf_ropen ( открытие контрольной точки на чтение) и cpf_wopen (открытие текущей контрольной точки на запись) можно использовать вместо cpf_open для упрощения интерфейса.

cpf_ropen ( cp_num,cp_nfiles,cp_id)
- открытие контрольной точки на чтение.

Параметры:

  • cp_num (тип INTEGER) - номер открываемой нонтрольной точки. Если cp_num больше нуля - открывается контрольная точка, соответствующая абсолютному значению cp_num. Если cp_num равно нулю - открывается текущая контрольная точка. Если cp_num меньше нуля - открывается контрольная точка, соответствующая разнице текущей контрольной точки и значения cp_num.
  • cp_nfiles (тип INTEGER) - количество отдельных файлов, которые входят в контрольную точку ( от 1 до 99).
  • cp_id (тип INTEGER ) - записывается идентификатор контрольной точки или код ошибки.

Пример:

call cpf_ropen ( 3, 2,cp_id)

Открывается контрольная точка номер 3, состоящая из двух файлов на чтение. При этом формируется идентификатор контрольной точки и присваивается переменной cp_id.

call cpf_ropen ( -1, 1,cp_id)

Открывается контрольная точка, номер которой равен текущему значению контрольной точки минус 1, состоящая из одного файла на чтение. При этом формируется идентификатор контрольной точки и присваивается переменной cp_id.

call cpf_ropen ( 0, 1,cp_id)

Открывается контрольная точка, номер которой равен текущему значению контрольной точки, состоящая из одного файла на чтение. При этом формируется идентификатор контрольной точки и присваивается переменной cp_id.

cpf_wopen ( cp_nfiles,cp_level,cp_id)
- открытие текущей контрольной точки на запись.

Параметры:

  • cp_nfiles (тип INTEGER) - количество отдельных файлов, которые входят в контрольную точку ( от 1 до 99).
  • cp_id (тип INTEGER ) - записывается идентификатор контрольной точки или код ошибки.
  • cp_level - уровень сжатия информации при записи в файл (значение от 0 до 9). Тип INTEGER. Значение параметра соответствует уровню сжатия, обеспечиваемому библиотекой libz.
По умолчанию параметру cp_level присваивается значение 0 - информация записывается без сжатия. Изменение уровня сжатия распространяется на запись всех последующих контрольных точек.

Пример:

call cpf_wopen (1,6,cp_id)

Открывается контрольная точка, номер которой равен текущему значению контрольной точки, состоящая из одного файла на чтение. При этом формируется идентификатор контрольной точки и присваивается переменной cp_id. Уровень сжатия устанавливается равным 6.

Чтение контрольной точки из файла.

cpf_read (cp_id,cp_nfile, cp_buf, cp_len, ierr, fl)
- чтение из файла cp_nfile контрольной точки, определяемой идентификатором cp_id.

Параметры:

  • cp_id (тип INTEGER) - идентификатор контрольной точки (формирует cpf_open или cpf_ropen).
  • cp_nfile (тип INTEGER) - номер файла в контрольной точке, определяемой идентификатором cp_id.
  • cp_buf - адрес буфера.
  • cp_len (тип INTEGER) - длина буфера.
  • ierr - возвращаемое значение (тип INTEGER).Возвращаемое значение - длина прочитанной информации или код ошибки.
  • fl - флаг (тип INTEGER). Флаг принимает значение 0 - информация принимается в соответствии с заданной длиной (cp_len).

Если флаг - 1 (форматный ввод) принимается запись длиной не более cp_len.

Пример:

........
character*80 str
integer ii
real r1
........
call cpf_read( cp_id,1,str,80,ierr,1)
read (str,*)ii,r1

Запись контрольной точки в файл

cpf_write (cp_id, cp_nfile, cp_buf, cp_len, ierr, fl)
- запись в файл cp_nfile контрольной точки, определяемой идентификатором cp_id.

Параметры:

  • cp_id (тип INTEGER) - идентификатор контрольной точки (формирует cpf_open или cpf_wopen).
  • cp_nfile (тип INTEGER) - номер файла в контрольной точке , определяемой идентификатором cp_id.
  • cp_buf - адрес буфера.
  • cp_len (тип INTEGER) - длина буфера.
  • ierr (тип INTEGER) - возвращаемое значение. Возвращаемое значение - длина записанной информации или код ошибки.
  • fl - флаг (тип INTEGER). Флаг принимает значение 0 - информация передается в соответствии с заданной длиной (cp_len).

Если флаг равен 1 (форматный вывод) выполняется запись с удалением пробелов в конце записи.

Пример:

........
character*80 str
integer ii
real r1
........
write(str,*)ii,r1
call cpf_write(cp_id,2,str,80,ierr,1)

Закрытие контрольной точки.

cpf_close (cp_id,ierr)
- закрытие контрольной точки, определяемой идентификатором cp_id.

Параметры:

  • cp_id (тип INTEGER) - идентификатор контрольной точки (формирует cpf_open).
  • ierr - возвращаемое значение (тип INTEGER).Возвращает нуль или код ошибки.

Получение номера текущей контрольной точки.

cpf_current_num ( cp_mode,ierr)

Параметры:

  • cp_mode (тип INTEGER) - получение контрольной точки на чтение (0) или контрольной точки на запись(1).
  • ierr - возвращаемое значение (тип INTEGER).Возвращаемое значение - номер текущей контрольной точки
  • .

Опрос флага завершения времени кванта очередного запуска задачи.

cpf_signal (flag)

Параметры:

  • flag (тип INTEGER) - возвращаемое значение 0 (флаг не установлен) или 1(флаг установлен).

При первоначальном запуске задачи вводится дополнительный параметр, определяющий время (в минутах) предупреждения задачи о завершении (например за 5 минут до завершения), что позволяет сформировать контрольную точку до выброса задачи из счета. При достижении соответствующего времени устанавливается флаг. Завершение очередного запуска задачи может возникнуть в результате истечения кванта времени, выдаче mkill и т.д.

Определение дополнительного параметра: время формирования контрольной точки плюс промежуток между двумя cpf_signal.

2.3 Компиляция программ для работы с библиотекой libcp.a.

2.3.1 Компиляция программ для работы с библиотекой libcp.a с использованием MPI (синхронный режим)

При написании программы на языке "С" включить в текст программы #include "libcp.h"

Для компиляции использовать команды mpicc, mpiCC, mpif77, mpif90.

Для подключения библиотек libcp.a и libz.a (сжатие информации) необходимо добавить ключи -lcp -lz (строго в таком порядке).

Пример:

mpicc -o test -L/common/runmvs/lib -I/common/runmvs/include test.c -lcp -lz
mpif77 -o testf -L/common/runmvs/lib testf.f  -lcp -lz

2.3.2 Компиляция программ для работы с библиотекой libcp.a без использования MPI.

При написании программы на языке "С" включить в текст программы #include "libcp.h".

Для подключения библиотек libcp.a и libz.a (сжатие информации) необходимо добавить ключи

-lcpnompi -lz (строго в таком порядке).

Пример:

cc -o test -L/common/runmvs/lib -I/common/runmvs/include test.c -lcpnompi -lz
f77 -o testf -L/common/runmvs/lib testf.f  -lcpnompi -lz

2.4 Пример использования механизма контрольных точек.

2.4.1 Пример использования механизма контрольных точек на языке "С".

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "mpi.h"
#include "libcp.h"
 
#define TESTERR if(rz<0) exit(-1)
#define MAX_ITER 1000000
#define OUT_CP 10
#define LEN_AR 256

void  main (int argc, char* argv[])
{  int i,j,l;
   int rz,cp_num,cp_id;
   char str[128];
   int ar[LEN_AR];
   int iter=1;
   
   MPI_Init(&argc,&argv);
   rz = cp_init(1,"/home/test/contrpnew/tt",1);
   printf("rz init=%d \n",rz);
   TESTERR;
   cp_num=rz;
   if (cp_num==0)    /* first start task */
   { for(i=0; i!= LEN_AR;i++) /* initialize array */
      ar[i]=i+1;
     iter=0;                  /* iteration 0!!!*/
     j=0;
   }
   else  /* don't first start task */

   { rz=cp_ropen(cp_num,2); /* open CP for read */
     TESTERR;
     cp_id=rz;
     rz=cp_read(cp_id,1,str,128); /* read data */
     TESTERR;       
     printf("out str=%s\n",str);
     rz=cp_read(cp_id,1,&iter,sizeof(int));
     TESTERR;       
     printf("out iter=%d\n",iter); /* read value iteration */
     rz=cp_read(cp_id,2,ar,LEN_AR*sizeof(int)); /*read array from file2*/
     TESTERR;
     cp_close(cp_id);
     j=0;
    }
    printf("test: before for iter=%d MAX_ITER=%d\n",iter,MAX_ITER);
    for(;iter!=MAX_ITER;iter++)  /* basic loop */
    { for(i=0;i!=LEN_AR;i++)
       ar[i]=ar[i]+(iter+1);
      j++;    
      if (j==OUT_CP)
      { printf("test: before open j=%d iter=%d\n",j,iter);
        rz=cp_wopen(2,6);    /* open CP for write */
/*        printf("test: after open rz=%d\n",rz);*/
      TESTERR;
	cp_id=rz;
	cp_num=cp_current_num(1);
        printf("test: cp_num=%d\n",cp_num);
	l=strlen(str);
	sprintf(str,"OUT CONTRP N%d iter=%d len=%d\n",cp_num,iter,l);
	rz=cp_write(cp_id,1,str,128); /* write data */
      TESTERR;
	rz=cp_write(cp_id,1,&iter,sizeof(int)); /*write number iteration */
      TESTERR;
    rz=cp_write(cp_id,2,ar,LEN_AR*sizeof(int)); /*write array in file2*/
	cp_close(cp_id);
	j=0;
       }
    } 	
   MPI_Finalize();      
}

2.4.2 Пример использования механизма контрольных точек на языке Фортран.

program test2
      include 'mpif.h'
      parameter (MAX_ITER=1000000, OUT_CP=10,LEN_AR=256)
      integer i,j,j1,l
      integer rz,cp_num,cp_id
      character*128 str
      integer ar(LEN_AR)
      integer iter
   
      call MPI_INIT(rz)
С     INITIALIZE LIBCP
      call cpf_init(1,'/home/testf/tt',1,rz)
      print *,'rz init=',rz
      if(rz<0) goto 111
      cp_num=rz
      if (cp_num.eq.0)then
C     FIRST START TASK, INITIALIZE ARRAY 
      do i=1,LEN_AR
      ar(i)=i+1
      enddo
C     VALUE ITERATION 1 !!!
      iter=1
      j=1
      else
C     DON'T FIRST START TASK, OPEN CONTRPOINT FOR READ
      call cpf_ropen(cp_num,2,rz)
      if(rz<0) goto 111
      cp_id=rz
C     READ INFORMATION, FILE1!!! 
      call cpf_read(cp_id,1,str,128,rz,1)
      if(rz<0) goto 111
      print *,'out str=',str
      call cpf_read(cp_id,1,iter,4,rz,0)
      if(rz<0) goto 111
      print *,'out iter=',iter
C     READ ARRAY, FILE2!!! 
      call cpf_read(cp_id,2,ar,LEN_AR*4,rz,0)
      if(rz<0) goto 111
      call cpf_close(cp_id,rz)
C     CLOSE CONTRPOINT 
      j=1;
      endif
      print *,'test: before do iter MAX_ITER',iter,MAX_ITER
      do j1=iter,MAX_ITER
C     BASIC LOOP 
      iter=j1
      do i=1,LEN_AR
      ar(i)=ar(i)+(iter+1)
      enddo
      j=j+1
      if(j.eq.OUT_CP)then
      print *,'test: before open j iter ',j,iter
C     OPEN CONTRPOINT FOR WRITE
      call cpf_wopen(2,6,rz)
      if(rz<0) goto 111
      cp_id=rz
      call cpf_current_num(1,cp_num)
      print *,'test: cp_num=',cp_num
      write(str,'(A12,2I12)'),'OUT CONTRP  ',cp_num,iter
C     WRITE INFORMATION, FILE1!!!
      call cpf_write(cp_id,1,str,128,rz,1)
      if(rz<0) goto 111
      call cpf_write(cp_id,1,iter,4,rz,0)       
      if(rz<0) goto 111
C     WRITE ARRAY, FILE2!!!
      call cpf_write(cp_id,2,ar,LEN_AR*4,rz,0)
C     CLOSE CONTRPOINT
      call cpf_close(cp_id,rz)
      j=1
      endif
      enddo
111   continue
      if(rz<0) print *,'error libcp'
      rz=0
      call MPI_FINALIZE(rz)      
      end
 
 
 
 
 
 
 
 
  Тел. +7(499)220-79-72; E-mail: inform@kiam.ru