- •О деська державна академія холоду
- •Введення
- •1.Теоретична частина. Варіант 3. Описати стандарти OpenMp I mpi, як основні засоби програмування для многопроцесорних систем.
- •1.1.1 Директиви OpenMp
- •If (скалярний логічне вираз)
- •2. Практична частина
- •2.1. Завдання а. Варіант 7. Розробити програму паралельного розрахунку означеного інтеграла для функції з кроком дискретизації 0,00002.
- •2.1.1. Метод рішення
- •2.1.2. Алгоритм і блок-схема роботи програми
- •2.1.3. Текст програми:
- •2.1.4. Таблиця і графік проведених експериментів.
- •2.1.5. Висновок
- •2.2. Завдання б. Варіант 3. Розробка паралельної програми множення квадратної матриці на квадратну матрицю.
- •2.2.1. Постановка завдання
- •2.2.2. Послідовний алгоритм множення двох квадратних матриць
- •2.2.3. Текст програми
- •2.2.4. Результати обчислювальних експериментів
- •2.2.5. Висновки
- •Перелік посилань
2.2.3. Текст програми
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include "mpi.h"
// Функція випадкового ініціалізації елементів матриці
void RandomDataInitialization (double* pAMatrix, double* pBMatrix,int Size) {
int i, j; // Loop variables
srand(unsigned(clock()));
for (i=0; i<Size; i++)
for (j=0; j<Size; j++) {
pAMatrix[i*Size+j] = rand()/double(1000);
pBMatrix[i*Size+j] = rand()/double(1000);
}
}
// Функція для виділення пам'яті і ініціалізації елементів матриці
void ProcessInitialization (double* &pAMatrix, double* &pBMatrix,
double* &pCMatrix, double* &pCMatrixSum, int &Size) {
// Установка розміру матриці
do {
printf("\nEnter size of matricies: ");
fflush(stdout);
scanf_s("%d", &Size);
printf("\nChosen matricies' size = %d\n", Size);
if (Size <= 0)
printf("\nSize of objects must be greater than 0!\n");
}
while (Size <= 0);
// Виділення пам'яті
pAMatrix = new double [Size*Size];
pBMatrix = new double [Size*Size];
pCMatrix = new double [Size*Size];
pCMatrixSum = new double [Size*Size];
// Ініціалізація елементів матриці
RandomDataInitialization(pAMatrix, pBMatrix, Size);
for (int i=0; i<Size*Size; i++) {
pCMatrix[i] = 0;
pCMatrixSum[i] = 0;
}
}
// Функція форматованого виведення матриці
void PrintMatrix (double* pMatrix, int RowCount, int ColCount) {
int i, j; // Loop variables
for (i=0; i<RowCount; i++) {
for (j=0; j<ColCount; j++)
printf("%7.4f ", pMatrix[i*RowCount+j]);
printf("\n");
}
}
// Функція для множення матриць
void SerialResultCalculation(double* pAMatrix, double* pBMatrix,
double* pCMatrix, int Size, int nCommRank, int nCommSize) {
int i, j, k; // Loop variables
for ( i=0; i<Size; i++ ) {
for (j=0+nCommRank; j<Size; j+=nCommSize) {
for (k=0; k<Size; k++) {
pCMatrix[i*Size+j] +=
pAMatrix[i*Size+k]*pBMatrix[k*Size+j];
}
}
}
}
// Функція для обчислювальних завершення процесу
void ProcessTermination (double* pAMatrix, double* pBMatrix,
double* pCMatrix, double* pCMatrixSum) {
delete [] pAMatrix;
delete [] pBMatrix;
delete [] pCMatrix;
delete [] pCMatrixSum;
}
int main(int argc, char* argv[]) {
double* pAMatrix; // Перший аргумент матричного множення
double* pBMatrix; // Другий аргумент матричного множення
double* pCMatrix; // Результат матриці
double* pCMatrixSum; // Результат матриці
int Size;// Розмір матриці
int nCommRank, nCommSize, namelen, nCounter;
int nIntervals;
char processor_name[MPI_MAX_PROCESSOR_NAME];
double t1, t2;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank( MPI_COMM_WORLD, &nCommRank );
MPI_Comm_size( MPI_COMM_WORLD, &nCommSize );
MPI_Get_processor_name(processor_name,&namelen);
if (nCommRank == 0) {
printf("Parallel matrix multiplication program\n");
// Розподіл пам'яті і ініціалізацію елементів матриці
ProcessInitialization(pAMatrix, pBMatrix, pCMatrix, pCMatrixSum, Size);
// Вихідна матриця
printf ("Initial A Matrix \n");
PrintMatrix(pAMatrix, Size, Size);
printf("Initial B Matrix \n");
PrintMatrix(pBMatrix, Size, Size);
t1 = MPI_Wtime();
for (nCounter = 1; nCounter < nCommSize; nCounter++) {
MPI_Send (&Size, 1, MPI_INT, nCounter, 0, MPI_COMM_WORLD);
MPI_Send (pAMatrix, Size*Size, MPI_DOUBLE, nCounter, 1,
MPI_COMM_WORLD);
MPI_Send (pBMatrix, Size*Size, MPI_DOUBLE, nCounter, 2,
MPI_COMM_WORLD);
MPI_Send (pCMatrix, Size*Size, MPI_DOUBLE, nCounter, 3,
MPI_COMM_WORLD);
}
} else {
MPI_Recv (&Size, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
pAMatrix = new double [Size*Size];
pBMatrix = new double [Size*Size];
pCMatrix = new double [Size*Size];
MPI_Recv (pAMatrix, Size*Size, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
MPI_Recv (pBMatrix, Size*Size, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
MPI_Recv (pCMatrix, Size*Size, MPI_DOUBLE, 0, 3, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
}
// множення матриць
SerialResultCalculation(pAMatrix, pBMatrix, pCMatrix, Size, nCommRank, nCommSize);
MPI_Reduce(pCMatrix,pCMatrixSum,Size*Size,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_W
ORLD);
printf ("Process %d of %d running on %s\n", nCommRank, nCommSize,
processor_name);
if (nCommRank == 0) {
// Виведення результатів матриці
printf ("\n Result Matrix Sum: \n");
PrintMatrix(pCMatrixSum, Size, Size);
// Завершення обчислювального процесу
ProcessTermination(pAMatrix, pBMatrix, pCMatrix, pCMatrixSum);
t2 = MPI_Wtime();
printf("Time is %f seconds \n", t2-t1);
}
MPI_Finalize( );
}