Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // newDynMatrix.cpp : Defines the entry point for the console application.
- //
- #include <iostream>
- #include <cstdlib>
- #include <iomanip>
- #include <mpi.h>
- #define MASTER 0
- #define FROM_MASTER 1
- #define FROM_WORKER 2
- using namespace std;
- int main(int argc, char **argv)
- {
- int NRA=4, NCA=3, NCB=2; //przyk�adowe wymiary macierzy
- int rank, size;
- //Zadeklaruj następujące zmienne:
- //Zmienną, która przyjmie numer zadania nadawcy wiadomości (source),
- int source = -1;
- //Zmienną, która przyjmie numer zadania odbiorcy komunikatu (destination),
- int destination = -1;
- //Rodzaj wiadomości (message type)
- // ??????
- //Zmienną, która określa ilość wierszy macierzy A wysłanych do każdego procesu/pracownika(rows),
- int rowsSent = -1;
- //Zmienną offset, służącą do wyznaczania które wiersze otrzyma dany proces,
- int offset = -1;
- //Dwie zmienne pomocnicze, które mogą służyć do uszczegółowienia liczby wierszy wysłanych do każdego pracownika,
- int rowsPerProcess = -1;
- int remainderToDistribute = 0;
- MPI_Status status;
- //Zainicjalizuj bibliotekę MPI,
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(MPI_COMM_WORLD, &rank);
- MPI_Comm_size(MPI_COMM_WORLD, &size);
- double startTime;
- //Rozpocznij pomiar czasu funkcją MPI_Wtime()
- if (rank == MASTER) {
- startTime = MPI_Wtime();
- }
- /*Zadeklaruj macierz A, B i C (macierz wynikowa) jako tablice dynamiczne,
- zajmij ciągłe miejsce w pamięci na wszystkie macierze,
- (Patrz: Pomoc, na końcu instrukcji)
- */
- double **b = new double *[NCA];
- b[0] = new double[NCA*NCB];
- for (int i = 1; i < NCA; i++)
- {
- b[i] = &b[0][i*NCB];
- }
- double **a = new double *[NRA];
- a = new double *[NRA]; //zadeklarowanie tablicy dynamicznej ci�g�ej contingous, aby mo�na j� by�o przes�a� w MPI bez problemu
- a[0] = new double[NRA*NCA];
- for (int i = 1; i < NRA; i++)
- {
- a[i] = &a[0][i*NCA];
- }
- if (rank == MASTER) {
- //Wypisz komunikat mówiący o ilości procesów z jakim wystartował program,
- cout << "Master przystępuje do zarządzania z łączną liczbą procesów " << size << endl;
- //Wypełnij macierze A i B,
- cout << "Master zgłasza wypełnianie tablicy A:" << endl;
- for (int i = 0; i < NRA; i++)
- {
- for (int j = 0; j < NCA; j++) //wpisanie wartosci do tablicy
- {
- a[i][j] = 1+i + j;
- cout << setw(5) << a[i][j] << " ";
- }
- cout<<endl;
- }
- cout << "Master zgłasza wypełnianie tablicy B" << endl;
- for (int i = 0; i < NCA; i++)
- {
- for (int j = 0; j < NCB; j++)
- {
- b[i][j] = 1 + i*j;
- cout << setw(5) << b[i][j] << " ";
- }
- cout<<endl;
- }
- cout << "###################### " << endl;
- double **c = new double*[NRA];//zadeklarowanie macierzy wynikowej
- c[0]=new double[NRA*NCB];
- for (int i = 1; i < NRA; i++)
- {
- c[i] = &c[0][i*NCB];
- }
- //Rozgłoś macierz B do wszystkich procesów stosując funkcję MPI_Bcast
- MPI_Bcast(&(b[0][0]), NCA*NCB, MPI_DOUBLE, 0, MPI_COMM_WORLD);
- //Wyślij odpowiednie dane z macierzy A do procesów/pracowników,
- rowsPerProcess = NRA / (size - 1);
- remainderToDistribute = NRA % (size - 1);
- offset = 0;
- for (int i = 1; i < size; i++) {
- //z którego kawałka macierzy dostanie
- MPI_Send(&offset, 1, MPI_INT, i, FROM_MASTER, MPI_COMM_WORLD);
- //ile wierszy dostanie
- if (remainderToDistribute > 0) {
- rowsSent = rowsPerProcess + 1;
- remainderToDistribute--;
- } else {
- rowsSent = rowsPerProcess;
- }
- MPI_Send(&rowsSent, 1, MPI_INT, i, FROM_MASTER, MPI_COMM_WORLD);
- //zawartość tego kawałka
- MPI_Send(&(a[offset][0]), rowsSent * NCA, MPI_DOUBLE, i, FROM_MASTER, MPI_COMM_WORLD);
- //przesunięcie niżej w macierz
- offset += rowsSent;
- }
- //oczekiwanie na wyniki od procesów
- for (int i = 1; i < size; i++) {
- cout << "Master oczekuje wyników od " << i << endl;
- //offsetu
- MPI_Recv(&offset, 1, MPI_INT, i, FROM_WORKER, MPI_COMM_WORLD, &status);
- cout << "Proces " << rank << " melduje otrzymanie offsetu: " << offset << endl;
- //l. wierszy
- MPI_Recv(&rowsSent, 1, MPI_INT, i, FROM_WORKER, MPI_COMM_WORLD, &status);
- cout << "Proces " << rank << " melduje otrzymanie l. wierszy: " << rowsSent << endl;
- //macierzy
- MPI_Recv(&(c[offset][0]), rowsSent * NCB, MPI_DOUBLE, i, FROM_WORKER, MPI_COMM_WORLD, &status);
- cout << "Proces " << rank << " melduje otrzymanie macierzy cc: " << endl;
- }
- //koniec
- cout << "Zakończono w czasie " << MPI_Wtime() - startTime << endl;
- cout << "Tablica wynikowa: " << endl;
- for (int i = 0; i<NRA; i++)
- {
- for (int j = 0; j<NCB; j++)
- {
- cout << setw(5) << c[i][j] << " ";
- }
- cout<<endl;
- }
- } else {
- double **cc = new double*[NRA];//zadeklarowanie macierzy wynikowej
- cc[0]=new double[NRA*NCB];
- for (int i = 1; i < NRA; i++)
- {
- cc[i] = &cc[0][i*NCB];
- }
- //odbieranie zadania od Mastera
- //<BCAST wysłał macierz b>
- //offsetu
- MPI_Recv(&offset, 1, MPI_INT, 0, FROM_MASTER, MPI_COMM_WORLD, &status);
- cout << "Proces " << rank << " melduje otrzymanie swojego offsetu: " << offset << endl;
- //l. wierszy
- MPI_Recv(&rowsSent, 1, MPI_INT, 0, FROM_MASTER, MPI_COMM_WORLD, &status);
- cout << "Proces " << rank << " melduje otrzymanie liczby wierszy: " << rowsSent << endl;
- //macierzy
- MPI_Recv(&(a[0][0]), rowsSent * NCA, MPI_DOUBLE, 0, FROM_MASTER, MPI_COMM_WORLD, &status);
- cout << "Proces " << rank << " melduje otrzymanie swoich wierszy: " << endl;
- for (int i = 0; i < rowsSent; i++) {
- for (int j = 0; j < NCA; j++) {
- cout << setw(5) << a[i][j] << " ";
- }
- cout << endl;
- }
- cout << "Proces " << rank << " melduje swoją B: " << endl;
- for (int i = 0; i < NCA; i++)
- {
- for (int j = 0; j < NCB; j++)
- {
- b[i][j] = 1 + i*j;
- cout << setw(5) << b[i][j] << " ";
- }
- cout<<endl;
- }
- //obliczanie
- for (int k = 0; k < NCB; k++)// obliczenie iloczynu macierzy
- {
- for (int i = 0; i < rowsSent; i++)
- {
- cc[i][k] = 0.0;
- for (int j = 0; j < NCA; j++)
- {
- cc[i][k] = cc[i][k] + a[i][j] * b[j][k];
- }
- }
- }
- cout << "Proces " << rank << " melduje zakończenie obliczeń i przechodzi do wysyłania wyników " << endl;
- //powrót do MASTERa
- //offsetu
- MPI_Send(&offset, 1, MPI_INT, MASTER, FROM_WORKER, MPI_COMM_WORLD);
- //l. wierszy
- MPI_Send(&rowsSent, 1, MPI_INT, MASTER, FROM_WORKER, MPI_COMM_WORLD);
- //macierzy
- MPI_Send(&(cc[0][0]), rowsSent * NCB, MPI_DOUBLE, MASTER, FROM_WORKER, MPI_COMM_WORLD);
- cout << "Proces " << rank << " melduje wysłanie wyników " << endl;
- }
- //cout << "Macierz wynikowa: " << endl;
- //cout << "##### WYNIK: ################# " << endl;
- /*
- for (int k = 0; k < NCB; k++)// obliczenie iloczynu macierzy
- {
- for (int i = 0; i < NRA; i++)
- {
- c[i][k] = 0.0;
- for (int j = 0; j < NCA; j++)
- {
- c[i][k] = c[i][k] + a[i][j] * b[j][k];
- }
- }
- }
- */
- MPI_Finalize();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement