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);
}
|