The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа
next up previous contents
Next: Пояснения к состоянию после Up: Пояснения к MPI-1.0 и Previous: Пояснения к MPI_INITIALIZED.   Contents

Пояснения к MPI_FINALIZE.

Данная подпрограмма очищает состояние MPI. Каждый процесс должен вызывать MPI_FINALIZE перед завершением. За исключением тех случаев, когда был вызов MPI_ABORT, каждый процесс должен убедиться в том, что все ожидающие неблокирующие взаимодействия завершены (локально) перед вызовом MPI_FINALIZE. Более того, на момент вызова MPI_FINALIZE последним процессом все ожидающие отправления информации должны быть сопоставлены с получениями информации и наоборот.

Например, следующая программа правильна:

Process 0                Process 1
        ---------                ---------
        MPI_Init();              MPI_Init();
        MPI_Send(dest=1);        MPI_Recv(src=0);
        MPI_Finalize();          MPI_Finalize();
Без соответствующего приема информации программа ошибочна:
Process 0                Process 1
        -----------              -----------
        MPI_Init();              MPI_Init();
        MPI_Send (dest=1);
        MPI_Finalize();          MPI_Finalize();

Успешный возврат из блокирующей операции связи или из MPI_WAIT или MPI_TEST говорит пользователю о том, что буфер может быть использован заново, и означает, что связь осуществлена пользователем, но не гарантирует, что у локального процесса нет больше работы. Успешный возврат из MPI_REQUEST_FREE с дескриптором, сгенерированным MPI_ISEND, обнуляет дескриптор, но не дает никакой уверенности в завершенности операции. MPI_ISEND завершен, только когда какими-либо средствами будет выяснено, что соответствующий прием информации завершен. MPI_FINALIZE гарантирует, что все локальные действия, требуемые соединениями, осуществленными пользователем, будут, в действительности, произведены до возврата из подпрограммы.

MPI_FINALIZE ничего не гарантирует относительно ожидающих соединений (завершение подтверждается только вызовом MPI_WAIT, MPI_TEST или MPI_REQUEST_FREE, вместе с другими средствами проверки завершения).

Пример Данная программа правильна:

rank 0                          rank 1
=====================================================
...                             ...
MPI_Isend();                    MPI_Recv();
MPI_Request_free();             MPI_Barrier();
MPI_Barrier();                  MPI_Finalize();
MPI_Finalize();                 exit();
exit();
Пример Данная программа ошибочна и ее поведение неопределено:
rank 0                          rank 1
=====================================================
...                             ...
MPI_Isend();                    MPI_Recv();
MPI_Request_free();             MPI_Finalize();
MPI_Finalize();                 exit();
exit();

Если не происходит MPI_BUFFER_DETACH между MPI_BSEND (или другой буферизованной отправкой) и MPI_FINALIZE, то MPI_FINALIZE неявно поддерживает MPI_BUFFER_DETACH.

Пример Данная программа правильна, и после MPI_Finalize, она ведет себя так, как если бы буфер был отсоединен.

rank 0                          rank 1
=====================================================
...                             ...
buffer = malloc(1000000);       MPI_Recv();
MPI_Buffer_attach();            MPI_Finalize();
MPI_Bsend();                    exit();
MPI_Finalize();
free(buffer);
exit();

Пример В данном примере подпрограмма MPI_Iprobe() должна возвращать флаг false (ложь). Подпрограмма MPI_Test_cancelled() должна возвращать флаг true(истина), независимо от относительного порядка выполнения MPI_Cancel() в процессе 0 и MPI_Finalize() в процессе 1.

Вызов MPI_Iprobe() здесь для того, чтобы убедиться, что реализация знает, что сообщение ``tag1'' существует в месте назначения, в то время как мы не можем утверждать, что об этом знает пользователь.

rank 0                          rank 1
========================================================
MPI_Init();                     MPI_Init();
MPI_Isend(tag1);
MPI_Barrier();                  MPI_Barrier();
                                MPI_Iprobe(tag2);
MPI_Barrier();                  MPI_Barrier();
                                MPI_Finalize();
                                exit();
MPI_Cancel();
MPI_Wait();
MPI_Test_cancelled();
MPI_Finalize();
exit();

Совет разработчикам: Реализации может быть нужно отложить возврат из MPI_FINALIZE, пока не будут произведены все потенциальные будущие отмены сообщений. Одним из важных решений является установка барьера в MPI_FINALIZE. []

После того как осуществляется возврат из MPI_FINALIZE, не может быть вызвана ни одна подпрограмма MPI (даже MPI_INIT), кроме MPI_GET_VERSION, MPI_INITIALIZED, и MPI-2 функции MPI_FINALIZED. Каждый процесс должен завершить все ожидающие соединения, которые он инициировал, перед вызовом MPI_FINALIZE. Если вызов возвращается, каждый процесс может продолжать локальные вычисления или завершиться без участия в дальнейших MPI соединениях с другими процессами. MPI_FINALIZE - коллективная над MPI_COMM_WORLD.

Совет разработчикам: Несмотря на то, что процесс завершил все соединения, которые он инициировал, некоторые соединения могут быть незавершены с точки зрения MPI системы. Например, блокирующая отправка может быть завершена, даже если данные все еще буферизованны у отправителя. Реализация MPI должна убеждаться, что процесс завершил все, связанное с MPI соединениями, перед возвратом из MPI_FINALIZE. Поэтому, если процесс завершается после вызова MPI_FINALIZE, это не станет причиной сбоя текущих соединений. []

Хотя и не требуется, чтобы все процессы осуществляли возврат из MPI_FINALIZE, требуется, чтобы как минимум процесс 0 в MPI_COMM_WORLD осуществлял возврат, чтобы пользователи могли знать, что вычисления MPI завершены. Кроме того, в среде POSIX, желательно поддерживать коды завершения для каждого процесса, который осуществляет возврат из MPI_FINALIZE.

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

...
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    ...
    MPI_Finalize();
    if (myrank == 0) {
        resultfile = fopen("outfile","w");
        dump_results(resultfile);
        fclose(resultfile);
    }
    exit(0);



Alex Otwagin 2002-12-10



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру