AbdullahC
AbdullahC

Reputation: 23

MPI Subarray Sending Error

I firstly initialize a 4x4 matrix and then try to send the first 2x2 block to the slave process by using MPI in C. However the slave process only receives the first row of the block, the second row is filled with random numbers from computer ram. I couldn't find what is missing. The code of the program is below :

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

#define     SIZE        4

int main(int argc, char** argv)
{
int rank, nproc;
const int root = 0;
const int tag = 3;

int** table;
int* datas;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);

datas = malloc(SIZE * SIZE * sizeof(int));
table = malloc(SIZE * sizeof(int*));

for (int i = 0; i < SIZE; i++)
    table[i] = &(datas[i * SIZE]);

for (int i = 0; i < SIZE; i++)
    for (int k = 0; k < SIZE; k++)
        table[i][k] = 0;

table[0][1] = 1;
table[0][2] = 2;
table[1][0] = 3;
table[2][3] = 2;
table[3][1] = 3;
table[3][2] = 4;


if (rank == root){
    MPI_Datatype newtype;
    int sizes[2] = { 4, 4 };  // size of table 
    int subsizes[2] = { 2, 2 };  // size of sub-region 
    int starts[2] = { 0, 0 };

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

    MPI_Send(&(table[0][0]), 1, newtype, 1, tag, MPI_COMM_WORLD);
}
else{
    int* local_datas = malloc(SIZE * SIZE * sizeof(int));
    int** local = malloc(SIZE * sizeof(int*));

    for (int i = 0; i < SIZE; i++)
        local[i] = &(local_datas[i * SIZE]);

    MPI_Recv(&(local[0][0]), 4, MPI_INT, root, tag, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);

    for (int i = 0; i < 2; i++){
        for (int k = 0; k < 2; k++)
            printf("%3d ", local[i][k]);
        printf("\n");
    }
}


MPI_Finalize();

return 0;

}

Upvotes: 0

Views: 155

Answers (1)

Hristo Iliev
Hristo Iliev

Reputation: 74385

You have instructed the receive operation to put four integer values consecutively in memory and therefore the 2x2 block is converted to a 1x4 row upon receive (since local is 4x4). The second row of local contains random values since the memory is never initialised.

You should either make use of MPI_Type_create_subarray in both the sender and the receiver in order to place the received data in a 2x2 block or redefine local to be a 2x2 matrix instead of 4x4.

Upvotes: 2

Related Questions