File: pscw_ordering.c

package info (click to toggle)
mpich 4.0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 423,384 kB
  • sloc: ansic: 1,088,434; cpp: 71,364; javascript: 40,763; f90: 22,829; sh: 17,463; perl: 14,773; xml: 14,418; python: 10,265; makefile: 9,246; fortran: 8,008; java: 4,355; asm: 324; ruby: 176; lisp: 19; php: 8; sed: 4
file content (141 lines) | stat: -rw-r--r-- 4,376 bytes parent folder | download | duplicates (4)
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

/* This test checks an oddball case for generalized active target
 * synchronization where the start occurs before the post.  Since start can
 * block until the corresponding post, the group passed to start must be
 * disjoint from the group passed to post and processes must avoid a circular
 * wait.  Here, odd/even groups are used to accomplish this and the even group
 * reverses its start/post calls.
 */

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "mpitest.h"
#include "squelch.h"

int main(int argc, char **argv)
{
    int i, rank, nproc, errors = 0;

    int *win_buf;
    MPI_Win win;

    int odd_nproc, even_nproc;
    int *odd_ranks, *even_ranks;
    MPI_Group odd_group, even_group, world_group;

    MTest_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);

    if (nproc < 2) {
        if (rank == 0)
            printf("Error: this test requires two or more processes\n");
        MPI_Abort(MPI_COMM_WORLD, 100);
    }

    /* Set up odd/even groups and buffers */

    odd_nproc = nproc / 2;
    even_nproc = nproc / 2 + ((nproc % 2 == 0) ? 0 : 1);

    odd_ranks = malloc(sizeof(int) * odd_nproc);
    even_ranks = malloc(sizeof(int) * even_nproc);

    for (i = 0; i < even_nproc; i++)
        even_ranks[i] = i * 2;

    for (i = 0; i < odd_nproc; i++)
        odd_ranks[i] = i * 2 + 1;

    MPI_Comm_group(MPI_COMM_WORLD, &world_group);
    MPI_Group_incl(world_group, odd_nproc, odd_ranks, &odd_group);
    MPI_Group_incl(world_group, even_nproc, even_ranks, &even_group);

    /* Create the window */

#ifdef USE_WIN_ALLOCATE
    MPI_Win_allocate(nproc * sizeof(int), sizeof(int), MPI_INFO_NULL,
                     MPI_COMM_WORLD, &win_buf, &win);
#else
    MPI_Alloc_mem(nproc * sizeof(int), MPI_INFO_NULL, &win_buf);
    MPI_Win_create(win_buf, nproc * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
#endif
    MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
    for (i = 0; i < nproc; i++)
        win_buf[i] = -1;
    MPI_Win_unlock(rank, win);

    /* Perform PSCW communication: Odd/even matchup */

    if (rank % 2 == 0) {
        MPI_Win_start(odd_group, 0, win);       /* Even-numbered procs target odd procs */
        MPI_Win_post(odd_group, 0, win);        /* Even procs are targeted by odd procs */

        /* Write to my slot at each target */
        for (i = 0; i < odd_nproc; i++)
            MPI_Put(&rank, 1, MPI_INT, odd_ranks[i], rank, 1, MPI_INT, win);
    } else {
        MPI_Win_post(even_group, 0, win);       /* Odd procs are targeted by even procs */
        MPI_Win_start(even_group, 0, win);      /* Odd-numbered procs target even procs */

        /* Write to my slot at each target */
        for (i = 0; i < even_nproc; i++)
            MPI_Put(&rank, 1, MPI_INT, even_ranks[i], rank, 1, MPI_INT, win);
    }


    MPI_Win_complete(win);
    MPI_Win_wait(win);

    /* Perform PSCW communication: Odd/odd and even/even matchup */

    if (rank % 2 == 0) {
        MPI_Win_post(even_group, 0, win);       /* Even procs are targeted by even procs */
        MPI_Win_start(even_group, 0, win);      /* Even-numbered procs target even procs */

        /* Write to my slot at each target */
        for (i = 0; i < even_nproc; i++)
            MPI_Put(&rank, 1, MPI_INT, even_ranks[i], rank, 1, MPI_INT, win);
    } else {
        MPI_Win_post(odd_group, 0, win);        /* Odd procs are targeted by odd procs */
        MPI_Win_start(odd_group, 0, win);       /* Odd-numbered procs target odd procs */

        /* Write to my slot at each target */
        for (i = 0; i < odd_nproc; i++)
            MPI_Put(&rank, 1, MPI_INT, odd_ranks[i], rank, 1, MPI_INT, win);
    }


    MPI_Win_complete(win);
    MPI_Win_wait(win);

    for (i = 0; i < nproc; i++) {
        if (win_buf[i] != i) {
            errors++;

            SQUELCH(printf("%d: Error -- win_buf[%d] = %d, expected %d\n", rank, i, win_buf[i], i);
);
        }
    }

    MPI_Win_free(&win);
#ifndef USE_WIN_ALLOCATE
    MPI_Free_mem(win_buf);
#endif

    MPI_Group_free(&world_group);
    MPI_Group_free(&odd_group);
    MPI_Group_free(&even_group);

    free(odd_ranks);
    free(even_ranks);

    MTest_Finalize(errors);
    return MTestReturnValue(errors);
}