File: Ring.c

package info (click to toggle)
mpich 4.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 101,184 kB
  • sloc: ansic: 1,040,629; cpp: 82,270; javascript: 40,763; perl: 27,933; python: 16,041; sh: 14,676; xml: 14,418; f90: 12,916; makefile: 9,270; fortran: 8,046; java: 4,635; asm: 324; ruby: 103; awk: 27; lisp: 19; php: 8; sed: 4
file content (93 lines) | stat: -rw-r--r-- 2,661 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
86
87
88
89
90
91
92
93
#include "mpi.h"
#include "stdio.h"
#include "stdlib.h"

#define LOOP_COUNT 10

void linear(MPI_Comm intracomm, int injectionPoint) {
    int lineRank, lineSize, message;
    MPI_Status status;  // eventually we have to start checking this...
    MPI_Comm intercomm;

    MPI_Comm_rank(intracomm, &lineRank);
    MPI_Comm_size(intracomm, &lineSize);

    MPI_Intercomm_create(intracomm, 0, MPI_COMM_WORLD, injectionPoint, 99, &intercomm);

    if (lineRank == lineSize-1) {
        // Injection point.
        MPI_Recv(&message,  1, MPI_INT, lineRank-1, 1, intracomm, &status);
        MPI_Send(&lineRank, 1, MPI_INT, 0, 2, intercomm);
    } else if (lineRank == 0) {
        // Line entrance.
        MPI_Send(&lineRank, 1, MPI_INT, lineRank+1, 1, intracomm);
    } else {
        // Rest of the line.
        MPI_Recv(&message,  1, MPI_INT, lineRank-1, 1, intracomm, &status);
        MPI_Send(&lineRank, 1, MPI_INT, lineRank+1, 1, intracomm);
    }

    MPI_Comm_free(&intercomm);
}

void loop(MPI_Comm intracomm, int injectionPoint) {
    int i;
    int ringRank, ringSize;
    int origin, dest, message;
    MPI_Status status;  // eventually we have to start checking this...
    MPI_Comm intercomm;

    int buf[10000] = { 10 };

    MPI_Comm_rank(intracomm, &ringRank);
    MPI_Comm_size(intracomm, &ringSize);

    MPI_Intercomm_create(intracomm, 0, MPI_COMM_WORLD, 0, 99, &intercomm);

    if (ringRank == 0) {
        origin = injectionPoint-1;
        MPI_Recv(buf, 10, MPI_INT, origin, 2, intercomm, &status);

        message = ringRank;
        MPI_Send(buf, 10, MPI_INT, (ringRank + 1) % ringSize, 2, intracomm);
    }

    dest = (ringRank + 1) % ringSize;
    origin = (ringRank + ringSize - 1) % ringSize;
    for (i = 0; i < LOOP_COUNT; ++i) {
        MPI_Recv(buf, 10, MPI_INT, origin, 2, intracomm, &status);

        message = ringRank;
        MPI_Send(buf, 10, MPI_INT, dest, 2, intracomm);
    }

    MPI_Comm_free(&intercomm);
}

int main(int argc, char *argv[])
{
    int i, color;
    int rank, nprocs, injectionPoint;
    MPI_Comm intracomm;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    // Divide ranks into injection line & ring.
    injectionPoint = atoi(argv[1]);
    color = (rank < injectionPoint) ? 0 : 1;
    MPI_Comm_split(MPI_COMM_WORLD, color, rank, &intracomm);

    // First send message down the linear path, then inject it into the ring.
    if (rank < injectionPoint) {
        linear(intracomm, injectionPoint);
    } else {
        loop(intracomm, injectionPoint);
    }

    MPI_Comm_free(&intracomm);
    MPI_Finalize();

    return 0;
}