Lumby
Lumby

Reputation: 17

Parellel Programming: How can I apply 'MPI_Gather' or 'MPI_Scatter' instead of 'MPI_Isend' and 'MPI_Recv'

This is my code counting prime numbers, I want to use only collective communication among those processes. However, I got error when I changed my code using 'MPI_Scatter' and 'MPI_Gather' instead of MPI_Recv and MPI_Isend. What should I change for it?

This is my original code:

MPI_Request req;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

if( my_rank == 0){
    printf("Input(50-1000) : ");
    fflush(stdout);
    scanf("%d",&w);
    for(i=0; i<w; i++) data[i] = i+1;
}

MPI_Bcast(&w, 1, MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(data, w, MPI_INT,0,MPI_COMM_WORLD);

if( my_rank != 0){
    x = w/(p-1);
    low = (my_rank-1)*x;
    high = low+x-1;
    for(num = data[low]; num <= data[high];num++){
        result = 0;
        t=1;
        while(num>=t){
                if(num%t==0)
                result = result +1;
            t += 1;
        }
        if(result==2) i += 1;
    }
    MPI_Isend(&i,1,MPI_INT,0,0,MPI_COMM_WORLD,&req);
}

if(my_rank == 0){
    int j = 0;
    for( j = 1; j < p; j++){
        MPI_Recv(&i,1,MPI_DOUBLE,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,&status);
    printf("Process %d : There are %d prime numbers\n",status.MPI_SOURCE,i );
    }
}
MPI_Finalize();

}

And the output is:

Input(50-1000) : 50
Process 1 : There are 5 prime numbers
Process 2 : There are 4 prime numbers
Process 3 : There are 2 prime numbers
Process 4 : There are 4 prime numbers

Here is the part where I changed my code:

if( my_rank != 0){
        x = w/(p-1);
        low = (my_rank-1)*x;
        high = low+x-1;
        for(num = data_send[low]; num <= data[high];num++){
            result = 0;
            t=1;
            while(num>=t){
                if(num%t==0)
                    result = result +1;
                    t += 1;
                }
            if(result==2) i += 1;
     }
 MPI_Scatter(data_send,1,MPI_INT,data_recv,1,MPI_INT,0,MPI_COMM_WORLD);
    }

Upvotes: 0

Views: 368

Answers (2)

Gilles Gouaillardet
Gilles Gouaillardet

Reputation: 8395

here is how you can use MPI_Gather()

int * results;
if( my_rank != 0){
    x = w/(p-1);
    low = (my_rank-1)*x;
    high = low+x-1;
    for(num = data[low]; num <= data[high];num++){
        result = 0;
        t=1;
        while(num>=t){
                if(num%t==0)
                result = result +1;
            t += 1;
        }
        if(result==2) i += 1;
    }
} else {
    results = (int *)malloc(p * sizeof(int));
}

MPI_Gather(&i, 1, MPI_INT, results, 1, MPI_INT, 0, MPI_COMM_WORLD);

if(my_rank == 0){
    int j = 0;
    for( j = 1; j < p; j++){
        printf("Process %d : There are %d prime numbers\n",j, results[j]);
    }
    free(results);
}

note you can arrange this algo in order to also do computations on rank 0, and hence use p MPI tasks instead of p-1

Upvotes: 1

vim_
vim_

Reputation: 2170

MPI_Scatter is a collective operation and need to be called by all ranks. Same thing goes for MPI_Gather.

The means that: MPI_Scatter call should be moved outside of the if block in your code (similarly for MPI_Gather).

You can find an example here.

Upvotes: 1

Related Questions