You are on page 1of 13

Національний технічний університет України

«Київський політехнічний інститут імені Ігоря Сікорського»

Факультет інформатики та обчислювальної техніки


Кафедра обчислювальної техніки

Паралельне програмування
Лабораторна робота №6
«Бібліотека МРІ»

Виконав:
студент групи ІО-11
Володін В. В.

Залікова книжка № 1105

Перевірив:
Корочкін О.В

Київ – 2023
Тема: «Бібліотека МРІ».
Мета роботи: розробка програми для ПКС СП.
Мова програмування: C++.
Засоби організації взаємодії процесів: посилання повідомлень
(Send/Receive, колективні операції Bcast, Scatter та граф зв’язку).

Варіант:

Вихідна функція
Z=X*(MA*MS) + min(X)*F
Етап1. Побудова паралельного алгоритму:
N – розмір векторів та матриць
P – кількість потоків
H = N/P
1. ci = min(XH)
2. c = max(c, ci) --CP - a
3. ZH = XH*(MAH*MSH) + c*FH --CP - a

Етап2. Розроблення алгоритмів роботи кожного потоку


Задача T1

1. Введення MA

2. Передати MA задачі Т2

3. Прийняти X, MSH, FH від задачі Т2

4. Обчислення с1 = min(XH)

5. Передати c1 задачі Т2

6. Прийняти c від задачі Т2

7. Обчислення ZH1 = X1*(MA1*MSH) + c*FH

8. Передати ZH1 задачі Т2

Задача T2
1. Введення X

2. Прийняти MA від задачі Т1

3. Прийняти MS від задачі Т3

4. Прийняти F від задачі Т4

5. Передати X, MA, MSH, XH, FH задачам Т1, Т3, Т4

6. Обчислення с2 = min(XH)

7. Прийняти c1, c3, c4 від задачі Т1, T3, T4


8. Обчислення с = min(c1, c2, c3, c4)

9. Передати c задачам T1,T3,T4

10.Обчислення ZH2 = X2*(MA2*MSH) + c*FH

11.Прийняти Zhi від задач Т1, Т3, Т4

12.Вивід Z

Задача T3

1. Введення MS

2. Передати MS задачі Т2

3. Прийняти X, MA, FH від задачі Т2

4. Обчислення с3 = min(XH)

5. Передати c3задачі Т2

6. Прийняти c від задачі Т2

7. Обчислення ZH3 = X3*(MA3*MSH) + c*FH

8. Передати задачі Т2 ZH3

Задача T4
1. Введення F

2. Передати F задачі Т2

3. Прийняти X, MA, MSH від задачі Т2

4. Обчислення с4 = min(XH)

5. Передати c4задачі Т2

6. Прийняти c від задачі Т2


7. Обчислення ZH4 = X4*(MA4*MSH) + c*FH

8. Передати ZH4 задачі Т2

Етап3. Розробка структурної схеми взаємодії задач

1. Етап4. Розробка програми


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

const int P = 4;
const int N = 4;
const int H = N / P;

void Calculation3(int Xi[], int MAi[][N], int MSh[][H], int c, int Fh[], int result[]);
void matrixMultiply(int matrix[][N], int submatrix[][H], int submatrix_result[][H]);
void vectorOnMatrixMultiply(int vector[], int submatrix[][H], int subvector_result[]);
void vectorMultiplyNumber(int vector[], int number, int size);
void vectorSum(int vector1[], int vector2[], int size);
void fillMatrix(int matrix[][N], int number);
void fillVector(int vector[], int number);
void printVector(int vector[], int size);
int vectorMin(int vector[], int size);
int min(int a, int b);

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


