|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Exercise communicator routines.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
This C version derived from a Fortran test program from ....
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include "mpi.h"
|
|
Packit Service |
c5cf8c |
#include "mpitest.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* #define DEBUG */
|
|
Packit Service |
c5cf8c |
int test_communicators(void);
|
|
Packit Service |
c5cf8c |
int copy_fn(MPI_Comm, int, void *, void *, void *, int *);
|
|
Packit Service |
c5cf8c |
int delete_fn(MPI_Comm, int, void *, void *);
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
#define FFLUSH fflush(stdout);
|
|
Packit Service |
c5cf8c |
#else
|
|
Packit Service |
c5cf8c |
#define FFLUSH
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int main(int argc, char **argv)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int errs = 0;
|
|
Packit Service |
c5cf8c |
MTest_Init(&argc, &argv);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
errs = test_communicators();
|
|
Packit Service |
c5cf8c |
MTest_Finalize(errs);
|
|
Packit Service |
c5cf8c |
return MTestReturnValue(errs);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int copy_fn(MPI_Comm oldcomm, int keyval, void *extra_state,
|
|
Packit Service |
c5cf8c |
void *attribute_val_in, void *attribute_val_out, int *flag)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* Note that if (sizeof(int) < sizeof(void *), just setting the int
|
|
Packit Service |
c5cf8c |
* part of attribute_val_out may leave some dirty bits
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
*(MPI_Aint *) attribute_val_out = (MPI_Aint) attribute_val_in;
|
|
Packit Service |
c5cf8c |
*flag = 1;
|
|
Packit Service |
c5cf8c |
return MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int delete_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int world_rank;
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
|
|
Packit Service |
c5cf8c |
if ((MPI_Aint) attribute_val != (MPI_Aint) world_rank) {
|
|
Packit Service |
c5cf8c |
printf("incorrect attribute value %d\n", *(int *) attribute_val);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 1005);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int test_communicators(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPI_Comm dup_comm_world, lo_comm, rev_comm, dup_comm, split_comm, world_comm;
|
|
Packit Service |
c5cf8c |
MPI_Group world_group, lo_group, rev_group;
|
|
Packit Service |
c5cf8c |
void *vvalue;
|
|
Packit Service |
c5cf8c |
int ranges[1][3];
|
|
Packit Service |
c5cf8c |
int flag, world_rank, world_size, rank, size, n, key_1, key_3;
|
|
Packit Service |
c5cf8c |
int color, key, result;
|
|
Packit Service |
c5cf8c |
int errs = 0;
|
|
Packit Service |
c5cf8c |
MPI_Aint value;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
if (world_rank == 0) {
|
|
Packit Service |
c5cf8c |
printf("*** Communicators ***\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_dup(MPI_COMM_WORLD, &dup_comm_world);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Exercise Comm_create by creating an equivalent to dup_comm_world
|
|
Packit Service |
c5cf8c |
* (sans attributes) and a half-world communicator.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
if (world_rank == 0) {
|
|
Packit Service |
c5cf8c |
printf(" Comm_create\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_group(dup_comm_world, &world_group);
|
|
Packit Service |
c5cf8c |
MPI_Comm_create(dup_comm_world, world_group, &world_comm);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(world_comm, &rank;;
|
|
Packit Service |
c5cf8c |
if (rank != world_rank) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect rank in world comm: %d\n", rank);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3001);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
n = world_size / 2;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
ranges[0][0] = 0;
|
|
Packit Service |
c5cf8c |
ranges[0][1] = (world_size - n) - 1;
|
|
Packit Service |
c5cf8c |
ranges[0][2] = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("world rank = %d before range incl\n", world_rank);
|
|
Packit Service |
c5cf8c |
FFLUSH;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
MPI_Group_range_incl(world_group, 1, ranges, &lo_group);
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("world rank = %d after range incl\n", world_rank);
|
|
Packit Service |
c5cf8c |
FFLUSH;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
MPI_Comm_create(world_comm, lo_group, &lo_comm);
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("world rank = %d before group free\n", world_rank);
|
|
Packit Service |
c5cf8c |
FFLUSH;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
MPI_Group_free(&lo_group);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("world rank = %d after group free\n", world_rank);
|
|
Packit Service |
c5cf8c |
FFLUSH;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (world_rank < (world_size - n)) {
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(lo_comm, &rank;;
|
|
Packit Service |
c5cf8c |
if (rank == MPI_UNDEFINED) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect lo group rank: %d\n", rank);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3002);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* printf("lo in\n");FFLUSH; */
|
|
Packit Service |
c5cf8c |
MPI_Barrier(lo_comm);
|
|
Packit Service |
c5cf8c |
/* printf("lo out\n");FFLUSH; */
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (lo_comm != MPI_COMM_NULL) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect lo comm:\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3003);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("worldrank = %d\n", world_rank);
|
|
Packit Service |
c5cf8c |
FFLUSH;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
MPI_Barrier(world_comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
printf("bar!\n");
|
|
Packit Service |
c5cf8c |
FFLUSH;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Check Comm_dup by adding attributes to lo_comm & duplicating
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
if (world_rank == 0) {
|
|
Packit Service |
c5cf8c |
printf(" Comm_dup\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (lo_comm != MPI_COMM_NULL) {
|
|
Packit Service |
c5cf8c |
value = 9;
|
|
Packit Service |
c5cf8c |
MPI_Keyval_create(copy_fn, delete_fn, &key_1, &value);
|
|
Packit Service |
c5cf8c |
value = 8;
|
|
Packit Service |
c5cf8c |
value = 7;
|
|
Packit Service |
c5cf8c |
MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key_3, &value);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This may generate a compilation warning; it is, however, an
|
|
Packit Service |
c5cf8c |
* easy way to cache a value instead of a pointer */
|
|
Packit Service |
c5cf8c |
/* printf("key1 = %x key3 = %x\n", key_1, key_3); */
|
|
Packit Service |
c5cf8c |
MPI_Attr_put(lo_comm, key_1, (void *) (MPI_Aint) world_rank);
|
|
Packit Service |
c5cf8c |
MPI_Attr_put(lo_comm, key_3, (void *) 0);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_dup(lo_comm, &dup_comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Note that if sizeof(int) < sizeof(void *), we can't use
|
|
Packit Service |
c5cf8c |
* (void **)&value to get the value we passed into Attr_put. To avoid
|
|
Packit Service |
c5cf8c |
* problems (e.g., alignment errors), we recover the value into
|
|
Packit Service |
c5cf8c |
* a (void *) and cast to int. Note that this may generate warning
|
|
Packit Service |
c5cf8c |
* messages from the compiler. */
|
|
Packit Service |
c5cf8c |
MPI_Attr_get(dup_comm, key_1, (void **) &vvalue, &flag;;
|
|
Packit Service |
c5cf8c |
value = (MPI_Aint) vvalue;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!flag) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("dup_comm key_1 not found on %d\n", world_rank);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3004);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (value != world_rank) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("dup_comm key_1 value incorrect: %ld, expected %d\n", (long) value, world_rank);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3005);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Attr_get(dup_comm, key_3, (void **) &vvalue, &flag;;
|
|
Packit Service |
c5cf8c |
value = (MPI_Aint) vvalue;
|
|
Packit Service |
c5cf8c |
if (flag) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("dup_comm key_3 found!\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3008);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Keyval_free(&key_1);
|
|
Packit Service |
c5cf8c |
MPI_Keyval_free(&key_3);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Split the world into even & odd communicators with reversed ranks.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
if (world_rank == 0) {
|
|
Packit Service |
c5cf8c |
printf(" Comm_split\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
color = world_rank % 2;
|
|
Packit Service |
c5cf8c |
key = world_size - world_rank;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_split(dup_comm_world, color, key, &split_comm);
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(split_comm, &size);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(split_comm, &rank;;
|
|
Packit Service |
c5cf8c |
if (rank != ((size - world_rank / 2) - 1)) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect split rank: %d\n", rank);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3009);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(split_comm);
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Test each possible Comm_compare result
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
if (world_rank == 0) {
|
|
Packit Service |
c5cf8c |
printf(" Comm_compare\n");
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_compare(world_comm, world_comm, &result);
|
|
Packit Service |
c5cf8c |
if (result != MPI_IDENT) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect ident result: %d\n", result);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3010);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (lo_comm != MPI_COMM_NULL) {
|
|
Packit Service |
c5cf8c |
MPI_Comm_compare(lo_comm, dup_comm, &result);
|
|
Packit Service |
c5cf8c |
if (result != MPI_CONGRUENT) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect congruent result: %d\n", result);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3011);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
ranges[0][0] = world_size - 1;
|
|
Packit Service |
c5cf8c |
ranges[0][1] = 0;
|
|
Packit Service |
c5cf8c |
ranges[0][2] = -1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Group_range_incl(world_group, 1, ranges, &rev_group);
|
|
Packit Service |
c5cf8c |
MPI_Comm_create(world_comm, rev_group, &rev_comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_compare(world_comm, rev_comm, &result);
|
|
Packit Service |
c5cf8c |
if (result != MPI_SIMILAR && world_size != 1) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect similar result: %d\n", result);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3012);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (lo_comm != MPI_COMM_NULL) {
|
|
Packit Service |
c5cf8c |
MPI_Comm_compare(world_comm, lo_comm, &result);
|
|
Packit Service |
c5cf8c |
if (result != MPI_UNEQUAL && world_size != 1) {
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
printf("incorrect unequal result: %d\n", result);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 3013);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Free all communicators created
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#ifdef DEBUG
|
|
Packit Service |
c5cf8c |
if (world_rank == 0)
|
|
Packit Service |
c5cf8c |
printf(" Comm_free\n");
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&world_comm);
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&dup_comm_world);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&rev_comm);
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&split_comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Group_free(&world_group);
|
|
Packit Service |
c5cf8c |
MPI_Group_free(&rev_group);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (lo_comm != MPI_COMM_NULL) {
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&lo_comm);
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&dup_comm);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return errs;
|
|
Packit Service |
c5cf8c |
}
|