Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В

..pdf
Скачиваний:
240
Добавлен:
24.05.2014
Размер:
1.69 Mб
Скачать

{ int iMyRank, iRoot = 0, iRow, iColumn, gsize, sizeof_double;

MPI_Comm _Comm = MPI_COMM_WORLD; /* в группе все процессы */ MPI_Status status;

double x[MATRIXSIZE][MATRIXSIZE], y[MATRIXSIZE][MATRIXSIZE]; MPI_Init(&argc, &argv);

MPI_Comm_size(_Comm, &gsize); MPI_Comm_rank(_Comm, &iMyRank); if (iMyRank == iRoot)

{printf("Transpose the matrix\n"); srand((int)((double)MPI_Wtime()*1e7));

for (iRow = 0; iRow < MATRIXSIZE; ++iRow)

{for (iColumn = 0; iColumn < MATRIXSIZE; ++iColumn)

{x[iRow][iColumn] = rand() % 100;

printf("%3.0f ", x[iRow][iColumn]);

}

printf("\n");

}

}

MPI_Type_extent(MPI_DOUBLE, &sizeof_double); MPI_Type_vector(MATRIXSIZE, 1, MATRIXSIZE, MPI_DOUBLE, &iRow); MPI_Type_hvector(MATRIXSIZE, 1, sizeof_double, iRow, &iColumn); MPI_Type_commit(&iColumn);

MPI_Sendrecv(x, 1, iColumn, iMyRank, 0, y, MATRIXSIZE * MATRIXSIZE, MPI_DOUBLE, iMyRank, iRoot, MPI_COMM_WORLD, &status);

if (iMyRank == iRoot)

{for (iRow = 0; iRow < MATRIXSIZE; ++iRow)

{printf("\n");

for (iColumn = 0; iColumn < MATRIXSIZE; ++iColumn)

printf("%3.0f ", y[iRow][iColumn]);

}

}

MPI_Finalize(); return 0;

}

Задание 4.1.

#include <stdio.h> #include "mpi.h"

int main( argc, argv ) int argc;

char **argv;

{int rank, value;

MPI_Init( &argc, &argv );

MPI_Comm_rank( MPI_COMM_WORLD, &rank ); do {

if (rank == 0) scanf( "%d", &value );

291

MPI_Bcast( &value, 1, MPI_INT, 0, MPI_COMM_WORLD ); printf( "Process %d got %d\n", rank, value );

} while (value >= 0); MPI_Finalize( ); return 0;

}

Задание 4.2.

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <mpi.h>

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

{int iRoot=0, iMyRank, iSize =0, i;

double dSum = 0, dResult = 0, Vec_1[20], Vec_2[20];

MPI_Comm _Comm = MPI_COMM_WORLD;

/* в группе все процессы */

MPI_Init(&argc, &argv);

 

MPI_Comm_rank(_Comm, &iMyRank);

 

MPI_Comm_size(_Comm, &iSize);

 

if ( iMyRank == iRoot )

 

{ srand((int)(MPI_Wtime()*1e4));

/* заполнение векторов */

printf("Vector1=\n");

 

for (i = 0; i < 20; ++i)

 

{ Vec_1[i] = rand() % 11;

 

printf("%3.0f ", Vec_1[i]);

 

}

 

printf("\nVector2=\n");

 

for (i = 0; i < 20; ++i)

 

{ Vec_2[i] = rand() % 11;

 

printf("%3.0f ", Vec_2[i]);

 

}

 

printf("\n");

 

}

 

MPI_Bcast(Vec_1, 20, MPI_DOUBLE, iRoot, _Comm);

MPI_Bcast(Vec_2, 20, MPI_DOUBLE, iRoot, _Comm);

/* считаем локальную сумму */

for (i = iMyRank, dSum = 0; i < 20; i += iSize) dSum += Vec_1[i] * Vec_2[i]; MPI_Reduce(&dSum, &dResult, 1, MPI_DOUBLE, MPI_SUM, iRoot, _Comm);

if (iMyRank == iRoot)

printf("Result is %f\n", dResult);

MPI_Finalize();

 

return 0;

 

}

