|
Packit |
0848f5 |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
* See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This test checks an oddball case for generalized active target
|
|
Packit |
0848f5 |
* synchronization where the start occurs before the post. Since start can
|
|
Packit |
0848f5 |
* block until the corresponding post, the group passed to start must be
|
|
Packit |
0848f5 |
* disjoint from the group passed to post and processes must avoid a circular
|
|
Packit |
0848f5 |
* wait. Here, odd/even groups are used to accomplish this and the even group
|
|
Packit |
0848f5 |
* reverses its start/post calls.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
#include <stdlib.h>
|
|
Packit |
0848f5 |
#include <mpi.h>
|
|
Packit |
0848f5 |
#include "mpitest.h"
|
|
Packit |
0848f5 |
#include "squelch.h"
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int main(int argc, char **argv)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i, rank, nproc, errors = 0;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int *win_buf;
|
|
Packit |
0848f5 |
MPI_Win win;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int odd_nproc, even_nproc;
|
|
Packit |
0848f5 |
int *odd_ranks, *even_ranks;
|
|
Packit |
0848f5 |
MPI_Group odd_group, even_group, world_group;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTest_Init(&argc, &argv);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
|
|
Packit |
0848f5 |
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (nproc < 2) {
|
|
Packit |
0848f5 |
if (rank == 0)
|
|
Packit |
0848f5 |
printf("Error: this test requires two or more processes\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, 100);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Set up odd/even groups and buffers */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
odd_nproc = nproc / 2;
|
|
Packit |
0848f5 |
even_nproc = nproc / 2 + ((nproc % 2 == 0) ? 0 : 1);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
odd_ranks = malloc(sizeof(int) * odd_nproc);
|
|
Packit |
0848f5 |
even_ranks = malloc(sizeof(int) * even_nproc);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i = 0; i < even_nproc; i++)
|
|
Packit |
0848f5 |
even_ranks[i] = i * 2;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i = 0; i < odd_nproc; i++)
|
|
Packit |
0848f5 |
odd_ranks[i] = i * 2 + 1;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_group(MPI_COMM_WORLD, &world_group);
|
|
Packit |
0848f5 |
MPI_Group_incl(world_group, odd_nproc, odd_ranks, &odd_group);
|
|
Packit |
0848f5 |
MPI_Group_incl(world_group, even_nproc, even_ranks, &even_group);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Create the window */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#ifdef USE_WIN_ALLOCATE
|
|
Packit |
0848f5 |
MPI_Win_allocate(nproc * sizeof(int), sizeof(int), MPI_INFO_NULL,
|
|
Packit |
0848f5 |
MPI_COMM_WORLD, &win_buf, &win);
|
|
Packit |
0848f5 |
#else
|
|
Packit |
0848f5 |
MPI_Alloc_mem(nproc * sizeof(int), MPI_INFO_NULL, &win_buf);
|
|
Packit |
0848f5 |
MPI_Win_create(win_buf, nproc * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit |
0848f5 |
for (i = 0; i < nproc; i++)
|
|
Packit |
0848f5 |
win_buf[i] = -1;
|
|
Packit |
0848f5 |
MPI_Win_unlock(rank, win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Perform PSCW communication: Odd/even matchup */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (rank % 2 == 0) {
|
|
Packit |
0848f5 |
MPI_Win_start(odd_group, 0, win); /* Even-numbered procs target odd procs */
|
|
Packit |
0848f5 |
MPI_Win_post(odd_group, 0, win); /* Even procs are targeted by odd procs */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Write to my slot at each target */
|
|
Packit |
0848f5 |
for (i = 0; i < odd_nproc; i++)
|
|
Packit |
0848f5 |
MPI_Put(&rank, 1, MPI_INT, odd_ranks[i], rank, 1, MPI_INT, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
MPI_Win_post(even_group, 0, win); /* Odd procs are targeted by even procs */
|
|
Packit |
0848f5 |
MPI_Win_start(even_group, 0, win); /* Odd-numbered procs target even procs */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Write to my slot at each target */
|
|
Packit |
0848f5 |
for (i = 0; i < even_nproc; i++)
|
|
Packit |
0848f5 |
MPI_Put(&rank, 1, MPI_INT, even_ranks[i], rank, 1, MPI_INT, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Win_complete(win);
|
|
Packit |
0848f5 |
MPI_Win_wait(win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Perform PSCW communication: Odd/odd and even/even matchup */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (rank % 2 == 0) {
|
|
Packit |
0848f5 |
MPI_Win_post(even_group, 0, win); /* Even procs are targeted by even procs */
|
|
Packit |
0848f5 |
MPI_Win_start(even_group, 0, win); /* Even-numbered procs target even procs */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Write to my slot at each target */
|
|
Packit |
0848f5 |
for (i = 0; i < even_nproc; i++)
|
|
Packit |
0848f5 |
MPI_Put(&rank, 1, MPI_INT, even_ranks[i], rank, 1, MPI_INT, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
MPI_Win_post(odd_group, 0, win); /* Odd procs are targeted by odd procs */
|
|
Packit |
0848f5 |
MPI_Win_start(odd_group, 0, win); /* Odd-numbered procs target odd procs */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Write to my slot at each target */
|
|
Packit |
0848f5 |
for (i = 0; i < odd_nproc; i++)
|
|
Packit |
0848f5 |
MPI_Put(&rank, 1, MPI_INT, odd_ranks[i], rank, 1, MPI_INT, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Win_complete(win);
|
|
Packit |
0848f5 |
MPI_Win_wait(win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i = 0; i < nproc; i++) {
|
|
Packit |
0848f5 |
if (win_buf[i] != i) {
|
|
Packit |
0848f5 |
errors++;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
SQUELCH(printf("%d: Error -- win_buf[%d] = %d, expected %d\n", rank, i, win_buf[i], i);
|
|
Packit |
0848f5 |
);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Win_free(&win);
|
|
Packit |
0848f5 |
#ifndef USE_WIN_ALLOCATE
|
|
Packit |
0848f5 |
MPI_Free_mem(win_buf);
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Group_free(&world_group);
|
|
Packit |
0848f5 |
MPI_Group_free(&odd_group);
|
|
Packit |
0848f5 |
MPI_Group_free(&even_group);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
free(odd_ranks);
|
|
Packit |
0848f5 |
free(even_ranks);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTest_Finalize(errors);
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
return MTestReturnValue(errors);
|
|
Packit |
0848f5 |
}
|