|
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 |
}
|