tags:

views:

358

answers:

3

Dear all,
I want to use MPI (MPICH2) on windows. I write this command:

MPI_Barrier(MPI_COMM_WORLD);  

And I expect it blocks all Processors until all group members have called it. But it is not happen. I add a schematic of my code:

int a;  
if(myrank == RootProc)  
   a = 4;  
MPI_Barrier(MPI_COMM_WORLD);  
cout << "My Rank = " << myrank << "\ta = " << a << endl;  

(With 2 processor:) Root processor (0) acts correctly, but processor with rank 1 doesn't know the a variable, so it display -858993460 instead of 4.

Can any one help me?
Regards

+1  A: 

Variable a is not initialized - it is possible that is why it displays that number. In MPI, variable a is duplicated between the processes - so there are two values for a, one of which is uninitialized. You want to write:

int a = 4;
if (myrank == RootProc)
...

Or, alternatively, do an MPI_send in the Root (id 0), and an MPI_recv in the slave (id 1) so the value in the root is also set in the slave.

Note: that code triggers a small alarm in my head, so I need to check something and I'll edit this with more info. Until then though, the uninitialized value is most certainly a problem for you. Ok I've checked the facts - your code was not properly indented and I missed the missing {}. The barrier looks fine now, although the snippet you posted does not do too much, and is not a very good example of a barrier because the slave enters it directly, whereas the root will set the value of the variable to 4 and then enter it. To test that it actually works, you probably want some sort of a sleep mechanism in one of the processes - that will yield (hope it's the correct term) the other process as well, preventing it from printing the cout until the sleep is over.

laura
+5  A: 

You're only assigning a in process 0. MPI doesn't share memory, so if you want the a in process 1 to get the value of 4, you need to call MPI_Send from process 0 and MPI_Recv from process 1.

eduffy
Thanks. It's true, but I have another question. As I know barrier blocks the caller until all group members have called it, but I tested and saw that process 1 pass this function (by writing a sentence, cout) and root process (0) is before the barrier. What's the problem? Thanks
aryan
You can't trust the order of output statements from different processes. If you're unsure, make sure your clocks are sync and output `time()` before and after the barrier.
eduffy
Don't expect clocks on different processors to be in such close synchronisation that the times they report allow you to correctly sequence output statements. The MPI_Barrier synchronises processes, not clocks.
High Performance Mark
So, how can I ensure that MPI_Barrier act correctly?
aryan
Until you've done a lot of MPI programming, like a couple of year's solid practice, I don't think you should even let it cross your mind that the MPI_Barrier is not working correctly. All the MPI libraries I have ever used were written in organisations with high reputations for product quality. If you think there is something wrong with a barrier, it is overwhelmingly more likely that you have made a mistake (in thinking or in coding) than that the barrier itself is faulty.
High Performance Mark
A: 

Blocking is not enough, you have to send data to other processes (memory in not shared between processes).

To share data across ALL processes use:

int MPI_Bcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm )

so in your case:

MPI_Bcast(&a, 1, MPI_INT, 0, MPI_COMM_WORLD);

here you send one integer pointed by &a form process 0 to all other. //MPI_Bcast is sender for root process and receiver for non-root processes

You can also send some data to specyfic process by:

int MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest, 
              int tag, MPI_Comm comm )

and then receive by:

int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
prog32