The OpenNET Project / Index page

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

Каталог документации / Раздел "Программирование, языки" / Оглавление документа
next up previous contents
Next: Ассоциирование информации со статусом Up: Обобщенные запросы Previous: Обобщенные запросы   Contents

Примеры

Пример 6.1. Этот пример показывает код для определяемой пользователем небольшой операции над типом int с использованием бинарного дерева: каждый некорневой узел получает два сообщения, суммирует их содержимое, и посылает на уровень выше. Принимается, что никакого статуса не возвращается и что операция не может быть отменена.

typedef struct {
   MPI_Comm comm;
   int tag;
   int root;
   int valin;
   int *valout;
   MPI_Request request;
} ARGS;

int myreduce(MPI_Comm comm, int tag, int root,
             int valin, int *valout, MPI_Request *request) {

     ARGS *args;
     pthread_t thread;

     /* Запрос стартует */
     MPI_Grequest_start(query_fn, free_fn, cancel_fn, NULL, request);
     args = (ARGS*)malloc(sizeof(ARGS));
     args->comm = comm;
     args->tag = tag;
     args->root = root;
     args->valin = valin;
     args->valout = valout;
     args->request = *request;

     /* Нить узла обработки запроса */
     /* Доступность вызова pthread_create определяется системой */
     pthread_create(&thread, NULL, reduce_thread, args);
     return MPI_SUCCESS;
}

/* код нити*/
void reduce_thread(void *ptr) {

     int Ichild, rchild, parent, lval, rval, val;
     MPI_Request req[2];
     ARGS *args;

     args = (ARGS*)ptr;

     /* Определение ссылкок вниз влево, вниз вправо и вверх для узла дерева; */
     /* Установка  в  MPI_PROC_NULL если ссылки     не существуют */
     /* Код не показан */
     ...
     MPI_Irecv(&lval,  1, MPI_INT, lchild,  args->tag,  args->comm, &req[0]);
     MPI_Irecv(&rval,  1, MPI_INT, rchild,  args->tag,  args->comm, &req[l]);

     MPI_Waitall(2, req, \verb|MPI_STATUSES_IGNORE|) ;
     val = Ival + args->valin + rval;
     MPI_Send( &val, 1, MPI_INT, parent, args->tag, args->comm );
     if (parent == MPI_PROC_NULL) *(args->valout) = val;
     MPI_Grequest_complete ((args->request));
     free(ptr) ;
     return ;
}

int \verb|query_fn|(void *extra_state, MPI_Status *status) {

     /* Всегда посылает только int */
     MPI_Status_set_elements (status, MPI_INT, 1);
     /*  Никогда нельзя отменить т.к. всегда истинна     */
     MPI_Status_set_cancelled(status, 0);
     /* Выбрано, что для этого ничего не возвращается     */
     status->MPI_SOURCE = MPI_UNDEFINED;
     /*  Тэг не имеет смысла для этого обобщенного запроса */
     status->MPI_TAG = MPI_UNDEFINED;
     /*  Этот обобщенный запрос всегда выполняется */
     return MPI_SUCCESS;
}

int \verb|free_fn|(void *extra_state) {

     /* Этот обобщенный запрос не требует никакого освобождения т.к. всегда 
выполняется */
     return MPI_SUCCESS;
}

int cancel_fn(void *extra_state, int complete) {
     /* Этот обобщенный запрос не поддерживает отмену. */
     /*Выход Ц, если уже выполнен. */
     /*Если выполнен, то нить такая же, как и для случая с отменой. */
     if (!complete) {
          fprintf (stderr,
               "Cannot  cancel generalized request - aborting
          program\n"); MPI_Abort(MPI_COMM_WORLD, 99);
     }
     return MPI_SUCCESS;
}



Alex Otwagin 2002-12-10



Спонсоры:
Слёрм
Inferno Solutions
Hosting by Ihor
Хостинг:

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