Skip to content
Snippets Groups Projects
ring_cxx.cc 2.71 KiB
Newer Older
  • Learn to ignore specific revisions
  • Lukáš Krupčík's avatar
    Lukáš Krupčík committed
    //
    // 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.
    //
    // Simple ring test program in C++.
    //
    // 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.
    //
    
    #include "mpi.h"
    #include <iostream>
    
    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();
    
        // 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;
                std::cout << "Process 0 decremented value: " << message
                          << 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);
        }
    
        // All done
    
        MPI::Finalize();
        return 0;
    }