A good way to print array of each rank after using MPI_Scather

I want to print the array of each rank in a proper way. First, the problem with this code is that output is not ordered, and second, I just want to eliminate the use of if the condition for printing the data of each rank. Is it possible?

#include <fstream>
#include <iostream>
#include <vector>
#include "mpi.h"
using namespace std;
const int N = 3;

    int main()
    {
    MPI_Init(NULL, NULL);
        int rank;
        int size;
        int root = 0; 
        vector<int> x(N);
        vector<int> receive_data(N); 
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);
        
        
        const int leng = size * N; 
        vector<int> single_arr(leng);
        
    
        for (int i = 0; i < N;i++) {
            x[i] = 1000*rank + i; 
            
        }
    
        MPI_Gather(x.data(), N, MPI_INT, single_arr.data(), N, MPI_INT, root, MPI_COMM_WORLD);
    
        if (rank == root) {
            cout << " After the gathering data inside single array at root is : " << endl; 
            for (int i = 0; i < single_arr.size();i++) {
                cout << i << "t" << single_arr[i] << endl; 
            }
        }
     MPI_Scatter(single_arr.data(),N, MPI_INT, receive_data.data(), N, 
     MPI_INT, root, MPI_COMM_WORLD);
        MPI_Barrier(MPI_COMM_WORLD); 
        // now checks for data of each rank: 
    
    
        if (rank == root) {
            //cout << " After scattering the data: " << endl;
            cout << " My rank is : " << rank << endl;
            for (int i = 0; i < receive_data.size(); i++) {
                cout << i << "t" << receive_data[i] << endl;
                cout << endl;
            }
        }
    
        if (rank == 1) {
            //cout << " After scattering the data: " << endl;
            cout << " My rank is : " << rank<<"t"<< endl;
            for (int i = 0; i < receive_data.size(); i++) {
                cout << i << "t" << receive_data[i] << endl;
                cout << endl;
            }
        }
       MPI_Finalize();
    }

The result is :

0       0
1       1
2       2
3       1000
4       1001
5       1002
6       2000
7       2001
8       2002
9       3000
10      3001
11      3002
 My rank is : 0
0       0

 My rank is : 1
1       1
0       1000


2       2
1       1001


2       1002

But, I want to see this instead without using if condition for each rank:

My rank is : 0
0     0
1     1
2     2
My rank is: 1
0          1000
1          1001
2          1002

Answer

First, the problem with this code is that output is not ordered, and second, I just want to eliminate the use of if the condition for printing the data of each rank. Is it possible?

This is not how MPI is meant to be used, actually parallelism in general IMO. The coordination of printing the output to the console among processes will greatly degrade the performance of the parallel version, which defeats one of the purposes of parallelism i.e., reducing the overall execution time.

Most of the times one is better off just making one process responsible for printing the output to the console (typically the master process i.e., process with rank = 0).

Citing @Gilles Gouaillardet:

Your best bet is to have all the data sent to one rank and have this rank print everything.

You could try using MPI_Barrier to coordinate the processes in a way that would print the output has you want, however (citing Hristo Iliev):

Using barriers like that only works for local launches when (and if) the processes share the same controlling terminal. Otherwise, it is entirely to the discretion of the I/O redirection mechanism of the MPI implementation.

Leave a Reply

Your email address will not be published. Required fields are marked *