Главная страница

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


Скачать 1.61 Mb.
НазваниеОрганизация вычислений в многопроцессорных системах
АнкорПрограммирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В..pdf
Дата15.03.2018
Размер1.61 Mb.
Формат файлаpdf
Имя файлаПрограммирование для многопроцессорных систем в стандарте MPI - .pdf
ТипКонтрольные вопросы
#16702
КатегорияИнформатика. Вычислительная техника
страница24 из 26
1   ...   18   19   20   21   22   23   24   25   26
Задание 3.15.
/* пересылка вектора из 1000 элементов типа MPI_DOUBLE со страйдом 24 между элементами. Самостоятельная упаковка и распаковка (не используем типы данных MPI) */
#include
#include
#include "mpi.h"
#define NUMBER_OF_TESTS 10 int main( argc, argv ) int argc; char **argv;
{ MPI_Datatype vec1, vec_n, old_types[2];
MPI_Aint indices[2]; double *buf, *lbuf, t1, t2, tmin; register double *in_p, *out_p; int i, j, k, nloop, rank, n, stride, blocklens[2];
MPI_Status status;

289
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank ); n = 1000; stride = 24; nloop = 100000/n; buf = (double *) malloc( n * stride * sizeof(double) ); if (!buf)
{ fprintf( stderr, "Could not allocate send/recv buffer of size %d\n",n * stride );
MPI_Abort( MPI_COMM_WORLD, 1 );
} lbuf = (double *) malloc( n * sizeof(double) ); if (!lbuf)
{ fprintf( stderr, "Could not allocated send/recv lbuffer of size %d\n", n );
MPI_Abort( MPI_COMM_WORLD, 1 );
} if (rank == 0) printf( "Kind\tn\tstride\ttime (sec)\tRate (MB/sec)\n" ); tmin = 1000; for (k=0; k { if (rank == 0) { /* убедимся, что оба процесса готовы к приему/передаче */
MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, 1, 14,
MPI_BOTTOM, 0, MPI_INT, 1, 14, MPI_COMM_WORLD, &status ); t1 = MPI_Wtime(); for (j=0; j { for (i=0; iMPI_Send( lbuf, n, MPI_DOUBLE, 1, k, MPI_COMM_WORLD );
MPI_Recv( lbuf, n, MPI_DOUBLE, 1, k, MPI_COMM_WORLD, &status ); for (i=0; i } t2 = (MPI_Wtime() - t1) / nloop; if (t2 < tmin) tmin = t2;
} else if (rank == 1)
{ /* убедимся, что оба процесса готовы к приему/передаче */
MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, 0, 14,
MPI_BOTTOM, 0, MPI_INT, 0, 14, MPI_COMM_WORLD, &status ); for (j=0; j { MPI_Recv( lbuf, n, MPI_DOUBLE, 0, k, MPI_COMM_WORLD, &status ); for (i=0; i MPI_Send( lbuf, n, MPI_DOUBLE, 0, k, MPI_COMM_WORLD );
}
}
} tmin = tmin / 2.0;

290
if (rank == 0) printf( "User\t%d\t%d\t%f\t%f\n",n,stride,tmin, n *sizeof(double)*1.0e-6 / tmin );
MPI_Finalize( ); return 0;
}
Задание 3.18.
#include
#include
#include
#include
#include int main(int argc, char* argv[])
{ int iMyRank, i, gsize;
MPI_Comm _Comm = MPI_COMM_WORLD; /* в группе все процессы */
MPI_Status status; double x[100][100][100], e[9][9][9]; int oneslice, twoslice, threeslice, sizeof_double;
MPI_Init(&argc, &argv);
MPI_Comm_size(_Comm, &gsize);
MPI_Comm_rank(_Comm, &iMyRank);
/* извлекаем секцию а(1-17-2, 3-11, 2-10) и записываем в е */
MPI_Type_extent(MPI_DOUBLE, &sizeof_double);
MPI_Type_vector(9, 1, 2, MPI_DOUBLE, &oneslice);
MPI_Type_hvector(9, 1, 100 * sizeof_double, oneslice, &twoslice);
MPI_Type_hvector(9, 1, 100 * 100 * sizeof_double, twoslice, &threeslice);
MPI_Type_commit(&threeslice);
MPI_Sendrecv(&x[1][3][2], 1, threeslice, iMyRank, 0, e, 9*9*9, MPI_DOUBLE, iMyRank, 0, MPI_COMM_WORLD, &status); if (iMyRank == 0)
{ printf("x = ("); for (i = 0; i < 100; ++i) printf("%f", x[i]); printf(")");
}
MPI_Finalize(); return 0;
}
Задание 3.19.
#include
#include
#include
#include
#include
#define MATRIXSIZE 10 int main(int argc, char* argv[])

291
{ 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
#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 );

292
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
#include
#include
#include 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;
}

293
Задание 4.3.
#include
#include
#include
#include
#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)

294
{ printf("Result is:\n"); for (i = 0; i < n; ++i) printf("%3.0f ", dResult[i]);
}
MPI_Finalize(); return 0;
}
Задание 4.5.
#include
#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
#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 );

295
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
#include
#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 { MPI_Barrier( MPI_COMM_WORLD ); d_in = 1.0; t1 = MPI_Wtime(); for (j=0; j MPI_Allreduce( &d_in, &d_out, 1, MPI_DOUBLE, MPI_SUM,

296
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
#include
#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 { MPI_Barrier( MPI_COMM_WORLD ); t1 = MPI_Wtime(); for (j=0; 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 );

297
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 { 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
#include "mpi.h"
#define maxn 12 /* В этом примере сетка 12 x 12, 4 процесса */ int main( argc, argv )

298
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 { 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 { 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;
}

299
Задание 4.14.
#include
#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 { 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 { 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 );

300
else printf( "No errors\n" );
}
MPI_Finalize( ); return 0;
}
Задание 4.16.
#include
#include
#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 { 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)

301
MPI_Recv( xlocal[maxn/size+1], maxn, MPI_DOUBLE, rank + 1, 1,
MPI_COMM_WORLD, &status );
/* Вычисляем новые значения ( не на границах) */ itcnt ++; diffnorm = 0.0; for (i=i_first; i<=i_last; i++) for (j=1; j { xnew[i][j] = (xlocal[i][j+1] + xlocal[i][j-1] + xlocal[i+1][j] + xlocal[i-1][j]) / 4.0; diffnorm += (xnew[i][j] - xlocal[i][j]) * (xnew[i][j] - xlocal[i][j]);
}
/* присваиваем новые значения внутренним точкам */ for (i=i_first; i<=i_last; i++) for (j=1; j MPI_Allreduce( &diffnorm, &gdiffnorm, 1, MPI_DOUBLE, MPI_SUM,
MPI_COMM_WORLD); gdiffnorm = sqrt( gdiffnorm ); if (rank == 0) printf( "At iteration %d, diff is %e\n", itcnt, gdiffnorm );
} while (gdiffnorm > 1.0e-2 && itcnt < 100);
MPI_Finalize( ); return 0;
}
1   ...   18   19   20   21   22   23   24   25   26


написать администратору сайта