{

int number = 1;
int numtasks, rank;

int X[N];
int MA[N][N];
int MSh[N][H];
int Xh[H];
int Fh[H];

int ci = 0;
int ci_arr[P];
int c;

int Z[N];
int Zh[H];

int* buf_F = NULL;


int buf_MS[N][N];

MPI_Init(argc, &argv);

MPI_Status status;

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

printf("T%d started\n", rank);

if (rank == 0)
{
int MA[N][N];
fillMatrix(MA, number);
MPI_Send(MA, N * N, MPI_INT, 1, 21, MPI_COMM_WORLD);
}
if (rank == 1)
{
fillVector(X, number);
MPI_Recv(MA, N * N, MPI_INT, 0, 21, MPI_COMM_WORLD, &status);
MPI_Recv(buf_MS, N * N, MPI_INT, 2, 23, MPI_COMM_WORLD, &status);
int F[N];
MPI_Recv(F, N, MPI_INT, 3, 24, MPI_COMM_WORLD, &status);
buf_F = F;
}
if (rank == 2)
{
int MS[N][N];
fillMatrix(MS, number);
MPI_Send(&MS, N * N, MPI_INT, 1, 23, MPI_COMM_WORLD);
}
if (rank == 3)
{
int F[N];
fillVector(F, number);
MPI_Send(F, N, MPI_INT, 1, 24, MPI_COMM_WORLD);
}
MPI_Bcast(X, N, MPI_INT, 1, MPI_COMM_WORLD);
MPI_Bcast(MA, N * N, MPI_INT, 1, MPI_COMM_WORLD);
MPI_Scatter(buf_MS, N * H, MPI_INT, MSh, N * H, MPI_INT, 1,
MPI_COMM_WORLD);
MPI_Scatter(X, H, MPI_INT, Xh, H, MPI_INT, 1, MPI_COMM_WORLD);
MPI_Scatter(buf_F, H, MPI_INT, Fh, H, MPI_INT, 1, MPI_COMM_WORLD);
ci = vectorMin(Xh, H);
MPI_Gather(&ci, 1, MPI_INT, ci_arr, 1, MPI_INT, 1, MPI_COMM_WORLD);
if (rank == 1)
c = vectorMin(ci_arr, P);
MPI_Bcast(&c, 1, MPI_INT, 1, MPI_COMM_WORLD);
Calculation3(X, MA, MSh, c, Fh, Zh);
MPI_Gather(Zh, H, MPI_INT, Z, H, MPI_INT, 1, MPI_COMM_WORLD);
if (rank == 1)
printVector(Z, N);

printf("T%d ended\n", rank);

MPI_Finalize();

return 0;
}

void Calculation3(int Xi[], int MAi[][N], int MSh[][H], int c, int Fh[], int result[])
{
int temp_MRh[N][H];
matrixMultiply(MAi, MSh, temp_MRh);
vectorOnMatrixMultiply(Xi, temp_MRh, result);
vectorMultiplyNumber(Fh, c, H);
vectorSum(result, Fh, H);
}

void matrixMultiply(int matrix[][N], int submatrix[][H], int submatrix_result[][H])


{
int temp = 0;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < H; j++)
{
temp = 0;
for (int k = 0; k < N; k++)
{
temp += matrix[i][k] * submatrix[k][j];
}
submatrix_result[i][j] = temp;
}
}
}

void vectorOnMatrixMultiply(int vector[], int submatrix[][H], int subvector_result[])


{
for (int i = 0; i < H; i++)
subvector_result[i] = 0;
for (int i = 0; i < H; i++)
for (int j = 0; j < N; j++)
subvector_result[i] += vector[j] * submatrix[j][i];
}
void vectorMultiplyNumber(int vector[], int number, int size)
{
for (int i = 0; i < size; i++)
vector[i] = vector[i] * number;
}

int min(int a, int b)


{
if (a < b)
return a;
else
return b;
}

void vectorSum(int vector1[], int vector2[], int size)


{
for (int i = 0; i < size; i++)
vector1[i] = vector1[i] + vector2[i];
}

int vectorMin(int vector[], int size)


{
int min = vector[0];
for (int i = 1; i < size; i++)
if (vector[i] < min)
min = vector[i];
return min;
}

void printVector(int vector[], int size)


{
for (int i = 0; i < size; i++)
printf("%d ", vector[i]);
printf("\n");
}
void fillMatrix(int matrix[][N], int number)
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
matrix[i][j] = number;
}

void fillVector(int vector[], int number)


{
for (int i = 0; i < N; i++)
vector[i] = number;
}

Результат виконання програми

Перевірка виконнаня програми:


Результати сходяться з калькулятором

Висновок
У результаті виконання лабораторної роботи створена програма на мові
С++ яка виконує паралельні обчислення. Програма реалізована за
допомогою бібліотеки MPI (Message Passing Interface).

Програма розпочинається ініціалізацією MPI, отриманням рангу процесу


та загальної кількості процесів. Потім відбувається розподілення даних
між процесами: процес з рангом 0 заповнює та надсилає матрицю MA
процесу з рангом 1.
Дані надсилаються та отримуються між процесами через MPI_Send та
MPI_Recv. MPI_Scatter використовується для розподілу даних між
процесами, а MPI_Gather – для їх об'єднання.

Кожен процес обчислює свою частину результату в функції Calculation3,


яка використовує операції, такі як множення матриць та векторів.
Процеси взаємодіють та синхронізуються за допомогою функцій MPI,
таких як MPI_Bcast.
Результати обчислені за допомогою калькулятора співпадають з
результатом виводу в консоль

You might also like