The OpenNET Project / Index page

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

Каталог документации / Раздел "Программирование, языки" / Оглавление документа
next up previous contents
Next: Интер-коммуникация Up: Примеры Previous: Библиотечный пример 1   Contents

Библиотечный пример 2

Головная программа:

   main(int argc, char **argv) 
   { 
     int ma, mb; 
     MPI_Group MPI_GROUP_WORLD, group_a, group_b; 
     MPI_Comm comm_a, comm_b; 
     static int list_a[] = {0, 1}; 

#if defined(EXAMPLE_2B) | defined(EXAMPLE_2C) 
     static int list_b[] = {0, 2 ,3}; 
#else/* EXAMPLE_2A */ 
     static int list_b[] = {0, 2}; 
#endif 
     int size_list_a = sizeof(list_a)/sizeof(int); 
     int size_list_b = sizeof(list_b)/sizeof(int); 
 
     ... 
     MPI_Init(&argc, &argv); 
     MPI_Comm_group(MPI_COMM_WORLD, &MPI_GROUP_WORLD); 
 
     MPI_Group_incl(MPI_GROUP_WORLD, size_list_a, list_a, &group_a); 
     MPI_Group_incl(MPI_GROUP_WORLD, size_list_b, list_b, &group_b); 
 
     MPI_Comm_create(MPI_COMM_WORLD, group_a, &comm_a); 
     MPI_Comm_create(MPI_COMM_WORLD, group_b, &comm_b);
 
     if(comm_a != MPI_COMM_NULL) 
        MPI_Comm_rank(comm_a, &ma); 
     if(comm_b != MPI_COMM_NULL) 
        MPI_Comm_rank(comm_b, &mb); 
 
     if(comm_a != MPI_COMM_NULL) 
        lib_call(comm_a); 
 
     if(comm_b != MPI_COMM_NULL) 
     { 
       lib_call(comm_b); 
       lib_call(comm_b); 
     } 
 
     if(comm_a != MPI_COMM_NULL) 
       MPI_Comm_free(&comm_a); 
     if(comm_b != MPI_COMM_NULL) 
       MPI_Comm_free(&comm_b);
     MPI_Group_free(&group_a);
     MPI_Group_free(&group_b);
     MPI_Group_free(&MPI_GROUP_WORLD); 
     MPI_Finalize(); 
   }

Библиотека:

   void lib_call(MPI_Comm comm) 
   { 
     int me, done = 0; 
     MPI_Comm_rank(comm, &me); 
     if(me == 0) 
        while(!сделано) 
        { 
           MPI_Recv(..., MPI_ANY_SOURCE, MPI_ANY_TAG, comm); 
           ... 
        } 
     else 
     { 
       /* работа */ 
       MPI_Send(..., 0, ARBITRARY_TAG, comm);
       .... 
     } 
#ifdef EXAMPLE_2C 
     /* include (resp, exclude) for safety
        (resp, no safety): */ 
     MPI_Barrier(comm); 
#endif 
   }

Приведенный выше пример - это на самом деле три примера, зависящих от того, включен или не включен процесс номер 3 в list_b, включена или не включена синхронизация в lib_call. Пример показывает, что нет необходимости защищать друг от друга последовательные обращения к lib_call с тем же самым контекстом. Безопасность будет реализована, еcли добавлена функция MPI_Barrier. Это демонстрирует тот факт, что библиотеки должны быть тщательно разработаны, даже при наличии контекстов.

Алгоритмы с недетерминированной широковещательной операцией или другие обращения с произвольными номерами поцессов-отправителей в общем случае будут уступать детерминированным реализациям ``reduce'', ``allreduce'', и ``broadcast''. Таким алгоритмам следовало бы использовать монотонно возрастающие тэги (в пределах контекста коммуникатора), чтобы сохранить корректность вычислений.

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



Alex Otwagin 2002-12-10



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

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