Process 矩阵乘法,Cannon算法的MPI实现

Process 矩阵乘法,Cannon算法的MPI实现,process,mpi,Process,Mpi,首先,我当然看到了类似的问题和解决方案,但我的实现有点不同。 主要问题是,“我的代码”只适用于一个进程,但不适用于更多进程。 我不知道这是什么原因。。。可能是进程之间的通信,但我无法理解/ #include <mpi.h> #include <stdio.h> #include <math.h> #include <iostream> using namespace std; int main(int argc, char **argv) {

首先,我当然看到了类似的问题和解决方案,但我的实现有点不同。 主要问题是,“我的代码”只适用于一个进程,但不适用于更多进程。 我不知道这是什么原因。。。可能是进程之间的通信,但我无法理解/

#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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,字符**argv)
{
int x=0;
双kk;
int过程;
国际货币基金组织;
int右嘶鸣,左嘶鸣,上嘶鸣,下嘶鸣;
int tag=99;
静态常量int n=6;//矩阵的大小
int psa[n][n];//nxn
国际公共广播局[n][n];
国际审慎监管局[n][n];
int prb[n][n];
国际c[n][n];
对于(inti=0;ik)
{
x=过程/k;
左邻右舍=(过程+k-1)%k)+x*k;
右下=((过程+k+1)%k)+x*k;
up_neigh=proces-k;
}
如果(过程==0 | |(过程/k)<(k-1))
{
down_neigh=proces+k;
}
如果((进程/k)=(k-1))
{
down_neigh=proces-((k-1)*k);
}
x=0;
for(int kk=0;kk好的,我成功了。现在一切都很好,我的朋友帮了我。但是管理员请不要删除它,它可能对某人有帮助

#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;
}
#包括
#包括
#包括
#包括使用命名空间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;
静态常数int n=4;//rozmiar tablic
const int PP=2;//pierwiastek z liczby procesow
int A[n][n]={},B[n][n]={};
对于(inti=0;i//如果你不想让它消失,你需要对问题(通过编辑问题)和解决方案(通过编辑答案)给出更多的解释。