292

Задание 4.3.

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <mpi.h> #define n 10 #define m 5

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

{int iRoot=0, iMyRank, iSize =0, i, j;

double dSum[n], dResult[n], Vec_1[m], Matr[m][n];

MPI_Comm _Comm = MPI_COMM_WORLD;

/* в группе все процессы */

MPI_Init(&argc, &argv);

 

MPI_Comm_rank(_Comm, &iMyRank);

 

MPI_Comm_size(_Comm, &iSize);

 

if ( iMyRank == iRoot )

 

{ srand((int)(MPI_Wtime()*1e4));

/* заполнение векторов */

printf("Vector1=\n");

 

for (i = 0; i < m; ++i)

 

{ Vec_1[i] = rand() % 11;

 

printf("%2.0f ", Vec_1[i]);

 

}

 

printf("\nMatrix=\n");

 

for (i = 0; i < m; ++i)

 

{ for (j = 0; j < n; ++j)

 

{ Matr[i][j] = rand() % 11;

 

printf("%2.0f ", Matr[i][j]);

 

}

 

printf("\n");

 

}

 

printf("\n");

 

}

MPI_Bcast(Vec_1, m, MPI_DOUBLE, iRoot, _Comm); for (i = 0; i < n; ++i)

MPI_Bcast(Matr[i], m, MPI_DOUBLE, iRoot, _Comm);

/* считаем локальную сумму */

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

{dSum[j] = 0;

for (i = iMyRank; i < m; i += iSize) dSum[j] += Vec_1[i] * Matr[i][j];

}

MPI_Reduce(&dSum, dResult, n, MPI_DOUBLE, MPI_SUM, iRoot, _Comm);

if (iMyRank == iRoot)

293

{ printf("Result is:\n");

for (i = 0; i < n; ++i) printf("%3.0f ", dResult[i]);

}

MPI_Finalize(); return 0;

}

Задание 4.5.

#include <stdio.h> #include "mpi.h"

int main( argc, argv ) int argc;

char **argv;

{struct { int a; double b } value; MPI_Datatype mystruct, old_types[2];

int blocklens[2], rank; MPI_Aint indices[2]; MPI_Init( &argc, &argv );

MPI_Comm_rank( MPI_COMM_WORLD, &rank ); blocklens[0] = 1; blocklens[1] = 1; /* базовые типы */ old_types[0] = MPI_INT; old_types[1] = MPI_DOUBLE;

/* адреса каждого элемента */ MPI_Address( &value.a, &indices[0] ); MPI_Address( &value.b, &indices[1] ); indices[1] = indices[1] - indices[0]; indices[0] = 0; /*новый тип данных */ MPI_Type_struct( 2, blocklens, indices, old_types, &mystruct ); MPI_Type_commit( &mystruct );

do

{if (rank == 0) scanf( "%d %lf", &value.a, &value.b ); MPI_Bcast( &value, 1, mystruct, 0, MPI_COMM_WORLD );

printf( "Process %d got %d and %lf\n", rank, value.a, value.b ); } while (value.a >= 0);

MPI_Type_free( &mystruct ); MPI_Finalize( );

return 0;

}

Задание 4.6.

#include <stdio.h> #include "mpi.h"

int main( argc, argv ) int argc;

char **argv;

{ int

rank, Packsize, position, a;

double

b;

char

Packbuf[100];

MPI_Init( &argc, &argv );

294

MPI_Comm_rank( MPI_COMM_WORLD, &rank ); do

{if (rank == 0)

{scanf( "%d %lf", &a, &b ); Packsize = 0;

MPI_Pack( &a, 1, MPI_INT, Packbuf, 100, &Packsize,

MPI_COMM_WORLD ); MPI_Pack( &b, 1, MPI_DOUBLE, Packbuf, 100,

&Packsize,MPI_COMM_WORLD);

}

MPI_Bcast( &Packsize, 1, MPI_INT, 0, MPI_COMM_WORLD ); MPI_Bcast( Packbuf, Packsize, MPI_PACKED, 0, MPI_COMM_WORLD ); if (rank != 0)

{position = 0;

MPI_UnPack( Packbuf, Packsize, &position, &a, 1, MPI_INT, MPI_COMM_WORLD );

MPI_UnPack( Packbuf, Packsize, &position, &b, 1, MPI_DOUBLE,MPI_COMM_WORLD );

}

printf( "Process %d got %d and %lf\n", rank, a, b ); } while (a >= 0);

MPI_Finalize( ); return 0;

}

