0

Okay, so here is another question related to my previous post MPI_Broadcast using vectors

I want to scatter a matrix (4x4) in such a way that each process receives one row (total of 4 processes). I am using vectors which need to be resized and a bit of playing around. It worked well when using arrays but with vectors I can't get the desired output.

updated code (Minimal)

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>
#include <chrono>
#include <cmath>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include"mpi.h"

using namespace std;



const int num_rows1 = 4, num_rows2 = 4, num_cols1 = 4, num_cols2 = 4;
const int root = 0;
int i, j, k;
vector<vector<int> > matrix1(num_rows1, vector <int>(num_cols1));
vector<vector<int> > matrix2(num_rows2, vector <int>(num_cols2));
vector<vector<int> > result(num_rows1, vector <int>(num_cols1));
int finale[num_rows1][num_cols2];
vector<vector<int> > transpose_mat(num_cols2, vector <int>(num_rows2));
vector<int> column1(num_rows1);
vector<int> column2(num_cols2);
double start_time, end_time;
int * column3 = new int[];


//Function working with the multiplication

vector<int> mult(vector<vector<int> > A, vector<int> B)
{
//Multiplication

    for (int i = 0; i < num_rows1; ++i)
    {
        int sum = 0;
        for (int j = 0; j < num_cols1; ++j)
        {
            sum += A[i][j] * B[j];
        }

        column1.push_back(sum);
    }


    return column1;
}


//Function generating random matrices
vector<vector<int>> generate_matrix(int nrow, int ncol)
{

    vector<vector<int>> matrix(nrow, vector <int>(ncol));

    for (int i = 0; i < nrow; ++i)
    {
        for (int j = 0; j < ncol; ++j)
        {
            matrix[i][j] = (15 *rand() / RAND_MAX - 3);
        }
    }



    return matrix;
}


//function taking the transpose
vector<vector<int>>transpose(vector<vector<int> > matrix , int nrow, int ncol)
{

    //Transpose of matrix 2
    for (i = 0; i < nrow; ++i)
        for (j = 0; j < ncol; ++j)
        {
            transpose_mat[j][i] = matrix2[i][j];
        }

    cout << "Transpose " << endl;

    for (int i = 0; i < num_rows2; ++i)
    {
        for (int j = 0; j < num_cols2; ++j)
        {
            cout << transpose_mat[i][j] << "     ";
        }
        cout << endl;
    }

    return transpose_mat;
}


//main function
int main(int argc, char *argv[])
{


    MPI_Status status;
    MPI_Request request;
    int tag = 1;
    int rank;
    int world_size;    //Number of processes

    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    // Get the rank of the process
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    // Get the name of the processor
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

    // Get the number of processes
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);


    if (rank == root)
    { 

        //Filling
        matrix1 = generate_matrix(num_rows1, num_cols1);


        for (int i = 0; i < num_rows1; ++i)
        {
                MPI_Bcast(&matrix1[i][0], num_rows1, MPI_INT, root, MPI_COMM_WORLD);

        }
    }

    else if (rank == 1)
    {
        srand(time(NULL));
        //Filling
        matrix2 = generate_matrix(num_rows2, num_cols2);

    transpose_mat = transpose(matrix2, num_rows2, num_cols2);

    }

    if (rank > root)
    {

    int size = matrix1.size();
    result.resize(size);
    for (int i = 0; i < size; i++){
        result[i].resize(size);
    }

    for (int i = 0; i < size; ++i)
    {
        MPI_Bcast(&result[i][0], size, MPI_INT, root, MPI_COMM_WORLD);

    }

    }

    int size1 = transpose_mat.size();
    column2.resize(size1);

    //Scattering the transposed matrix

            for (j = 0; j < num_rows2; ++j)
            {

    MPI_Scatter(&transpose_mat[0][j], size1*size1 / world_size, MPI_INT, &column2[j], size1*size1 / world_size, MPI_INT, 1, MPI_COMM_WORLD);
            }


     cout << "The scattered data at process " << rank << " is: " << endl;

    for (int j = 0; j < num_cols2; ++j)
        {
            cout << column2[j] << endl;
        }


    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();

    return 0;

}

In the updated PNG one can see that the first two rows of the matrix are scattered. The first one being received by Process 0 and the second row by Process 2. Why do Process 1 and Process 3 don't give the desired reault. Updated PNG

shaibi
  • 31
  • 4
  • 1
    Your code is missing all important types, please provide a [mcve]. Also do not post text as pictures, but rather as text. – Zulan Oct 21 '16 at 15:07
  • @Zulan I edited the question, it now has the complete code. The output of the run is also attached in the original question. It can be seen that the transpose matrix is not scattered in the way it actually should be. – shaibi Oct 24 '16 at 09:47
  • The code is not verifiable, it cannot possibly compile. It is far from minimal, please remove commented out code and format it properly. You only link the same png twice. It's much better if the question is self-contained. – Zulan Oct 24 '16 at 11:57
  • The code is compiling well on MS Visual Studio 2013 and it also runs using the MPI. But the only problem is that the desired output isn't obtained. I updated the code which is both minimal and working. – shaibi Oct 24 '16 at 12:26
  • let's start with `vector mult(...)` function, check the size of `column1` and call it few times. The `transpose()` doesn't make sense to me. It take the `matrix` as an argument, but inside it is using `matrix2`. Why `matrix2` is generated at all? and `srand()` should be initialized before generating the matrix. The compiler which I am using doesn't like `vector>` because of `>>`, you can put space there to be more compatible. It cannot possible work due to, `int size=matrix1.size()` : slaves doesn't know about matrix1.size(), for test put 4 there. No need for n_rows, n_cols. – Stefan Oct 24 '16 at 13:12
  • @Stefan `matrix2` is passed as an argument to `transpose()` which is scattered later and passed to `vector mult(...)` `int size = matrix1.size()` is used for the broadcast which is working fine – shaibi Oct 24 '16 at 13:24
  • Look, I know what `transpose()` of the matrix mean and it doesn't do what you asked for. Anyway, there are still problems not related to MPI_Bcast or MPI_Scatter. I have found one more week spot. Check the size of int and MPI_INT in my case it is `4` and `8`. For broader audience it would be better to remove all functions like: `transpose()`, `generate_matrix()` and `mult` – Stefan Oct 24 '16 at 13:43
  • Scatter, by default, works on contiguous data. The rows of your Matrix are not stored contigously in memory, as they are all parts of separate vectors. This question is a duplicate of http://stackoverflow.com/questions/16702418/how-to-use-multi-dimensional-stl-vector-in-mpi / http://stackoverflow.com/questions/34888889/mpi-scatter-2d-vector. You are also misusing the `send_count` / `recv_count` parameters of scatter. The rest of your code are very problematic as well. Avoid global variables, give your variables meaningful names, consider input/output of functions and learn about references. – Zulan Oct 24 '16 at 18:25

0 Answers0