2006-07-14 01:03:36 +04:00
|
|
|
//
|
|
|
|
// Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
|
|
|
|
// University Research and Technology
|
|
|
|
// Corporation. All rights reserved.
|
|
|
|
// Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
|
|
|
|
//
|
2015-05-04 17:47:53 +03:00
|
|
|
// Simple ring test program in C++.
|
2006-07-14 01:03:36 +04:00
|
|
|
//
|
2013-01-29 02:22:26 +04:00
|
|
|
// NOTE: The MPI C++ bindings were deprecated in MPI-2.2 and removed
|
|
|
|
// from the standard in MPI-3. Open MPI still provides C++ MPI
|
|
|
|
// bindings, but they are no longer built by default (and may be
|
|
|
|
// removed in a future version of Open MPI). You must
|
|
|
|
// --enable-mpi-cxx when configuring Open MPI to enable the MPI C++
|
|
|
|
// bindings.
|
|
|
|
//
|
2006-07-14 01:03:36 +04:00
|
|
|
|
2006-10-16 17:22:22 +04:00
|
|
|
#include "mpi.h"
|
2006-10-16 18:20:31 +04:00
|
|
|
#include <iostream>
|
2006-07-14 01:03:36 +04:00
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int rank, size, next, prev, message, tag = 201;
|
|
|
|
|
|
|
|
// Start up MPI
|
|
|
|
|
|
|
|
MPI::Init();
|
|
|
|
rank = MPI::COMM_WORLD.Get_rank();
|
|
|
|
size = MPI::COMM_WORLD.Get_size();
|
2015-05-04 17:47:53 +03:00
|
|
|
|
2006-07-14 01:03:36 +04:00
|
|
|
// Calculate the rank of the next process in the ring. Use the
|
|
|
|
// modulus operator so that the last process "wraps around" to
|
|
|
|
// rank zero.
|
|
|
|
|
|
|
|
next = (rank + 1) % size;
|
|
|
|
prev = (rank + size - 1) % size;
|
|
|
|
|
|
|
|
// If we are the "master" process (i.e., MPI_COMM_WORLD rank 0),
|
|
|
|
// put the number of times to go around the ring in the message.
|
|
|
|
|
|
|
|
if (0 == rank) {
|
|
|
|
message = 10;
|
|
|
|
|
|
|
|
std::cout << "Process 0 sending " << message << " to " << next
|
|
|
|
<< ", tag " << tag << " (" << size << " processes in ring)"
|
|
|
|
<< std::endl;
|
|
|
|
MPI::COMM_WORLD.Send(&message, 1, MPI::INT, next, tag);
|
|
|
|
std::cout << "Process 0 sent to " << next << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass the message around the ring. The exit mechanism works as
|
|
|
|
// follows: the message (a positive integer) is passed around the
|
|
|
|
// ring. Each time it passes rank 0, it is decremented. When
|
|
|
|
// each processes receives a message containing a 0 value, it
|
|
|
|
// passes the message on to the next process and then quits. By
|
|
|
|
// passing the 0 message first, every process gets the 0 message
|
|
|
|
// and can quit normally.
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
MPI::COMM_WORLD.Recv(&message, 1, MPI::INT, prev, tag);
|
|
|
|
|
|
|
|
if (0 == rank) {
|
|
|
|
--message;
|
2015-05-04 17:47:53 +03:00
|
|
|
std::cout << "Process 0 decremented value: " << message
|
2006-07-14 01:03:36 +04:00
|
|
|
<< std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
MPI::COMM_WORLD.Send(&message, 1, MPI::INT, next, tag);
|
|
|
|
if (0 == message) {
|
|
|
|
std::cout << "Process " << rank << " exiting" << std::endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The last process does one extra send to process 0, which needs
|
|
|
|
// to be received before the program can exit */
|
|
|
|
|
|
|
|
if (0 == rank) {
|
|
|
|
MPI::COMM_WORLD.Recv(&message, 1, MPI::INT, prev, tag);
|
|
|
|
}
|
2015-05-04 17:47:53 +03:00
|
|
|
|
2006-07-14 01:03:36 +04:00
|
|
|
// All done
|
|
|
|
|
|
|
|
MPI::Finalize();
|
|
|
|
return 0;
|
|
|
|
}
|