Я преобразовал MPI-код из точки в точку для коллективного общения, мне нужна помощь, чтобы исправить некоторые значения в коде (Matrix-Vector Multiplication) - PullRequest
0 голосов
/ 19 апреля 2020

Мне нужна ваша помощь. Я преобразовал код c / c ++ MPI в Visual Studio 2019 для преобразования умножения матрицы на вектор из кода точка-точка в код коллективной связи, и есть некоторые значения, которые я не знаю, что мне нужно надеть это после того, как я заменил код на коллективный, но оригинальная функция все еще там как комментарии, вы можете мне помочь. Я приложу код ниже

моей проблемы с разбросом и сбором (void * sendbuf, int sendcount, void * recvbuf и int recvcount. Вы можете помочь мне решить эту проблему

#include <iostream>
#include <mpi.h>
#include <time.h>
#include <iomanip>
using namespace std;
//matrix in two dimension in memory!!
int main(int argc, char** argv)
{
    const int WIDTH = 100;
    const int HEIGHT = 100;
    int id, P;
    double tempValue = 0;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &P);
    MPI_Comm_rank(MPI_COMM_WORLD, &id);
    double timer = MPI_Wtime();
    double A[WIDTH][HEIGHT];
    double x[HEIGHT], b[WIDTH];
    int upperBound, lowerBound = 0;
    // Master controls worksharing..
    if (id == 0)
    {
        // Init A & x
        for (int i = 0; i < WIDTH; i++)
            for (int j = 0; j < HEIGHT; j++)
                A[i][j] = 1;
        for (int j = 0; j < HEIGHT; j++)
            x[j] = 2;
        // Send to each node its portion of A to be processed
     //   int portionSize = WIDTH / P;
       // for (int i = 0; i < P; i++)
        //{
          //  lowerBound = i * portionSize;
            //upperBound = (i + 1) * portionSize;
            // let the last node process the remainder
            //if (i == (P - 1))
             //   upperBound += (HEIGHT - portionSize * P);
            //if (i > 0)// Do not send to master node!!
           // {
                // Send to node i the lower & upper bounds the A portion
                //and complete vector x
             //   MPI_Send(&lowerBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
               // MPI_Send(&upperBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
                //MPI_Send(&A[lowerBound][0], (upperBound - lowerBound) * HEIGHT,
                  //  MPI_DOUBLE, i, 0, MPI_COMM_WORLD);

           // }
        //}
             MPI_Scatter(
             &A, int sendcount, MPI_INT,
             void* recvbuf, int recvcount, MPI_INT,
             0, MPI_Comm comm)
            MPI_Bcast(&x[0], HEIGHT, MPI_DOUBLE , 0, MPI_COMM_WORLD);

        // master perform part of the job...
        for (int i = 0; i < portionSize; i++)
        {
            tempValue = 0;
            for (int j = 0; j < HEIGHT; j++)
                tempValue += A[i][j] * x[j];
            b[i] = tempValue;
        }
        //Get the results in order, each node would send their boundaries and data part
        int receivedValues[WIDTH * HEIGHT];
        //for (int i = 1; i < P; i++)  // replaced with gather 
        //{
           // MPI_Recv(&lowerBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
            //MPI_Recv(&upperBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
           // MPI_Recv(&receivedValues[0], (upperBound - lowerBound), MPI_DOUBLE, i, 0,
         //       MPI_COMM_WORLD, MPI_STATUSES_IGNORE);

            // do your computation here with receivedValues
       // }
         MPI_Gather(
       void* sendbuf, int sendcount, MPI_DOUBLE,
       void* recvbuf, int recvcount, MPI_DOUBLE,
       0, MPI_COMM_WORLD)

        // Print the first 2 values to check..
        cout << "b[0]=" << b[0] << " b[Width-1]=" << b[WIDTH - 1] << endl;
    }
    //else // the rest of the workers do their parts // it is part of scatter 
    //{
        //Receive the inputs
      //  MPI_Recv(&lowerBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
        //MPI_Recv(&upperBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
        //MPI_Recv(&A[lowerBound][0], (upperBound - lowerBound) * WIDTH, MPI_DOUBLE, 0, 0,
          //  MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
        //MPI_Recv(&x, HEIGHT, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
        //cout << "Node:" << id << " Received from:" << lowerBound << " to " << upperBound - 1
          //  << endl;
        //double* result = new double[upperBound - lowerBound];
        //Do the job
        for (int i = lowerBound, resultCounter = 0; i < upperBound; i++, resultCounter++)
        {
            tempValue = 0;
            for (int j = 0; j < HEIGHT; j++)
                tempValue += A[i][j] * x[j];
            result[resultCounter] = tempValue;
        }
        //send the results
       // MPI_Send(&lowerBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
       // MPI_Send(&upperBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
       //  MPI_Send(&result[0], upperBound - lowerBound, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
       // delete[] result;
       MPI_Gather(
       void* sendbuf, int sendcount, MPI_INT,
       void* recvbuf, int recvcount, MPI_INT,
       int root, MPI_Comm comm)
    }
    timer = MPI_Wtime() - timer;
    MPI_Finalize();
    cout << "\n\nPoint To Point Time Needed for all ops = " << std::setprecision(15) << timer << " Seconds" << endl;
    return 0;
}
...