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 }