1 //
2 // Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
3 // University Research and Technology
4 // Corporation. All rights reserved.
5 // Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
6 //
7 // Simple ring test program in C++.
8 //
9 // NOTE: The MPI C++ bindings were deprecated in MPI-2.2 and removed
10 // from the standard in MPI-3. Open MPI still provides C++ MPI
11 // bindings, but they are no longer built by default (and may be
12 // removed in a future version of Open MPI). You must
13 // --enable-mpi-cxx when configuring Open MPI to enable the MPI C++
14 // bindings.
15 //
16
17 #include "mpi.h"
18 #include <iostream>
19
20 int main(int argc, char *argv[])
21 {
22 int rank, size, next, prev, message, tag = 201;
23
24 // Start up MPI
25
26 MPI::Init();
27 rank = MPI::COMM_WORLD.Get_rank();
28 size = MPI::COMM_WORLD.Get_size();
29
30 // Calculate the rank of the next process in the ring. Use the
31 // modulus operator so that the last process "wraps around" to
32 // rank zero.
33
34 next = (rank + 1) % size;
35 prev = (rank + size - 1) % size;
36
37 // If we are the "master" process (i.e., MPI_COMM_WORLD rank 0),
38 // put the number of times to go around the ring in the message.
39
40 if (0 == rank) {
41 message = 10;
42
43 std::cout << "Process 0 sending " << message << " to " << next
44 << ", tag " << tag << " (" << size << " processes in ring)"
45 << std::endl;
46 MPI::COMM_WORLD.Send(&message, 1, MPI::INT, next, tag);
47 std::cout << "Process 0 sent to " << next << std::endl;
48 }
49
50 // Pass the message around the ring. The exit mechanism works as
51 // follows: the message (a positive integer) is passed around the
52 // ring. Each time it passes rank 0, it is decremented. When
53 // each processes receives a message containing a 0 value, it
54 // passes the message on to the next process and then quits. By
55 // passing the 0 message first, every process gets the 0 message
56 // and can quit normally.
57
58 while (1) {
59 MPI::COMM_WORLD.Recv(&message, 1, MPI::INT, prev, tag);
60
61 if (0 == rank) {
62 --message;
63 std::cout << "Process 0 decremented value: " << message
64 << std::endl;
65 }
66
67 MPI::COMM_WORLD.Send(&message, 1, MPI::INT, next, tag);
68 if (0 == message) {
69 std::cout << "Process " << rank << " exiting" << std::endl;
70 break;
71 }
72 }
73
74 // The last process does one extra send to process 0, which needs
75 // to be received before the program can exit */
76
77 if (0 == rank) {
78 MPI::COMM_WORLD.Recv(&message, 1, MPI::INT, prev, tag);
79 }
80
81 // All done
82
83 MPI::Finalize();
84 return 0;
85 }