Alessandroempire - 11 months ago 45

C Question

I am trying to parallelize the following code for calculation of pi.

My approach is to use scatter to parallelize the for, and then use a reduce to calculate the sum value and finally show pi.

My code is the following

`#include <stdio.h>`

#include <mpi.h>

long num_steps = 100000;

double step = 1.0/100000.0;

int main() {

int i, myid, size;

double x, pi, local_sum = 0.0, sum=0.0;

double send_vec[num_steps], recv_vect[num_steps];

// Initialize the MPI environment

MPI_Init(NULL, NULL);

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD,&myid);

if (myid ==0){

int i=0;

for (i=0; i<num_steps;i++){

send_vec[i]=i;

}

}

MPI_Scatter(send_vec, num_steps/size, MPI_INT, recv_vect,

num_steps, MPI_INT, 0, MPI_COMM_WORLD);

for(i = 0; i < num_steps; ++i) {

x = (recv_vect[i]-0.5)*step;

local_sum += 4.0/(1.0+x*x);

}

MPI_Reduce(&local_sum, &sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

if (myid == 0){

pi = step*sum;

printf("PI value = %f\n", pi);

}

// Finalize the MPI environment.

MPI_Finalize();

}

The thing is when I run the program with the option -np 1 and 2

I do get the desired result.

Yet when I run with 3, 4 and higher I get the following error:

`PIC_Send(284).........: Negative count, value is -240000`

Fatal error in PMPI_Scatter: Invalid count, error stack

Answer Source

The call to `MPI_Scatter()`

is to be corrected:

```
MPI_Scatter(send_vec, num_steps/size, MPI_INT, recv_vect,
num_steps, MPI_INT, 0, MPI_COMM_WORLD);
```

- To send
`double`

, use the datatype`MPI_DOUBLE`

as you did in the`MPI_Reduce()`

- Since the
`sendtype`

is similar to the`recvtype`

, the number of item sent to each process`sendcount`

must be equal to the number of item received by each process`recvcount`

. In the present case, it's`num_steps/size`

.

Finally, the call to `MPI_Scatter()`

will look like:

```
MPI_Scatter(send_vec, num_steps/size, MPI_DOUBLE, recv_vect,
num_steps/size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
```

Lastly, dynamic memory allocation can be used to avoid using the stack for storing large arrays. Moreover, the allocated space can be decreased so as to reduce the memory footprint:

```
num_steps=(num_steps/size)*size;
double* send_vec=NULL;
double* recv_vec=NULL;
if(rank==0){
send_vec=malloc((num_steps/size)*sizeof(double));
if(send_vec==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
}
recv_vec=malloc(num_steps*sizeof(double));
if(recv_vec==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
...
if(rank==0){
free(send_vec);
}
free(recv_vec);
```