Beispiel #1
1
int main( int argc, char *argv[] )
{
    int errs = 0;
    int wrank, wsize, mrank, msize, inter_rank;
    int np = 2;
    int errcodes[2];
    int rrank = -1;
    MPI_Comm      parentcomm, intercomm, intercomm2, even_odd_comm, merged_world;
    int can_spawn;

    MTest_Init( &argc, &argv );

    errs += MTestSpawnPossible(&can_spawn);

    if (can_spawn) {
        MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
        MPI_Comm_size( MPI_COMM_WORLD, &wsize );

        if (wsize != 2) {
            printf( "world size != 2, this test will not work correctly\n" );
            errs++;
        }

        MPI_Comm_get_parent( &parentcomm );

        if (parentcomm == MPI_COMM_NULL) {
            MPI_Comm_spawn( (char*)"./spaiccreate2", MPI_ARGV_NULL, np,
                    MPI_INFO_NULL, 0, MPI_COMM_WORLD,
                    &intercomm, errcodes );
        }
        else {
            intercomm = parentcomm;
        }

        MPI_Intercomm_merge( intercomm, (parentcomm == MPI_COMM_NULL ? 0 : 1), &merged_world );
        MPI_Comm_rank( merged_world, &mrank );
        MPI_Comm_size( merged_world, &msize );

        MPI_Comm_split( merged_world, mrank % 2, wrank, &even_odd_comm );

        MPI_Intercomm_create( even_odd_comm, 0, merged_world, (mrank + 1) % 2, 123, &intercomm2 );
        MPI_Comm_rank( intercomm2, &inter_rank );

        /* odds receive from evens */
        MPI_Sendrecv( &inter_rank, 1, MPI_INT, inter_rank, 456,
                &rrank, 1, MPI_INT, inter_rank, 456, intercomm2, MPI_STATUS_IGNORE );
        if (rrank != inter_rank) {
            printf( "Received %d from %d; expected %d\n",
                    rrank, inter_rank, inter_rank );
            errs++;
        }

        MPI_Barrier( intercomm2 );

        MPI_Comm_free( &intercomm );
        MPI_Comm_free( &intercomm2 );
        MPI_Comm_free( &merged_world );
        MPI_Comm_free( &even_odd_comm );

        /* Note that the MTest_Finalize get errs only over COMM_WORLD */
        /* Note also that both the parent and child will generate "No Errors"
           if both call MTest_Finalize */
        if (parentcomm == MPI_COMM_NULL) {
            MTest_Finalize( errs );
        }
    } else {
        MTest_Finalize( errs );
    }

    MPI_Finalize();
    return 0;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    int errs = 0;
    int rank, size, rsize;
    int np = 3;
    MPI_Comm parentcomm, intercomm;
    int verbose = 0;
    char *env;
    int can_spawn;

    env = getenv("MPITEST_VERBOSE");
    if (env) {
        if (*env != '0')
            verbose = 1;
    }

    MTest_Init(&argc, &argv);

    errs += MTestSpawnPossible(&can_spawn);

    if (can_spawn) {
        MPI_Comm_get_parent(&parentcomm);

        if (parentcomm == MPI_COMM_NULL) {
            IF_VERBOSE(("spawning %d processes\n", np));
            /* Create 3 more processes */
            MPI_Comm_spawn((char *) "./disconnect", MPI_ARGV_NULL, np,
                           MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, MPI_ERRCODES_IGNORE);
        } else {
            intercomm = parentcomm;
        }

        /* We now have a valid intercomm */

        MPI_Comm_remote_size(intercomm, &rsize);
        MPI_Comm_size(intercomm, &size);
        MPI_Comm_rank(intercomm, &rank);

        if (parentcomm == MPI_COMM_NULL) {
            IF_VERBOSE(("parent rank %d alive.\n", rank));
            /* Parent */
            if (rsize != np) {
                errs++;
                printf("Did not create %d processes (got %d)\n", np, rsize);
                fflush(stdout);
            }
            IF_VERBOSE(("disconnecting child communicator\n"));
            MPI_Comm_disconnect(&intercomm);

            /* Errors cannot be sent back to the parent because there is no
             * communicator connected to the children
             * for (i=0; i<rsize; i++)
             * {
             * MPI_Recv(&err, 1, MPI_INT, i, 1, intercomm, MPI_STATUS_IGNORE);
             * errs += err;
             * }
             */
        } else {
            IF_VERBOSE(("child rank %d alive.\n", rank));
            /* Child */
            if (size != np) {
                errs++;
                printf("(Child) Did not create %d processes (got %d)\n", np, size);
                fflush(stdout);
            }

            IF_VERBOSE(("disconnecting communicator\n"));
            MPI_Comm_disconnect(&intercomm);

            /* Send the errs back to the master process */
            /* Errors cannot be sent back to the parent because there is no
             * communicator connected to the parent */
            /*MPI_Ssend(&errs, 1, MPI_INT, 0, 1, intercomm); */
        }

        /* Note that the MTest_Finalize get errs only over COMM_WORLD */
        /* Note also that both the parent and child will generate "No Errors"
         * if both call MTest_Finalize */
        if (parentcomm == MPI_COMM_NULL) {
            MTest_Finalize(errs);
        } else {
            MPI_Finalize();
        }
    } else {
        MTest_Finalize(errs);
    }

    IF_VERBOSE(("calling finalize\n"));
    return MTestReturnValue(errs);
}
Beispiel #3
0
int main(int argc, char *argv[])
{
    int error;
    int rank, size, i;
    char *argv1[2] = { (char*)"connector", NULL };
    char *argv2[2] = { (char*)"acceptor", NULL };
    MPI_Comm comm_connector, comm_acceptor, comm_parent, comm;
    char port[MPI_MAX_PORT_NAME];
    MPI_Status status;
    MPI_Info spawn_path = MPI_INFO_NULL;
    int verbose = 0;
    int can_spawn, errs = 0;

    if (getenv("MPITEST_VERBOSE"))
    {
	verbose = 1;
    }

    IF_VERBOSE(("init.\n"));
    error = MPI_Init(&argc, &argv);
    check_error(error, "MPI_Init");

    errs += MTestSpawnPossible(&can_spawn);
    if (!can_spawn) {
        if (errs)
            printf( " Found %d errors\n", errs );
        else
            printf( " No Errors\n" );
        fflush( stdout );
    } else {
        IF_VERBOSE(("size.\n"));
        error = MPI_Comm_size(MPI_COMM_WORLD, &size);
        check_error(error, "MPI_Comm_size");

        IF_VERBOSE(("rank.\n"));
        error = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        check_error(error, "MPI_Comm_rank");

        if (argc == 1)
        {
            /* Make sure that the current directory is in the path.
               Not all implementations may honor or understand this, but
               it is highly recommended as it gives users a clean way
               to specify the location of the executable without
               specifying a particular directory format (e.g., this
               should work with both Windows and Unix implementations) */
            MPI_Info_create( &spawn_path );
            MPI_Info_set( spawn_path, (char*)"path", (char*)"." );

            IF_VERBOSE(("spawn connector.\n"));
            error = MPI_Comm_spawn((char*)"spaconacc2", argv1, 1, spawn_path, 0,
                    MPI_COMM_SELF, &comm_connector,
                    MPI_ERRCODES_IGNORE);
            check_error(error, "MPI_Comm_spawn");

            IF_VERBOSE(("spawn acceptor.\n"));
            error = MPI_Comm_spawn((char*)"spaconacc2", argv2, 1, spawn_path, 0,
                    MPI_COMM_SELF, &comm_acceptor,
                    MPI_ERRCODES_IGNORE);
            check_error(error, "MPI_Comm_spawn");
            MPI_Info_free( &spawn_path );

            IF_VERBOSE(("recv port.\n"));
            error = MPI_Recv(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0,
                    comm_acceptor, &status);
            check_error(error, "MPI_Recv");

            IF_VERBOSE(("send port.\n"));
            error = MPI_Send(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0,
                    comm_connector);
            check_error(error, "MPI_Send");

            IF_VERBOSE(("barrier acceptor.\n"));
            error = MPI_Barrier(comm_acceptor);
            check_error(error, "MPI_Barrier");

            IF_VERBOSE(("barrier connector.\n"));
            error = MPI_Barrier(comm_connector);
            check_error(error, "MPI_Barrier");

            error = MPI_Comm_free(&comm_acceptor);
            check_error(error, "MPI_Comm_free");
            error = MPI_Comm_free(&comm_connector);
            check_error(error, "MPI_Comm_free");

            printf(" No Errors\n");
        }
        else if ((argc == 2) && (strcmp(argv[1], "acceptor") == 0))
        {
            IF_VERBOSE(("get_parent.\n"));
            error = MPI_Comm_get_parent(&comm_parent);
            check_error(error, "MPI_Comm_get_parent");
            if (comm_parent == MPI_COMM_NULL)
            {
                printf("acceptor's parent is NULL.\n");fflush(stdout);
                MPI_Abort(MPI_COMM_WORLD, -1);
            }
            IF_VERBOSE(("open_port.\n"));
            error = MPI_Open_port(MPI_INFO_NULL, port);
            check_error(error, "MPI_Open_port");

            IF_VERBOSE(("0: opened port: <%s>\n", port));
            IF_VERBOSE(("send.\n"));
            error = MPI_Send(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, comm_parent);
            check_error(error, "MPI_Send");

            IF_VERBOSE(("accept.\n"));
            error = MPI_Comm_accept(port, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm);
            check_error(error, "MPI_Comm_accept");

            IF_VERBOSE(("close_port.\n"));
            error = MPI_Close_port(port);
            check_error(error, "MPI_Close_port");

            /* Send some data before disconnecting */
            IF_VERBOSE(("sending int.\n"));
            i = 123;
            error = MPI_Send(&i, 1, MPI_INT, 0, 0, comm);
            check_error(error, "MPI_Send");

            IF_VERBOSE(("disconnect.\n"));
            error = MPI_Comm_disconnect(&comm);
            check_error(error, "MPI_Comm_disconnect");

            IF_VERBOSE(("barrier.\n"));
            error = MPI_Barrier(comm_parent);
            check_error(error, "MPI_Barrier");

            MPI_Comm_free( &comm_parent );
        }
        else if ((argc == 2) && (strcmp(argv[1], "connector") == 0))
        {
            IF_VERBOSE(("get_parent.\n"));
            error = MPI_Comm_get_parent(&comm_parent);
            check_error(error, "MPI_Comm_get_parent");
            if (comm_parent == MPI_COMM_NULL)
            {
                printf("acceptor's parent is NULL.\n");fflush(stdout);
                MPI_Abort(MPI_COMM_WORLD, -1);
            }

            IF_VERBOSE(("recv.\n"));
            error = MPI_Recv(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0,
                    comm_parent, &status);
            check_error(error, "MPI_Recv");

            IF_VERBOSE(("1: received port: <%s>\n", port));
            IF_VERBOSE(("connect.\n"));
            error = MPI_Comm_connect(port, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm);
            check_error(error, "MPI_Comm_connect");

            /* Receive some data before disconnecting */
            IF_VERBOSE(("receiving int\n"));
            i = -1;
            error = MPI_Recv(&i, 1, MPI_INT, 0, 0, comm, &status);
            check_error(error, "MPI_Recv");
            if (i != 123)
            {
                printf("expected 123 but received %d\n", i);
                fflush(stdout);
                MPI_Abort(MPI_COMM_WORLD, 1);
            }

            IF_VERBOSE(("disconnect.\n"));
            error = MPI_Comm_disconnect(&comm);
            check_error(error, "MPI_Comm_disconnect");

            IF_VERBOSE(("barrier.\n"));
            error = MPI_Barrier(comm_parent);
            check_error(error, "MPI_Barrier");

            MPI_Comm_free( &comm_parent );
        }
        else
        {
            printf("invalid command line.\n");fflush(stdout);
            {
                int ii;
                for (ii=0; ii<argc; ii++)
                {
                    printf("argv[%d] = <%s>\n", ii, argv[ii]);
                }
            }
            fflush(stdout);
            MPI_Abort(MPI_COMM_WORLD, -2);
        }
    }

    MPI_Finalize();
    return 0;
}
Beispiel #4
0
int main(int argc, char *argv[])
{
    int errs = 0;
    int child_errs = 0;
    int size, rsize, i, num_spawns = 0;
    char description[100];
    char child_spawns[10];
    char *argv1[3] = { child_spawns, description, NULL };
    MPI_Comm parentcomm, intercomm[MAX_NUM_SPAWNS];
    MPI_Status status;
    int verbose = 0;
    char *env;
    int can_spawn;

    env = getenv("MPITEST_VERBOSE");
    if (env) {
        if (*env != '0')
            verbose = 1;
    }

    MTest_Init(&argc, &argv);

    errs += MTestSpawnPossible(&can_spawn);

    if (can_spawn) {
        /* Set the num_spawns for the first process to MAX_NUM_SPAWNS */
        MPI_Comm_get_parent(&parentcomm);
        if (parentcomm == MPI_COMM_NULL) {
            num_spawns = MAX_NUM_SPAWNS;
        }

        /* If an argument is passed in use it for num_spawns */
        /* This is the case for all spawned processes and optionally the first
         * process as well */
        if (argc > 1) {
            num_spawns = atoi(argv[1]);
            if (num_spawns < 0)
                num_spawns = 0;
            if (num_spawns > MAX_NUM_SPAWNS)
                num_spawns = MAX_NUM_SPAWNS;
        }

        /* Send num_spawns - 1 on the command line to the spawned children */
        sprintf(child_spawns, "%d", num_spawns - 1 > 0 ? num_spawns - 1 : 0);

        /* Spawn the children */
        IF_VERBOSE(("spawning %d\n", num_spawns));
        for (i = 0; i < num_spawns; i++) {
            if (argc > 2) {
                sprintf(description, "%s:%d", argv[2], i);
            } else {
                sprintf(description, "%d", i);
            }
            IF_VERBOSE(("spawning %s\n", description));
            MPI_Comm_spawn((char *) "./concurrent_spawns", argv1, 1,
                           MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm[i], MPI_ERRCODES_IGNORE);

            MPI_Comm_remote_size(intercomm[i], &rsize);
            MPI_Comm_size(intercomm[i], &size);
            if (rsize != 1) {
                errs++;
                printf("Did not create 1 process (got %d)\n", rsize);
                fflush(stdout);
            }
        }

        /* Receive the error count from each of your children and add it to your
         * error count */
        for (i = 0; i < num_spawns; i++) {
            MPI_Recv(&child_errs, 1, MPI_INT, 0, 0, intercomm[i], &status);
            errs += child_errs;
            MPI_Comm_disconnect(&intercomm[i]);
        }

        /* If you are a spawned process send your errors to your parent */
        if (parentcomm != MPI_COMM_NULL) {
            MPI_Send(&errs, 1, MPI_INT, 0, 0, parentcomm);
            MPI_Comm_disconnect(&parentcomm);
            MPI_Finalize();
        } else {
            /* Note that the MTest_Finalize get errs only over COMM_WORLD */
            /* Note also that both the parent and child will generate "No Errors"
             * if both call MTest_Finalize */
            MTest_Finalize(errs);
        }
    } else {
        MTest_Finalize(errs);
    }

    IF_VERBOSE(("calling finalize\n"));
    return MTestReturnValue(errs);
}
Beispiel #5
0
int main(int argc, char *argv[])
{
    int errs = 0;
    int rank, size, rsize, i, j, data, num_loops = 100;
    int np = 3;
    MPI_Comm parentcomm, intercomm;
    MPI_Status status;
    char port[MPI_MAX_PORT_NAME] = { 0 };
    int verbose = 0;
    int do_messages = 1;
    char *env;
    int can_spawn;

    env = getenv("MPITEST_VERBOSE");
    if (env) {
        if (*env != '0')
            verbose = 1;
    }

    MTest_Init(&argc, &argv);

    errs += MTestSpawnPossible(&can_spawn);

    if (can_spawn) {
        /* FIXME: Document arguments */
        if (argc > 1) {
            num_loops = atoi(argv[1]);
            if (num_loops < 0)
                num_loops = 0;
            if (num_loops > 100)
                num_loops = 100;
        }
        if (argc > 2) {
            do_messages = atoi(argv[2]);
        }
        MPI_Comm_get_parent(&parentcomm);

        if (parentcomm == MPI_COMM_NULL) {
            MPI_Comm_rank(MPI_COMM_WORLD, &rank);       /* Get rank for verbose msg */
            IF_VERBOSE(("[%d] spawning %d processes\n", rank, np));
            /* Create 3 more processes */
            MPI_Comm_spawn((char *) "./disconnect_reconnect",
                           /*MPI_ARGV_NULL */ &argv[1], np,
                           MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, MPI_ERRCODES_IGNORE);
        }
        else {
            intercomm = parentcomm;
        }

        /* We now have a valid intercomm */

        MPI_Comm_remote_size(intercomm, &rsize);
        MPI_Comm_size(intercomm, &size);
        MPI_Comm_rank(intercomm, &rank);

        if (parentcomm == MPI_COMM_NULL) {
            IF_VERBOSE(("[%d] parent rank %d alive.\n", rank, rank));
            /* Parent */
            if (rsize != np) {
                errs++;
                printf("Did not create %d processes (got %d)\n", np, rsize);
                fflush(stdout);
            }
            if (rank == 0 && num_loops > 0) {
                MPI_Open_port(MPI_INFO_NULL, port);
                IF_VERBOSE(("[%d] port = %s\n", rank, port));
                MPI_Send(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, intercomm);
            }
            IF_VERBOSE(("[%d] disconnecting child communicator\n", rank));
            MPI_Comm_disconnect(&intercomm);
            for (i = 0; i < num_loops; i++) {
                IF_VERBOSE(("[%d] accepting connection\n", rank));
                MPI_Comm_accept(port, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm);
                MPI_Comm_remote_size(intercomm, &rsize);
                if (do_messages && (rank == 0)) {
                    j = 0;
                    for (j = 0; j < rsize; j++) {
                        data = i;
                        IF_VERBOSE(("[%d]sending int to child process %d\n", rank, j));
                        MPI_Send(&data, 1, MPI_INT, j, 100, intercomm);
                        IF_VERBOSE(("[%d] receiving int from child process %d\n", rank, j));
                        data = i - 1;
                        MPI_Recv(&data, 1, MPI_INT, j, 100, intercomm, &status);
                        if (data != i) {
                            errs++;
                        }
                    }
                }
                IF_VERBOSE(("[%d] disconnecting communicator\n", rank));
                MPI_Comm_disconnect(&intercomm);
            }

            /* Errors cannot be sent back to the parent because there is no
             * communicator connected to the children
             * for (i=0; i<rsize; i++)
             * {
             * MPI_Recv(&err, 1, MPI_INT, i, 1, intercomm, MPI_STATUS_IGNORE);
             * errs += err;
             * }
             */
        }
        else {
            IF_VERBOSE(("[%d] child rank %d alive.\n", rank, rank));
            /* Child */
            if (size != np) {
                errs++;
                printf("(Child) Did not create %d processes (got %d)\n", np, size);
                fflush(stdout);
            }

            if (rank == 0 && num_loops > 0) {
                IF_VERBOSE(("[%d] receiving port\n", rank));
                MPI_Recv(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, intercomm, &status);
            }

            IF_VERBOSE(("[%d] disconnecting communicator\n", rank));
            MPI_Comm_disconnect(&intercomm);
            for (i = 0; i < num_loops; i++) {
                IF_VERBOSE(("[%d] connecting to port (loop %d)\n", rank, i));
                MPI_Comm_connect(port, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm);
                if (do_messages) {
                    IF_VERBOSE(("[%d] receiving int from parent process 0\n", rank));
                    MPI_Recv(&data, 1, MPI_INT, 0, 100, intercomm, &status);
                    if (data != i) {
                        printf("expected %d but received %d\n", i, data);
                        fflush(stdout);
                        MPI_Abort(MPI_COMM_WORLD, 1);
                    }
                    IF_VERBOSE(("[%d] sending int back to parent process 1\n", rank));
                    MPI_Send(&data, 1, MPI_INT, 0, 100, intercomm);
                }
                IF_VERBOSE(("[%d] disconnecting communicator\n", rank));
                MPI_Comm_disconnect(&intercomm);
            }

            /* Send the errs back to the master process */
            /* Errors cannot be sent back to the parent because there is no
             * communicator connected to the parent */
            /*MPI_Ssend(&errs, 1, MPI_INT, 0, 1, intercomm); */
        }

        /* Note that the MTest_Finalize get errs only over COMM_WORLD */
        /* Note also that both the parent and child will generate "No Errors"
         * if both call MTest_Finalize */
        if (parentcomm == MPI_COMM_NULL) {
            MTest_Finalize(errs);
        }
    }
    else {
        MTest_Finalize(errs);
    }

    IF_VERBOSE(("[%d] calling finalize\n", rank));
    MPI_Finalize();
    return 0;
}
Beispiel #6
0
int main(int argc, char *argv[])
{
    int errs = 0, err;
    int rank, size, rsize, i;
    int np = 2;
    int errcodes[2];
    MPI_Comm parentcomm, intercomm;
    MPI_Status status;
    int can_spawn;

    MTest_Init(&argc, &argv);

    errs += MTestSpawnPossible(&can_spawn);
    if (can_spawn) {
        MPI_Comm_get_parent(&parentcomm);

        if (parentcomm == MPI_COMM_NULL) {
            /* Create 2 more processes */
            MPI_Comm_spawn((char *) "./spawn1", MPI_ARGV_NULL, np,
                           MPI_INFO_NULL, 0, MPI_COMM_WORLD, &intercomm, errcodes);
        } else
            intercomm = parentcomm;

        /* We now have a valid intercomm */

        MPI_Comm_remote_size(intercomm, &rsize);
        MPI_Comm_size(intercomm, &size);
        MPI_Comm_rank(intercomm, &rank);

        if (parentcomm == MPI_COMM_NULL) {
            /* Master */
            if (rsize != np) {
                errs++;
                printf("Did not create %d processes (got %d)\n", np, rsize);
            }
            if (rank == 0) {
                for (i = 0; i < rsize; i++) {
                    MPI_Send(&i, 1, MPI_INT, i, 0, intercomm);
                }
                /* We could use intercomm reduce to get the errors from the
                 * children, but we'll use a simpler loop to make sure that
                 * we get valid data */
                for (i = 0; i < rsize; i++) {
                    MPI_Recv(&err, 1, MPI_INT, i, 1, intercomm, MPI_STATUS_IGNORE);
                    errs += err;
                }
            }
        } else {
            /* Child */
            char cname[MPI_MAX_OBJECT_NAME];
            int rlen;

            if (size != np) {
                errs++;
                printf("(Child) Did not create %d processes (got %d)\n", np, size);
            }
            /* Check the name of the parent */
            cname[0] = 0;
            MPI_Comm_get_name(intercomm, cname, &rlen);
            /* MPI-2 section 8.4 requires that the parent have this
             * default name */
            if (strcmp(cname, "MPI_COMM_PARENT") != 0) {
                errs++;
                printf("Name of parent is not correct\n");
                if (rlen > 0 && cname[0]) {
                    printf(" Got %s but expected MPI_COMM_PARENT\n", cname);
                } else {
                    printf(" Expected MPI_COMM_PARENT but no name set\n");
                }
            }
            MPI_Recv(&i, 1, MPI_INT, 0, 0, intercomm, &status);
            if (i != rank) {
                errs++;
                printf("Unexpected rank on child %d (%d)\n", rank, i);
            }
            /* Send the errs back to the master process */
            MPI_Ssend(&errs, 1, MPI_INT, 0, 1, intercomm);
        }

        /* It isn't necessary to free the intercomm, but it should not hurt */
        /* Using Comm_disconnect instead of free should provide a stronger
         * test, as a high-quality MPI implementation will be able to
         * recover some resources that it should hold on to in the case
         * of MPI_Comm_free */
        /*     MPI_Comm_free(&intercomm); */
        MPI_Comm_disconnect(&intercomm);

        /* Note that the MTest_Finalize get errs only over COMM_WORLD */
        /* Note also that both the parent and child will generate "No Errors"
         * if both call MTest_Finalize */
        if (parentcomm == MPI_COMM_NULL) {
            MTest_Finalize(errs);
        } else {
            MPI_Finalize();
        }
    } else {
        MTest_Finalize(errs);
    }

    return MTestReturnValue(errs);
}