Blame test/mpi/cxx/spawn/spawnargvx.cxx

Packit Service c5cf8c
/* -*- Mode: C++; c-basic-offset:4 ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *  (C) 2003 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 "mpitestconf.h"
Packit Service c5cf8c
#ifdef HAVE_IOSTREAM
Packit Service c5cf8c
// Not all C++ compilers have iostream instead of iostream.h
Packit Service c5cf8c
#include <iostream>
Packit Service c5cf8c
#ifdef HAVE_NAMESPACE_STD
Packit Service c5cf8c
// Those that do need the std namespace; otherwise, a bare "cout"
Packit Service c5cf8c
// is likely to fail to compile
Packit Service c5cf8c
using namespace std;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#else
Packit Service c5cf8c
#include <iostream.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#include "mpitestcxx.h"
Packit Service c5cf8c
#ifdef HAVE_STRING_H
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
static char MTEST_Descrip[] = "A simple test of Comm_spawn, with complex arguments";
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char *argv[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int errs = 0, err;
Packit Service c5cf8c
    int rank, size, rsize, i;
Packit Service c5cf8c
    int np = 2;
Packit Service c5cf8c
    int errcodes[2];
Packit Service c5cf8c
    MPI::Intercomm parentcomm, intercomm;
Packit Service c5cf8c
    MPI::Status status;
Packit Service c5cf8c
    const char *inargv[] = { "a", "b=c", "d e", "-pf", " Ss", 0 };
Packit Service c5cf8c
    const char *outargv[] = { "a", "b=c", "d e", "-pf", " Ss", 0 };
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Init();
Packit Service c5cf8c
Packit Service c5cf8c
    parentcomm = MPI::Comm::Get_parent();
Packit Service c5cf8c
Packit Service c5cf8c
    if (parentcomm == MPI::COMM_NULL) {
Packit Service c5cf8c
        /* Create 2 more processes */
Packit Service c5cf8c
        /* ./ is unix specific .
Packit Service c5cf8c
         * The more generic approach would be to specify "spawnargv" as the
Packit Service c5cf8c
         * executable and pass an info with ("path", ".") */
Packit Service c5cf8c
        intercomm = MPI::COMM_WORLD.Spawn("./spawnargvx", inargv, np, MPI::INFO_NULL, 0, errcodes);
Packit Service c5cf8c
    } else
Packit Service c5cf8c
        intercomm = parentcomm;
Packit Service c5cf8c
Packit Service c5cf8c
    /* We now have a valid intercomm */
Packit Service c5cf8c
Packit Service c5cf8c
    rsize = intercomm.Get_remote_size();
Packit Service c5cf8c
    size = intercomm.Get_size();
Packit Service c5cf8c
    rank = intercomm.Get_rank();
Packit Service c5cf8c
Packit Service c5cf8c
    if (parentcomm == MPI::COMM_NULL) {
Packit Service c5cf8c
        /* Master */
Packit Service c5cf8c
        if (rsize != np) {
Packit Service c5cf8c
            errs++;
Packit Service c5cf8c
            cout << "Did not create " << np << " processes (got " << rsize << ")\n";
Packit Service c5cf8c
        }
Packit Service c5cf8c
        for (i = 0; i < rsize; i++) {
Packit Service c5cf8c
            intercomm.Send(&i, 1, MPI::INT, i, 0);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* We could use intercomm reduce to get the errors from the
Packit Service c5cf8c
         * children, but we'll use a simpler loop to make sure that
Packit Service c5cf8c
         * we get valid data */
Packit Service c5cf8c
        for (i = 0; i < rsize; i++) {
Packit Service c5cf8c
            intercomm.Recv(&err, 1, MPI::INT, i, 1);
Packit Service c5cf8c
            errs += err;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    } else {
Packit Service c5cf8c
        /* Child */
Packit Service c5cf8c
        /* FIXME: This assumes that stdout is handled for the children
Packit Service c5cf8c
         * (the error count will still be reported to the parent) */
Packit Service c5cf8c
        if (size != np) {
Packit Service c5cf8c
            errs++;
Packit Service c5cf8c
            cout << "(Child) Did not create " << np << " (got " << size << ")\n";
Packit Service c5cf8c
        }
Packit Service c5cf8c
        intercomm.Recv(&i, 1, MPI::INT, 0, 0, status);
Packit Service c5cf8c
        if (i != rank) {
Packit Service c5cf8c
            errs++;
Packit Service c5cf8c
            cout << "Unexpected rank on child " << rank << " (" << i << "\n";
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* Check the command line */
Packit Service c5cf8c
        for (i = 1; i < argc; i++) {
Packit Service c5cf8c
            if (!outargv[i - 1]) {
Packit Service c5cf8c
                errs++;
Packit Service c5cf8c
                cout << "Wrong number of arguments (" << argc << ")\n";
Packit Service c5cf8c
                break;
Packit Service c5cf8c
            }
Packit Service c5cf8c
            if (strcmp(argv[i], outargv[i - 1]) != 0) {
Packit Service c5cf8c
                errs++;
Packit Service c5cf8c
                cout << "Found arg " << argv[i] << " but expected " << outargv[i - 1] << "\n";
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
        if (outargv[i - 1]) {
Packit Service c5cf8c
            /* We had too few args in the spawned command */
Packit Service c5cf8c
            errs++;
Packit Service c5cf8c
            cout << "Too few arguments to spawned command\n";
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* Send the errs back to the master process */
Packit Service c5cf8c
        intercomm.Ssend(&errs, 1, MPI::INT, 0, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* It isn't necessary to free the intercomm, but it should not hurt */
Packit Service c5cf8c
    intercomm.Free();
Packit Service c5cf8c
Packit Service c5cf8c
    /* Note that the MTest_Finalize get errs only over COMM_WORLD */
Packit Service c5cf8c
    if (parentcomm == MPI::COMM_NULL) {
Packit Service c5cf8c
        MTest_Finalize(errs);
Packit Service c5cf8c
    } else {
Packit Service c5cf8c
        MPI_Finalize();
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}