Blame test/mpi/spawn/disconnect_reconnect.c

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *
Packit 0848f5
 *  (C) 2003 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
#include "mpi.h"
Packit 0848f5
#include "mpitest.h"
Packit 0848f5
#include <stdio.h>
Packit 0848f5
#include <stdlib.h>
Packit 0848f5
#ifdef HAVE_STRINGS_H
Packit 0848f5
#include <strings.h>
Packit 0848f5
#endif
Packit 0848f5
#ifdef HAVE_STRING_H
Packit 0848f5
#include <string.h>
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
Packit 0848f5
Packit 0848f5
/*
Packit 0848f5
static char MTEST_Descrip[] = "A simple test of Comm_connect/accept/disconnect";
Packit 0848f5
*/
Packit 0848f5
Packit 0848f5
int main(int argc, char *argv[])
Packit 0848f5
{
Packit 0848f5
    int errs = 0;
Packit 0848f5
    int rank, size, rsize, i, j, data, num_loops = 100;
Packit 0848f5
    int np = 3;
Packit 0848f5
    MPI_Comm parentcomm, intercomm;
Packit 0848f5
    MPI_Status status;
Packit 0848f5
    char port[MPI_MAX_PORT_NAME] = { 0 };
Packit 0848f5
    int verbose = 0;
Packit 0848f5
    int do_messages = 1;
Packit 0848f5
    char *env;
Packit 0848f5
    int can_spawn;
Packit 0848f5
Packit 0848f5
    env = getenv("MPITEST_VERBOSE");
Packit 0848f5
    if (env) {
Packit 0848f5
        if (*env != '0')
Packit 0848f5
            verbose = 1;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    MTest_Init(&argc, &argv);
Packit 0848f5
Packit 0848f5
    errs += MTestSpawnPossible(&can_spawn);
Packit 0848f5
Packit 0848f5
    if (can_spawn) {
Packit 0848f5
        /* FIXME: Document arguments */
Packit 0848f5
        if (argc > 1) {
Packit 0848f5
            num_loops = atoi(argv[1]);
Packit 0848f5
            if (num_loops < 0)
Packit 0848f5
                num_loops = 0;
Packit 0848f5
            if (num_loops > 100)
Packit 0848f5
                num_loops = 100;
Packit 0848f5
        }
Packit 0848f5
        if (argc > 2) {
Packit 0848f5
            do_messages = atoi(argv[2]);
Packit 0848f5
        }
Packit 0848f5
        MPI_Comm_get_parent(&parentcomm);
Packit 0848f5
Packit 0848f5
        if (parentcomm == MPI_COMM_NULL) {
Packit 0848f5
            MPI_Comm_rank(MPI_COMM_WORLD, &rank;;       /* Get rank for verbose msg */
Packit 0848f5
            IF_VERBOSE(("[%d] spawning %d processes\n", rank, np));
Packit 0848f5
            /* Create 3 more processes */
Packit 0848f5
            MPI_Comm_spawn((char *) "./disconnect_reconnect",
Packit 0848f5
                           /*MPI_ARGV_NULL */ &argv[1], np,
Packit 0848f5
                           MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, MPI_ERRCODES_IGNORE);
Packit 0848f5
        }
Packit 0848f5
        else {
Packit 0848f5
            intercomm = parentcomm;
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        /* We now have a valid intercomm */
Packit 0848f5
Packit 0848f5
        MPI_Comm_remote_size(intercomm, &rsize);
Packit 0848f5
        MPI_Comm_size(intercomm, &size);
Packit 0848f5
        MPI_Comm_rank(intercomm, &rank;;
Packit 0848f5
Packit 0848f5
        if (parentcomm == MPI_COMM_NULL) {
Packit 0848f5
            IF_VERBOSE(("[%d] parent rank %d alive.\n", rank, rank));
Packit 0848f5
            /* Parent */
Packit 0848f5
            if (rsize != np) {
Packit 0848f5
                errs++;
Packit 0848f5
                printf("Did not create %d processes (got %d)\n", np, rsize);
Packit 0848f5
                fflush(stdout);
Packit 0848f5
            }
Packit 0848f5
            if (rank == 0 && num_loops > 0) {
Packit 0848f5
                MPI_Open_port(MPI_INFO_NULL, port);
Packit 0848f5
                IF_VERBOSE(("[%d] port = %s\n", rank, port));
Packit 0848f5
                MPI_Send(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, intercomm);
Packit 0848f5
            }
Packit 0848f5
            IF_VERBOSE(("[%d] disconnecting child communicator\n", rank));
Packit 0848f5
            MPI_Comm_disconnect(&intercomm);
Packit 0848f5
            for (i = 0; i < num_loops; i++) {
Packit 0848f5
                IF_VERBOSE(("[%d] accepting connection\n", rank));
Packit 0848f5
                MPI_Comm_accept(port, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm);
Packit 0848f5
                MPI_Comm_remote_size(intercomm, &rsize);
Packit 0848f5
                if (do_messages && (rank == 0)) {
Packit 0848f5
                    j = 0;
Packit 0848f5
                    for (j = 0; j < rsize; j++) {
Packit 0848f5
                        data = i;
Packit 0848f5
                        IF_VERBOSE(("[%d]sending int to child process %d\n", rank, j));
Packit 0848f5
                        MPI_Send(&data, 1, MPI_INT, j, 100, intercomm);
Packit 0848f5
                        IF_VERBOSE(("[%d] receiving int from child process %d\n", rank, j));
Packit 0848f5
                        data = i - 1;
Packit 0848f5
                        MPI_Recv(&data, 1, MPI_INT, j, 100, intercomm, &status);
Packit 0848f5
                        if (data != i) {
Packit 0848f5
                            errs++;
Packit 0848f5
                        }
Packit 0848f5
                    }
Packit 0848f5
                }
Packit 0848f5
                IF_VERBOSE(("[%d] disconnecting communicator\n", rank));
Packit 0848f5
                MPI_Comm_disconnect(&intercomm);
Packit 0848f5
            }
Packit 0848f5
Packit 0848f5
            /* Errors cannot be sent back to the parent because there is no
Packit 0848f5
             * communicator connected to the children
Packit 0848f5
             * for (i=0; i
Packit 0848f5
             * {
Packit 0848f5
             * MPI_Recv(&err, 1, MPI_INT, i, 1, intercomm, MPI_STATUS_IGNORE);
Packit 0848f5
             * errs += err;
Packit 0848f5
             * }
Packit 0848f5
             */
Packit 0848f5
        }
Packit 0848f5
        else {
Packit 0848f5
            IF_VERBOSE(("[%d] child rank %d alive.\n", rank, rank));
Packit 0848f5
            /* Child */
Packit 0848f5
            if (size != np) {
Packit 0848f5
                errs++;
Packit 0848f5
                printf("(Child) Did not create %d processes (got %d)\n", np, size);
Packit 0848f5
                fflush(stdout);
Packit 0848f5
            }
Packit 0848f5
Packit 0848f5
            if (rank == 0 && num_loops > 0) {
Packit 0848f5
                IF_VERBOSE(("[%d] receiving port\n", rank));
Packit 0848f5
                MPI_Recv(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, intercomm, &status);
Packit 0848f5
            }
Packit 0848f5
Packit 0848f5
            IF_VERBOSE(("[%d] disconnecting communicator\n", rank));
Packit 0848f5
            MPI_Comm_disconnect(&intercomm);
Packit 0848f5
            for (i = 0; i < num_loops; i++) {
Packit 0848f5
                IF_VERBOSE(("[%d] connecting to port (loop %d)\n", rank, i));
Packit 0848f5
                MPI_Comm_connect(port, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm);
Packit 0848f5
                if (do_messages) {
Packit 0848f5
                    IF_VERBOSE(("[%d] receiving int from parent process 0\n", rank));
Packit 0848f5
                    MPI_Recv(&data, 1, MPI_INT, 0, 100, intercomm, &status);
Packit 0848f5
                    if (data != i) {
Packit 0848f5
                        printf("expected %d but received %d\n", i, data);
Packit 0848f5
                        fflush(stdout);
Packit 0848f5
                        MPI_Abort(MPI_COMM_WORLD, 1);
Packit 0848f5
                    }
Packit 0848f5
                    IF_VERBOSE(("[%d] sending int back to parent process 1\n", rank));
Packit 0848f5
                    MPI_Send(&data, 1, MPI_INT, 0, 100, intercomm);
Packit 0848f5
                }
Packit 0848f5
                IF_VERBOSE(("[%d] disconnecting communicator\n", rank));
Packit 0848f5
                MPI_Comm_disconnect(&intercomm);
Packit 0848f5
            }
Packit 0848f5
Packit 0848f5
            /* Send the errs back to the master process */
Packit 0848f5
            /* Errors cannot be sent back to the parent because there is no
Packit 0848f5
             * communicator connected to the parent */
Packit 0848f5
            /*MPI_Ssend(&errs, 1, MPI_INT, 0, 1, intercomm); */
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        /* Note that the MTest_Finalize get errs only over COMM_WORLD */
Packit 0848f5
        /* Note also that both the parent and child will generate "No Errors"
Packit 0848f5
         * if both call MTest_Finalize */
Packit 0848f5
        if (parentcomm == MPI_COMM_NULL) {
Packit 0848f5
            MTest_Finalize(errs);
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
        MTest_Finalize(errs);
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    IF_VERBOSE(("[%d] calling finalize\n", rank));
Packit 0848f5
    MPI_Finalize();
Packit 0848f5
    return 0;
Packit 0848f5
}