| |
Например, следующая программа правильна:
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);
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |