2015-08-31 73 views
0

首先,當然我看到了類似的問題和解決方案,但我的實現有點不同。 主要問題是,我的代碼只適用於一個進程,但它不適用於更多的進程。 我不知道這個是什麼原因...大概在進程間的通信,但我無法弄清楚;/矩陣乘法,使用MPI的Cannon算法實現

#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]; 

    for (int i = 0; i < n; i++) { //let's make fist matrix 
     for (int j = 0; j < n; j++) { 
      psa[i][j] = (int)rand() % 100 + 1; 
      psb[i][j] = (int)rand() % 100 + 1; 
      c[i][j] = 0; 
     } 
    } 

    for (int i = 0; i < n; i++) { //an the 2nd one 
     for (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 
    { 
     for (int i = 0; i < n/PP; i++) 
     { 
      for (int j = 0; j < n/PP; j++) 
      { 
       for (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 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      cout << pra[i][j] << " "; 
     } 
     cout << endl; 
    } 
    cout << "B" << endl; 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      cout << prb[i][j] << " "; 
     } 
     cout << endl; 
    } 
    cout << "C" << endl; 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      cout << c[i][j] << " "; 
     } 
     cout << endl; 
    } 


    MPI_Finalize(); 

    return 0; 
} 

回答

0

好,我做到了。現在一切都很好,我的朋友幫助我。但管理員請不要刪除它,它可能對某人有幫助。

#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] = {}; 
for (int i = 0; i < n; i++) {//inicjalizacja macierzy glownych 
for (int j = 0; j < n; j++) { 
A[i][j] = (int)rand() % 100 + 1; 
B[i][j] = (int)rand() % 100 + 1; 
} 
} 

/* 
int val = 1; 
for (int i = 0; i < n; i++) { //inicjalizacja macierzy glownych 
    for (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; 
for (int i = 0; i < n/PP; i++)//podzielenie macierzy glownej na podmacierze, kazdy proces otrzymuje inna podmacierz 
{ 
    for (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); 
     for (int i = 0; i < n/PP; i++) 
     { 
      for (int j = 0; j < n/PP; j++) 
      { 
       psa[i][j] = pra[i][j]; 
      } 
     } 
} 
    MPI_Barrier(MPI_COMM_WORLD); 
if (p < proces % PP)// i 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); 
    for (int i = 0; i < n/PP; i++) 
    { 
     for (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); 


for (int kkk = 0; kkk < PP; kkk++) //algorytm 
{ 
    for (int i = 0; i < n/PP; i++) 
    { 
     for (int j = 0; j < n/PP; j++) 
     { 
      for (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); 

    for (int i = 0; i < n/PP; i++) 
    { 
     for (int j = 0; j < n/PP; j++) 
     { 
      psa[i][j] = pra[i][j]; 
     } 
    } 


    for (int i = 0; i < n/PP; i++) 
    { 
     for (int j = 0; j < n/PP; j++) 
     { 
      psb[i][j] = prb[i][j]; 
     } 
    } 


} 


cout << "Proces: " << proces << " "; 
for (int i = 0; i < n/PP; i++) 
{ 
    for (int j = 0; j < n/PP; j++) 
    { 
     cout << C[i][j] << " "; 
    } 
} 

MPI_Finalize(); 

return 0; 
} 
+1

如果你不想讓它消失,你需要給出更多的解釋(通過編輯問題)和解決方案(通過編輯答案)。 –