Ian Nemo
Ian Nemo

Reputation: 23

Scatter a 2D matrix - MPI

I am now studying and trying to understand MPI.

I have a matrix n*n, for example (with n = 4):

0 1 2 3 
4 5 6 7 
8 9 10 11 
12 13 14 15

I wanted to scatter this matrix, and create four new ones (I have four processes):

Rank 0:

0 1
4 5

Rank 1:

2 3
6 7

Rank 2:

8 9
12 13

Rank 3:

10 11
14 15

I tried to do this but only rank 0 is obtaining the correct result.

Bellow is my implemented code:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <mpi.h>



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

  int rank;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);


  int n;
  if(rank == 0){
    scanf("%d", &n);
  }

  MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);


  MPI_Barrier(MPI_COMM_WORLD);


  int **matrix = (int **)malloc(n * sizeof(int *));
  int *matrix_1D = (int *)malloc(n * n * sizeof(int));


  for(int i = 0; i < n; i++){
    matrix[i] = (int *)malloc(n * sizeof(int));
  }

  if(rank == 0){
    // Reading the matrix
    for(int i = 0; i < n; i++)
      for(int j = 0; j < n; j++){
        scanf(" %d", &matrix[i][j]);
        matrix_1D[i*n + j] = matrix[i][j];
      }
    printf("\n");

    for(int i=0; i<n; ++i){
      for(int j=0; j<n; ++j){
        printf("%d ", matrix[i][j]);
      } printf("\n");
    } printf("\n");
  }



  int new_n = n / 2; // Size of each smaller square matrix block

  MPI_Datatype block_type;
  int sizes[2]    ={n, n};          // Dimensions of the full matrix
  int subsizes[2] ={new_n, new_n};  // Dimensions of the smaller block
  int starts[2]   ={0, 0};          // Starting coordinates

  MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_INT, &block_type);
  MPI_Type_commit(&block_type);


  int *local_matrix = (int *)malloc(new_n * new_n * sizeof(int)); // Each process will hold a block of the matrix

  MPI_Scatter(matrix_1D, 1, block_type, local_matrix, new_n*new_n, MPI_INT, 0, MPI_COMM_WORLD);

  printf("Rank %d received data:\n", rank);
  for(int i = 0; i < new_n; i++){
    for(int j = 0; j < new_n; j++){
      printf("%d ", local_matrix[i*new_n + j]);
    }
    printf("\n");
  } printf("\n");

  free(local_matrix);
  MPI_Type_free(&block_type);

  MPI_Finalize();
}

What am I understanding wrong?

I tried to find patterns, but the only invariant is that the rank 0 always gets the right result, and all the others fail.

I also tried the scatter this way:

  MPI_Scatter(matrix_1D, 1, block_type, local_matrix, 1, block_type, 0, MPI_COMM_WORLD);

But it did not work

Upvotes: 1

Views: 64

Answers (0)

Related Questions