Лабораторная работа №3. Лабораторная работа №1
Лабораторная работа №1
Знакомство с MPI. Настройка среды программирования. Написать программу для определения общего числа процессоров (MPI_Comm_Size), индивидуального номера процесса (MPI_Comm_Rank), вывода имен узлов кластера (MPI_Get_Processor_Name).
Листинг программы:
#include "C:/Program Files/Microsoft HPC Pack 2008 SDK/include/mpi.h"
#include "stdio.h"
#pragma comment(lib, "C:/Program Files/Microsoft HPC Pack 2008 SDK/lib/i386/msmpi.lib")
int main(int argc, char**argv)
{
MPI_Init(&argc, &argv);
int proccount, rank, proga;
char p[80];
MPI_Comm_size(MPI_COMM_WORLD, &proccount);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Get_processor_name(p, &proga);
printf("%d,%d,Imya processa %d", proccount, rank, proga);
MPI_Finalize();
return 0;
}
Результат выполнения:
Рисунок 1
Лабораторная работа №2
Написать программу, используя блокирующие коммуникационные функции (MPI_Send, MPI_Recv), реализующую алгоритм передачи данных по двум кольцам: нечетные процессора образуют 1 кольцо, четные – второе.
Модифицировать программу, использую функцию MPI_Sendrecv.
Листинг программы:
#include "C:/Program Files/Microsoft HPC Pack 2008 SDK/include/mpi.h"
#include <stdio.h>
#pragma comment (lib,"C:/Program Files/Microsoft HPC Pack 2008 SDK/lib/i386/msmpi.lib")
int main (int argc,char**argv){
MPI_Init(&argc,&argv);
int proccount,rank,me,size,a;
char *procname=new char[100];
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Get_processor_name(procname,&me);
printf("Process %d size %d Yzel %s \n",me,size,procname);
if(rank==0){
int a=148;
MPI_Send(&a,1,MPI_INT,1,0,MPI_COMM_WORLD);
}
else if (rank==1) {
int a;
MPI_Status status;
MPI_Recv(&a,1,MPI_INT,0,0,MPI_COMM_WORLD,&status);
printf("%d",a);
}
MPI_Finalize();
}
Результат выполнения:
Рисунок 2
Лабораторная работа №3
Используя функции MPI_Bcast/MPI_Gather/MPI_Allgather/MPI_Scatter написать параллельную программу, реализующую параллельный алгоритм скалярного умножения векторов.
Листинг программы:
#include "C:/Program Files/Microsoft HPC Pack 2008 SDK/include/mpi.h"
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#pragma comment (lib,"C:/Program Files/Microsoft HPC Pack 2008 SDK/lib/i386/msmpi.lib")
int main (int argc,char**argv){
double *x=NULL, *y=NULL, *local_x, *local_y;
int n_bar;
double dot, local_dot;
int p, my_rank, i, n;
double start, finish, dt1;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if (my_rank == 0)
{
n = 10;
printf("Number of elements in each vector: %d\n", n);
x = (double *) calloc(n, sizeof(double));
y = (double *) calloc(n, sizeof(double));
//генерируем случайые векторы
for (i=0; i<n; i++)
{
x[i] = 1000 * rand() / MPI_Wtime();
y[i] = 1000 * rand() * MPI_Wtime();
}
printf("x[i] = \n");
for (i=0; i<n; i++)
{
printf("%f ", x[i]);
}
printf("\ny[i]\n");
for (i=0; i<n; i++)
{
printf("%f ", y[i]);
}
printf("\n");
}
if (my_rank==0)
{
start = MPI_Wtime();
}
//отправляем на все узлы
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
n_bar = n/p;
local_x = (double *) calloc(n_bar, sizeof(double));
local_y = (double *) calloc(n_bar, sizeof(double));
//собираем результаты
MPI_Scatter(x, n_bar, MPI_DOUBLE, local_x, n_bar, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Scatter(y, n_bar, MPI_DOUBLE, local_y, n_bar, MPI_DOUBLE, 0, MPI_COMM_WORLD);
//вычисляем частичное скалярное произведение
local_dot = 0.0;
for (i = 0; i < n_bar; i++)
local_dot += (local_x[i]) * (local_y[i]);
free(local_x); free(local_y);
//вычисляем сумму
MPI_Reduce(&local_dot, &dot, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (my_rank==0)
{
finish = MPI_Wtime();
}
if (my_rank == 0)
{
printf("Dot product is %12.3f\n", dot);
printf("Total Time = %12.3f secs\n",finish-start);
}
MPI_Finalize();
return 0;
}
Результат выполнения:
Рисунок 3
Поиск по сайту: