Mehar Charan Sahai
Mehar Charan Sahai

Reputation: 183

MPI_Gatherv: Garbage values received in root's array

I am trying to implement MPI_Gatherv function in C.

According to my program, every process including root should create a local array of size equal to the (process' rank + 1) which will hold process' rank in all the cells.

This local array is then gathered into the root's rcv_array.

Somehow, I'm getting garbage values. Can someone tell me what am I doing wrong? Also I am new to MPI and had tough time getting to understand disp and rcv_count of MPI_Gatherv.

My code:

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

int sum(int);

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

    int proc_count, proc_rank, root = 0;
    int *localdata = NULL;
    int *rcv_array = NULL;
    int *disp = NULL;
    int *rcv_count = NULL;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &proc_count);
    MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);

    if(proc_rank == root){
        rcv_array = malloc((sum(proc_count)+1) * sizeof(int));
        rcv_count = malloc(proc_count * sizeof(int));
        disp = malloc(proc_count * sizeof(int));
        rcv_count[0] = 1;
        disp[0] = 0;

        for(int i=1; i<proc_count; i++){
            rcv_count[i] = i+1;
            disp[i] = rcv_count[i-1] + disp[i-1];
        }
    }   

    localdata = malloc(proc_rank * sizeof(int));
    for(int i=0; i<=proc_rank; i++)
        localdata[i]=proc_rank;

    MPI_Gatherv(&localdata, proc_rank+1, MPI_INT, rcv_array, rcv_count, disp, MPI_INT, root, MPI_COMM_WORLD);

    if(proc_rank == root){
        printf("Elements gathered from each process rank wise:\n\n");
        for(int i=0; i<sum(proc_count)+1; i++){
            printf("-%d-", rcv_array[i]);
        }
        printf("\n");   
    }


    MPI_Finalize();
    return 0;
}

int sum(int n){
    int total = 0;

    for(int i=1; i<=n; i++)
        total+=i;

    return total;
}

Upvotes: 3

Views: 247

Answers (1)

Zulan
Zulan

Reputation: 22660

Three small issues:

  1. You say that you want to create a local array of size equal to the (process' rank + 1), but you only do localdata = malloc(proc_rank * sizeof(int)); Simply malloc((proc_rank + 1) * sizeof(int)); instead.

  2. As a first parameter to MPI_Gatherv you use &localdata. This is the address of the pointer, use the pointer itself localdata instead.

  3. sum(proc_count)+1 (used for printing and allocation), is actually one too many.

Otherwise you're good to go. In particular the tricky displacement / offset calculation looks just fine.

Upvotes: 2

Related Questions