user3195458
user3195458

Reputation: 31

Changing value of a variable with MPI

#include<stdio.h>
#include<mpi.h>
int a=1;
int *p=&a;
int main(int argc, char **argv)
{

MPI_Init(&argc,&argv);

int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
//printf("Address val: %u \n",p);

*p=*p+1;


MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();

printf("Value of a : %d\n",*p);

return 0;
}

Here, I am trying to execute the program with 3 processes where each tries to increment the value of a by 1, so the value at the end of execution of all processes should be 4. Then why does the value printed as 2 only at the printf statement after MPI_Finalize(). And isnt it that the parallel execution stops at MPI_Finalize() and there should be only one process running after it. Then why do I get the print statement 3 times, one for each process, during execution?

Upvotes: 3

Views: 1605

Answers (3)

High Performance Mark
High Performance Mark

Reputation: 78364

It is a common misunderstanding to think that mpi_init starts up the requested number of processes (or whatever mechanism is used to implement MPI) and that mpi_finalize stops them. It's better to think of mpi_init starting the MPI system on top of a set of operating-system processes. The MPI standard is silent on what MPI actually runs on top of and how the underlying mechanism(s) is/are started. In practice a call to mpiexec (or mpirun) is likely to fire up a requested number of processes, all of which are alive when the program starts. It is also likely that the processes will continue to live after the call to mpi_finalize until the program finishes.

This means that prior to the call to mpi_init, and after the call to mpi_finalize it is likely that there is a number of o/s processes running, each of them executing the same program. This explains why you get the printf statement executed once for each of your processes.

As to why the value of a is set to 2 rather than to 4, well, essentially you are running n copies of the same program (where n is the number of processes) each of which adds 1 to its own version of a. A variable in the memory of one process has no relationship to a variable of the same name in the memory of another process. So each process sets a to 2.

To get any data from one process to another the processes need to engage in message-passing.

EDIT, in response to OP's comment

Just as a variable in the memory of one process has no relationship to a variable of the same name in the memory of another process, a pointer (which is a kind of variable) has no relationship to a pointer of the same name in the memory of another process. Do not be fooled, if the ''same'' pointer has the ''same'' address in multiple processes, those addresses are in different address spaces and are not the same, the pointers don't point to the same place.

An analogy: 1 High Street, Toytown is not the same address as 1 High Street, Legotown; there is a coincidence in names across address spaces.

To get any data (pointer or otherwise) from one process to another the processes need to engage in message-passing. You seem to be clinging to a notion that MPI processes share memory in some way. They don't, let go of that notion.

Upvotes: 4

DevEhmeth
DevEhmeth

Reputation: 74

In your implementation there is no communication between the spawned threads. Each process has his own int a variable which it increments and prints to the screen. Making the variable global doesn't make it shared between processes and all the pointer gimmicks show me that you don't know what you are doing. I would suggest learning a little more C and Operating Systems before you move on.

Anyway, you have to make the processes communicate. Here's how an example might look like:

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

// this program will count the number of spawned processes in a *very* bad way
int main(int argc, char **argv)
{
   int partial = 1;
   int sum;
   int my_id = 0;

   // let's just assume the process with id 0 is root
   int root_process = 0;

   // spawn processes, etc.
   MPI_Init(&argc,&argv);

   // every process learns his id
   MPI_Comm_rank(MPI_COMM_WORLD, &my_id);

   // all processes add their 'partial' to the 'sum'
   MPI_Reduce(&partial, &sum, 1, MPI_INT, MPI_SUM, root_process, MPI_COMM_WORLD); 

   // de-init MPI
   MPI_Finalize();

   // the root process communicates the summation result
   if (my_id == root_process)
   {
      printf("Sum total : %d\n", sum);
   }

   return 0;
}

Upvotes: 0

Chiel
Chiel

Reputation: 6194

Since MPI is only giving you the option to communicate between separate processes, you have to do message passing. For your purpose there is something like MPI_Allreduce, which can sum data over the separate processes. Note that this adds the values, so in your case you want to sum the increment, and add the sum later to p:

int inc = 1;
MPI_Allreduce(MPI_IN_PLACE, &inc, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
*p += inc;

Upvotes: 0

Related Questions