The OpenNET Project / Index page

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

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

Примеры использования MPI_SCAN

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


values v$_{1}$ v$_{2}$ v$_{3}$ v$_{4}$ v$_{5}$ v$_{6}$ v$_{7}$ v$_{8}$
logicals 0 0 1 1 1 0 0 1
result v$_{1}$ v$_{1}$+v$_{2}$ v$_{3}$ v$_{3}$+v$_{4}$ v$_{3}$+v$_{4}$+v$_{5}$ v$_{6}$ v$_{6}$+v$_{7}$ v$_{8}$

Оператор, производящий этот эффект


\begin{displaymath}
\left({{\begin{array}{*{20}c}
u \hfill \\
i \hfill \\
\e...
...y}{*{20}c}
w \hfill \\
j \hfill \\
\end{array} }} \right),
\end{displaymath}

где


\begin{displaymath}
w = \left\{ {{\begin{array}{*{20}c}
{u + v} \hfill \\
v \...
...{\mbox{ if i } \ne \mbox{ j}} \hfill \\
\end{array} } \quad .
\end{displaymath}

Отметим, что это некоммутативный оператор. Код на языке Си, реализующий вычисления, представлен ниже.

typedef struct {
    double val;
    int log;
} SegScanPair;

/* функция, определенная пользователем 
 */ 
void segScan(SegScanPair *in, SegScanPair *inout,
        int *len, MPI_Datatype *dptr) 
{ 
    int i; 
    SegScanPair c; 
 
    for (i=0; i< *len; ++i) { 
        if (in->log == inout->log) 
            c.val = in->val + inout->val; 
        else 
            c.val = inout->val; 
        c.log = inout->log; 
        *inout = c; 
        in++; inout++; 
    } 
}

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

    int i,base;
    SeqScanPair  a, answer;
    MPI_Op       myOp;
    MPI_Datatype type[2] = {MPI_DOUBLE, MPI_INT};
    MPI_Aint     disp[2]; 
    int          blocklen[2] = { 1, 1}; 
    MPI_Datatype sspair; 
 
    /* объяснение для MPI, как определяется тип SegScanPair 
     */ 
    MPI_Address(a, disp); 
    MPI_Address(a.log, disp+1); 
    base = disp[0]; 
    for (i=0; i<2; ++i) disp[i] -= base; 
    MPI_Type_struct(2, blocklen, disp, type, &sspair); 
    MPI_Type_commit(&sspair); 
    /* создается пользовательская операция segmented-scan 
     */ 
    MPI_Op_create(segScan, False, &myOp); 
    ... 
    MPI_Scan(a, answer, 1, sspair, myOp, root, comm);



Alex Otwagin 2002-12-10



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

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