File: ring_cxx.cc

package info (click to toggle)
openmpi 3.1.3-11
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 118,572 kB
  • sloc: ansic: 628,972; f90: 17,993; makefile: 13,761; sh: 7,051; java: 6,360; perl: 3,215; cpp: 2,225; python: 1,350; lex: 988; fortran: 52; tcl: 12
file content (85 lines) | stat: -rw-r--r-- 2,770 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//
// 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;
}