Blame test/mpi/comm/icsplit.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *  (C) 2007 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
#include "mpi.h"
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include "mpitest.h"
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * This program tests that MPI_Comm_split applies to intercommunicators;
Packit Service c5cf8c
 * this is an extension added in MPI-2
Packit Service c5cf8c
 */
Packit Service c5cf8c
int main(int argc, char *argv[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int errs = 0;
Packit Service c5cf8c
    int size, isLeft;
Packit Service c5cf8c
    MPI_Comm intercomm, newcomm;
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Init(&argc, &argv);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &size);
Packit Service c5cf8c
    if (size < 4) {
Packit Service c5cf8c
        printf("This test requires at least 4 processes\n");
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    while (MTestGetIntercomm(&intercomm, &isLeft, 2)) {
Packit Service c5cf8c
        int key, color;
Packit Service c5cf8c
Packit Service c5cf8c
        if (intercomm == MPI_COMM_NULL)
Packit Service c5cf8c
            continue;
Packit Service c5cf8c
Packit Service c5cf8c
        /* Split this intercomm.  The new intercomms contain the
Packit Service c5cf8c
         * processes that had odd (resp even) rank in their local group
Packit Service c5cf8c
         * in the original intercomm */
Packit Service c5cf8c
        MTestPrintfMsg(1, "Created intercomm %s\n", MTestGetIntercommName());
Packit Service c5cf8c
        MPI_Comm_rank(intercomm, &key);
Packit Service c5cf8c
        color = (key % 2);
Packit Service c5cf8c
        MPI_Comm_split(intercomm, color, key, &newcomm);
Packit Service c5cf8c
        /* Make sure that the new communicator has the appropriate pieces */
Packit Service c5cf8c
        if (newcomm != MPI_COMM_NULL) {
Packit Service c5cf8c
            int orig_rsize, orig_size, new_rsize, new_size;
Packit Service c5cf8c
            int predicted_size, flag, commok = 1;
Packit Service c5cf8c
Packit Service c5cf8c
            MPI_Comm_test_inter(intercomm, &flag;;
Packit Service c5cf8c
            if (!flag) {
Packit Service c5cf8c
                errs++;
Packit Service c5cf8c
                printf("Output communicator is not an intercomm\n");
Packit Service c5cf8c
                commok = 0;
Packit Service c5cf8c
            }
Packit Service c5cf8c
Packit Service c5cf8c
            MPI_Comm_remote_size(intercomm, &orig_rsize);
Packit Service c5cf8c
            MPI_Comm_remote_size(newcomm, &new_rsize);
Packit Service c5cf8c
            MPI_Comm_size(intercomm, &orig_size);
Packit Service c5cf8c
            MPI_Comm_size(newcomm, &new_size);
Packit Service c5cf8c
            /* The local size is 1/2 the original size, +1 if the
Packit Service c5cf8c
             * size was odd and the color was even.  More precisely,
Packit Service c5cf8c
             * let n be the orig_size.  Then
Packit Service c5cf8c
             * color 0     color 1
Packit Service c5cf8c
             * orig size even    n/2         n/2
Packit Service c5cf8c
             * orig size odd     (n+1)/2     n/2
Packit Service c5cf8c
             *
Packit Service c5cf8c
             * However, since these are integer valued, if n is even,
Packit Service c5cf8c
             * then (n+1)/2 = n/2, so this table is much simpler:
Packit Service c5cf8c
             * color 0     color 1
Packit Service c5cf8c
             * orig size even    (n+1)/2     n/2
Packit Service c5cf8c
             * orig size odd     (n+1)/2     n/2
Packit Service c5cf8c
             *
Packit Service c5cf8c
             */
Packit Service c5cf8c
            predicted_size = (orig_size + !color) / 2;
Packit Service c5cf8c
            if (predicted_size != new_size) {
Packit Service c5cf8c
                errs++;
Packit Service c5cf8c
                printf("Predicted size = %d but found %d for %s (%d,%d)\n",
Packit Service c5cf8c
                       predicted_size, new_size, MTestGetIntercommName(), orig_size, orig_rsize);
Packit Service c5cf8c
                commok = 0;
Packit Service c5cf8c
            }
Packit Service c5cf8c
            predicted_size = (orig_rsize + !color) / 2;
Packit Service c5cf8c
            if (predicted_size != new_rsize) {
Packit Service c5cf8c
                errs++;
Packit Service c5cf8c
                printf("Predicted remote size = %d but found %d for %s (%d,%d)\n",
Packit Service c5cf8c
                       predicted_size, new_rsize, MTestGetIntercommName(), orig_size, orig_rsize);
Packit Service c5cf8c
                commok = 0;
Packit Service c5cf8c
            }
Packit Service c5cf8c
            /* ... more to do */
Packit Service c5cf8c
            if (commok) {
Packit Service c5cf8c
                errs += MTestTestComm(newcomm);
Packit Service c5cf8c
            }
Packit Service c5cf8c
        } else {
Packit Service c5cf8c
            int orig_rsize;
Packit Service c5cf8c
            /* If the newcomm is null, then this means that remote group
Packit Service c5cf8c
             * for this color is of size zero (since all processes in this
Packit Service c5cf8c
             * test have been given colors other than MPI_UNDEFINED).
Packit Service c5cf8c
             * Confirm that here */
Packit Service c5cf8c
            /* FIXME: ToDo */
Packit Service c5cf8c
            MPI_Comm_remote_size(intercomm, &orig_rsize);
Packit Service c5cf8c
            if (orig_rsize == 1) {
Packit Service c5cf8c
                if (color == 0) {
Packit Service c5cf8c
                    errs++;
Packit Service c5cf8c
                    printf("Returned null intercomm when non-null expected\n");
Packit Service c5cf8c
                }
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
        if (newcomm != MPI_COMM_NULL)
Packit Service c5cf8c
            MPI_Comm_free(&newcomm);
Packit Service c5cf8c
        MPI_Comm_free(&intercomm);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    MTest_Finalize(errs);
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
    return MTestReturnValue(errs);
Packit Service c5cf8c
}