process - Matrices multiply, Cannon algorithm implementation using MPI -
first of all, of course saw similar questions , solutions, implementation little bit different. main problem that, code works 1 process, doesn't work more processes. don't know cause of this... in communication between processes can't figure out ;/
#include <mpi.h> #include <stdio.h> #include <math.h> #include <iostream> using namespace std; int main(int argc, char **argv) { int x = 0; double kk; int proces; int numprocs; int right_neigh, left_neigh, up_neigh, down_neigh; int tag = 99; static const int n = 6; //size of matrices int psa[n][n]; //nxn int psb[n][n]; int pra[n][n]; int prb[n][n]; int c[n][n]; (int = 0; < n; i++) { //let's make fist matrix (int j = 0; j < n; j++) { psa[i][j] = (int)rand() % 100 + 1; psb[i][j] = (int)rand() % 100 + 1; c[i][j] = 0; } } (int = 0; < n; i++) { //an 2nd 1 (int j = 0; j < n; j++) { pra[i][j] = psa[i][j]; prb[i][j] = psb[i][j]; } } mpi_status statrecv[2]; mpi_request reqsend[2], reqrecv[2]; mpi_init(&argc, &argv); mpi_comm_rank(mpi_comm_world, &proces); mpi_comm_size(mpi_comm_world, &numprocs); int pp = numprocs; double np = numprocs; kk = sqrt(np); int k = (int)kk; if (proces < k) // below neighbour set { left_neigh = (proces + k - 1) % k; right_neigh = (proces + k + 1) % k; up_neigh = ((k - 1)*k) + proces; } if (proces == k) { left_neigh = ((proces + k - 1) % k) + k; right_neigh = ((proces + k + 1) % k) + k; up_neigh = proces - k; } if (proces > k) { x = proces / k; left_neigh = ((proces + k - 1) % k) + x * k; right_neigh = ((proces + k + 1) % k) + x * k; up_neigh = proces - k; } if (proces == 0 || (proces / k) < (k - 1)) { down_neigh = proces + k; } if ((proces / k) == (k - 1)) { down_neigh = proces - ((k - 1)*k); } x = 0; for(int kk = 0; kk < pp; kk++) //algorithm { (int = 0; < n / pp; i++) { (int j = 0; j < n / pp; j++) { (int k = 0; k < n / pp; k++) { c[i][j] += psa[i][k] * psb[k][j]; } } } mpi_irecv(pra, n*n / pp / pp,mpi_float,left_neigh, tag,mpi_comm_world, reqrecv); mpi_irecv(prb, n*n / pp / pp,mpi_float,down_neigh,tag,mpi_comm_world,&reqrecv[1]); mpi_isend(psa, n*n / pp / pp,mpi_float,right_neigh,tag,mpi_comm_world, reqsend); mpi_isend(psb, n*n / pp / pp,mpi_float,up_neigh,tag,mpi_comm_world,&reqsend[1]); mpi_wait(reqrecv, statrecv); } cout << "a" << endl; //show result (int = 0; < n; i++) { (int j = 0; j < n; j++) { cout << pra[i][j] << " "; } cout << endl; } cout << "b" << endl; (int = 0; < n; i++) { (int j = 0; j < n; j++) { cout << prb[i][j] << " "; } cout << endl; } cout << "c" << endl; (int = 0; < n; i++) { (int j = 0; j < n; j++) { cout << c[i][j] << " "; } cout << endl; } mpi_finalize(); return 0; }
ok made it. cool, friend helped me out. admin please not remove it, can helpful someone.
#include <mpi.h> #include <stdio.h> #include <math.h> #include <iostream> using namespace std; int main(int argc, char **argv) { int x = 0; double kk; int proces; int numprocs; int prawy_sasiad, lewy_sasiad, gorny_sasiad, dolny_sasiad; int tag = 99; static const int n = 4; //rozmiar tablic const int pp = 2; // pierwiastek z liczby procesow int a[n][n] = {}, b[n][n] = {}; (int = 0; < n; i++) {//inicjalizacja macierzy glownych (int j = 0; j < n; j++) { a[i][j] = (int)rand() % 100 + 1; b[i][j] = (int)rand() % 100 + 1; } } /* int val = 1; (int = 0; < n; i++) { //inicjalizacja macierzy glownych (int j = 0; j < n; j++) { a[i][j] = val; b[i][j] = val; val++; } } */ mpi_status statrecv2; mpi_request reqsend2, reqrecv2; mpi_status statrecv[2]; mpi_request reqsend[2], reqrecv[2]; mpi_init(0, 0); mpi_comm_rank(mpi_comm_world, &proces); mpi_comm_size(mpi_comm_world, &numprocs); int pra[n / pp][n / pp] = {}, psa[n / pp][n / pp] = {};// podmacierze int prb[n / pp][n / pp] = {}, psb[n / pp][n / pp] = {}; //int c[n / pp][n / pp] = {};//wynikowa int c[n][n] = {};//wynikowa //cout << proces << endl; (int = 0; < n / pp; i++)//podzielenie macierzy glownej na podmacierze, kazdy proces otrzymuje inna podmacierz { (int j = 0; j < n / pp; j++) { psa[i][j] = a[proces / pp*(n / pp) + i][proces%pp*(n / pp) + j]; psb[i][j] = b[proces / pp*(n / pp) + i][proces%pp*(n / pp) + j]; //cout << a[proces / pp*(n / pp) + i][proces%pp*(n / pp) + j] << " "; } //cout << endl; } double np = numprocs; kk = sqrt(np); int k = (int)kk; if (proces < k) // ustawienie sasiadow { lewy_sasiad = (proces + k - 1) % k; prawy_sasiad = (proces + k + 1) % k; gorny_sasiad = ((k - 1)*k) + proces; } if (proces == k) { lewy_sasiad = ((proces + k - 1) % k) + k; prawy_sasiad = ((proces + k + 1) % k) + k; gorny_sasiad = proces - k; } if (proces > k) { x = proces / k; lewy_sasiad = ((proces + k - 1) % k) + x * k; prawy_sasiad = ((proces + k + 1) % k) + x * k; gorny_sasiad = proces - k; } if (proces == 0 || (proces / k) < (k - 1)) { dolny_sasiad = proces + k; } if ((proces / k) == (k - 1)) { dolny_sasiad = proces - ((k - 1)*k); } x = 0; int p = 0; do{ //przesuniecia if (p < proces / pp)// w wierszu { mpi_irecv(pra, n*n / pp / pp, mpi_float, prawy_sasiad, tag, mpi_comm_world, &reqrecv2); mpi_isend(psa, n*n / pp / pp, mpi_float, lewy_sasiad, tag, mpi_comm_world, &reqsend2); mpi_wait(&reqrecv2, &statrecv2); (int = 0; < n / pp; i++) { (int j = 0; j < n / pp; j++) { psa[i][j] = pra[i][j]; } } } mpi_barrier(mpi_comm_world); if (p < proces % pp)// w kolumnie { mpi_irecv(prb, n*n / pp / pp, mpi_float, dolny_sasiad, tag, mpi_comm_world, &reqrecv2); mpi_isend(psb, n*n / pp / pp, mpi_float, gorny_sasiad, tag, mpi_comm_world, &reqsend2); mpi_wait(&reqrecv2, &statrecv2); (int = 0; < n / pp; i++) { (int j = 0; j < n / pp; j++) { psb[i][j] = prb[i][j]; } } } mpi_barrier(mpi_comm_world); p++; } while (p < n); //mpi_barrier(mpi_comm_world); (int kkk = 0; kkk < pp; kkk++) //algorytm { (int = 0; < n / pp; i++) { (int j = 0; j < n / pp; j++) { (int k = 0; k < n / pp; k++) { c[i][j] += psa[i][k] * psb[k][j]; } } } mpi_irecv(pra, n*n / pp / pp, mpi_float, prawy_sasiad, tag, mpi_comm_world, reqrecv); mpi_irecv(prb, n*n / pp / pp, mpi_float, dolny_sasiad, tag, mpi_comm_world, &reqrecv[1]); mpi_isend(psa, n*n / pp / pp, mpi_float, lewy_sasiad, tag, mpi_comm_world, reqsend); mpi_isend(psb, n*n / pp / pp, mpi_float, gorny_sasiad, tag, mpi_comm_world, &reqsend[1]); mpi_wait(reqrecv, statrecv); mpi_barrier(mpi_comm_world); (int = 0; < n / pp; i++) { (int j = 0; j < n / pp; j++) { psa[i][j] = pra[i][j]; } } (int = 0; < n / pp; i++) { (int j = 0; j < n / pp; j++) { psb[i][j] = prb[i][j]; } } } cout << "proces: " << proces << " "; (int = 0; < n / pp; i++) { (int j = 0; j < n / pp; j++) { cout << c[i][j] << " "; } } mpi_finalize(); return 0; }
Comments
Post a Comment