Задание 4.8.

#include <stdio.h>

 

 

#include <stdlib.h>

 

#include "mpi.h"

 

 

#define NUMBER_OF_TESTS 10

 

int main( argc, argv )

 

int argc;

 

 

 

char **argv;

 

 

{ int

rank,

size, j, k, nloop;

 

double

t1, t2, tmin, d_in, d_out;

 

MPI_Init( &argc, &argv );

 

MPI_Comm_rank( MPI_COMM_WORLD, &rank );

MPI_Comm_size( MPI_COMM_WORLD, &size );

if (rank == 0 && size == 1)

printf( "Kind\t\tnp\ttime (sec)\n" );

nloop = 1000;

tmin = 1000;

 

for (k=0; k<NUMBER_OF_TESTS; k++)

{MPI_Barrier( MPI_COMM_WORLD ); d_in = 1.0;

t1 = MPI_Wtime(); for (j=0; j<nloop; j++)

MPI_Allreduce( &d_in, &d_out, 1, MPI_DOUBLE, MPI_SUM,

295

MPI_COMM_WORLD );

t2 = (MPI_Wtime() - t1) / nloop; if (t2 < tmin) tmin = t2;

}

if (rank == 0) printf( "Allreduce\t%d\t%f\n", size, tmin ); MPI_Finalize( );

return 0; }

Задание 4.9.

#include <stdio.h> #include <stdlib.h> #include "mpi.h"

#define NUMBER_OF_TESTS 10 int main( argc, argv )

int argc; char **argv;

{ double

t1, t2, tmin;

int

j, k, nloop, rank, size;

MPI_Init( &argc, &argv );

MPI_Comm_rank( MPI_COMM_WORLD, &rank ); MPI_Comm_size( MPI_COMM_WORLD, &size );

if (rank == 0 && size == 1) printf( "Kind\tnp\ttime (sec)\n" ); nloop = 1000; tmin = 1000;

for (k=0; k<NUMBER_OF_TESTS; k++)

{MPI_Barrier( MPI_COMM_WORLD ); t1 = MPI_Wtime();

for (j=0; j<nloop; j++)

MPI_Barrier( MPI_COMM_WORLD );

t2 = (MPI_Wtime() - t1) / nloop; if (t2 < tmin) tmin = t2;

}

if (rank == 0) printf( "Barrier\t%d\t%f\n", size, tmin ); MPI_Finalize( );

return 0;

}

Задание 4.11.

int main( argc, argv ) int argc;

char *argv[];

{double A[8][8], alocal[4][4]; int i, j, r, rank, size;

MPI_Datatype stype, t[2], vtype; MPI_Aint displs[2];

int blklen[2], sendcount[4], sdispls[4]; MPI_Init( &argc, &argv );

MPI_Comm_rank( MPI_COMM_WORLD, &rank ); 296

MPI_Comm_size( MPI_COMM_WORLD, &size ); if (size != 4)

{fprintf( stderr, "This program requires exactly four processors\n" ); MPI_Abort( MPI_COMM_WORLD, 1 );

}

 

 

 

 

if (rank == 0)

 

 

 

 

{

 

/* Инициализация матрицы */

for (j=0; j<8; j++)

 

 

 

for (i=0; i<8; i++)

A[i][j] = 1.0 + i / 10.0 + j / 100.0;

 

 

/* новый векторный тип для подматриц */

MPI_Type_vector( 4, 4, 8, MPI_DOUBLE, &vtype );

 

t[0] = vtype;

t[1] = MPI_UB;

 

 

displs[0] = 0; displs[1] = 4 * sizeof(double);

 

blklen[0] = 1;

blklen[1] = 1;

 

 

MPI_Type_struct( 2, blklen, displs, t, &stype );

 

MPI_Type_commit( &stype );

 

 

sendcount[0] = 1; sendcount[1] = 1;

sendcount[2] = 1;

sendcount[3] = 1;

sdispls[0] = 0;

sdispls[1] = 1;

sdispls[2] = 8;

sdispls[3] = 9;

MPI_Scatterv( &A[0][0], sendcount, sdispls, stype, &alocal[0][0], 4*4, MPI_DOUBLE, 0, MPI_COMM_WORLD );

}

else

MPI_Scatterv( (void *)0, (void *)0, (void *)0, MPI_DATATYPE_NULL, &alocal[0][0], 4*4, MPI_DOUBLE, 0, MPI_COMM_WORLD );

/* каждый процесс печатает свою часть матрицы */

for (r = 0; r<size; r++) { if (rank == r)

{printf( "Output for process %d\n", r ); for (j=0; j<4; j++)

{for (i=0; i<4; i++) printf( "%.2f ", alocal[i][j] ); printf( "\n" );

}

fflush( stdout );

}

MPI_Barrier( MPI_COMM_WORLD );

}

MPI_Finalize( ); return 0;

}

Задание 4.12.

#include <stdio.h> #include "mpi.h"

#define maxn 12 /* В этом примере сетка 12 x 12, 4 процесса */ int main( argc, argv )

297

int argc; char **argv;

{int rank, value, size, errcnt, toterr, i, j; MPI_Status status;

double x[12][12], xlocal[(12/4)+2][12];

MPI_Init( &argc, &argv );

MPI_Comm_rank( MPI_COMM_WORLD, &rank ); MPI_Comm_size( MPI_COMM_WORLD, &size ); if (size != 4) MPI_Abort( MPI_COMM_WORLD, 1 );

/* xlocal[][0] – нижние теневые точки, xlocal[][maxn+2] - верхние */ for (i=1; i<=maxn/size; i++)

for (j=0; j<maxn; j++) xlocal[i][j] = rank; for (j=0; j<maxn; j++)

{ xlocal[0][j] = -1; xlocal[maxn/size+1][j] = -1; }

/* передаем - вверх, получаем - снизу используем xlocal[i] вместо xlocal[i][0] */ if (rank < size - 1)

MPI_Send( xlocal[maxn/size], maxn, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD );

if (rank > 0)

MPI_Recv( xlocal[0], maxn, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &status );

/* передаем вниз, получаем сверху*/

if (rank > 0)

MPI_Send( xlocal[1], maxn, MPI_DOUBLE, rank - 1, 1, MPI_COMM_WORLD ); if (rank < size - 1)

MPI_Recv( xlocal[maxn/size+1], maxn, MPI_DOUBLE, rank + 1, 1, MPI_COMM_WORLD, &status );

/* Проверяем на корректность результаты */

errcnt = 0;

for (i=1; i<=maxn/size; i++)

for (j=0; j<maxn; j++) if (xlocal[i][j] != rank) errcnt++; for (j=0; j<maxn; j++)

{if (xlocal[0][j] != rank - 1) errcnt++;

if (rank < size-1 && xlocal[maxn/size+1][j] != rank + 1) errcnt++;

}

MPI_Reduce( &errcnt, &toterr, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD ); if (rank == 0)

{ if (toterr) printf( "! found %d errors\n", toterr ); else printf( "No errors\n" );

}

MPI_Finalize( ); return 0;

}

298

Задание 4.14.

#include <stdio.h> #include "mpi.h"

#define maxn 12 /* В этом примере сетка 12 x 12, 4 процесса */ int main( argc, argv )

int argc; char **argv;

