- •Введение
- •Порядок выполнения и защиты лабораторных работ
- •Лабораторная работа №1. Определение параметров n-мерных коммутационных структур вс типа гиперкуб, тор и циркулянт
- •Приведение схем алгоритмов к виду, удобному для организации параллельных вычислений.
- •Использование граф-схем для представления параллельных алгоритмов
- •Определение контуров в граф-схеме алгоритма
- •Лабораторная работа №4. Построение матрицы логической несовместимости операторов
- •Лабораторная работа №5. Построение множеств взаимно независимых операторов
- •Лабораторная работа №6. Определение ранних и поздних сроков окончания выполнения операторов и оценка снизу требуемого количества процессоров и времени решения задачи на вс
- •Лабораторная работа №8. Написание программ с использованием библиотеки mpi
- •Определение характеристик таймера
- •Приём и передача сообщений
- •Определения структуры приходящего сообщения
- •Определение базовых характеристик коммуникационной сети
- •Анализ тупиковых ситуаций при обмене
- •Организация передачи-приёма сообщений без блокировки
- •Реализация отложенных запросов на взаимодействие
- •Сравнительная оценка различных способов обмена данными
- •Использование глобальных операций в mpi
- •Взаимодействие процессов в mpi
- •Оглавление
Организация передачи-приёма сообщений без блокировки
Демонстрация применениея неблокирующих операций для реализации транспонирования квадратной матрицы, распределенной между процессами по строкам, приведена ниже. Сначала каждый процесс локально определяет 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;}
