#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
int size;
typedef struct process_struct
{
int start;
int end;
} process_tag;
int main(int argc, char **argv)
{ //array size
size=11;
int rc, myrank, world_size;
rc = MPI_Init(&argc, &argv);
if (rc != MPI_SUCCESS) {
printf ("Error starting MPI program\n");
MPI_Abort(MPI_COMM_WORLD, rc);
}
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int i, j;
int process_num=4;
int processs_i;
int start, end;
double **a = malloc(size*sizeof(double*));
if (a == NULL) { printf("malloc failed\n"); return 1; }
for (i = 0; i < size; i++) {
a[i] = malloc(size*sizeof(double));
if (a[i] == NULL) { printf("malloc failed\n"); return 1; }
}
//initialize array "a"
a=ini(a);
if(myrank == 0 ) {
printarray(a,size);
}
// store starting row and ending row for each process
process_tag process[process_num];
int chunk_size = (size - 2 ) / process_num ;
int remain = (size - 2) - chunk_size * process_num ;
start = 1;
end = 1;
int process_i =0;
while(start < size) {
start = end;
end = start + chunk_size;
if (remain > 0) {
end++;
remain--;
}
process[process_i].start = start;
process[process_i].end = end;
process_i++;
}
int send_count[process_num];
for (process_i = 0; process_i < process_num; process_i++) {
send_count[process_i] = process[process_i].end - process[process_i].start;
}
int receive_count = send_count[myrank];
int *displs = malloc(sizeof(int)*size);
int sum =1;
for (i = 0; i < process_num; i++) {
displs[i] = sum;
sum += send_count[i];
}
double **blocal;
blocal = malloc(receive_count*sizeof(double*));
if (blocal == NULL)
{ printf("malloc failed\n"); return 1; }
for (i = 0; i < size; i++) {
blocal[i] = malloc(size*sizeof(double));
if (blocal[i] == NULL)
{ printf("malloc failed\n"); return 1; }
}
MPI_Scatterv(a, send_count, displs, MPI_DOUBLE, blocal,
receive_count, MPI_DOUBLE, 0, MPI_COMM_WORLD);
printarray(blocal,receive_count);
printf("from rank %d \n", myrank);
}
output is:
array a is
1.000000 3.700000 2.000000 6.000000 5.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 8.200000 3.000000 7.000000 3.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 6.000000 9.000000 1.000000 6.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 5.000000 1.000000 3.000000 4.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 4.500000 6.000000 4.000000 7.600000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
blocal from rank 0
1.000000 8.200000 3.000000 7.000000 3.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 6.000000 9.000000 1.000000 6.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 5.000000 1.000000 3.000000 4.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
blocal from rank 1
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
blocal from rank 2
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
blocal from rank 3
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
I want to scatter the elements of 11*11 sendbuf array "a" to arrays "blocal" (receivebuf).
What I want to achieve is that blocal at process 0 get row 1 to 3, process 1 get row 4 to 5, process 2 get row 6 to 7, and process 3 get row 8 to 9. Row 0 and row 10 are ignored.
However in my output only process 0 got the sub-array from array "a".
Could anybody spot any error in my code? I think the problem might be the displacement.