{int rank, value, size, errcnt, toterr, i, j, up_nbr, down_nbr; MPI_Status status;

double x[12][12],xlocal[(12/4)+2][12];

MPI_Init( &argc, &argv );

MPI_Comm_rank( MPI_COMM_WORLD, &rank );

MPI_Comm_size( MPI_COMM_WORLD, &size ); if (size != 4) MPI_Abort( MPI_COMM_WORLD, 1 );

/* xlocal[][0] – нижние теневые точки, xlocal[][maxn+2] - верхние */ for (i=1; i<=maxn/size; i++)

for (j=0; j<maxn; j++) xlocal[i][j] = rank; for (j=0; j<maxn; j++)

{xlocal[0][j] = -1; xlocal[maxn/size+1][j] = -1;

}

/* Передаем и получаем от нижних процессов.

Используем xlocal[i] вместо xlocal[i][0] */

up_nbr = rank + 1;

if (up_nbr >= size) up_nbr = MPI_PROC_NULL; down_nbr = rank - 1;

if (down_nbr < 0) down_nbr = MPI_PROC_NULL;

MPI_Sendrecv( xlocal[maxn/size], maxn, MPI_DOUBLE, up_nbr, 0,

xlocal[0], maxn, MPI_DOUBLE, down_nbr, 0, MPI_COMM_WORLD, &status ); /* Передаем и получаем от верхних процессов. */

MPI_Sendrecv( xlocal[1], maxn, MPI_DOUBLE, down_nbr, 1, xlocal[maxn/size+1], maxn, MPI_DOUBLE, up_nbr, 1, MPI_COMM_WORLD, &status );

/* Проверяем на корректность результаты */

errcnt = 0;

for (i=1; i<=maxn/size; i++)

for (j=0; j<maxn; j++) if (xlocal[i][j] != rank) errcnt++; for (j=0; j<maxn; j++)

{if (xlocal[0][j] != rank - 1) errcnt++;

if (rank < size-1 && xlocal[maxn/size+1][j] != rank + 1) errcnt++;

}

MPI_Reduce( &errcnt, &toterr, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD );

if (rank == 0)

{

if (toterr)

printf( "! found %d errors\n", toterr );

 

299

else printf( "No errors\n" );

}

MPI_Finalize( ); return 0;

}

Задание 4.16.

#include <stdio.h>

 

#include <math.h>

 

#include "mpi.h"

 

#define maxn 12

/* В этом примере сетка 12 x 12, 4 процесса */

int main( argc, argv )

 

int argc;

 

 

char **argv;

 

{ int

rank, value, size, errcnt, toterr, i, j, itcnt, i_first, i_last;

MPI_Status status;

 

double

diffnorm, gdiffnorm, xlocal[(12/4)+2][12], xnew[(12/3)+2][12];

MPI_Init( &argc, &argv );

MPI_Comm_rank( MPI_COMM_WORLD, &rank ); MPI_Comm_size( MPI_COMM_WORLD, &size ); if (size != 4) MPI_Abort( MPI_COMM_WORLD, 1 );

/* xlocal[][0] – нижние теневые точки, xlocal[][maxn+2] - верхние */

/* В первом и последних процессах на одну строку меньше внутренних точек */

i_first = 1; i_last

= maxn/size;

if (rank == 0)

i_first++;

if (rank == size - 1) i_last--;

for (i=1; i<=maxn/size; i++)

 

for (j=0; j<maxn; j++) xlocal[i][j] = rank;

for (j=0; j<maxn; j++)

{

xlocal[i_first-1][j] = -1;

}

xlocal[i_last+1][j] = -1;

 

 

itcnt = 0;

 

do

 

{

/* передаем вверх, получаем снизу, xlocal[i] вместо xlocal[i][0] */

 

if (rank < size - 1)

 

MPI_Send( xlocal[maxn/size], maxn, MPI_DOUBLE, rank + 1, 0,

 

MPI_COMM_WORLD );

 

if (rank > 0)

 

MPI_Recv( xlocal[0], maxn, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &status );

/* передаем вниз, получаем сверху*/

if (rank > 0)

MPI_Send( xlocal[1], maxn, MPI_DOUBLE, rank - 1, 1, MPI_COMM_WORLD ); if (rank < size - 1)

300

Соседние файлы в предмете Программирование