Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лабы по ВС 1-09 -2011г.doc
Скачиваний:
10
Добавлен:
14.11.2019
Размер:
1 Мб
Скачать
☆

Организация передачи-приёма сообщений без блокировки

Демонстрация применениея неблокирующих операций для реализации транспонирования квадратной матрицы, распределенной между процессами по строкам, приведена ниже. Сначала каждый процесс локально определяет nl строк массива а. Затем при помощи неблокирующих операций MPI_Isend и MPI_Irecv инициализируются все необходимые для транспонирования обмены данными. На фоне начинающихся обменов каждый процесс транспонирует свою локальную часть массива а. После этого процесс при помощи вызова процедуры MPI_Waitany дожидается прихода сообщения от любого другого процесса и транспонирует полученную от данного процесса часть массива а. Обработка продолжается до тех пор, пока не будут получены сообщения от всех процессов. В конце исходный массив а и транспонированный массив b распечатываются.

Пример 12:

#include "mpi.h"

#include <stdio.h>

#include <stdlib.h>

#define N 9

double a[N][N],b[N][N];

void work(int n,int nl,int size,int rank)

{

int ierr,i,j,ii,jj,ir,irr;

const int MAXPROC=64;

char *a,*b,c;

MPI_Status status;

MPI_Request req1[MAXPROC] ;

MPI_Request req2[MAXPROC] ;

// creating arrays

a=(char*) malloc(nl*n);

b=(char*) malloc(nl*n);

//ok

for (i=1;i<nl;i++)

for (j=1;j<n;j++)

{

ii=i+rank*nl;

if (ii<=n) a[i*n+j]=100*ii+j;

}

for (ir=0;ir<size-1;ir++)

if (ir!=rank)

ierr=MPI_Irecv(&b[i*n+ir*nl+1],nl*nl,MPI_DOUBLE, ir,MPI_ANY_TAG,MPI_COMM_WORLD,&req1[ir] ) ;

req1[rank]=MPI_REQUEST_NULL;

for (ir=0;ir<size-1;ir++)

if (ir!=rank)

ierr=MPI_Isend(&a[i*n+ir*nl+1],nl*nl,MPI_DOUBLE,ir, 6,MPI_COMM_WORLD, &req2[ir] ) ;

ir=rank;

for (i=1;i<nl;i++)

{

ii=i+ir*nl;

for (j=i+1;j<nl;j++)

{ jj=j+ir*nl;

b[i*n+jj]=a[j*n+ii];

b[j*n+ii]=a[i*n+jj]; }

b[i*n+ii] =a[i*n+ii];

}

for (irr=1;irr<size-1;irr++)

{

ierr=MPI_Waitany(size-1,req1,&ir, &status) ;

if (rank==0) printf("Process ir %i nl %i\n",ir,nl); fflush(stdout);

//ir=ir-1;

for (i=1;i<nl;i++)

{

ii=i+ir*nl;

for (j=i + 1;j<nl;j++)

{

jj=j+ir*nl;

if (rank==0) printf("i,j %i,%i \n",i*n+jj,j*n+ii);fflush(stdout);

c=b[i*n+jj];

b[i*n+jj]=b[j*n+ii];

b[j*n+ii]=c;}

}

}

for (i=1;i<nl;i++)

for (j=1;j<N;j++)

{ ii=i+rank*nl;

if (ii<=n)

printf("Process %i : a (%i,%i)= %4.4d, b(%i,%i)=%4.4d\n",rank,ii,j,a[i*n+j],ii,j , b[i*n+j]);

fflush(stdout);

}

// deleting arrays

free(a);

free(b);

}

int main(int argc,char * argv[])

{

int ierr,rank,size,nl,i, j;

ierr=MPI_Init(&argc,&argv);

ierr=MPI_Comm_size(MPI_COMM_WORLD, &size) ;

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank) ;

nl=(N-1)/size+1;

work(N,nl,size,rank);

printf("OK\n");

fflush(stdout);

//ierr=MPI_Finalize();

return 0;

}

Задание: Измените программу так, чтобы она проверяла, является ли введённая матрица симметрической.

В следующем примере операции двунаправленного обмена с соседними процессами в кольцевой топологии производятся при помощи двух вызовов про­цедуры MPI_Sendrecv. При этом гарантированно не возникает тупиковой си­туации.

Пример 13:

#include <stdio.h>

#include "mpi.h"

int main(int argc,char * argv[]) {

int ierr,rank,size,prev,next,buf[2];

MPI_Status status1,status2;

ierr=MPI_Init(&argc,&argv);

ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

prev=rank==0?size-1:rank-1;

next=rank==size-1?0:rank+1;

ierr=MPI_Sendrecv(&rank,1,MPI_INT,prev,6,&buf[1],1,MPI_INT,next, 6,MPI_COMM_WORLD,&status2);

ierr=MPI_Sendrecv(&rank,1,MPI_INT,next,5,&buf[0],1,MPI_INT,prev, 5,MPI_COMM_WORLD,&status1);

printf("Process %i prev=%i next = %i\n",rank,buf[0],buf[1]);

ierr=MPI_Finalize();

return 0;}