Index: /mpich2/branches/dev/dkim/test/.codingcheck
===================================================================
--- /mpich2/branches/dev/dkim/test/.codingcheck (revision 100)
+++ /mpich2/branches/dev/dkim/test/.codingcheck (revision 100)
@@ -0,0 +1,18 @@
+#
+# We allow these routines for the test programs 
+#
+%gTestFuncs = ( 
+	'printf' => sys, 'fprintf' => sys , 'sprintf' => sys, 'vprintf' => sys,
+	'strcpy' => sys, 'strncpy' => sys,
+	'malloc' => sys, 'free' => sys, 'calloc' => sys,
+	'assert' => sys,
+	);
+&PushAllowFuncNames( gTestFuncs, "tree", "add");
+#
+# Also add additional CPP names
+%gTestNames = ( 'DEBUG' => 1 );
+if (defined(&PushDefinesNames)) {
+   &PushDefinesNames( "gTestNames", "tree", "add" );
+}
+
+1;
Index: /mpich2/branches/dev/dkim/test/basic/srvec.c
===================================================================
--- /mpich2/branches/dev/dkim/test/basic/srvec.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/basic/srvec.c (revision 100)
@@ -0,0 +1,207 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+/* define TEST_RECV_VECTOR to receive the data using the vector datatype.
+   undefine TEST_RECV_VECTOR to receive the data into a contiguous array. */
+#define TEST_RECV_VECTOR
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "mpi.h"
+#include <limits.h>
+
+int MPID_Progress_test(void);
+
+int main(int argc, char **argv)
+{
+    int size;
+    int rank;
+    int niter = 1;
+    int msg_count = 0;
+    int msg_blocklength = 1;
+    int msg_stride = 1;
+    int msg_sz;
+    int * buf;
+    int buf_sz;
+    int iter;
+    int i;
+    MPI_Datatype dt;
+    
+    if (MPI_Init(&argc, &argv) != MPI_SUCCESS)
+    {
+        printf("ERROR: problem with MPI_Init\n"); fflush(stdout);
+    }
+
+    if (MPI_Comm_size(MPI_COMM_WORLD, &size) != MPI_SUCCESS)
+    {
+	printf("ERROR: problem with MPI_Comm_size\n"); fflush(stdout);
+    }
+    
+    if (MPI_Comm_rank(MPI_COMM_WORLD, &rank) != MPI_SUCCESS)
+    {
+	printf("ERROR: problem with MPI_Comm_rank\n"); fflush(stdout);
+    }
+
+    printf("srvec: size %d rank %d\n", size, rank); fflush(stdout);
+    
+    if (size < 2)
+    {
+	if (rank == 0)
+	{
+	    printf("ERROR: needs to be run with at least 2 procs\n");
+	    fflush(stdout);
+	}
+	goto main_exit;
+    }
+
+    if (argc > 1)
+    {
+	sscanf(argv[1], "%d", &niter);
+    }
+
+    if (argc > 2)
+    {
+	sscanf(argv[2], "%d", &msg_count);
+    }
+    
+    if (argc > 3)
+    {
+	sscanf(argv[3], "%d", &msg_blocklength);
+    }
+    
+    if (argc > 4)
+    {
+	sscanf(argv[4], "%d", &msg_stride);
+    }
+
+    if (msg_stride < msg_blocklength)
+    {
+	if (rank == 0)
+	{
+	    printf("ERROR: stride < blocklength\n");
+	    fflush(stdout);
+	}
+	goto main_exit;
+    }
+    
+
+    msg_sz = msg_count * msg_blocklength;
+    buf_sz = msg_count * msg_stride;
+    
+    if (rank == 0)
+    {
+	printf("niter=%d, msg_count=%d, msg_blocklength=%d, msg_stride=%d\n",
+	    niter, msg_count, msg_blocklength, msg_stride);
+	printf("msg_sz=%d, buf_sz=%d\n", msg_sz, buf_sz);
+	fflush(stdout);
+    }
+
+    if (buf_sz > 0)
+    {
+	buf = (int *) malloc(buf_sz * sizeof(int));
+	/* printf("%d: buf=%p\n", rank, buf); fflush(stdout); */
+    }
+    else
+    {
+	buf = NULL;
+    }
+
+    MPI_Type_vector(msg_count, msg_blocklength, msg_stride, MPI_INT, &dt);
+    MPI_Type_commit(&dt);
+
+    if (rank == 0)
+    {
+	/* usleep(10000); */
+
+	for (i = 0; i < buf_sz; i++)
+	{
+	    buf[i] = INT_MAX;
+	}
+	
+	for (iter = 0; iter < niter; iter++)
+	{
+	    for (i = 0; i < buf_sz; i++)
+	    {
+		buf[i] = iter * buf_sz + i;
+	    }
+	    
+	    if (MPI_Send(buf, 1, dt, 1, iter, MPI_COMM_WORLD) != MPI_SUCCESS)
+	    {
+		printf("ERROR: problem with MPI_Send\n"); fflush(stdout);
+	    }
+	}
+	
+    }
+    else if (rank == 1)
+    {
+	MPI_Status status;
+	    
+	for (i = 0; i < buf_sz; i++)
+	{
+	    buf[i] = INT_MIN;
+	}
+
+	for (iter = 0; iter < niter; iter++)
+	{
+#	    if defined(TEST_RECV_VECTOR)
+	    {
+		if (MPI_Recv(buf, msg_sz, MPI_INT, 0, iter, MPI_COMM_WORLD,
+		    &status) != MPI_SUCCESS)
+		{
+		    printf("ERROR: problem with MPI_Recv\n"); fflush(stdout);
+		}
+		
+		for (i = 0; i < msg_sz; i++)
+		{
+		    const int expected = iter * buf_sz + i / msg_blocklength *
+			msg_stride + i % msg_blocklength;
+		    if (buf[i] != expected)
+		    {
+			printf("ERROR: %d != %d, i=%d iter=%d\n", buf[i],
+			    expected, i, iter);
+			fflush(stdout);
+			abort();
+		    }
+		}
+	    }
+#	    else
+	    {
+		if (MPI_Recv(buf, 1, dt, 0, iter, MPI_COMM_WORLD, &status)
+		    != MPI_SUCCESS)
+		{
+		    printf("ERROR: problem with MPI_Recv\n"); fflush(stdout);
+		}
+		
+		for (i = 0; i < buf_sz; i++)
+		{
+		    if (i % msg_stride < msg_blocklength && buf[i] != iter *
+			buf_sz + i)
+		    {
+			printf("ERROR: %d != %d, i=%d iter=%d\n", buf[i],
+			    iter * buf_sz + i, i, iter);
+			fflush(stdout);
+			abort();
+		    }
+		}
+	    }
+#	    endif
+	}
+	
+	printf("All messages successfully received!\n");
+	fflush(stdout);
+    }
+
+  main_exit:
+    MPI_Barrier(MPI_COMM_WORLD);
+    printf("srvec: process %d finished\n", rank); fflush(stdout);
+    
+    if (MPI_Finalize() != MPI_SUCCESS)
+    {
+        printf("ERROR: problem with MPI_Finalize\n"); fflush(stdout);
+    }
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/basic/sr.c
===================================================================
--- /mpich2/branches/dev/dkim/test/basic/sr.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/basic/sr.c (revision 100)
@@ -0,0 +1,120 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <mpi.h>
+
+int main(int argc, char **argv)
+{
+    int size;
+    int rank;
+    int * msg = NULL;
+    int msg_sz = 0;
+    int niter = 1;
+    int iter;
+    int i;
+    
+    if (MPI_Init(&argc, &argv) != MPI_SUCCESS)
+    {
+        printf("ERROR: problem with MPI_Init\n"); fflush(stdout);
+    }
+
+    if (MPI_Comm_size(MPI_COMM_WORLD, &size) != MPI_SUCCESS)
+    {
+	printf("ERROR: problem with MPI_Comm_size\n"); fflush(stdout);
+    }
+    
+    if (MPI_Comm_rank(MPI_COMM_WORLD, &rank) != MPI_SUCCESS)
+    {
+	printf("ERROR: problem with MPI_Comm_rank\n"); fflush(stdout);
+    }
+
+    printf("sr: size %d rank %d\n", size, rank); fflush(stdout);
+    
+    if (size < 2)
+    {
+	printf("ERROR: needs to be run with at least 2 procs\n");
+	fflush(stdout);
+    }
+
+    if (argc > 1)
+    {
+	sscanf(argv[1], "%d", &msg_sz);
+    }
+    
+    if (argc > 2)
+    {
+	sscanf(argv[2], "%d", &niter);
+    }
+
+    if (rank == 0)
+    {
+	printf("msg_sz=%d, niter=%d\n", msg_sz, niter);
+	fflush(stdout);
+    }
+    
+    if (msg_sz > 0)
+    {
+	msg = (int *) malloc(msg_sz * sizeof(int));
+    }
+
+    if (rank == 0)
+    {
+	/* usleep(10000); */
+	    
+	for (iter = 0; iter < niter; iter++)
+	{
+	    for (i = 0; i < msg_sz; i++)
+	    {
+		msg[i] = iter * msg_sz + i;
+	    }
+	    
+	    if (MPI_Send(msg, msg_sz, MPI_INT, 1, iter, MPI_COMM_WORLD)
+		!= MPI_SUCCESS)
+	    {
+		printf("ERROR: problem with MPI_Send\n"); fflush(stdout);
+	    }
+	}
+	
+    }
+    else if (rank == 1)
+    {
+	MPI_Status status;
+	    
+	for (iter = 0; iter < niter; iter++)
+	{
+	    if (MPI_Recv(msg, msg_sz, MPI_INT, 0, iter, MPI_COMM_WORLD,
+			 &status) != MPI_SUCCESS)
+	    {
+		printf("ERROR: problem with MPI_Recv\n"); fflush(stdout);
+	    }
+	
+	    for (i = 0; i < msg_sz; i++)
+	    {
+		if (msg[i] != iter * msg_sz + i)
+		{
+		    printf("ERROR: %d != %d, i=%d iter=%d\n", msg[i],
+			   iter * msg_sz + i, i, iter);
+		    fflush(stdout);
+		    abort();
+		}
+	    }
+	}
+	
+	printf("All messages successfully received!\n");
+	fflush(stdout);
+    }
+
+    printf("sr: process %d finished\n", rank); fflush(stdout);
+    
+    if (MPI_Finalize() != MPI_SUCCESS)
+    {
+        printf("ERROR: problem with MPI_Finalize\n"); fflush(stdout);
+    }
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/basic/sr1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/basic/sr1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/basic/sr1.c (revision 100)
@@ -0,0 +1,41 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+/*
+ * A simple code that can be used to test the basic message passing or
+ * debug parts of the code.  This is less a test than a way to exercise
+ * the primary code path for short message send-receives
+ */
+#include <stdio.h>
+#include "mpi.h"
+
+int main( int argc, char *argv[] )
+{
+    int myrank, size, src=0, dest=1, msgsize=1;
+    int buf[20];
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
+
+    if (myrank == src) {
+        buf[0] = 0xabcd0123;
+	MPI_Send( buf, msgsize, MPI_INT, dest, 0, MPI_COMM_WORLD );
+    }
+    else if (myrank == dest) {
+        buf[0] = 0xffffffff;
+	MPI_Recv( buf, msgsize, MPI_INT, src, 0, MPI_COMM_WORLD, 
+		  MPI_STATUS_IGNORE );
+	if (buf[0] != 0xabcd0123) {
+	    printf( "Expected %x but got %x\n", 0xabcd0123, buf[0] );
+	    fflush(stdout);
+	}
+    }
+
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/basic/srbtest.c
===================================================================
--- /mpich2/branches/dev/dkim/test/basic/srbtest.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/basic/srbtest.c (revision 100)
@@ -0,0 +1,50 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+/* A very simple program that performs only a send and a receive.  This
+   program can be use with logging enabled (configure with 
+   --enable-g=dbg,log) and run with -mpich-dbg-class=routine to get
+   a trace of the execution of the functions in MPICH2 */
+#include <stdio.h>
+#include "mpi.h"
+
+#define SENDER_RANK 0
+#define RECEIVER_RANK 1
+int main( int argc, char *argv[] )
+{
+    int rank, size, val;
+    MPI_Status status;
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    if (size < 2) {
+	fprintf( stderr, "This program requires at least 2 processes\n" );
+	MPI_Abort( MPI_COMM_WORLD, 1 );
+    }
+    if (rank == SENDER_RANK) {
+	MPI_Send( &rank, 1, MPI_INT, RECEIVER_RANK, 0, MPI_COMM_WORLD );
+    }
+    else if (rank == RECEIVER_RANK) {
+	/* This may or may not post the receive before the send arrives */
+	MPI_Recv( &val, 1, MPI_INT, SENDER_RANK, 0, MPI_COMM_WORLD, &status );
+    }
+    /* Perform a second send/receive to allow the first pair to handle
+       any connection logic */
+#if 1
+    if (rank == SENDER_RANK) {
+	MPI_Send( &rank, 1, MPI_INT, RECEIVER_RANK, 0, MPI_COMM_WORLD );
+    }
+    else if (rank == RECEIVER_RANK) {
+	/* This may or may not post the receive before the send arrives */
+	MPI_Recv( &val, 1, MPI_INT, SENDER_RANK, 0, MPI_COMM_WORLD, &status );
+    }
+#endif
+
+    MPI_Finalize( );
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/basic/Makefile.sm
===================================================================
--- /mpich2/branches/dev/dkim/test/basic/Makefile.sm (revision 100)
+++ /mpich2/branches/dev/dkim/test/basic/Makefile.sm (revision 100)
@@ -0,0 +1,12 @@
+srbtest_SOURCES = srbtest.c
+sr_SOURCES      = sr.c
+srvec_SOURCES   = srvec.c
+sendrecvt_SOURCES = sendrecvt.c
+sr1_SOURCES     = sr1.c
+#
+# Replace the value of CC
+prefix          = @prefix@
+exec_prefix     = @exec_prefix@
+bindir          = @bindir@
+CC              = @MPICC@
+CPPFLAGS        = 
Index: /mpich2/branches/dev/dkim/test/basic/sendrecvt.c
===================================================================
--- /mpich2/branches/dev/dkim/test/basic/sendrecvt.c (revision 1118)
+++ /mpich2/branches/dev/dkim/test/basic/sendrecvt.c (revision 1118)
@@ -0,0 +1,36 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2008 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+
+int main( int argc, char *argv[] )
+{
+    int myrank, size, src=0, dest=1;
+    int buf[20];
+
+    MPI_Init( 0, 0 );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
+
+    if (myrank == src || myrank == dest) {
+	int partner = src;
+	if (myrank == partner) partner = dest;
+        MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0, 
+  	    	      MPI_BOTTOM, 0, MPI_INT, partner,  0, MPI_COMM_WORLD, 
+		      MPI_STATUS_IGNORE );
+    }
+    
+    if (myrank == src) {
+	MPI_Send( buf, 20, MPI_INT, dest, 0, MPI_COMM_WORLD );
+    }
+    else if (myrank == dest) {
+	MPI_Recv( buf, 20, MPI_INT, src, 0, MPI_COMM_WORLD, 
+		  MPI_STATUS_IGNORE );
+    }
+
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/rtest.c
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/rtest.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/rtest.c (revision 100)
@@ -0,0 +1,11 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*  
+ *  (C) 2006 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include <stdio.h>
+int main( int argc, char *argv[] )
+{
+    printf( testname );
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/stdintest.c
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/stdintest.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/stdintest.c (revision 100)
@@ -0,0 +1,29 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+/* This simple test reads stdin and copies to stdout */
+#include <stdio.h>
+#include "mpi.h"
+
+/* style: allow:puts:1 sig:0 */
+/* style: allow:fgets:1 sig:0 */
+
+int main( int argc, char *argv[] )
+{
+    int rank;
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    if (rank == 0) {
+	char buf[128];
+	while (fgets(buf,sizeof(buf),stdin)) {
+	    puts(buf);
+	}
+    }
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/stdiotest.c
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/stdiotest.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/stdiotest.c (revision 100)
@@ -0,0 +1,23 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include <stdio.h>
+#include "mpi.h"
+
+int main( int argc, char *argv[] )
+{
+    int rank;
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    if (rank == 0) {
+	fprintf( stdout, "This is stdout\n" );
+	fprintf( stderr, "This is stderr\n" );
+    }
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/stdintest2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/stdintest2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/stdintest2.c (revision 100)
@@ -0,0 +1,27 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+/* This simple test ignores stdin and exits.  This is used to test the
+   handling of stdin by programs that do not read all of the stdin 
+   data that they may have */
+#include <stdio.h>
+#include "mpi.h"
+
+/* style: allow:printf:1 sig:0 */
+
+int main( int argc, char *argv[] )
+{
+    int rank;
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    if (rank == 0) {
+	printf( " No Errors\n" );
+    }
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/checkenv1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/checkenv1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/checkenv1.c (revision 100)
@@ -0,0 +1,48 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*  
+ *  (C) 2006 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi.h"
+
+int main(int argc, char **argv )
+{
+    char *p;
+    int errs = 0, toterrs;
+    int size, rank;
+
+    MPI_Init( &argc, &argv );
+    
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    if (size != 2) {
+	errs++;
+	printf( "Communicator size is %d, should be 2\n", size );
+    }
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+
+    p = getenv("TMP_ENV_VAR");
+    if (!p) {
+	errs++;
+	printf( "Did not find TMP_ENV_VAR\n" );
+    }
+    else if (strcmp(p,"1") != 0) {
+	errs++;
+	printf( "Value of TMP_ENV_VAR was %s, expected 1\n", p );
+    }
+
+    MPI_Reduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD );
+    if (rank == 0) {
+	if (toterrs == 0) {
+	    printf( " No Errors\n" );
+	}
+	else {
+	    printf( " Found %d errors\n", toterrs );
+	}
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/testout.c
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/testout.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/testout.c (revision 100)
@@ -0,0 +1,20 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2006 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include <stdio.h>
+
+int main()
+{
+    setvbuf(stdout,NULL,_IOLBF,0);  
+    printf( "first line\n" );
+    sleep(1);
+    printf( "second line\n" );
+    sleep(1); 
+    printf( "last line\n" ); 
+    fflush(stdout);
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/rtestx.cxx
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/rtestx.cxx (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/rtestx.cxx (revision 100)
@@ -0,0 +1,11 @@
+/* -*- Mode: C++; c-basic-offset:4 ; -*- */
+/*  
+ *  (C) 2006 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include <iostream.h>
+int main( int argc, char *argv[] )
+{
+    cout << testname;
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/commands/Makefile.sm
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/Makefile.sm (revision 490)
+++ /mpich2/branches/dev/dkim/test/commands/Makefile.sm (revision 490)
@@ -0,0 +1,30 @@
+stdiotest_SOURCES = stdiotest.c
+stdintest_SOURCES = stdintest.c
+stdintest2_SOURCES = stdintest2.c
+checkenv1_SOURCES = checkenv1.c
+rtest_SOURCES     = rtest.c
+rtestf_SOURCES    = rtestf.f
+rtestx_SOURCES    = rtestx.cxx
+testout_SOURCES   = testout.c
+
+C_LINK = $(bindir)/mpicc
+MPICC = $(bindir)/mpicc
+MPICXX = $(bindir)/mpicxx
+MPIF77 = $(bindir)/mpif77
+
+.c:
+	$(MPICC) -o $* $<
+.c.o:
+	$(MPICC) -c $<
+.f.o:
+	$(MPIF77) -c $<
+.F.o:
+	$(MPIF77) -c $<
+.cxx.o:
+	$(MPICXX) -c $<
+
+testing:
+#	./cmdtests
+
+clean-local:
+	-rm -f err.txt out.log out.txt stdintest stdintest2 sdtiotest a.out
Index: /mpich2/branches/dev/dkim/test/commands/cmdtests.in
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/cmdtests.in (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/cmdtests.in (revision 100)
@@ -0,0 +1,709 @@
+#! @PERL@ -w
+# -*- Mode: perl; -*-
+#
+# Test the commands provided as part of MPICH2
+#
+# mpicc, mpicxx - handle -Dname="foo bar" and -Dname='"foo bar"'
+# (not done yet - see mpich1 test/command/runtests)
+# mpiexec - environment handling; stdout, stderr redirection
+#
+# Configuration values
+my $prefix      = "@prefix@";
+my $exec_prefix = "@exec_prefix@";
+my $bindir      = "@bindir@";
+my $srcdir      = "@srcdir@";
+
+# Global variables
+my $errors = 0;
+
+$gVerbose = 0;
+
+$xmlOutput = 0;
+$xmlFile = "";
+$xmlOutputContinue = 0;
+# testoutput is used to keep a copy of all output in case there is an
+# error and XML output containing the messages is desired.
+$testoutput = "";
+
+# The MPD process manager has trouble with stdin.  While this should be
+# fixed, for the moment, we provide a way to turn off those tests
+$testStdin = 0;
+if (defined($ENV{"MPIEXEC_HAS_STDIN"})) { $testStdin = 1; }
+
+# Set a default for the timeout 
+# (The stdintest has hung sometimes; a correctly functioning mpiexec
+# will abort when this timelimit is exceeded)
+if (!defined($ENV{"MPIEXEC_TIMEOUT"})) {
+    $ENV{"MPIEXEC_TIMEOUT"} = 20;
+}
+
+#
+# Get a way to kill processes
+my $killall = '@KILLALL@';
+my $myusername = "";
+if (defined($ENV{'LOGNAME'})) {
+    $myusername = $ENV{'LOGNAME'};
+}
+
+# -------------------------------------------------------------------------
+if (defined($ENV{'XMLFILE'})) {
+    $xmlOutput = 1;
+    $xmlFile   = $ENV{'XMLFILE'};
+}
+if (defined($ENV{'XMLCONTINUE'}) && $ENV{'XMLCONTINUE'} eq "YES") {
+    $xmlOutputContinue = 1;
+}
+
+foreach $_ (@ARGV) {
+    if (/-debug/ || /-verbose/) { 
+	$gVerbose = 1;
+    }
+    if (/-xmlfile=(.*)/) {
+	$xmlFile = $1;
+	$xmlOutput = 1;
+    }
+    else {
+	print STDERR "Unrecognized argument $_\n";
+    }
+}
+# -------------------------------------------------------------------------
+if ($xmlOutput) {
+    if ($xmlOutputContinue) {
+	open XMLFD, ">>$xmlFile" || die "Cannot append to $xmlFile";
+    }
+    else {
+	open XMLFD, ">$xmlFile" || die "Cannot open $xmlFile for writing";
+    }
+}
+# -------------------------------------------------------------------------
+# mpiexec env handling
+# We assume that we can run non-MPI programs
+%SaveENV = %ENV;
+
+$ENV{TestEnvVar} = "test var name";
+%EnvBase = ('PMI_FD' => 1, 'PMI_RANK' => 0, 'PMI_SIZE' => 1, 
+	    'PMI_DEBUG' => 0, 
+	    'MPI_APPNUM' => 0, 'MPI_UNIVERSE_SIZE' => 1, 
+	    'PMI_PORT' => 1, 
+	    'MPICH_INTERFACE_HOSTNAME' => 1,
+	    'MPICH_INTERFACE_HOSTNAME_R0' => 1,
+	    'MPICH_INTERFACE_HOSTNAME_R1' => 1,
+	    'MPICH_INTERFACE_HOSTNAME_R2' => 1,
+	    'MPICH_INTERFACE_HOSTNAME_R3' => 1,
+	    # These are suspicious
+	    'PMI_SPAWNED' => 0, 
+	    'PMI_TOTALVIEW' => 0,
+	    );
+# Other environment variables should be rejected
+
+# Processes on cygwin always have SYSTEMROOT and WINDIR set
+%EnvForced = ( 'SYSTEMROOT' => 1, 'WINDIR' => 1 );
+
+%EnvExpected = ();
+
+print "Try some environment args\n" if $gVerbose;
+
+$mpiexec = "$bindir/mpiexec" ;
+
+# Do we get the environment?
+%EnvSeen = ();
+%EnvExpected = ( 'PATH' => $ENV{PATH} );
+
+&Announce( "$mpiexec printenv" );
+open MOUT, "$mpiexec printenv 2>&1 |" || die "Could not run $mpiexec";
+while (<MOUT>) {
+    # We check for the error output from gforker mpiexec; we can
+    # add others here as well
+    if (/([^=]+)=(.*)/ && ! /Return code/) {
+	$EnvSeen{$1} = $2;
+    }
+    else {
+	&ReportError( "Unexpected output from mpiexec: $_" );
+	$errors ++;
+    }
+}
+close MOUT;
+$rc = $?;
+if ($rc != 0) {
+    $errors ++;
+    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
+}
+# Check that all vars in save are seen
+%copyEnv = %SaveENV;
+foreach my $key (keys(%EnvSeen)) {
+    if (defined($EnvBase{$key})) { next; }
+    delete $copyEnv{$key};
+}
+foreach my $key (keys(%copyEnv)) {
+    print "Enviroment variable $key not delivered to target program\n";
+    $errors ++;
+}
+
+%EnvSeen = ();
+%EnvExpected = ( 'PATH' => $ENV{PATH} );
+&Announce( "$mpiexec -envnone -envlist PATH printenv" );
+open MOUT, "$mpiexec -envnone -envlist PATH printenv 2>&1 |" || die "Could not run $mpiexec";
+while (<MOUT>) {
+    # We check for the error output from gforker mpiexec; we can
+    # add others here as well
+    if (/([^=]+)=(.*)/ && ! /Return code/) {
+	$EnvSeen{$1} = $2;
+    }
+    else {
+	&ReportError( "Unexpected output from mpiexec: $_" );
+	$errors ++;
+    }
+}
+close MOUT;
+$rc = $?;
+if ($rc != 0) {
+    $errors ++;
+    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
+}
+# Check that only PATH and the PMI variables are set
+$errors += &CheckEnvVars;
+
+%EnvSeen = ();
+%EnvExpected = ( 'PATH' => $ENV{PATH} );
+&Announce( "$mpiexec -genvnone -genvlist PATH printenv " );
+open MOUT, "$mpiexec -genvnone -genvlist PATH printenv 2>&1 |" || die "Could not run $mpiexec";
+while (<MOUT>) {
+    # We check for the error output from gforker mpiexec; we can
+    # add others here as well
+    if (/([^=]+)=(.*)/ && ! /Return code/) {
+	$EnvSeen{$1} = $2;
+    }
+    else {
+	&ReportError( "Unexpected output from mpiexec: $_" );
+	$errors ++;
+    }
+}
+close MOUT;
+$rc = $?;
+if ($rc != 0) {
+    $errors ++;
+    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
+}
+# Check that only PATH and the PMI variables are set
+$errors += &CheckEnvVars;
+
+%EnvSeen = ();
+%EnvExpected = ( 'PATH' => $ENV{PATH},
+		 'TestEnvVar' => $ENV{TestEnvVar} );
+&Announce ( "$mpiexec -genvnone -genvlist PATH printenv : -envlist TestEnvVar,PATH printenv" );
+open MOUT, "$mpiexec -genvnone -genvlist PATH printenv : -envlist TestEnvVar,PATH printenv 2>&1 |" || die "Could not run $mpiexec";
+while (<MOUT>) {
+    # We check for the error output from gforker mpiexec; we can
+    # add others here as well
+    if (/Return code/) { next; }
+    if (/([^=]+)=(.*)/) {
+	$EnvSeen{$1} = $2;
+    }
+    else {
+	&ReportError( "Unexpected output from mpiexec: $_" );
+	$errors ++;
+    }
+}
+close MOUT;
+$rc = $?;
+if ($rc != 0) {
+    $errors ++;
+    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
+}
+# Check that only PATH and the PMI variables are set
+$errors += &CheckEnvVars;
+
+# This test creates long env variables
+my $varvalue = "a";
+for (my $i=0; $i<11; $i++) {
+    $varvalue .= $varvalue;
+}
+
+$ENV{TESTVAR} = $varvalue;
+%EnvSeen = ();
+%EnvExpected = ( 'PATH' => $ENV{PATH},
+		 'TESTVAR' => $ENV{TESTVAR},
+		 );
+&Announce( "$mpiexec -envnone -envlist PATH,TESTVAR printenv" );
+open MOUT, "$mpiexec -envnone -envlist PATH,TESTVAR printenv 2>&1 |" || die "Could not run $mpiexec";
+while (<MOUT>) {
+    # We check for the error output from gforker mpiexec; we can
+    # add others here as well
+    if (/([^=]+)=(.*)/ && ! /Return code/) {
+	$EnvSeen{$1} = $2;
+    }
+    else {
+	&ReportError( "Unexpected output from mpiexec: $_" );
+	$errors ++;
+    }
+}
+close MOUT;
+$rc = $?;
+if ($rc != 0) {
+    $errors ++;
+    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
+}
+# Check that only PATH, TESTVAR, and the PMI variables are set, and
+# that they have the correct values
+$errors += &CheckEnvVars;
+
+delete $ENV{TESTVAR};
+
+# Intel reports problems with
+# export TMP_ENV_VAR=1
+# mpiexec -genvlist TMP_ENV_VAR -n 1 -host host1 ./a.out : -n 1 -host host2 \
+#   ./a.out
+# or using the equivalent config file:
+# mpiexec -configfile a.out.cfgfile
+# where a.out.cfgfile contains
+#   -genvlist TMP_ENV_VAR
+#   -n 1 -host host1 ./a.out
+#   -n 1 -host host2 ./a.out
+#
+$ENV{'TMP_ENV_VAR'} = 1;
+$myhost = `hostname`;
+$myhost =~ s/\r?\n//;
+&Announce( "$mpiexec -genvlist TMP_ENV_VAR -n 1 -host $myhost ./checkenv1 : -n 1 -host $myhost ./checkenv1" );
+if (! -x "checkenv1" ) {
+    system "make checkenv1";
+    if (! -x "checkenv1") {
+	&ReportError( "Unable to build checkenv1 program\n" );
+	$errors ++;
+    }
+}
+open MOUT, "$mpiexec -genvlist TMP_ENV_VAR -n 1 -host $myhost ./checkenv1 : -n 1 -host $myhost ./checkenv1 |" || die "Could not run $mpiexec";
+$foundNoErrors = 0;
+while (<MOUT>) {
+    if (/ No Errors/) {
+	$foundNoErrors = 1;
+    }
+    else {
+	&ReportError( "Unexpected output from mpiexec: $_" );
+	$errors ++;
+    }
+}
+close MOUT;
+$rc = $?;
+if ($rc != 0) {
+    $errors ++;
+    &ReportError( "Non-zero return ($rc) from mpiexec\n" );
+}
+if (! $foundNoErrors) {
+    $errors ++;
+    &ReportError( "checkenv1 did not return No Errors\n" );
+}
+delete $ENV{'TMP_ENV_VAR'};
+
+# -------------------------------------------------------------------------
+# mpiexec stdout/stderr handling
+&Announce( "$mpiexec ./stdiotest 2>err.txt 1>out.txt" );
+if (! -x "stdiotest" ) {
+    system "make stdiotest";
+    if (! -x "stdiotest") {
+	&ReportError( "Unable to build stdiotest program\n" );
+	$errors ++;
+    }
+}
+if (-x "stdiotest") {
+    unlink "err.txt";
+    unlink "out.txt";
+    system "$mpiexec ./stdiotest 2>err.txt 1>out.txt";
+    # Compare the expected output
+    if (-s "err.txt" && -s "out.txt") {
+	# We check for the expected output line.  We allow (but warn about)
+	# output that was not generated by the program, since that
+	# makes it impossible to write Unix-style pipes that include
+	# parallel programs.
+        open TFD, "<err.txt";
+ 	$sawOutput = 0;
+	$sawExtraLine = 0;
+	$sawExtraChars = 0;
+	while (<TFD>) {
+	    if (/(.*)This is stderr(.*)/) {
+		my $pre = $1;
+		my $post = $2;
+		$sawOutput++;
+		if ($pre ne "" || $post ne "") { $sawExtraChars++; }
+	    }
+	    else {
+		print STDERR "Unexpected text in stderr: $_" if $showWarnings;
+		$sawExtraLine ++;
+	    }
+	}
+	close TFD;
+	if ($sawOutput != 1) {
+	    &ReportError( "Saw expected stderr line $sawOutput times\n" );
+	    $errors ++;
+	}
+	open TFD, "<out.txt";
+ 	$sawOutput = 0;
+	$sawExtraLine = 0;
+	$sawExtraChars = 0;
+	while (<TFD>) {
+	    if (/(.*)This is stdout(.*)/) {
+		my $pre = $1;
+		my $post = $2;
+		$sawOutput++;
+		if ($pre ne "" || $post ne "") { $sawExtraChars++; }
+	    }
+	    else {
+		if (/This is stderr/) {
+		    &ReportError( "stderr output in stdout file\n" );
+		    $errors++;
+		}
+		print STDERR "Unexpected text in stderr: $_" if $showWarnings;
+		$sawExtraLine ++;
+	    }
+	}
+	close TFD;
+	if ($sawOutput != 1) {
+	    &ReportError( "Saw expected stdout line $sawOutput times\n" );
+	    $errors ++;
+	}
+    }
+    else {
+	if (! -s "out.txt") {
+	    &ReportError( "Program stdiotest did not create stdout file\n" );
+	    $errors ++;
+	}
+	if (! -s "err.txt") {
+	    &ReportError( "Program stdiotest did not create stderr file\n" );
+	    $errors ++;
+	}
+    }
+    unlink "err.txt";
+    unlink "out.txt";
+}
+# -------------------------------------------------------------------------
+# mpiexec stdin handling
+if ($testStdin) {
+    &Announce( "$mpiexec ./stdintest <in.txt 2>err.txt 1>out.txt" );
+    if (! -x "stdintest" ) {
+	system "make stdintest";
+	if (! -x "stdintest") {
+	    &ReportError( "Unable to build stdintest program\n" );
+	    $errors ++;
+	}
+    }
+    if (-x "stdintest") {
+	unlink "in.txt";
+	unlink "err.txt";
+	unlink "out.txt";
+	# Create the input file
+	open TFD, ">in.txt" || die "Cannot create test input file";
+	for (my $i = 0; $i < 1024; $i++) {
+	    print TFD "This is line $i\n";
+	}
+	close TFD;
+	
+	$rc = system "$mpiexec ./stdintest <in.txt 2>err.txt 1>out.txt";
+	if ($rc != 0) {
+	    &ReportError( "Program stdintest failed with return $rc" );
+	    $errors ++;
+	}
+	# Because some mpiexec programs fail to properly handle these stdio
+	# tests, we add a step to kill the test program if mpiexec failed
+	# to remove it.
+	if ($killall ne "true" && $myusername ne "") {
+	    system "$killall -u $myusername stdintest";
+	}
+	# Compare the expected output
+	if (-s "out.txt") {
+	    &CheckEchoedOutput;
+	}
+	else {
+	    &ReportError( "Program stdintest did not create stdout file\n" );
+	    $errors ++;
+	}
+	if (-s "err.txt") {
+	    &ReportError( "Program stdintest created a non-empty stderr file\n" );
+	    $errors ++;
+	    system "cat err.txt";
+	}
+	unlink "err.txt";
+	unlink "out.txt";
+	
+	# Try with a parallel job
+	&Announce( "$mpiexec -n 3 ./stdintest <in.txt 2>err.txt 1>out.txt" );
+	$rc = system "$mpiexec -n 3 ./stdintest <in.txt 2>err.txt 1>out.txt";
+	if ($rc != 0) {
+	    &ReportError( "Program stdintest (3 processes) failed with return $rc" );
+	    $errors ++;
+	}
+	# Because some mpiexec programs fail to properly handle these stdio
+	# tests, we add a step to kill the test program if mpiexec failed
+	# to remove it.
+	if ($killall ne "true" && $myusername ne "") {
+	    system "$killall -u $myusername stdintest";
+	}
+	# Compare the expected output
+	if (-s "out.txt") {
+	    &CheckEchoedOutput;
+	}
+	else {
+	    &ReportError( "Program stdintest did not create stdout file\n" );
+	    $errors ++;
+	}
+	if (-s "err.txt") {
+	    &ReportError( "Program stdintest created a non-empty stderr file\n" );
+	    $errors ++;
+	    system "cat err.txt";
+	}
+	unlink "err.txt";
+	unlink "out.txt";
+
+	unlink "in.txt";
+    }
+    #
+    # Test for allowing stdin to have unread data
+    &Announce( "$mpiexec ./stdintest2 <in.txt 2>err.txt 1>out.txt" );
+    if (! -x "stdintest2" ) {
+	system "make stdintest2";
+	if (! -x "stdintest2") {
+	    &ReportError( "Unable to build stdintest2 program\n" );
+	    $errors ++;
+	}
+    }
+    if (-x "stdintest2") {
+	unlink "in.txt";
+	unlink "err.txt";
+	unlink "out.txt";
+	# Create the input file
+	open TFD, ">in.txt" || die "Cannot create test input file";
+	for (my $i = 0; $i < 1024; $i++) {
+	    print TFD "This is line $i\n";
+	}
+	close TFD;
+	$rc = system "$mpiexec ./stdintest2 <in.txt 2>err.txt 1>out.txt";
+	if ($rc != 0) {
+	    &ReportError( "Program stdintest2 failed with return $rc" );
+	    $errors ++;
+	}
+	# Because some mpiexec programs fail to properly handle these stdio
+	# tests, we add a step to kill the test program if mpiexec failed
+	# to remove it.
+	if ($killall ne "true" && $myusername ne "") {
+	    system "$killall -u $myusername stdintest2";
+	}
+	# Compare the expected output
+	if (-s "out.txt") {
+	    # Check for No Errors ONLY
+	    open TFD, "<out.txt" || die "Cannot create test input file";
+	    $found_no_errors = 0;
+	    my $found_other = 0;
+	    while (<TFD>) {
+		if (/No Errors/) {
+		    $found_no_errors = 1;
+		}
+		else {
+		    if (!$found_other) {
+			&ReportError( "Found unexpected text %_" );
+		    }
+		    $found_other = 1;
+		    $errors ++;
+		}
+	    }
+	    close TFD;
+	    if (! $found_no_errors) {
+		&ReportError( "Did not find No Errors" );
+		$errors++;
+	    }
+	}
+	if (-s "err.txt") {
+	    &ReportError( "Program stdintest2 created a non-empty stderr file\n" );
+	    $errors ++;
+	    system "cat err.txt";
+	}
+	unlink "err.txt";
+	unlink "out.txt";
+	unlink "in.txt";
+    }
+}
+# -------------------------------------------------------------------------
+# Compliation script testing, particularly for special command-line arguments
+$cmd = "mpicc";
+#$outlog = "/dev/null";
+$outlog = "out.log";
+unlink $outlog;
+&Announce( "$bindir/mpicc -Dtestname=\\\"foo\\\" $srcdir/rtest.c" );
+system "$bindir/mpicc -Dtestname=\\\"foo\\\" $srcdir/rtest.c > $outlog 2>&1";
+$rc = $?;
+if ($rc != 0) {
+    &ReportError( "Error with escaped double quotes in $cmd\n" );
+    system( "cat $outlog" );
+    $errors ++;
+}
+
+unlink $outlog;
+&Announce( "$bindir/mpicc -Dtestname='\"foo bar\"' $srcdir/rtest.c" );
+system "$bindir/mpicc -Dtestname='\"foo bar\"' $srcdir/rtest.c  > $outlog 2>&1";
+$rc = $?;
+if ($rc != 0) {
+    &ReportError( "Error with double inside of single quotes in $cmd\n" );
+    system( "cat $outlog" );
+    $errors ++;
+}
+unlink "a.out";
+
+# Run this test only if mpicxx is valid
+if ("@bindings@" =~ /cxx/) {
+    $cmd = "mpicxx";
+    unlink $outlog;
+    &Announce( "$bindir/mpicxx -Dtestname=\\\"foo\\\" $srcdir/rtestx.cxx" );
+    system "$bindir/mpicxx -Dtestname=\\\"foo\\\" $srcdir/rtestx.cxx  > $outlog 2>&1";
+    $rc = $?;
+    if ($rc != 0) {
+	&ReportError( "Error with escaped double quotes in $cmd\n" );
+	system( "cat $outlog" );
+	$errors ++;
+    }
+    unlink $outlog;
+    &Announce( "$bindir/mpicxx -Dtestname='\"foo bar\"' $srcdir/rtestx.cxx" );
+    system "$bindir/mpicxx -Dtestname='\"foo bar\"' $srcdir/rtestx.cxx > $outlog 2>&1";
+    $rc = $?;
+    if ($rc != 0) {
+	&ReportError( "Error with double inside of single quotes in $cmd\n" );
+	system( "cat $outlog" );
+	$errors ++;
+    }
+    unlink "a.out";
+}
+# Run this test only if mpif77 is valid
+if ("@bindings@" =~ /f77/) {
+    $cmd = "mpif77";
+    unlink $outlog;
+    &Announce( "$bindir/mpif77 -Dtestname=\\\"foo\\\" $srcdir/rtestf.F" );
+    system "$bindir/mpif77 -Dtestname=\\\"foo\\\" $srcdir/rtestf.F  > $outlog 2>&1";
+    $rc = $?;
+    if ($rc != 0) {
+	&ReportError( "Error with escaped double quotes in $cmd\n" );
+	system( "cat $outlog" );
+	$errors ++;
+    }
+    unlink $outlog;
+    &Announce( "$bindir/mpif77 -Dtestname='\"foo bar\"' $srcdir/rtestf.F" );
+    system "$bindir/mpif77 -Dtestname='\"foo bar\"' $srcdir/rtestf.F > $outlog 2>&1";
+    $rc = $?;
+    if ($rc != 0) {
+	&ReportError( "Error with double inside of single quotes in $cmd\n" );
+	system( "cat $outlog" );
+	$errors ++;
+    }
+    unlink "a.out";
+}
+
+# FIXME: 
+# Still to do:
+# Tests for other options to mpiexec (other combinations of env options,
+# all MPI-2 mandated options)
+#
+# ------------------------------------------------------------------------
+# Test Summary
+if ($errors != 0) {
+    print " Found $errors errors\n";
+}
+else {
+    print " No Errors\n";
+}
+if ($xmlOutput) {
+    $newline = "\r\n";
+    my $workdir = `pwd`;
+    $workdir =~ s/\r?\n//;
+    print XMLFD "<MPITEST>$newline<NAME>cmdtest</NAME>$newline";
+    print XMLFD "<WORKDIR>$workdir</WORKDIR>$newline";
+    if ($errors != 0) {
+	print XMLFD "<STATUS>fail</STATUS>$newline";
+	$testoutput =~ s/</\*AMP\*lt;/g;
+	$testoutput =~ s/>/\*AMP\*gt;/g;
+	$testoutput =~ s/&/\*AMP\*amp;/g;
+	$testoutput =~ s/\*AMP\*/&/g;
+	print XMLFD "<TESTDIFF>$newline$testoutput</TESTDIFF>$newline";
+    }
+    else {
+	print XMLFD "<STATUS>pass</STATUS>$newline";
+    }
+    print XMLFD "</MPITEST>$newline</MPITESTRESULTS>$newline";
+    close XMLFD;
+}
+exit 0;
+# ------------------------------------------------------------------------
+# Testing routines
+# Check for environment variables
+# For simplicity, uses global variables:
+#    EnvSeen - variables seen
+#    EnvBase - variables part of the PMI interface
+#    EnvExpected - other variables
+sub CheckEnvVars {
+    my $errcount = 0;
+    foreach my $key (keys(%EnvSeen)) {
+	if (defined($EnvBase{$key})) { next; }
+	if (defined($EnvExpected{$key})) { 
+	    my $expectedValue = $EnvExpected{$key};
+	    my $observedValue = $EnvSeen{$key};
+	    if ($expectedValue ne $observedValue) {
+		$errcount++;
+		&ReportError( "Environment variable $key has value $observedValue but $expectedValue expected\n" );
+	    }
+	    next; 
+	}
+	if (defined($EnvForced{$key})) { next; }
+	$value = $EnvSeen{$key};
+	&ReportError( "Unexpected environment variable $key with $value\n" );
+	$errcount ++;
+    }
+    return $errcount;
+}
+    
+sub Announce {
+    my $msg = $_[0];
+
+    print STDOUT $msg . "\n";
+    $testoutput .= $msg . "\n";
+}
+
+sub ReportError {
+    my $msg = $_[0];
+    if ( !($msg =~ /\n/) ) { $msg .= "\n"; }
+    print STDERR $msg;
+    $testoutput .= $msg;
+}
+
+# This routine is used to check the output from a program that reads 
+# from stdin and echos the output.
+sub CheckEchoedOutput {
+    # We check for the expected output line.  We allow (but warn about)
+    # output that was not generated by the program, since that
+    # makes it impossible to write Unix-style pipes that include
+    # parallel programs.
+    open TFD, "<out.txt";
+    my $sawOutput = 0;
+    my $sawExtraLine = 0;
+    my $sawExtraChars = 0;
+    my $expectedLinenum = 0;
+    my $linesSeen = 0;
+
+    while (<TFD>) {
+	if (/(.*)This is line (\d+)(.*)/) {
+	    my $pre = $1;
+	    my $linenum = $2;
+	    my $post = $3;
+	    $sawOutput++;
+	    $linesSeen++;
+	    if ($pre ne "" || $post ne "") { $sawExtraChars++; }
+	    if ($linenum != $expectedLinenum) {
+		&ReportError( "Unexpected linenumber in output; expected $expectedLinenum but say $linenum\n" );
+		$errors++;
+	    }
+	    $expectedLinenum++;
+	}
+	else {
+	    print STDERR "Unexpected text in stdout: $_" if $showWarnings;
+	    $sawExtraLine ++;
+	}
+    }
+    close TFD;
+    if ($linesSeen != 1024) {
+	&ReportError( "Did not see entire input file (only $linesSeen lines)\n" );
+	$errors++;
+    }
+}
Index: /mpich2/branches/dev/dkim/test/commands/rtestf.F
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/rtestf.F (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/rtestf.F (revision 100)
@@ -0,0 +1,3 @@
+        program main
+        print *, testname
+        end
Index: /mpich2/branches/dev/dkim/test/commands/README
===================================================================
--- /mpich2/branches/dev/dkim/test/commands/README (revision 100)
+++ /mpich2/branches/dev/dkim/test/commands/README (revision 100)
@@ -0,0 +1,11 @@
+This directory contains tests for commands that are included with MPICH2.
+These include tests of commands for compiling and linking MPI programs, 
+such as mpicc and mpif77, and for using mpiexec to run MPI programs.
+These tests cover both command-line options recommended by the MPI-Forum and
+options that are part of the common MPICH2 extensions for mpiexec.
+
+In addition, the program testout.c can be used to check the buffering of
+stdio.  As a quality of implementation issue, users expect programs run
+by mpiexec to preserve their buffering choice (or at least the appearence of
+it).  This program writes several lines of output with delays between each
+line; those delays should be observed when the program is run under mpiexec.
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/errmsg.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/errmsg.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/errmsg.c (revision 100)
@@ -0,0 +1,28 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include <stdio.h>
+#include "mpi.h"
+
+void ChkMsg( int, int, const char [] );
+
+/*
+ * This routine is used to check the message associated with an error
+ * code.  Currently, it uses MPI_Error_string to get the corresponding
+ * message for a code, and prints out the cooresponding class and original
+ * message.
+ * 
+ * Eventually, we should also access the generic anc specific messages
+ * separately.
+ */
+void ChkMsg( int err, int msgclass, const char msg[] )
+{
+    char errmsg[MPI_MAX_ERROR_STRING];
+    int len;
+
+    MPI_Error_string( err, errmsg, &len );
+    
+    fprintf( stdout, "[0x%08x] %2d %s \tgives %s\n", err, msgclass, msg, errmsg );
+}
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/errstring.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/errstring.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/errstring.c (revision 100)
@@ -0,0 +1,22 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+
+int main( int argc, char **argv )
+{
+    char msg[MPI_MAX_ERROR_STRING+1];
+    int i, len;
+
+    MPI_Init(0,0);
+    for (i=0; i<54; i++) {
+	MPI_Error_string( i, msg, &len );
+	printf( "msg for %d is %s\n", i, msg );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/errfatal.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/errfatal.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/errfatal.c (revision 100)
@@ -0,0 +1,43 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2004 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include <mpi.h>
+#include <stdio.h>
+
+static int verbose = 0;
+
+int main(int argc, char** argv) {
+	int MY_ERROR_CLASS;
+	int MY_ERROR_CODE;
+	char MY_ERROR_STRING[10];
+	
+	sprintf(MY_ERROR_STRING, "MY ERROR");
+	
+	MPI_Init(&argc, &argv);
+	
+	if (verbose) 
+	    printf("Adding My Error Class\n");
+	MPI_Add_error_class(&MY_ERROR_CLASS);
+	if (verbose) 
+	    printf("Adding My Error Code\n");
+	MPI_Add_error_code(MY_ERROR_CLASS, &MY_ERROR_CODE);
+	if (verbose)
+	    printf("Adding My Error String\n");
+	MPI_Add_error_string(MY_ERROR_CODE, MY_ERROR_STRING);
+
+	if (verbose)
+	    printf("Calling Error Handler\n");
+	MPI_Comm_call_errhandler(MPI_COMM_WORLD, MY_ERROR_CODE);
+
+	/* We should not get here, because the default error handler
+	   is ERRORS_ARE_FATAL.  This makes sure that the correct error 
+	   handler is called and that no failure occured (such as 
+	   a SEGV) in Comm_call_errhandler on the default 
+	   error handler. */
+	printf("After the Error Handler Has Been Called\n");
+
+	MPI_Finalize();
+	return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/adderr.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/adderr.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/adderr.c (revision 100)
@@ -0,0 +1,68 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/* Create NCLASSES new classes, each with 5 codes (160 total) */
+#define NCLASSES 32
+#define NCODES   5
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    char string[MPI_MAX_ERROR_STRING], outstring[MPI_MAX_ERROR_STRING];
+    int newclass[NCLASSES], newcode[NCLASSES][NCODES];
+    int i, j, slen, outclass;
+
+    MTest_Init( &argc, &argv );
+
+    /* Initialize the new codes */
+    for (i=0; i<NCLASSES; i++) {
+	MPI_Add_error_class( &newclass[i] );
+	for (j=0; j<NCODES; j++) {
+	    MPI_Add_error_code( newclass[i], &newcode[i][j] );
+	    sprintf( string, "code for class %d code %d\n", i, j );
+	    MPI_Add_error_string( newcode[i][j], string );
+	}
+    }
+
+    /* check the values */
+    for (i=0; i<NCLASSES; i++) {
+	MPI_Error_class( newclass[i], &outclass );
+	if (outclass != newclass[i]) {
+	    errs++;
+	    printf( "Error class %d is not a valid error code %x %x\n", i,
+		    outclass, newclass[i]);
+	}
+	for (j=0; j<NCODES; j++) {
+	    MPI_Error_class( newcode[i][j], &outclass );
+	    if (outclass != newclass[i]) {
+		errs++;
+		printf( "Class of code for %d is not correct %x %x\n", j,
+			outclass, newclass[i] );
+	    }
+	    MPI_Error_string( newcode[i][j], outstring, &slen );
+	    sprintf( string, "code for class %d code %d\n", i, j );
+	    if (strcmp( outstring, string )) {
+		errs++;
+		printf( "Error string is :%s: but should be :%s:\n",
+			outstring, string );
+	    }
+	}
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/commcall.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/commcall.c (revision 3347)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/commcall.c (revision 3347)
@@ -0,0 +1,82 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Test comm_call_errhandler";
+
+static int calls = 0;
+static int errs = 0;
+static MPI_Comm mycomm;
+void eh( MPI_Comm *comm, int *err, ... )
+{
+    if (*err != MPI_ERR_OTHER) {
+	errs++;
+	printf( "Unexpected error code\n" );
+    }
+    if (*comm != mycomm) {
+	errs++;
+	printf( "Unexpected communicator\n" );
+    }
+    calls++;
+    return;
+}
+int main( int argc, char *argv[] )
+{
+    MPI_Comm       comm;
+    MPI_Errhandler newerr;
+    int            i;
+
+    MTest_Init( &argc, &argv );
+
+    comm = MPI_COMM_WORLD;
+    mycomm = comm;
+
+    MPI_Comm_create_errhandler( eh, &newerr );
+
+    MPI_Comm_set_errhandler( comm, newerr );
+    MPI_Comm_call_errhandler( comm, MPI_ERR_OTHER );
+    MPI_Errhandler_free( &newerr );
+    if (calls != 1) {
+	errs++;
+	printf( "Error handler not called\n" );
+    }
+
+    /* Here we apply the test to many copies of a communicator */
+    for (i=0; i<1000; i++) {
+	MPI_Comm comm2;
+	calls = 0;
+	MPI_Comm_dup( MPI_COMM_WORLD, &comm );
+	mycomm = comm;
+	MPI_Comm_create_errhandler( eh, &newerr );
+
+	MPI_Comm_set_errhandler( comm, newerr );
+	MPI_Comm_call_errhandler( comm, MPI_ERR_OTHER );
+	if (calls != 1) {
+	    errs++;
+	    printf( "Error handler not called\n" );
+	}
+	MPI_Comm_dup( comm, &comm2 );
+	calls = 0;
+	mycomm = comm2;
+	/* comm2 must inherit the error handler from comm */
+	MPI_Comm_call_errhandler( comm2, MPI_ERR_OTHER );
+	MPI_Errhandler_free( &newerr );
+	if (calls != 1) {
+	    errs++;
+	    printf( "Error handler not called\n" );
+	}
+
+	MPI_Comm_free( &comm );
+	MPI_Comm_free( &comm2 );
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/errring.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/errring.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/errring.c (revision 100)
@@ -0,0 +1,28 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include <stdio.h>
+#include "mpi.h"
+
+#define MPIR_ERR_FATAL 1
+#define MPIR_ERR_RECOVERABLE 0
+int MPIR_Err_create_code(int, int, char *, int, int, const char [], const char [], ...);
+void MPIR_Err_print_stack(FILE * fp, int errcode);
+
+int main(int argc, char **argv)
+{
+    int err;
+    
+    MPI_Init( 0, 0 );
+
+    err = MPIR_Err_create_code(MPI_ERR_INTERN, MPIR_ERR_RECOVERABLE, "main", __LINE__, MPI_ERR_UNKNOWN, "**buffer", 0);
+    err = MPIR_Err_create_code(err, MPIR_ERR_RECOVERABLE, "main", __LINE__, MPI_ERR_UNKNOWN, "**count", 0);
+    err = MPIR_Err_create_code(err, MPIR_ERR_RECOVERABLE, "main", __LINE__, MPI_ERR_UNKNOWN, "**dtype", 0);
+    MPIR_Err_print_stack(stdout, err);
+    
+    MPI_Finalize();
+    return 0;
+}
+
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/Makefile.sm
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/Makefile.sm (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/Makefile.sm (revision 100)
@@ -0,0 +1,21 @@
+INCLUDES = -I../include -I${top_srcdir}/include
+LDADD = ../util/mtest.o 
+DEPADD = @MPILIBLOC@ ../util/mtest.o
+smvar_do_sharedlibs = 0
+
+adderr_SOURCES = adderr.c
+errstring_SOURCES = errstring.c
+errcode_SOURCES = errcode.c errmsg.c
+errring_SOURCES = errring.c
+commcall_SOURCES = commcall.c
+errfatal_SOURCES = errfatal.c
+
+EXTRA_PROGRAMS = errcode errring errstring
+
+../util/mtest.o: 
+	(cd ../util && make mtest.o)
+
+testing:
+	../runtests -srcdir=$(srcdir) -tests=testlist \
+			-mpiexec=$(bindir)/mpiexec \
+		   	-xmlfile=summary.xml
Index: /mpich2/branches/dev/dkim/test/mpi/errhan/testlist
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/errhan/testlist (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/errhan/testlist (revision 100)
@@ -0,0 +1,3 @@
+adderr 1
+commcall 2
+errfatal 1 resultTest=TestErrFatal
Index: /mpich2/branches/dev/dkim/test/mpi/basic/allmpi.vcproj
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/allmpi.vcproj (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/allmpi.vcproj (revision 100)
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="allmpi"
+	ProjectGUID="{D9F19E35-7870-4549-A69D-AD810E8BC167}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_WINCONF_H"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="mpich2d.lib"
+				OutputFile="$(OutDir)/allmpi.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/allmpi.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_WINCONF_H"
+				StringPooling="TRUE"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="mpich2.lib"
+				OutputFile="$(OutDir)/allmpi.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\allmpi.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/basic/patterns.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/patterns.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/patterns.c (revision 100)
@@ -0,0 +1,440 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define DEFAULT_RNDV_SIZE 24*1024
+/* Prototypes */
+int SendRecvTest(int, int);
+int IsendIrecvTest(int);
+int IsenIrecvTest2(int,int);
+int OutOfOrderTest(int,int);
+int ForceUnexpectedTest(int,int);
+int RndvTest(int,int,int);
+
+int SendRecvTest(int rank, int n)
+{
+    int tag = 1;
+    MPI_Status status;
+    char buffer[100];
+    int i;
+
+    if (rank == 0)
+    {
+	strcpy(buffer, "Hello process one.");
+	for (i=0; i<n; i++)
+	    MPI_Send(buffer, 100, MPI_BYTE, 1, tag, MPI_COMM_WORLD);
+    }
+    else if (rank == 1)
+    {
+	for (i=0; i<n; i++)
+	    MPI_Recv(buffer, 100, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
+	/*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout);*/
+    }
+
+    return TRUE;
+}
+
+int IsendIrecvTest(int rank)
+{
+    int tag = 1;
+    MPI_Status status;
+    MPI_Request request;
+    char buffer[100];
+
+    if (rank == 0)
+    {
+	strcpy(buffer, "Hello process one.");
+	MPI_Isend(buffer, 100, MPI_BYTE, 1, tag, MPI_COMM_WORLD, &request);
+	MPI_Wait(&request, &status);
+    }
+    else if (rank == 1)
+    {
+	MPI_Irecv(buffer, 100, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &request);
+	MPI_Wait(&request, &status);
+	/*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout);*/
+    }
+
+    return TRUE;
+}
+
+int IsendIrecvTest2(int rank, int buf_size)
+{
+    int tag1 = 1;
+    int tag2 = 2;
+    MPI_Status status;
+    MPI_Request request1, request2;
+    char *buffer;
+
+    buffer = (char*)malloc(buf_size);
+    if (buffer == NULL)
+	return FALSE;
+    if (rank == 0)
+    {
+	strcpy(buffer, "Hello process one.");
+	MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &request1);
+	MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag2, MPI_COMM_WORLD, &request2);
+	MPI_Wait(&request1, &status);
+	MPI_Wait(&request2, &status);
+    }
+    else if (rank == 1)
+    {
+	MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD, &request1);
+	MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag2, MPI_COMM_WORLD, &request2);
+	MPI_Wait(&request1, &status);
+	MPI_Wait(&request2, &status);
+	/*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout);*/
+    }
+
+    free(buffer);
+    return TRUE;
+}
+
+int OutOfOrderTest(int rank, int buf_size)
+{
+    int tag1 = 1;
+    int tag2 = 2;
+    MPI_Status status;
+    MPI_Request request1, request2;
+    char *buffer;
+
+    buffer = (char*)malloc(buf_size);
+    if (buffer == NULL)
+	return FALSE;
+    if (rank == 0)
+    {
+	strcpy(buffer, "Hello process one.");
+	MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &request1);
+	MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag2, MPI_COMM_WORLD, &request2);
+	MPI_Wait(&request1, &status);
+	MPI_Wait(&request2, &status);
+    }
+    else if (rank == 1)
+    {
+	MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag2, MPI_COMM_WORLD, &request1);
+	MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD, &request2);
+	MPI_Wait(&request2, &status);
+	MPI_Wait(&request1, &status);
+	/*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout);*/
+    }
+
+    free(buffer);
+    return TRUE;
+}
+
+int ForceUnexpectedTest(int rank, int buf_size)
+{
+    int tag1 = 1;
+    int tag2 = 2;
+    MPI_Status status;
+    MPI_Request request1, request2;
+    char *buffer;
+
+    buffer = (char*)malloc(buf_size);
+    if (buffer == NULL)
+	return FALSE;
+
+    if (rank == 0)
+    {
+	strcpy(buffer, "Hello process one.");
+	MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &request1);
+	MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag2, MPI_COMM_WORLD, &request2);
+	MPI_Wait(&request1, &status);
+	MPI_Wait(&request2, &status);
+	MPI_Recv(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &status);
+    }
+    else if (rank == 1)
+    {
+	MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag2, MPI_COMM_WORLD, &request2);
+	MPI_Wait(&request2, &status);
+	MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD, &request1);
+	MPI_Wait(&request1, &status);
+	/*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout);*/
+	MPI_Send(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD);
+    }
+
+    free(buffer);
+
+    return TRUE;
+}
+
+int RndvTest(int rank, int size, int reps)
+{
+    int tag = 1;
+    MPI_Status status;
+    char *buffer;
+    int i;
+
+    buffer = (char*)malloc(size);
+    if (buffer == NULL)
+    {
+	printf("malloc failed to allocate %d bytes.\n", size);
+	exit(0);
+    }
+    if (rank == 0)
+    {
+	for (i=0; i<reps; i++)
+	{
+	    if (reps == 1)
+	    {
+		printf("0: sending to process 1\n");
+		fflush(stdout);
+	    }
+	    MPI_Send(buffer, size, MPI_BYTE, 1, tag, MPI_COMM_WORLD);
+	    if (reps == 1)
+	    {
+		printf("0: receiving from process 1\n");
+		fflush(stdout);
+	    }
+	    MPI_Recv(buffer, size, MPI_BYTE, 1, tag, MPI_COMM_WORLD, &status);
+	    if (reps == 1)
+	    {
+		printf("0: done\n");
+		fflush(stdout);
+	    }
+	}
+    }
+    else if (rank == 1)
+    {
+	for (i=0; i<reps; i++)
+	{
+	    if (reps == 1)
+	    {
+		printf("1: receiving from process 0\n");
+		fflush(stdout);
+	    }
+	    MPI_Recv(buffer, size, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
+	    if (reps == 1)
+	    {
+		printf("1: sending to process 0\n");
+		fflush(stdout);
+	    }
+	    MPI_Send(buffer, size, MPI_BYTE, 0, tag, MPI_COMM_WORLD);
+	    if (reps == 1)
+	    {
+		printf("1: done\n");
+		fflush(stdout);
+	    }
+	}
+    }
+    free(buffer);
+
+    return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+    int result;
+    int size, rank;
+    int bDoAll = FALSE;
+    int reps;
+    int rndv_size = DEFAULT_RNDV_SIZE;
+
+    MPI_Init(&argc, &argv);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+    if (size < 2)
+    {
+	printf("Two processes needed.\n");
+	printf("options:\n");
+	printf(" sr [reps] ............... send/recv\n");
+	printf(" isr ..................... isend/irecv\n");
+	printf(" iisr .................... isend,isend/irecv,irecv wait\n");
+	printf(" oo ...................... out of order isend/irecv\n");
+	printf(" unex .................... force unexpected msg\n");
+	printf(" rndv [size] ............. rndv\n");
+	printf(" rndv_reps [reps] [size] . rndv\n");
+	printf(" rndv_iisr [size] ........ rndv iisr\n");
+	printf(" rndv_oo [size] .......... rndv oo\n");
+	printf(" rndv_unex [size] ........ rndv unex\n");
+	printf("default rndv size = %d bytes\n", DEFAULT_RNDV_SIZE);
+	MPI_Finalize();
+	return 0;
+    }
+
+    if (rank > 1)
+    {
+	printf("Rank %d, I am not participating.\n", rank);
+	fflush(stdout);
+    }
+    else
+    {
+	if (argc < 2)
+	    bDoAll = TRUE;
+
+	if (bDoAll || (strcmp(argv[1], "sr") == 0))
+	{
+	    reps = 1;
+	    if (argc > 2)
+	    {
+		reps = atoi(argv[2]);
+		if (reps < 1)
+		    reps = 1;
+	    }
+	    if (rank == 0)
+	    {
+		printf("Send/recv test: %d reps\n", reps);
+		fflush(stdout);
+	    }
+	    result = SendRecvTest(rank, reps);
+	    printf(result ? "%d:SUCCESS - sr\n" : "%d:FAILURE - sr\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "isr") == 0))
+	{
+	    if (rank == 0)
+	    {
+		printf("Isend/irecv wait test\n");
+		fflush(stdout);
+	    }
+	    result = IsendIrecvTest(rank);
+	    printf(result ? "%d:SUCCESS - isr\n" : "%d:FAILURE - isr\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "iisr") == 0))
+	{
+	    if (rank == 0)
+	    {
+		printf("Isend,isend/irecv,irecv wait wait test\n");
+		fflush(stdout);
+	    }
+	    result = IsendIrecvTest2(rank, 100);
+	    printf(result ? "%d:SUCCESS - iisr\n" : "%d:FAILURE - iisr\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "oo") == 0))
+	{
+	    if (rank == 0)
+	    {
+		printf("Out of order isend/irecv test\n");
+		fflush(stdout);
+	    }
+	    result = OutOfOrderTest(rank, 100);
+	    printf(result ? "%d:SUCCESS - oo\n" : "%d:FAILURE - oo\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "unex") == 0))
+	{
+	    if (rank == 0)
+	    {
+		printf("Force unexpected message test\n");
+		fflush(stdout);
+	    }
+	    result = ForceUnexpectedTest(rank, 100);
+	    printf(result ? "%d:SUCCESS - unex\n" : "%d:FAILURE - unex\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "rndv") == 0))
+	{
+	    if (argc > 2)
+	    {
+		rndv_size = atoi(argv[2]);
+		if (rndv_size < 1024)
+		    rndv_size = 1024;
+	    }
+	    if (rank == 0)
+	    {
+		printf("Rndv test\n");
+		fflush(stdout);
+	    }
+	    result = RndvTest(rank, rndv_size, 1);
+	    printf(result ? "%d:SUCCESS - rndv\n" : "%d:FAILURE - rndv\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "rndv_reps") == 0))
+	{
+	    reps = 100;
+	    if (argc > 2)
+	    {
+		reps = atoi(argv[2]);
+		if (reps < 1)
+		    reps = 1;
+	    }
+	    if (argc > 3)
+	    {
+		rndv_size = atoi(argv[3]);
+	    }
+	    if (rank == 0)
+	    {
+		printf("Rndv test: %d reps of size %d\n", reps, rndv_size);
+		fflush(stdout);
+	    }
+	    result = RndvTest(rank, rndv_size, reps);
+	    printf(result ? "%d:SUCCESS - rndv_reps\n" : "%d:FAILURE - rndv_reps\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "rndv_iisr") == 0))
+	{
+	    if (rank == 0)
+	    {
+		printf("Rndv isend,isend/irecv,irecv wait wait test\n");
+		fflush(stdout);
+	    }
+	    if (argc > 2)
+	    {
+		rndv_size = atoi(argv[2]);
+	    }
+	    result = IsendIrecvTest2(rank, rndv_size);
+	    printf(result ? "%d:SUCCESS - rndv_iisr\n" : "%d:FAILURE - rndv_iisr\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "rndv_oo") == 0))
+	{
+	    if (rank == 0)
+	    {
+		printf("Rndv out of order isend/irecv test\n");
+		fflush(stdout);
+	    }
+	    if (argc > 2)
+	    {
+		rndv_size = atoi(argv[2]);
+	    }
+	    result = OutOfOrderTest(rank, rndv_size);
+	    printf(result ? "%d:SUCCESS - rndv_oo\n" : "%d:FAILURE - rndv_oo\n", rank);
+	    fflush(stdout);
+	}
+
+	if (bDoAll || (strcmp(argv[1], "rndv_unex") == 0))
+	{
+	    if (argc > 2)
+	    {
+		rndv_size = atoi(argv[2]);
+		if (rndv_size < 1024)
+		    rndv_size = 1024;
+	    }
+	    if (rank == 0)
+	    {
+		printf("Force unexpected rndv message test\n");
+		fflush(stdout);
+	    }
+	    result = ForceUnexpectedTest(rank, rndv_size);
+	    printf(result ? "%d:SUCCESS - rndv_unex\n" : "%d:FAILURE - rndv_unex\n", rank);
+	    fflush(stdout);
+	}
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/GetOpt.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/GetOpt.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/GetOpt.c (revision 100)
@@ -0,0 +1,114 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "GetOpt.h"
+#include <stdio.h>
+
+bool GetOpt(int *argc, LPTSTR **argv, LPTSTR flag)
+{
+  int i,j;
+  if (flag == NULL)
+    return false;
+  
+  for (i=0; i<*argc; i++)
+    {
+      if (_tcsicmp((*argv)[i], flag) == 0)
+	{
+	  for (j=i; j<*argc; j++)
+	    {
+	      (*argv)[j] = (*argv)[j+1];
+	    }
+	  *argc -= 1;
+	  return true;
+	}
+    }
+  return false;
+}
+
+bool GetOptInt(int *argc, LPTSTR **argv, LPTSTR flag, int *n)
+{
+  int i,j;
+  if (flag == NULL)
+    return false;
+  
+  for (i=0; i<*argc; i++)
+    {
+      if (_tcsicmp((*argv)[i], flag) == 0)
+	{
+	  if (i+1 == *argc)
+	    return false;
+	  *n = _ttoi((*argv)[i+1]);
+	  for (j=i; j<*argc-1; j++)
+	    {
+	      (*argv)[j] = (*argv)[j+2];
+	    }
+	  *argc -= 2;
+	  return true;
+	}
+    }
+  return false;
+}
+
+bool GetOptLong(int *argc, LPTSTR **argv, LPTSTR flag, long *n)
+{
+  int i;
+  if (GetOptInt(argc, argv, flag, &i))
+    {
+      *n = (long)i;
+      return true;
+    }
+  return false;
+}
+
+bool GetOptDouble(int *argc, LPTSTR **argv, LPTSTR flag, double *d)
+{
+  int i,j;
+
+  if (flag == NULL)
+    return false;
+  
+  for (i=0; i<*argc; i++)
+    {
+      if (_tcsicmp((*argv)[i], flag) == 0)
+	{
+	  if (i+1 == *argc)
+	    return false;
+	  *d = _tcstod((*argv)[i+1], NULL);
+	  for (j=i; j<*argc-1; j++)
+	    {
+	      (*argv)[j] = (*argv)[j+2];
+	    }
+	  *argc -= 2;
+	  return true;
+	}
+    }
+  return false;
+}
+
+bool GetOptString(int *argc, LPTSTR **argv, LPTSTR flag, char *str)
+{
+  int i,j;
+
+  if (flag == NULL)
+    return false;
+
+  for (i=0; i<*argc; i++)
+    {
+      if (_tcsicmp((*argv)[i], flag) == 0)
+	{
+	  if (i+1 == *argc)
+	    return false;
+	  strcpy(str, (*argv)[i+1]);
+	  for (j=i; j<*argc-1; j++)
+	    {
+	      (*argv)[j] = (*argv)[j+2];
+	    }
+	  *argc -= 2;
+	  return true;
+	}
+    }
+  return false;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/srtest.vcproj
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/srtest.vcproj (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/srtest.vcproj (revision 100)
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="srtest"
+	ProjectGUID="{64826B3B-5D4D-426A-BA86-C7AC08DAD826}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="mpich2d.lib"
+				OutputFile="$(OutDir)/srtest.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/srtest.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="4"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="mpich2.lib"
+				OutputFile="$(OutDir)/srtest.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\srtest.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/basic/GetOpt.h
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/GetOpt.h (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/GetOpt.h (revision 100)
@@ -0,0 +1,30 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#ifndef GETOPT_H
+#define GETOPT_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define LPTSTR char *
+#define LPCTSTR char *
+#define _tcsicmp strcmp
+#define _ttoi atoi
+#define _tcstod(a,b) atof(a)
+#define stricmp strcmp
+#define bool int
+#define true 1
+#define false 0
+
+bool GetOpt(int *argc, char ***argv, char * flag);
+bool GetOptInt(int *argc, char ***argv, char * flag, int *n);
+bool GetOptLong(int *argc, char ***argv, char * flag, long *n);
+bool GetOptDouble(int *argc, char ***argv, char * flag, double *d);
+bool GetOptString(int *argc, char ***argv, char * flag, char *str);
+
+#endif
Index: /mpich2/branches/dev/dkim/test/mpi/basic/sendrecv.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/sendrecv.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/sendrecv.c (revision 100)
@@ -0,0 +1,97 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LARGE_SIZE  100*1024
+#define RNDV_SIZE   256*1024
+
+int main(int argc, char *argv[])
+{
+    int size, rank;
+    char buffer[100] = "garbage";
+    char big_buffer[RNDV_SIZE] = "big garbage";
+    MPI_Status status;
+    int tag = 1;
+    int reps = 1;
+    int i;
+
+    printf("Simple Send/Recv test.\n"); fflush(stdout);
+
+    MPI_Init(&argc, &argv);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+    if (size < 2)
+    {
+	printf("Two processes needed.\n");
+	MPI_Finalize();
+	return 0;
+    }
+
+    if (argc > 1)
+    {
+	reps = atoi(argv[1]);
+	if (reps < 1)
+	    reps = 1;
+    }
+
+    if (rank == 0)
+    {
+	printf("Rank 0: sending 100 bytes messages to process 1.\n"); fflush(stdout);
+	strcpy(buffer, "Hello process one.");
+	for (i = 0; i<reps; i++)
+	{
+	    MPI_Send(buffer, 100, MPI_BYTE, 1, tag, MPI_COMM_WORLD);
+	    MPI_Recv(buffer, 100, MPI_BYTE, 1, tag, MPI_COMM_WORLD, &status);
+	}
+	strcpy(big_buffer, "Hello again process one.");
+	printf("Rank 0: sending %dk bytes messages to process 1.\n", LARGE_SIZE/1024); fflush(stdout);
+	for (i = 0; i<reps; i++)
+	{
+	    MPI_Send(big_buffer, LARGE_SIZE, MPI_BYTE, 1, tag, MPI_COMM_WORLD);
+	    MPI_Recv(big_buffer, LARGE_SIZE, MPI_BYTE, 1, tag, MPI_COMM_WORLD, &status);
+	}
+	strcpy(big_buffer, "Hello yet again process one.");
+	printf("Rank 0: sending %dk bytes messages to process 1.\n", RNDV_SIZE/1024); fflush(stdout);
+	for (i = 0; i<reps; i++)
+	{
+	    MPI_Send(big_buffer, RNDV_SIZE, MPI_BYTE, 1, tag, MPI_COMM_WORLD);
+	    MPI_Recv(big_buffer, RNDV_SIZE, MPI_BYTE, 1, tag, MPI_COMM_WORLD, &status);
+	}
+    }
+    else if (rank == 1)
+    {
+	printf("Rank 1: receiving messages from process 0.\n"); fflush(stdout);
+	for (i = 0; i<reps; i++)
+	{
+	    MPI_Recv(buffer, 100, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
+	    MPI_Send(buffer, 100, MPI_BYTE, 0, tag, MPI_COMM_WORLD);
+	}
+	printf("Rank 1: received message '%s'\n", buffer); fflush(stdout);
+	for (i = 0; i<reps; i++)
+	{
+	    MPI_Recv(big_buffer, LARGE_SIZE, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
+	    MPI_Send(big_buffer, LARGE_SIZE, MPI_BYTE, 0, tag, MPI_COMM_WORLD);
+	}
+	printf("Rank 1: received message '%s'\n", big_buffer); fflush(stdout);
+	for (i = 0; i<reps; i++)
+	{
+	    MPI_Recv(big_buffer, RNDV_SIZE, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
+	    MPI_Send(big_buffer, RNDV_SIZE, MPI_BYTE, 0, tag, MPI_COMM_WORLD);
+	}
+	printf("Rank 1: received message '%s'\n", big_buffer); fflush(stdout);
+    }
+    else
+    {
+	printf("Rank %d, I am not participating.\n", rank); fflush(stdout);
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/Makefile.sm
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/Makefile.sm (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/Makefile.sm (revision 100)
@@ -0,0 +1,17 @@
+INCLUDES = -I../include -I${srcdir}/../include
+LDADD = 
+DEPADD = @MPILIBLOC@
+smvar_do_sharedlibs = 0
+
+# The allmpi program uses MPICH internal header files
+EXTRA_PROGRAMS = allmpi
+
+self_SOURCES = self.c
+simple_SOURCES = simple.c
+sendrecv_SOURCES = sendrecv.c
+srtest_SOURCES = srtest.c
+wtime_SOURCES = wtime.c
+netpipe_SOURCES = netmpi.c GetOpt.c
+patterns_SOURCES = patterns.c
+adapt_SOURCES = adapt.c GetOpt.c
+allmpi_SOURCES = allmpi.c
Index: /mpich2/branches/dev/dkim/test/mpi/basic/adapt.vcproj
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/adapt.vcproj (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/adapt.vcproj (revision 100)
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="adapt"
+	ProjectGUID="{007A861C-6EA1-4FF5-BD37-93C21EDE532D}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;HAVE_WINDOWS_H"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="mpich2d.lib ws2_32.lib "
+				OutputFile="$(OutDir)/adapt.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/adapt.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="TRUE"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;HAVE_WINDOWS_H"
+				StringPooling="TRUE"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="mpich2.lib ws2_32.lib"
+				OutputFile="$(OutDir)/adapt.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+			<File
+				RelativePath="adapt.c">
+			</File>
+			<File
+				RelativePath="GetOpt.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc">
+			<File
+				RelativePath="GetOpt.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/basic/simple.vcproj
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/simple.vcproj (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/simple.vcproj (revision 100)
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="simple"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\Release"
+			IntermediateDirectory=".\Release"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
+				StringPooling="TRUE"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Release/simple.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpich2.lib odbc32.lib odbccp32.lib"
+				OutputFile=".\Release/simple.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				ProgramDatabaseFile=".\Release/simple.pdb"
+				SubSystem="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Release/simple.tlb"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Debug/simple.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="4"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpich2d.lib odbc32.lib odbccp32.lib"
+				OutputFile=".\Debug/simple.exe"
+				LinkIncremental="2"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\Debug/simple.pdb"
+				SubSystem="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Debug/simple.tlb"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp">
+			<File
+				RelativePath=".\simple.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;fi;fd">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/basic/allmpi.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/allmpi.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/allmpi.c (revision 100)
@@ -0,0 +1,381 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+/* necessary to get the conditional definitions:
+   HAVE_FORTRAN_BINDING
+   MPI_MPI_IO
+*/
+#include "mpitestconf.h"
+#include <stdio.h>
+#include <string.h>
+
+void handler( MPI_Comm *comm_ptr, int *int_ptr, ... ) {}
+int comm_copy_attr_fn(MPI_Comm comm, int i, void * buf1, void *buf2, void *buf3, int *int_ptr) {return 0;}
+int comm_delete_attr_fn(MPI_Comm comm, int i, void *buf1, void *buf2) {return 0;}
+int tcopy_attr_fn(MPI_Datatype dtype, int i, void *buf1, void *buf2, void *buf3, int *int_ptr) {return 0;}
+int tdelete_attr_fn(MPI_Datatype dtype, int i, void *buf1, void *buf2) {return 0;}
+int win_copy_attr_fn(MPI_Win win, int i, void *buf1, void *buf2, void *buf3, int *int_ptr) {return 0;}
+int win_delete_attr_fn(MPI_Win win, int i, void *buf1, void *buf2) {return 0;}
+void comm_errhan(MPI_Comm *comm_ptr, int *int_ptr, ...) {}
+#ifdef HAVE_MPI_IO
+void file_errhan(MPI_File *file_ptr, int *int_ptr, ...) {}
+#endif
+void win_errhan(MPI_Win *win_ptr, int *int_ptr, ...) {}
+void user_fn( void *buf1, void *buf2, int *int_ptr, MPI_Datatype *dtype_ptr) {}
+int copy_fn(MPI_Comm comm, int i, void *buf1, void *buf2, void *buf3, int *int_ptr) {return 0;}
+int delete_fn(MPI_Comm comm, int i, void *buf1, void *buf2) {return 0;}
+int cancel_fn(void *buf, int i) {return 0;}
+int free_fn(void *buf) {return 0;}
+int query_fn(void *buf, MPI_Status *status_ptr) {return 0;}
+int conversion_fn(void *buf1, MPI_Datatype dtype, int i, void *buf2, MPI_Offset offset, void *buf3) {return 0;}
+int extent_fn(MPI_Datatype dtype, MPI_Aint *aint_ptr, void *buf) {return 0;}
+
+void testAll(void)
+{
+    char *cbuf = NULL;
+    int *ibuf = NULL;
+    void *vbuf = NULL;
+    int i = 0;
+    int rank = 0;
+    int tag = 0;
+    MPI_Datatype dtype = MPI_BYTE;
+    MPI_Comm comm = MPI_COMM_WORLD;
+    MPI_Request request = MPI_REQUEST_NULL;
+    MPI_Status status;
+    MPI_Group group = MPI_GROUP_NULL;
+    MPI_Win win = MPI_WIN_NULL;
+    MPI_User_function user_fn;
+    MPI_Op op = MPI_SUM;
+    MPI_Aint aint = 0;
+    MPI_Fint fint = 0;
+    MPI_Copy_function copy_fn;
+    MPI_Delete_function delete_fn;
+    MPI_Errhandler errhan;
+    int a3[1][3];
+    int argc = 0;
+    char **argv = NULL;
+    char ***argvp = NULL;
+    MPI_Info info = MPI_INFO_NULL;
+    char *cmd = NULL;
+    char *type_name = NULL;
+#ifdef HAVE_MPI_IO
+    MPI_File file = MPI_FILE_NULL;
+    char *filename = NULL;
+    int amode = 0;
+    MPI_Offset size = 0, offset = 0;
+    MPI_Request iorequest;
+#endif
+
+    MPI_Send(vbuf, i, dtype, i, i, comm);
+    MPI_Recv(vbuf, i, dtype, rank, tag, comm, &status);
+    MPI_Get_count(&status, dtype, &i);
+    MPI_Bsend(vbuf, i, dtype, rank, tag, comm);
+    MPI_Ssend(vbuf, i, dtype, rank, tag, comm);
+    MPI_Rsend(vbuf, i, dtype, rank, tag, comm);
+    MPI_Buffer_attach( vbuf, i);
+    MPI_Buffer_detach( vbuf, &i);
+    MPI_Isend(vbuf, i, dtype, rank, tag, comm, &request);
+    MPI_Ibsend(vbuf, i, dtype, rank, tag, comm, &request);
+    MPI_Issend(vbuf, i, dtype, rank, tag, comm, &request);
+    MPI_Irsend(vbuf, i, dtype, rank, tag, comm, &request);
+    MPI_Irecv(vbuf, i, dtype, rank, tag, comm, &request);
+    MPI_Wait(&request, &status);
+    MPI_Test(&request, &i, &status);
+    MPI_Request_free(&request);
+    MPI_Waitany(i, &request, &i, &status);
+    MPI_Testany(i, &request, &i, &i, &status);
+    MPI_Waitall(i, &request, &status);
+    MPI_Testall(i, &request, &i, &status);
+    MPI_Waitsome(i, &request, &i, &i, &status);
+    MPI_Testsome(i, &request, &i, &i, &status);
+    MPI_Iprobe(i, i, comm, &i, &status);
+    MPI_Probe(i, i, comm, &status);
+    MPI_Cancel(&request);
+    MPI_Test_cancelled(&status, &i);
+    MPI_Send_init(vbuf, i, dtype, rank, tag, comm, &request);
+    MPI_Bsend_init(vbuf, i, dtype, i,i, comm, &request);
+    MPI_Ssend_init(vbuf, i, dtype, i,i, comm, &request);
+    MPI_Rsend_init(vbuf, i, dtype, i,i, comm, &request);
+    MPI_Recv_init(vbuf, i, dtype, i,i, comm, &request);
+    MPI_Start(&request);
+    MPI_Startall(i, &request);
+    MPI_Sendrecv(vbuf, i, dtype,rank, tag, vbuf, i, dtype, rank, tag, comm, &status);
+    MPI_Sendrecv_replace(vbuf, i, dtype, rank, tag, rank, tag, comm, &status);
+    MPI_Type_contiguous(i, dtype, &dtype);
+    MPI_Type_vector(i, i, i, dtype, &dtype);
+    MPI_Type_hvector(i, i, aint, dtype, &dtype);
+    MPI_Type_indexed(i, &i, &i, dtype, &dtype);
+    MPI_Type_hindexed(i, &i, &aint, dtype, &dtype);
+    MPI_Type_struct(i, &i, &aint, &dtype, &dtype);
+    MPI_Address(vbuf, &aint);
+    MPI_Type_extent(dtype, &aint);
+    MPI_Type_size(dtype, &i);
+    MPI_Type_lb(dtype, &aint);
+    MPI_Type_ub(dtype, &aint);
+    MPI_Type_commit(&dtype);
+    MPI_Type_free(&dtype);
+    MPI_Get_elements(&status, dtype, &i);
+    MPI_Pack(vbuf, i, dtype, vbuf, i, &i,  comm);
+    MPI_Unpack(vbuf, i, &i, vbuf, i, dtype, comm);
+    MPI_Pack_size(i, dtype, comm, &i);
+    MPI_Barrier(comm );
+    MPI_Bcast(vbuf, i, dtype, i, comm );
+    MPI_Gather(vbuf , i, dtype, vbuf, i, dtype, i, comm); 
+    MPI_Gatherv(vbuf , i, dtype, vbuf, &i, &i, dtype, i, comm); 
+    MPI_Scatter(vbuf , i, dtype, vbuf, i, dtype, i, comm);
+    MPI_Scatterv(vbuf , &i, &i,  dtype, vbuf, i, dtype, i, comm);
+    MPI_Allgather(vbuf , i, dtype, vbuf, i, dtype, comm);
+    MPI_Allgatherv(vbuf , i, dtype, vbuf, &i, &i, dtype, comm);
+    MPI_Alltoall(vbuf , i, dtype, vbuf, i, dtype, comm);
+    MPI_Alltoallv(vbuf , &i, &i, dtype, vbuf, &i, &i, dtype, comm);
+    MPI_Reduce(vbuf , vbuf, i, dtype, op, i, comm);
+    MPI_Op_create(&user_fn, i, &op);
+    MPI_Op_free( &op);
+    MPI_Allreduce(vbuf , vbuf, i, dtype, op, comm);
+    MPI_Reduce_scatter(vbuf , vbuf, &i, dtype, op, comm);
+    MPI_Scan(vbuf , vbuf, i, dtype, op, comm );
+    MPI_Group_size(group, &i);
+    MPI_Group_rank(group, &i);
+    MPI_Group_translate_ranks (group, i, &i, group, &i);
+    MPI_Group_compare(group, group, &i);
+    MPI_Comm_group(comm, &group);
+    MPI_Group_union(group, group, &group);
+    MPI_Group_intersection(group, group, &group);
+    MPI_Group_difference(group, group, &group);
+    MPI_Group_incl(group, i, &i, &group);
+    MPI_Group_excl(group, i, &i, &group);
+    MPI_Group_range_incl(group, i, a3, &group);
+    MPI_Group_range_excl(group, i, a3, &group);
+    MPI_Group_free(&group);
+    MPI_Comm_size(comm, &i);
+    MPI_Comm_rank(comm, &i);
+    MPI_Comm_compare(comm, comm, &i);
+    MPI_Comm_dup(comm, &comm);
+    MPI_Comm_create(comm, group, &comm);
+    MPI_Comm_split(comm, i, i, &comm);
+    MPI_Comm_free(&comm);
+    MPI_Comm_test_inter(comm, &i);
+    MPI_Comm_remote_size(comm, &i);
+    MPI_Comm_remote_group(comm, &group);
+    MPI_Intercomm_create(comm, i, comm, i, i, &comm );
+    MPI_Intercomm_merge(comm, i, &comm);
+    MPI_Keyval_create(&copy_fn, &delete_fn, &i, vbuf);
+    MPI_Keyval_free(&i);
+    MPI_Attr_put(comm, i, vbuf);
+    MPI_Attr_get(comm, i, vbuf, &i);
+    MPI_Attr_delete(comm, i);
+    MPI_Topo_test(comm, &i);
+    MPI_Cart_create(comm, i, &i, &i, i, &comm);
+    MPI_Dims_create(i, i, &i);
+    MPI_Graph_create(comm, i, &i, &i, i, &comm);
+    MPI_Graphdims_get(comm, &i, &i);
+    MPI_Graph_get(comm, i, i, &i, &i);
+    MPI_Cartdim_get(comm, &i);
+    MPI_Cart_get(comm, i, &i, &i, &i);
+    MPI_Cart_rank(comm, &i, &i);
+    MPI_Cart_coords(comm, i, i, &i);
+    MPI_Graph_neighbors_count(comm, i, &i);
+    MPI_Graph_neighbors(comm, i, i, &i);
+    MPI_Cart_shift(comm, i, i, &i, &i);
+    MPI_Cart_sub(comm, &i, &comm);
+    MPI_Cart_map(comm, i, &i, &i, &i);
+    MPI_Graph_map(comm, i, &i, &i, &i);
+    MPI_Get_processor_name(cbuf, &i);
+    MPI_Get_version(&i, &i);
+    MPI_Errhandler_create(&handler, &errhan);
+    MPI_Errhandler_set(comm, errhan);
+    MPI_Errhandler_get(comm, &errhan);
+    MPI_Errhandler_free(&errhan);
+    MPI_Error_string(i, cbuf, &i);
+    MPI_Error_class(i, &i);
+    MPI_Wtime();
+    MPI_Wtick();
+    MPI_Init(&argc, &argv);
+    MPI_Finalize();
+    MPI_Initialized(&i);
+    MPI_Abort(comm, i);
+    MPI_Pcontrol(0);
+    MPI_DUP_FN( comm, i, vbuf, vbuf, vbuf, &i );
+    MPI_Close_port(cbuf);
+    MPI_Comm_accept(cbuf, info, i, comm, &comm);
+    MPI_Comm_connect(cbuf, info, i, comm, &comm);
+    MPI_Comm_disconnect(&comm);
+    MPI_Comm_get_parent(&comm);
+    MPI_Comm_join(i, &comm);
+    MPI_Comm_spawn(cbuf, &cmd, i, info, i, comm, &comm, &i);
+    MPI_Comm_spawn_multiple(i, &cmd, argvp, &i, &info, i, comm, &comm, &i); 
+    MPI_Lookup_name(cbuf, info, cbuf);
+    MPI_Open_port(info, cbuf);
+    MPI_Publish_name(cbuf, info, cbuf);
+    MPI_Unpublish_name(cbuf, info, cbuf);
+    MPI_Accumulate(vbuf, i, dtype, i, aint, i, dtype,  op, win);
+    MPI_Get(vbuf, i, dtype, i, aint, i, dtype, win);
+    MPI_Put(vbuf, i, dtype, i, aint, i, dtype, win);
+    MPI_Win_complete(win);
+    MPI_Win_create(vbuf, aint, i, info, comm, &win);
+    MPI_Win_fence(i, win);
+    MPI_Win_free(&win);
+    MPI_Win_get_group(win, &group);
+    MPI_Win_lock(i, i, i, win);
+    MPI_Win_post(group, i, win);
+    MPI_Win_start(group, i, win);
+    MPI_Win_test(win, &i);
+    MPI_Win_unlock(i, win);
+    MPI_Win_wait(win);
+    MPI_Alltoallw(vbuf, &i, &i, &dtype, vbuf, &i, &i, &dtype, comm);
+    MPI_Exscan(vbuf, vbuf, i, dtype, op, comm) ;
+    MPI_Add_error_class(&i);
+    MPI_Add_error_code(i, &i);
+    MPI_Add_error_string(i, cbuf);
+    MPI_Comm_call_errhandler(comm, i);
+    MPI_Comm_create_keyval(&comm_copy_attr_fn, &comm_delete_attr_fn, &i, vbuf);
+    MPI_Comm_delete_attr(comm, i);
+    MPI_Comm_free_keyval(&i);
+    MPI_Comm_get_attr(comm, i, vbuf, &i);
+    MPI_Comm_get_name(comm, cbuf, &i);
+    MPI_Comm_set_attr(comm, i, vbuf);
+    MPI_Comm_set_name(comm, cbuf);
+#ifdef HAVE_MPI_IO
+    MPI_File_call_errhandler(file, i);
+#endif
+    MPI_Grequest_complete(request);
+    MPI_Grequest_start(&query_fn, &free_fn, &cancel_fn, vbuf, &request);
+    MPI_Init_thread(&argc, &argv, i, &i);
+    MPI_Is_thread_main(&i);
+    MPI_Query_thread(&i);
+    MPI_Status_set_cancelled(&status, i);
+    MPI_Status_set_elements(&status, dtype, i);
+    MPI_Type_create_keyval(&tcopy_attr_fn, &tdelete_attr_fn, &i, vbuf);
+    MPI_Type_delete_attr(dtype, i);
+    MPI_Type_dup(dtype, &dtype);
+    MPI_Type_free_keyval(&i);
+    MPI_Type_get_attr(dtype, i, vbuf, &i);
+    MPI_Type_get_contents(dtype, i, i, i, &i, &aint, &dtype);
+    MPI_Type_get_envelope(dtype, &i, &i, &i, &i);
+    MPI_Type_get_name(dtype, cbuf, &i);
+    MPI_Type_set_attr(dtype, i, vbuf);
+    MPI_Type_set_name(dtype, type_name);
+    MPI_Win_call_errhandler(win, i);
+    MPI_Win_create_keyval(&win_copy_attr_fn, win_delete_attr_fn, &i, vbuf);
+    MPI_Win_delete_attr(win, i);
+    MPI_Win_free_keyval(&i);
+    MPI_Win_get_attr(win, i, vbuf, &i);
+    MPI_Win_get_name(win, cbuf, &i);
+    MPI_Win_set_attr(win, i, vbuf);
+    MPI_Win_set_name(win, cbuf);
+    MPI_Alloc_mem(aint, info, vbuf);
+    MPI_Comm_create_errhandler(&comm_errhan, &errhan);
+    MPI_Comm_get_errhandler(comm, &errhan);
+    MPI_Comm_set_errhandler(comm, errhan);
+#ifdef HAVE_MPI_IO
+    MPI_File_create_errhandler(&file_errhan, &errhan);
+    MPI_File_get_errhandler(file, &errhan);
+    MPI_File_set_errhandler(file, errhan);
+#endif
+    MPI_Finalized(&i);
+    MPI_Free_mem(vbuf);
+    MPI_Get_address(vbuf, &aint);
+    MPI_Info_create(&info);
+    MPI_Info_delete(info, cbuf);
+    MPI_Info_dup(info, &info);
+    MPI_Info_free(&info);
+    MPI_Info_get(info, cbuf, i, cbuf, &i);
+    MPI_Info_get_nkeys(info, &i);
+    MPI_Info_get_nthkey(info, i, cbuf);
+    MPI_Info_get_valuelen(info, cbuf, &i, &i);
+    MPI_Info_set(info, cbuf, cbuf);
+    MPI_Pack_external(cbuf, vbuf, i, dtype, vbuf, aint, &aint); 
+    MPI_Pack_external_size(cbuf, i, dtype, &aint); 
+    MPI_Request_get_status(request, &i, &status);
+#ifdef HAVE_FORTRAN_BINDING
+    MPI_Status_c2f(&status, &fint);
+    MPI_Status_f2c(&fint, &status);
+#endif
+    MPI_Type_create_darray(i, i, i, &i, &i, &i, &i, i, dtype, &dtype);
+    MPI_Type_create_subarray(i, &i, &i, &i, i, dtype, &dtype);
+    MPI_Type_create_hindexed(i, &i, &aint, dtype, &dtype);
+    MPI_Type_create_hvector(i, i, aint, dtype, &dtype);
+    MPI_Type_create_indexed_block(i, i, &i, dtype, &dtype);
+    MPI_Type_create_resized(dtype, aint, aint, &dtype);
+    MPI_Type_create_struct(i, &i, &aint, &dtype, &dtype);
+    MPI_Type_get_extent(dtype, &aint, &aint);
+    MPI_Type_get_true_extent(dtype, &aint, &aint);
+    MPI_Unpack_external(cbuf, vbuf, aint, &aint, vbuf, i, dtype); 
+    MPI_Win_create_errhandler(&win_errhan, &errhan);
+    MPI_Win_get_errhandler(win, &errhan);
+    MPI_Win_set_errhandler(win, errhan);
+#ifdef HAVE_MPI_IO
+    MPI_File_open(comm, filename, amode, info, &file);
+    MPI_File_close(&file);
+    MPI_File_delete(filename, info);
+    MPI_File_set_size(file, size);
+    MPI_File_preallocate(file, size);
+    MPI_File_get_size(file, &size);
+    MPI_File_get_group(file, &group);
+    MPI_File_get_amode(file, &amode);
+    MPI_File_set_info(file, info);
+    MPI_File_get_info(file, &info);
+    MPI_File_set_view(file, offset, dtype, dtype, cbuf, info);
+    MPI_File_get_view(file, &offset, &dtype, &dtype, cbuf);
+    MPI_File_read_at(file, offset, vbuf, i, dtype, &status);
+    MPI_File_read_at_all(file, offset, vbuf, i, dtype, &status);
+    MPI_File_write_at(file, offset, vbuf, i, dtype, &status);
+    MPI_File_write_at_all(file, offset, vbuf, i, dtype, &status);
+    MPI_File_iread_at(file, offset, vbuf, i, dtype, &iorequest);
+    MPI_File_iwrite_at(file, offset, vbuf, i, dtype, &iorequest);
+    MPI_File_read(file, vbuf, i, dtype, &status); 
+    MPI_File_read_all(file, vbuf, i, dtype, &status);
+    MPI_File_write(file, vbuf, i, dtype, &status);
+    MPI_File_write_all(file, vbuf, i, dtype, &status);
+    MPI_File_iread(file, vbuf, i, dtype, &iorequest);
+    MPI_File_iwrite(file, vbuf, i, dtype, &iorequest);
+    MPI_File_seek(file, offset, i);
+    MPI_File_get_position(file, &offset);
+    MPI_File_get_byte_offset(file, offset, &offset);
+    MPI_File_read_shared(file, vbuf, i, dtype, &status);
+    MPI_File_write_shared(file, vbuf, i, dtype, &status);
+    MPI_File_iread_shared(file, vbuf, i, dtype, &iorequest);
+    MPI_File_iwrite_shared(file, vbuf, i, dtype, &iorequest);
+    MPI_File_read_ordered(file, vbuf, i, dtype, &status);
+    MPI_File_write_ordered(file, vbuf, i, dtype, &status);
+    MPI_File_seek_shared(file, offset, i);
+    MPI_File_get_position_shared(file, &offset);
+    MPI_File_read_at_all_begin(file, offset, vbuf, i, dtype);
+    MPI_File_read_at_all_end(file, vbuf, &status);
+    MPI_File_write_at_all_begin(file, offset, vbuf, i, dtype);
+    MPI_File_write_at_all_end(file, vbuf, &status);
+    MPI_File_read_all_begin(file, vbuf, i, dtype);
+    MPI_File_read_all_end(file, vbuf, &status);
+    MPI_File_write_all_begin(file, vbuf, i, dtype);
+    MPI_File_write_all_end(file, vbuf, &status);
+    MPI_File_read_ordered_begin(file, vbuf, i, dtype);
+    MPI_File_read_ordered_end(file, vbuf, &status);
+    MPI_File_write_ordered_begin(file, vbuf, i, dtype);
+    MPI_File_write_ordered_end(file, vbuf, &status);
+    MPI_File_get_type_extent(file, dtype, &aint);
+    MPI_File_set_atomicity(file, i);
+    MPI_File_get_atomicity(file, &i);
+    MPI_File_sync(file);
+    MPI_File_set_errhandler(file, errhan);
+    MPI_File_get_errhandler(file, &errhan);
+    MPI_Type_create_subarray(i, &i, &i, &i, i, dtype, &dtype);
+    MPI_Type_create_darray(i, i, i, &i, &i, &i, &i, i, dtype, &dtype);
+    MPI_File_f2c(fint);
+    MPI_File_c2f(file);
+#endif
+}
+
+int main(int argc, char *argv[])
+{
+    MPI_Init(&argc, &argv);
+
+    /* make it possible to call testAll so the compiler doesn't optimize out the code? */
+    if (argc > 1 && strcmp(argv[1], "flooglebottom") == 0)
+	testAll();
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/patterns.vcproj
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/patterns.vcproj (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/patterns.vcproj (revision 100)
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="patterns"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\Release"
+			IntermediateDirectory=".\Release"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
+				StringPooling="TRUE"
+				RuntimeLibrary="4"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Release/patterns.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpich2.lib odbc32.lib odbccp32.lib"
+				OutputFile=".\Release/patterns.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				ProgramDatabaseFile=".\Release/patterns.pdb"
+				SubSystem="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Release/patterns.tlb"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Debug/patterns.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="4"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpich2d.lib odbc32.lib odbccp32.lib"
+				OutputFile=".\Debug/patterns.exe"
+				LinkIncremental="2"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\Debug/patterns.pdb"
+				SubSystem="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Debug/patterns.tlb"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp">
+			<File
+				RelativePath=".\patterns.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;fi;fd">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/basic/srtest.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/srtest.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/srtest.c (revision 100)
@@ -0,0 +1,53 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <string.h>
+
+#define BUFLEN 512
+
+int main(int argc, char *argv[])
+{
+    int myid, numprocs, next, namelen;
+    char buffer[BUFLEN], processor_name[MPI_MAX_PROCESSOR_NAME];
+    MPI_Status status;
+
+    MPI_Init(&argc,&argv);
+    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
+    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
+    MPI_Get_processor_name(processor_name,&namelen);
+    fprintf(stderr,"Process %d of %d is alive on %s\n", myid, numprocs, processor_name);
+
+    strcpy(buffer,"hello there");
+    if (myid == numprocs-1)
+	next = 0;
+    else
+	next = myid+1;
+
+    if (myid == 0)
+    {
+	printf("%d sending '%s' \n",myid,buffer);
+	MPI_Send(buffer, (int)strlen(buffer)+1, MPI_CHAR, next, 99, MPI_COMM_WORLD);
+	printf("%d receiving \n",myid);
+	MPI_Recv(buffer, BUFLEN, MPI_CHAR, MPI_ANY_SOURCE, 99, MPI_COMM_WORLD,
+		 &status);
+	printf("%d received '%s' \n",myid,buffer);
+	/* mpdprintf(001,"%d receiving \n",myid); */
+    }
+    else
+    {
+	printf("%d receiving  \n",myid);
+	MPI_Recv(buffer, BUFLEN, MPI_CHAR, MPI_ANY_SOURCE, 99, MPI_COMM_WORLD,
+		 &status);
+	printf("%d received '%s' \n",myid,buffer);
+	/* mpdprintf(001,"%d receiving \n",myid); */
+	MPI_Send(buffer, (int)strlen(buffer)+1, MPI_CHAR, next, 99, MPI_COMM_WORLD);
+	printf("%d sent '%s' \n",myid,buffer);
+    }
+    MPI_Barrier(MPI_COMM_WORLD);
+    MPI_Finalize();
+    return (0);
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/wtime.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/wtime.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/wtime.c (revision 100)
@@ -0,0 +1,27 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+	int i;
+	double dStart, dFinish, dDuration;
+
+	MPI_Init(&argc, &argv);
+	MPI_Comm_rank(MPI_COMM_WORLD, &i);
+
+	dStart = MPI_Wtime();
+	sleep(1);
+	dFinish = MPI_Wtime();
+	dDuration = dFinish - dStart;
+
+	printf("start:%g\nfinish:%g\nduration:%g\n", dStart, dFinish, dDuration);
+
+	MPI_Finalize();
+	return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/netpipe.vcproj
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/netpipe.vcproj (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/netpipe.vcproj (revision 100)
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="netpipe"
+	ProjectGUID="{FF13401B-AB0F-4659-823E-E3AA20D85E8B}"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\Release"
+			IntermediateDirectory=".\Release"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Release/netpipe.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\src\include\win32"
+				PreprocessorDefinitions="NDEBUG,WIN32,_CONSOLE,HAVE_WINDOWS_H"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				PrecompiledHeaderFile=".\Release/netpipe.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpi.lib odbc32.lib odbccp32.lib ws2_32.lib"
+				OutputFile=".\Release/netpipe.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				ProgramDatabaseFile=".\Release/netpipe.pdb"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Debug/netpipe.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\src\include\win32"
+				PreprocessorDefinitions="_DEBUG,WIN32,_CONSOLE,HAVE_WINDOWS_H"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				PrecompiledHeaderFile=".\Debug/netpipe.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="4"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpid.lib ws2_32.lib odbc32.lib odbccp32.lib"
+				OutputFile=".\Debug/netpipe.exe"
+				LinkIncremental="2"
+				SuppressStartupBanner="true"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\Debug/netpipe.pdb"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+			>
+			<File
+				RelativePath=".\GetOpt.c"
+				>
+			</File>
+			<File
+				RelativePath=".\netmpi.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl"
+			>
+			<File
+				RelativePath=".\GetOpt.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/basic/self.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/self.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/self.c (revision 100)
@@ -0,0 +1,22 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+
+int main(int argc, char *argv[])
+{
+    int i, j;
+    MPI_Status status;
+
+    MPI_Init(&argc,&argv);
+
+    MPI_Sendrecv ( &i, 1, MPI_INT, 0, 100,
+                   &j, 1, MPI_INT, 0, 100,
+                   MPI_COMM_WORLD, &status );
+
+    MPI_Finalize();
+    return (0);
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/simple.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/simple.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/simple.c (revision 100)
@@ -0,0 +1,14 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+
+int main(int argc, char *argv[])
+{
+    MPI_Init(&argc, &argv);
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/adapt.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/adapt.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/adapt.c (revision 100)
@@ -0,0 +1,1599 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#ifdef HAVE_WINDOWS_H
+#include <winsock2.h>
+#include <windows.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi.h"
+#include "GetOpt.h"
+
+#ifndef BOOL
+typedef int BOOL;
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define MIN(x, y)	(((x) < (y))?(x):(y))
+#define MAX(x, y)	(((x) > (y))?(x):(y))
+
+#ifdef HAVE_WINDOWS_H
+#define POINTER_TO_INT(a)   ( ( int )( 0xffffffff & (__int64) ( a ) ) )
+#else
+#define POINTER_TO_INT(a)   ( ( MPI_Aint )( a ) )
+#endif
+
+#define CREATE_DIFFERENCE_CURVES
+#undef CREATE_SINGLE_CURVE
+
+#define MAX_NUM_O12_TRIALS 18
+#define TRIALS          7
+#define PERT            3
+#define LONGTIME        1e99
+#define CHARSIZE        8
+#define RUNTM		0.1
+#define MAXINT          2147483647
+#define MAX_LAT_TIME    2
+#define LEFT_PROCESS    0
+#define MIDDLE_PROCESS  1
+#define RIGHT_PROCESS   2
+#define MSG_TAG_01      9901
+#define MSG_TAG_12      9912
+#define MSG_TAG_012     9012
+
+int     g_left_rank       = -1;
+int     g_middle_rank     = -1;
+int     g_right_rank      = -1;
+int     g_proc_loc        = -1;
+int 	g_NSAMP           = 250;
+double	g_STOPTM          = 0.1;
+int     g_latency012_reps = 1000;
+int     g_nIproc          = 0;
+int     g_nNproc          = 0;
+
+typedef struct ArgStruct
+{
+    char *sbuff;        /* Send buffer      */
+    char *rbuff;        /* Recv buffer      */
+    int  bufflen;       /* Length of buffer */
+    int  nbor, nbor2;   /* neighbor */
+    int  iproc;         /* rank */
+    int  tr;            /* transmitter/receiver flag */
+    int  latency_reps;  /* reps needed to time latency */
+} ArgStruct;
+
+typedef struct Data
+{
+    double t;
+    double bps;
+    int    bits;
+    int    repeat;
+} Data;
+
+int Setup(int middle_rank, ArgStruct *p01, ArgStruct *p12, ArgStruct *p012);
+void Sync(ArgStruct *p);
+void Sync012(ArgStruct *p);
+void SendTime(ArgStruct *p, double *t);
+void RecvTime(ArgStruct *p, double *t);
+void SendReps(ArgStruct *p, int *rpt);
+void RecvReps(ArgStruct *p, int *rpt);
+double TestLatency(ArgStruct *p);
+double TestLatency012(ArgStruct *p);
+void PrintOptions(void);
+int DetermineLatencyReps(ArgStruct *p);
+int DetermineLatencyReps012(ArgStruct *p);
+
+void PrintOptions()
+{
+    printf("\n");
+    printf("Usage: adapt flags\n");
+    printf(" flags:\n");
+    printf("       -reps #iterations\n");
+    printf("       -time stop_time\n");
+    printf("       -start initial_msg_size\n");
+    printf("       -end final_msg_size\n");
+    printf("       -out outputfile\n");
+    printf("       -nocache\n");
+    printf("       -pert\n");
+    printf("       -noprint\n");
+    printf("       -middle rank_0_1_or_2\n");
+    printf("Requires exactly three processes\n");
+    printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+    FILE *out=0;		/* Output data file 			*/
+    char s[255]; 		/* Generic string			*/
+    char *memtmp;
+    char *memtmp1;
+    MPI_Status status;
+
+    int ii, i, j, k, n, nq,	/* Loop indices				*/
+	bufoffset = 0,		/* Align buffer to this			*/
+	bufalign = 16*1024,	/* Boundary to align buffer to		*/
+	nrepeat01, nrepeat12,	/* Number of time to do the transmission*/
+	nrepeat012,
+	len,			/* Number of bytes to be transmitted	*/
+	inc = 1,		/* Increment value			*/
+	pert,			/* Perturbation value			*/
+        ipert,                  /* index of the perturbation loop	*/
+	start = 0,		/* Starting value for signature curve 	*/
+	end = MAXINT,		/* Ending value for signature curve	*/
+	printopt = 1,		/* Debug print statements flag		*/
+	middle_rank = 0,        /* rank 0, 1 or 2 where 2-0-1 or 0-1-2 or 1-2-0 */
+	tint;
+    
+    ArgStruct	args01, args12, args012;/* Argumentsfor all the calls	*/
+    
+    double t, t0, t1,           /* Time variables			*/
+	tlast01, tlast12, tlast012,/* Time for the last transmission	*/
+	latency01, latency12,	/* Network message latency		*/
+	latency012, tdouble;    /* Network message latency to go from 0 -> 1 -> 2 */
+#ifdef CREATE_DIFFERENCE_CURVES
+    int itrial, ntrials;
+    double *dtrials;
+#endif
+
+    Data *bwdata01, *bwdata12, *bwdata012;/* Bandwidth curve data 	*/
+    
+    BOOL bNoCache = FALSE;
+    BOOL bSavePert = FALSE;
+    BOOL bUseMegaBytes = FALSE;
+
+    MPI_Init(&argc, &argv);
+    
+    MPI_Comm_size(MPI_COMM_WORLD, &g_nNproc);
+    MPI_Comm_rank(MPI_COMM_WORLD, &g_nIproc);
+    
+    if (g_nNproc != 3)
+    {
+	if (g_nIproc == 0)
+	    PrintOptions();
+	MPI_Finalize();
+	exit(0);
+    }
+
+    GetOptDouble(&argc, &argv, "-time", &g_STOPTM);
+    GetOptInt(&argc, &argv, "-reps", &g_NSAMP);
+    GetOptInt(&argc, &argv, "-start", &start);
+    GetOptInt(&argc, &argv, "-end", &end);
+    bNoCache = GetOpt(&argc, &argv, "-nocache");
+    bUseMegaBytes = GetOpt(&argc, &argv, "-mb");
+    if (GetOpt(&argc, &argv, "-noprint"))
+	printopt = 0;
+    bSavePert = GetOpt(&argc, &argv, "-pert");
+    GetOptInt(&argc, &argv, "-middle", &middle_rank);
+    if (middle_rank < 0 || middle_rank > 2)
+	middle_rank = 0;
+
+    bwdata01 = malloc((g_NSAMP+1) * sizeof(Data));
+    bwdata12 = malloc((g_NSAMP+1) * sizeof(Data));
+    bwdata012 = malloc((g_NSAMP+1) * sizeof(Data));
+
+    if (g_nIproc == 0)
+	strcpy(s, "adapt.out");
+    GetOptString(&argc, &argv, "-out", s);
+    
+    if (start > end)
+    {
+	fprintf(stdout, "Start MUST be LESS than end\n");
+	exit(420132);
+    }
+
+    Setup(middle_rank, &args01, &args12, &args012);
+
+    if (g_nIproc == 0)
+    {
+	if ((out = fopen(s, "w")) == NULL)
+	{
+	    fprintf(stdout,"Can't open %s for output\n", s);
+	    exit(1);
+	}
+    }
+
+    /* Calculate latency */
+    switch (g_proc_loc)
+    {
+    case LEFT_PROCESS:
+	latency01 = TestLatency(&args01);
+	/*printf("[0] latency01 = %0.9f\n", latency01);fflush(stdout);*/
+	RecvTime(&args01, &latency12);
+	/*printf("[0] latency12 = %0.9f\n", latency12);fflush(stdout);*/
+	break;
+    case MIDDLE_PROCESS:
+	latency01 = TestLatency(&args01);
+	/*printf("[1] latency01 = %0.9f\n", latency01);fflush(stdout);*/
+	SendTime(&args12, &latency01);
+	latency12 = TestLatency(&args12);
+	/*printf("[1] latency12 = %0.9f\n", latency12);fflush(stdout);*/
+	SendTime(&args01, &latency12);
+	break;
+    case RIGHT_PROCESS:
+	RecvTime(&args12, &latency01);
+	/*printf("[2] latency01 = %0.9f\n", latency01);fflush(stdout);*/
+	latency12 = TestLatency(&args12);
+	/*printf("[2] latency12 = %0.9f\n", latency12);fflush(stdout);*/
+	break;
+    }
+
+    latency012 = TestLatency012(&args012);
+
+    if ((g_nIproc == 0) && printopt)
+    {
+	printf("Latency%d%d_ : %0.9f\n", g_left_rank, g_middle_rank, latency01);
+	printf("Latency_%d%d : %0.9f\n", g_middle_rank, g_right_rank, latency12);
+	printf("Latency%d%d%d : %0.9f\n", g_left_rank, g_middle_rank, g_right_rank, latency012);
+	fflush(stdout);
+	printf("Now starting main loop\n");
+	fflush(stdout);
+    }
+    tlast01 = latency01;
+    tlast12 = latency12;
+    tlast012 = latency012;
+    inc = (start > 1) ? start/2: inc;
+    args01.bufflen = start;
+    args12.bufflen = start;
+    args012.bufflen = start;
+
+#ifdef CREATE_DIFFERENCE_CURVES
+    /* print the header line of the output file */
+    if (g_nIproc == 0)
+    {
+	fprintf(out, "bytes\tMbits/s\ttime\tMbits/s\ttime");
+	for (ii=1, itrial=0; itrial<MAX_NUM_O12_TRIALS; ii <<= 1, itrial++)
+	    fprintf(out, "\t%d", ii);
+	fprintf(out, "\n");
+	fflush(out);
+    }
+    ntrials = MAX_NUM_O12_TRIALS;
+    dtrials = malloc(sizeof(double)*ntrials);
+#endif
+
+    /* Main loop of benchmark */
+    for (nq = n = 0, len = start; 
+         n < g_NSAMP && tlast012 < g_STOPTM && len <= end; 
+	 len = len + inc, nq++)
+    {
+	if (nq > 2)
+	    inc = (nq % 2) ? inc + inc : inc;
+
+	/* clear the old values */
+	for (itrial = 0; itrial < ntrials; itrial++)
+	{
+	    dtrials[itrial] = LONGTIME;
+	}
+
+	/* This is a perturbation loop to test nearby values */
+	for (ipert = 0, pert = (inc > PERT + 1) ? -PERT : 0;
+	     pert <= PERT; 
+	     ipert++, n++, pert += (inc > PERT + 1) ? PERT : PERT + 1)
+	{
+
+
+	    /*****************************************************/
+	    /*         Run a trial between rank 0 and 1          */
+	    /*****************************************************/
+
+	    MPI_Barrier(MPI_COMM_WORLD);
+
+
+	    if (g_proc_loc == RIGHT_PROCESS)
+		goto skip_01_trial;
+
+	    /* Calculate howmany times to repeat the experiment. */
+	    if (args01.tr)
+	    {
+		if (args01.bufflen == 0)
+		    nrepeat01 = args01.latency_reps;
+		else
+		    nrepeat01 = (int)(MAX((RUNTM / ((double)args01.bufflen /
+			           (args01.bufflen - inc + 1.0) * tlast01)), TRIALS));
+		SendReps(&args01, &nrepeat01);
+	    }
+	    else
+	    {
+		RecvReps(&args01, &nrepeat01);
+	    }
+
+	    /* Allocate the buffer */
+	    args01.bufflen = len + pert;
+	    /* printf("allocating %d bytes\n", args01.bufflen * nrepeat01 + bufalign); */
+	    if (bNoCache)
+	    {
+		if ((args01.sbuff = (char *)malloc(args01.bufflen * nrepeat01 + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    else
+	    {
+		if ((args01.sbuff = (char *)malloc(args01.bufflen + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    /* if ((args01.rbuff = (char *)malloc(args01.bufflen * nrepeat01 + bufalign)) == (char *)NULL) */
+	    if ((args01.rbuff = (char *)malloc(args01.bufflen + bufalign)) == (char *)NULL)
+	    {
+		fprintf(stdout,"Couldn't allocate memory\n");
+		fflush(stdout);
+		break;
+	    }
+
+	    /* save the original pointers in case alignment moves them */
+	    memtmp = args01.sbuff;
+	    memtmp1 = args01.rbuff;
+
+	    /* Possibly align the data buffer */
+	    if (!bNoCache)
+	    {
+		if (bufalign != 0)
+		{
+		    args01.sbuff += (bufalign - (POINTER_TO_INT(args01.sbuff) % bufalign) + bufoffset) % bufalign;
+		    /* args01.rbuff += (bufalign - ((MPI_Aint)args01.rbuff % bufalign) + bufoffset) % bufalign; */
+		}
+	    }
+	    args01.rbuff += (bufalign - (POINTER_TO_INT(args01.rbuff) % bufalign) + bufoffset) % bufalign;
+	    
+	    if (args01.tr && printopt)
+	    {
+		fprintf(stdout,"%3d: %9d bytes %4d times --> ",
+		    n, args01.bufflen, nrepeat01);
+		fflush(stdout);
+	    }
+	    
+	    /* Finally, we get to transmit or receive and time */
+	    if (args01.tr)
+	    {
+		bwdata01[n].t = LONGTIME;
+		t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args01.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args01.sbuff) % bufalign) + bufoffset) % bufalign);
+			    /* args01.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args01.rbuff % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args01.sbuff = memtmp;
+			    /* args01.rbuff = memtmp1; */
+			}
+		    }
+		    
+		    Sync(&args01);
+		    t0 = MPI_Wtime();
+		    for (j = 0; j < nrepeat01; j++)
+		    {
+			MPI_Send(args01.sbuff,  args01.bufflen, MPI_BYTE,  args01.nbor, MSG_TAG_01, MPI_COMM_WORLD);
+			MPI_Recv(args01.rbuff,  args01.bufflen, MPI_BYTE,  args01.nbor, MSG_TAG_01, MPI_COMM_WORLD, &status);
+			if (bNoCache)
+			{
+			    args01.sbuff += args01.bufflen;
+			    /* args01.rbuff += args01.bufflen; */
+			}
+		    }
+		    t = (MPI_Wtime() - t0)/(2 * nrepeat01);
+
+		    t1 += t;
+		    bwdata01[n].t = MIN(bwdata01[n].t, t);
+		}
+		SendTime(&args01, &bwdata01[n].t);
+	    }
+	    else
+	    {
+		bwdata01[n].t = LONGTIME;
+		t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args01.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args01.sbuff) % bufalign) + bufoffset) % bufalign);
+			    /* args01.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args01.rbuff % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args01.sbuff = memtmp;
+			    /* args01.rbuff = memtmp1; */
+			}
+		    }
+		    
+		    Sync(&args01);
+		    t0 = MPI_Wtime();
+		    for (j = 0; j < nrepeat01; j++)
+		    {
+			MPI_Recv(args01.rbuff,  args01.bufflen, MPI_BYTE,  args01.nbor, MSG_TAG_01, MPI_COMM_WORLD, &status);
+			MPI_Send(args01.sbuff,  args01.bufflen, MPI_BYTE,  args01.nbor, MSG_TAG_01, MPI_COMM_WORLD);
+			if (bNoCache)
+			{
+			    args01.sbuff += args01.bufflen;
+			    /* args01.rbuff += args01.bufflen; */
+			}
+		    }
+		    t = (MPI_Wtime() - t0)/(2 * nrepeat01);
+		}
+		RecvTime(&args01, &bwdata01[n].t);
+	    }
+	    tlast01 = bwdata01[n].t;
+	    bwdata01[n].bits = args01.bufflen * CHARSIZE;
+	    bwdata01[n].bps = bwdata01[n].bits / (bwdata01[n].t * 1024 * 1024);
+	    bwdata01[n].repeat = nrepeat01;
+	    
+	    if (args01.tr)
+	    {
+		if (bSavePert)
+		{
+		    if (args01.iproc == 0)
+		    {
+			if (bUseMegaBytes)
+			    fprintf(out, "%d\t%f\t%0.9f\t", bwdata01[n].bits / 8, bwdata01[n].bps / 8, bwdata01[n].t);
+			else
+			    fprintf(out, "%d\t%f\t%0.9f\t", bwdata01[n].bits / 8, bwdata01[n].bps, bwdata01[n].t);
+			fflush(out);
+		    }
+		    else
+		    {
+			MPI_Send(&bwdata01[n].bits, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
+			MPI_Send(&bwdata01[n].bps, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
+			MPI_Send(&bwdata01[n].t, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
+		    }
+		}
+	    }
+	    
+	    free(memtmp);
+	    free(memtmp1);
+	    
+	    if (args01.tr && printopt)
+	    {
+		if (bUseMegaBytes)
+		    printf(" %6.2f MBps in %0.9f sec\n", bwdata01[n].bps / 8, tlast01);
+		else
+		    printf(" %6.2f Mbps in %0.9f sec\n", bwdata01[n].bps, tlast01);
+		fflush(stdout);
+	    }
+
+skip_01_trial:
+	    if (g_proc_loc == RIGHT_PROCESS && g_nIproc == 0 && bSavePert)
+	    {
+		MPI_Recv(&tint, 1, MPI_INT, g_left_rank, 1, MPI_COMM_WORLD, &status);
+		fprintf(out, "%d\t", tint/8);
+		MPI_Recv(&tdouble, 1, MPI_DOUBLE, g_left_rank, 1, MPI_COMM_WORLD, &status);
+		if (bUseMegaBytes)
+		    tdouble = tdouble / 8.0;
+		fprintf(out, "%f\t", tdouble);
+		MPI_Recv(&tdouble, 1, MPI_DOUBLE, g_left_rank, 1, MPI_COMM_WORLD, &status);
+		fprintf(out, "%0.9f\t", tdouble);
+		fflush(out);
+	    }
+
+
+	    /*****************************************************/
+	    /*         Run a trial between rank 1 and 2          */
+	    /*****************************************************/
+
+	    MPI_Barrier(MPI_COMM_WORLD);
+
+
+	    if (g_proc_loc == LEFT_PROCESS)
+		goto skip_12_trial;
+
+	    /* Calculate howmany times to repeat the experiment. */
+	    if (args12.tr)
+	    {
+		if (args12.bufflen == 0)
+		    nrepeat12 = args12.latency_reps;
+		else
+		    nrepeat12 = (int)(MAX((RUNTM / ((double)args12.bufflen /
+			           (args12.bufflen - inc + 1.0) * tlast12)), TRIALS));
+		SendReps(&args12, &nrepeat12);
+	    }
+	    else
+	    {
+		RecvReps(&args12, &nrepeat12);
+	    }
+	    
+	    /* Allocate the buffer */
+	    args12.bufflen = len + pert;
+	    /* printf("allocating %d bytes\n", args12.bufflen * nrepeat12 + bufalign); */
+	    if (bNoCache)
+	    {
+		if ((args12.sbuff = (char *)malloc(args12.bufflen * nrepeat12 + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    else
+	    {
+		if ((args12.sbuff = (char *)malloc(args12.bufflen + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    /* if ((args12.rbuff = (char *)malloc(args12.bufflen * nrepeat12 + bufalign)) == (char *)NULL) */
+	    if ((args12.rbuff = (char *)malloc(args12.bufflen + bufalign)) == (char *)NULL)
+	    {
+		fprintf(stdout,"Couldn't allocate memory\n");
+		fflush(stdout);
+		break;
+	    }
+
+	    /* save the original pointers in case alignment moves them */
+	    memtmp = args12.sbuff;
+	    memtmp1 = args12.rbuff;
+	    
+	    /* Possibly align the data buffer */
+	    if (!bNoCache)
+	    {
+		if (bufalign != 0)
+		{
+		    args12.sbuff += (bufalign - (POINTER_TO_INT(args12.sbuff) % bufalign) + bufoffset) % bufalign;
+		    /* args12.rbuff += (bufalign - ((MPI_Aint)args12.rbuff % bufalign) + bufoffset) % bufalign; */
+		}
+	    }
+	    args12.rbuff += (bufalign - (POINTER_TO_INT(args12.rbuff) % bufalign) + bufoffset) % bufalign;
+	    
+	    if (args12.tr && printopt)
+	    {
+		printf("%3d: %9d bytes %4d times --> ", n, args12.bufflen, nrepeat12);
+		fflush(stdout);
+	    }
+	    
+	    /* Finally, we get to transmit or receive and time */
+	    if (args12.tr)
+	    {
+		bwdata12[n].t = LONGTIME;
+		t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args12.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args12.sbuff) % bufalign) + bufoffset) % bufalign);
+			    /* args12.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args12.rbuff % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args12.sbuff = memtmp;
+			    /* args12.rbuff = memtmp1; */
+			}
+		    }
+		    
+		    Sync(&args12);
+		    t0 = MPI_Wtime();
+		    for (j = 0; j < nrepeat12; j++)
+		    {
+			MPI_Send(args12.sbuff,  args12.bufflen, MPI_BYTE,  args12.nbor, MSG_TAG_12, MPI_COMM_WORLD);
+			MPI_Recv(args12.rbuff,  args12.bufflen, MPI_BYTE,  args12.nbor, MSG_TAG_12, MPI_COMM_WORLD, &status);
+			if (bNoCache)
+			{
+			    args12.sbuff += args12.bufflen;
+			    /* args12.rbuff += args12.bufflen; */
+			}
+		    }
+		    t = (MPI_Wtime() - t0)/(2 * nrepeat12);
+
+		    t1 += t;
+		    bwdata12[n].t = MIN(bwdata12[n].t, t);
+		}
+		SendTime(&args12, &bwdata12[n].t);
+	    }
+	    else
+	    {
+		bwdata12[n].t = LONGTIME;
+		t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args12.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args12.sbuff) % bufalign) + bufoffset) % bufalign);
+			    /* args12.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args12.rbuff % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args12.sbuff = memtmp;
+			    /* args12.rbuff = memtmp1; */
+			}
+		    }
+		    
+		    Sync(&args12);
+		    t0 = MPI_Wtime();
+		    for (j = 0; j < nrepeat12; j++)
+		    {
+			MPI_Recv(args12.rbuff,  args12.bufflen, MPI_BYTE,  args12.nbor, MSG_TAG_12, MPI_COMM_WORLD, &status);
+			MPI_Send(args12.sbuff,  args12.bufflen, MPI_BYTE,  args12.nbor, MSG_TAG_12, MPI_COMM_WORLD);
+			if (bNoCache)
+			{
+			    args12.sbuff += args12.bufflen;
+			    /* args12.rbuff += args12.bufflen; */
+			}
+		    }
+		    t = (MPI_Wtime() - t0)/(2 * nrepeat12);
+		}
+		RecvTime(&args12, &bwdata12[n].t);
+	    }
+	    tlast12 = bwdata12[n].t;
+	    bwdata12[n].bits = args12.bufflen * CHARSIZE;
+	    bwdata12[n].bps = bwdata12[n].bits / (bwdata12[n].t * 1024 * 1024);
+	    bwdata12[n].repeat = nrepeat12;
+
+	    if (args12.tr)
+	    {
+		if (bSavePert)
+		{
+		    if (g_nIproc == 0)
+		    {
+			if (bUseMegaBytes)
+			    fprintf(out,"%f\t%0.9f\t", bwdata12[n].bps / 8, bwdata12[n].t);
+			else
+			    fprintf(out,"%f\t%0.9f\t", bwdata12[n].bps, bwdata12[n].t);
+			fflush(out);
+		    }
+		    else
+		    {
+			MPI_Send(&bwdata12[n].bps, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
+			MPI_Send(&bwdata12[n].t, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
+		    }
+		}
+	    }
+	    
+	    free(memtmp);
+	    free(memtmp1);
+	    
+	    if (args12.tr && printopt)
+	    {
+		if (bUseMegaBytes)
+		    printf(" %6.2f MBps in %0.9f sec\n", bwdata12[n].bps / 8, tlast12);
+		else
+		    printf(" %6.2f Mbps in %0.9f sec\n", bwdata12[n].bps, tlast12);
+		fflush(stdout);
+	    }
+
+skip_12_trial:
+	    if (g_proc_loc == LEFT_PROCESS && g_nIproc == 0 && bSavePert)
+	    {
+		MPI_Recv(&tdouble, 1, MPI_DOUBLE, g_middle_rank, 1, MPI_COMM_WORLD, &status);
+		if (bUseMegaBytes)
+		    tdouble = tdouble / 8.0;
+		fprintf(out, "%f\t", tdouble);
+		MPI_Recv(&tdouble, 1, MPI_DOUBLE, g_middle_rank, 1, MPI_COMM_WORLD, &status);
+		fprintf(out, "%0.9f\t", tdouble);
+		fflush(out);
+	    }
+
+
+#ifdef CREATE_DIFFERENCE_CURVES
+	    /*****************************************************/
+	    /*         Run a trial between rank 0, 1 and 2       */
+	    /*****************************************************/
+
+	    MPI_Barrier(MPI_COMM_WORLD);
+
+
+	    /* Calculate howmany times to repeat the experiment. */
+	    if (g_nIproc == 0)
+	    {
+		if (args012.bufflen == 0)
+		    nrepeat012 = g_latency012_reps;
+		else
+		    nrepeat012 = (int)(MAX((RUNTM / ((double)args012.bufflen /
+			           (args012.bufflen - inc + 1.0) * tlast012)), TRIALS));
+		MPI_Bcast(&nrepeat012, 1, MPI_INT, 0, MPI_COMM_WORLD);
+	    }
+	    else
+	    {
+		MPI_Bcast(&nrepeat012, 1, MPI_INT, 0, MPI_COMM_WORLD);
+	    }
+
+	    /* Allocate the buffer */
+	    args012.bufflen = len + pert;
+	    /* printf("allocating %d bytes\n", args12.bufflen * nrepeat012 + bufalign); */
+	    if (bNoCache)
+	    {
+		if ((args012.sbuff = (char *)malloc(args012.bufflen * nrepeat012 + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    else
+	    {
+		if ((args012.sbuff = (char *)malloc(args012.bufflen + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    /* if ((args012.rbuff = (char *)malloc(args012.bufflen * nrepeat012 + bufalign)) == (char *)NULL) */
+	    if ((args012.rbuff = (char *)malloc(args012.bufflen + bufalign)) == (char *)NULL)
+	    {
+		fprintf(stdout,"Couldn't allocate memory\n");
+		fflush(stdout);
+		break;
+	    }
+
+	    /* save the original pointers in case alignment moves them */
+	    memtmp = args012.sbuff;
+	    memtmp1 = args012.rbuff;
+	    
+	    /* Possibly align the data buffer */
+	    if (!bNoCache)
+	    {
+		if (bufalign != 0)
+		{
+		    args012.sbuff += (bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign;
+		    /* args12.rbuff += (bufalign - ((MPI_Aint)args12.rbuff % bufalign) + bufoffset) % bufalign; */
+		}
+	    }
+	    args012.rbuff += (bufalign - (POINTER_TO_INT(args012.rbuff) % bufalign) + bufoffset) % bufalign;
+	    
+	    if (g_nIproc == 0 && printopt)
+	    {
+		printf("%3d: %9d bytes %4d times --> ", n, args012.bufflen, nrepeat012);
+		fflush(stdout);
+	    }
+
+	    for (itrial=0, ii=1; ii <= nrepeat012 && itrial < ntrials; ii <<= 1, itrial++)
+	    {
+		/* Finally, we get to transmit or receive and time */
+		switch (g_proc_loc)
+		{
+		case LEFT_PROCESS:
+		    bwdata012[n].t = LONGTIME;
+		    t1 = 0;
+		    for (i = 0; i < TRIALS; i++)
+		    {
+			if (bNoCache)
+			{
+			    if (bufalign != 0)
+			    {
+				args012.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign);
+				/* args012.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args012.rbuff % bufalign) + bufoffset) % bufalign); */
+			    }
+			    else
+			    {
+				args012.sbuff = memtmp;
+				/* args012.rbuff = memtmp1; */
+			    }
+			}
+
+			Sync012(&args012);
+			t0 = MPI_Wtime();
+			for (j = 0; j < nrepeat012; j++)
+			{
+			    MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD);
+			    MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			    if (bNoCache)
+			    {
+				args012.sbuff += args012.bufflen;
+				/* args012.rbuff += args012.bufflen; */
+			    }
+			}
+			t = (MPI_Wtime() - t0)/(2 * nrepeat012);
+
+			t1 += t;
+			bwdata012[n].t = MIN(bwdata012[n].t, t);
+		    }
+		    MPI_Bcast(&bwdata012[n].t, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+		    break;
+		case MIDDLE_PROCESS:
+		    bwdata012[n].t = LONGTIME;
+		    t1 = 0;
+		    for (i = 0; i < TRIALS; i++)
+		    {
+			if (bNoCache)
+			{
+			    if (bufalign != 0)
+			    {
+				args012.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign);
+				/* args012.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args012.rbuff % bufalign) + bufoffset) % bufalign); */
+			    }
+			    else
+			    {
+				args012.sbuff = memtmp;
+				/* args012.rbuff = memtmp1; */
+			    }
+			}
+
+			Sync012(&args012);
+			t0 = MPI_Wtime();
+
+			/******* use the ii variable here !!! ******/
+
+			for (j = 0; j <= nrepeat012-ii; j+=ii)
+			{
+			    for (k=0; k<ii; k++)
+			    {
+				MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor2, MSG_TAG_012, MPI_COMM_WORLD);
+				MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor2, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			    }
+			    /* do the left process second because it does the timing and needs to include time to send to the right process. */
+			    for (k=0; k<ii; k++)
+			    {
+				MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD, &status);
+				MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD);
+			    }
+			    if (bNoCache)
+			    {
+				args012.sbuff += args012.bufflen;
+				/* args012.rbuff += args012.bufflen; */
+			    }
+			}
+			j = nrepeat012 % ii;
+			for (k=0; k < j; k++)
+			{
+			    MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor2, MSG_TAG_012, MPI_COMM_WORLD);
+			    MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor2, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			}
+			/* do the left process second because it does the timing and needs to include time to send to the right process. */
+			for (k=0; k < j; k++)
+			{
+			    MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			    MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD);
+			}
+			t = (MPI_Wtime() - t0)/(2 * nrepeat012);
+		    }
+		    MPI_Bcast(&bwdata012[n].t, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+		    break;
+		case RIGHT_PROCESS:
+		    bwdata012[n].t = LONGTIME;
+		    t1 = 0;
+		    for (i = 0; i < TRIALS; i++)
+		    {
+			if (bNoCache)
+			{
+			    if (bufalign != 0)
+			    {
+				args012.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign);
+				/* args012.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args012.rbuff % bufalign) + bufoffset) % bufalign); */
+			    }
+			    else
+			    {
+				args012.sbuff = memtmp;
+				/* args012.rbuff = memtmp1; */
+			    }
+			}
+
+			Sync012(&args012);
+			t0 = MPI_Wtime();
+			for (j = 0; j < nrepeat012; j++)
+			{
+			    MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			    MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD);
+			    if (bNoCache)
+			    {
+				args012.sbuff += args012.bufflen;
+				/* args012.rbuff += args012.bufflen; */
+			    }
+			}
+			t = (MPI_Wtime() - t0)/(2 * nrepeat012);
+		    }
+		    MPI_Bcast(&bwdata012[n].t, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+		    break;
+		}
+		tlast012 = bwdata012[n].t;
+		bwdata012[n].bits = args012.bufflen * CHARSIZE;
+		bwdata012[n].bps = bwdata012[n].bits / (bwdata012[n].t * 1024 * 1024);
+		bwdata012[n].repeat = nrepeat012;
+		if (itrial < ntrials)
+		{
+		    dtrials[itrial] = MIN(dtrials[itrial], bwdata012[n].t);
+		}
+
+		if (g_nIproc == 0)
+		{
+		    if (bSavePert)
+		    {
+			fprintf(out, "\t%0.9f", bwdata012[n].t);
+			fflush(out);
+		    }
+		    if (printopt)
+		    {
+			printf(" %0.9f", tlast012);
+			fflush(stdout);
+		    }
+		}
+	    }
+	    if (g_nIproc == 0)
+	    {
+		if (bSavePert)
+		{
+		    fprintf(out, "\n");
+		    fflush(out);
+		}
+		if (printopt)
+		{
+		    printf("\n");
+		    fflush(stdout);
+		}
+	    }
+	    
+	    free(memtmp);
+	    free(memtmp1);
+#endif
+
+#ifdef CREATE_SINGLE_CURVE
+	    /*****************************************************/
+	    /*         Run a trial between rank 0, 1 and 2       */
+	    /*****************************************************/
+
+	    MPI_Barrier(MPI_COMM_WORLD);
+
+
+	    /* Calculate howmany times to repeat the experiment. */
+	    if (g_nIproc == 0)
+	    {
+		if (args012.bufflen == 0)
+		    nrepeat012 = g_latency012_reps;
+		else
+		    nrepeat012 = (int)(MAX((RUNTM / ((double)args012.bufflen /
+			           (args012.bufflen - inc + 1.0) * tlast012)), TRIALS));
+		MPI_Bcast(&nrepeat012, 1, MPI_INT, 0, MPI_COMM_WORLD);
+	    }
+	    else
+	    {
+		MPI_Bcast(&nrepeat012, 1, MPI_INT, 0, MPI_COMM_WORLD);
+	    }
+
+	    /* Allocate the buffer */
+	    args012.bufflen = len + pert;
+	    /* printf("allocating %d bytes\n", args12.bufflen * nrepeat012 + bufalign); */
+	    if (bNoCache)
+	    {
+		if ((args012.sbuff = (char *)malloc(args012.bufflen * nrepeat012 + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    else
+	    {
+		if ((args012.sbuff = (char *)malloc(args012.bufflen + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    /* if ((args012.rbuff = (char *)malloc(args012.bufflen * nrepeat012 + bufalign)) == (char *)NULL) */
+	    if ((args012.rbuff = (char *)malloc(args012.bufflen + bufalign)) == (char *)NULL)
+	    {
+		fprintf(stdout,"Couldn't allocate memory\n");
+		fflush(stdout);
+		break;
+	    }
+
+	    /* save the original pointers in case alignment moves them */
+	    memtmp = args012.sbuff;
+	    memtmp1 = args012.rbuff;
+	    
+	    /* Possibly align the data buffer */
+	    if (!bNoCache)
+	    {
+		if (bufalign != 0)
+		{
+		    args012.sbuff += (bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign;
+		    /* args12.rbuff += (bufalign - ((MPI_Aint)args12.rbuff % bufalign) + bufoffset) % bufalign; */
+		}
+	    }
+	    args012.rbuff += (bufalign - (POINTER_TO_INT(args012.rbuff) % bufalign) + bufoffset) % bufalign;
+	    
+	    if (g_nIproc == 0 && printopt)
+	    {
+		printf("%3d: %9d bytes %4d times --> ", n, args012.bufflen, nrepeat012);
+		fflush(stdout);
+	    }
+	    
+	    /* Finally, we get to transmit or receive and time */
+	    switch (g_proc_loc)
+	    {
+	    case LEFT_PROCESS:
+		bwdata012[n].t = LONGTIME;
+		t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args012.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign);
+			    /* args012.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args012.rbuff % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args012.sbuff = memtmp;
+			    /* args012.rbuff = memtmp1; */
+			}
+		    }
+		    
+		    Sync012(&args012);
+		    t0 = MPI_Wtime();
+		    for (j = 0; j < nrepeat012; j++)
+		    {
+			MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD);
+			MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			if (bNoCache)
+			{
+			    args012.sbuff += args012.bufflen;
+			    /* args012.rbuff += args012.bufflen; */
+			}
+		    }
+		    t = (MPI_Wtime() - t0)/(2 * nrepeat012);
+
+		    t1 += t;
+		    bwdata012[n].t = MIN(bwdata012[n].t, t);
+		}
+		MPI_Bcast(&bwdata012[n].t, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+		break;
+	    case MIDDLE_PROCESS:
+		bwdata012[n].t = LONGTIME;
+		t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args012.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign);
+			    /* args012.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args012.rbuff % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args012.sbuff = memtmp;
+			    /* args012.rbuff = memtmp1; */
+			}
+		    }
+		    
+		    Sync012(&args012);
+		    t0 = MPI_Wtime();
+		    for (j = 0; j < nrepeat012; j++)
+		    {
+			MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor2, MSG_TAG_012, MPI_COMM_WORLD);
+			MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor2, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD);
+			if (bNoCache)
+			{
+			    args012.sbuff += args012.bufflen;
+			    /* args012.rbuff += args012.bufflen; */
+			}
+		    }
+		    t = (MPI_Wtime() - t0)/(2 * nrepeat012);
+		}
+		MPI_Bcast(&bwdata012[n].t, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+		break;
+	    case RIGHT_PROCESS:
+		bwdata012[n].t = LONGTIME;
+		t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args012.sbuff = memtmp + ((bufalign - (POINTER_TO_INT(args012.sbuff) % bufalign) + bufoffset) % bufalign);
+			    /* args012.rbuff = memtmp1 + ((bufalign - ((MPI_Aint)args012.rbuff % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args012.sbuff = memtmp;
+			    /* args012.rbuff = memtmp1; */
+			}
+		    }
+		    
+		    Sync012(&args012);
+		    t0 = MPI_Wtime();
+		    for (j = 0; j < nrepeat012; j++)
+		    {
+			MPI_Recv(args012.rbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD, &status);
+			MPI_Send(args012.sbuff, args012.bufflen, MPI_BYTE, args012.nbor, MSG_TAG_012, MPI_COMM_WORLD);
+			if (bNoCache)
+			{
+			    args012.sbuff += args012.bufflen;
+			    /* args012.rbuff += args012.bufflen; */
+			}
+		    }
+		    t = (MPI_Wtime() - t0)/(2 * nrepeat012);
+		}
+		MPI_Bcast(&bwdata012[n].t, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+		break;
+	    }
+	    tlast012 = bwdata012[n].t;
+	    bwdata012[n].bits = args012.bufflen * CHARSIZE;
+	    bwdata012[n].bps = bwdata012[n].bits / (bwdata012[n].t * 1024 * 1024);
+	    bwdata012[n].repeat = nrepeat012;
+
+	    if (g_nIproc == 0)
+	    {
+		if (bSavePert)
+		{
+		    if (bUseMegaBytes)
+			fprintf(out, "%f\t%0.9f\n", bwdata012[n].bps / 8, bwdata012[n].t);
+		    else
+			fprintf(out, "%f\t%0.9f\n", bwdata012[n].bps, bwdata012[n].t);
+		    fflush(out);
+		}
+	    }
+	    
+	    free(memtmp);
+	    free(memtmp1);
+	    
+	    if (g_nIproc == 0 && printopt)
+	    {
+		if (bUseMegaBytes)
+		    printf(" %6.2f MBps in %0.9f sec\n", bwdata012[n].bps / 8, tlast012);
+		else
+		    printf(" %6.2f Mbps in %0.9f sec\n", bwdata012[n].bps, tlast012);
+		fflush(stdout);
+	    }
+#endif
+
+	} /* End of perturbation loop */
+
+	if (!bSavePert)/* && g_nIproc == 0)*/
+	{
+	    /* if we didn't save all of the perturbation loops, find the max and save it */
+	    int index01 = 1, index12 = 1, index012 = 1;
+	    double dmax01 = bwdata01[n-1].bps;
+	    double dmax12 = bwdata12[n-1].bps;
+#ifdef CREATE_SINGLE_CURVE
+	    double dmax012 = bwdata012[n-1].bps;
+#endif
+	    for (; ipert > 1; ipert--)
+	    {
+		if (bwdata01[n-ipert].bps > dmax01)
+		{
+		    index01 = ipert;
+		    dmax01 = bwdata01[n-ipert].bps;
+		}
+		if (bwdata12[n-ipert].bps > dmax12)
+		{
+		    index12 = ipert;
+		    dmax12 = bwdata12[n-ipert].bps;
+		}
+#ifdef CREATE_SINGLE_CURVE
+		if (bwdata012[n-ipert].bps > dmax012)
+		{
+		    index012 = ipert;
+		    dmax012 = bwdata012[n-ipert].bps;
+		}
+#endif
+	    }
+	    /* get the left stuff out */
+	    MPI_Bcast(&index01, 1, MPI_INT, g_left_rank, MPI_COMM_WORLD);
+	    MPI_Bcast(&bwdata01[n-index01].bits, 1, MPI_INT, g_left_rank, MPI_COMM_WORLD);
+	    MPI_Bcast(&bwdata01[n-index01].bps, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+	    MPI_Bcast(&bwdata01[n-index01].t, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+	    /* get the right stuff out */
+	    MPI_Bcast(&index12, 1, MPI_INT, g_middle_rank, MPI_COMM_WORLD);
+	    MPI_Bcast(&bwdata12[n-index12].bps, 1, MPI_DOUBLE, g_middle_rank, MPI_COMM_WORLD);
+	    MPI_Bcast(&bwdata12[n-index12].t, 1, MPI_DOUBLE, g_middle_rank, MPI_COMM_WORLD);
+	    if (g_nIproc == 0)
+	    {
+		if (bUseMegaBytes)
+		{
+		    fprintf(out, "%d\t%f\t%0.9f\t", bwdata01[n-index01].bits / 8, bwdata01[n-index01].bps / 8, bwdata01[n-index01].t);
+		    fprintf(out, "%f\t%0.9f\t", bwdata12[n-index12].bps / 8, bwdata12[n-index12].t);
+#ifdef CREATE_SINGLE_CURVE
+		    fprintf(out, "%f\t%0.9f\n", bwdata012[n-index012].bps / 8, bwdata012[n-index012].t);
+#endif
+		}
+		else
+		{
+		    fprintf(out, "%d\t%f\t%0.9f\t", bwdata01[n-index01].bits / 8, bwdata01[n-index01].bps, bwdata01[n-index01].t);
+		    fprintf(out, "%f\t%0.9f\t", bwdata12[n-index12].bps, bwdata12[n-index12].t);
+#ifdef CREATE_SINGLE_CURVE
+		    fprintf(out, "%f\t%0.9f\n", bwdata012[n-index012].bps, bwdata012[n-index012].t);
+#endif
+		}
+#ifdef CREATE_DIFFERENCE_CURVES
+		for (itrial = 0; itrial < ntrials && dtrials[itrial] != LONGTIME; itrial++)
+		{
+		    fprintf(out, "%0.9f\t", dtrials[itrial]);
+		}
+		fprintf(out, "\n");
+#endif
+		fflush(out);
+	    }
+	}
+    } /* End of main loop  */
+	
+    if (g_nIproc == 0)
+	fclose(out);
+    /* THE_END:		 */
+    MPI_Finalize();
+    free(bwdata01);
+    free(bwdata12);
+    free(bwdata012);
+    return 0;
+}
+
+int Setup(int middle_rank, ArgStruct *p01, ArgStruct *p12, ArgStruct *p012)
+{
+    char s[255];
+    int len = 255;
+    
+    p01->iproc = p12->iproc = p012->iproc = g_nIproc;
+    
+    MPI_Get_processor_name(s, &len);
+    /*gethostname(s, len);*/
+    printf("%d: %s\n", p01->iproc, s);
+    fflush(stdout);
+
+    switch (middle_rank)
+    {
+    case 0:
+	switch (g_nIproc)
+	{
+	case 0:
+	    g_proc_loc = MIDDLE_PROCESS;
+	    p01->nbor = 2;
+	    p01->tr = FALSE;
+	    p12->nbor = 1;
+	    p12->tr = TRUE;
+	    p012->nbor = 2;
+	    p012->nbor2 = 1;
+	    break;
+	case 1:
+	    g_proc_loc = RIGHT_PROCESS;
+	    p01->nbor = -1;
+	    p01->tr = FALSE;
+	    p12->nbor = 0;
+	    p12->tr = FALSE;
+	    p012->nbor = 0;
+	    p012->nbor2 = -1;
+	    break;
+	case 2:
+	    g_proc_loc = LEFT_PROCESS;
+	    p01->nbor = 0;
+	    p01->tr = TRUE;
+	    p12->nbor = -1;
+	    p12->tr = FALSE;
+	    p012->nbor = 0;
+	    p012->nbor2 = -1;
+	    break;
+	}
+	g_left_rank = 2;
+	g_middle_rank = 0;
+	g_right_rank = 1;
+	break;
+    case 1:
+	switch (g_nIproc)
+	{
+	case 0:
+	    g_proc_loc = LEFT_PROCESS;
+	    p01->nbor = 1;
+	    p01->tr = TRUE;
+	    p12->nbor = -1;
+	    p12->tr = FALSE;
+	    p012->nbor = 1;
+	    p012->nbor2 = -1;
+	    break;
+	case 1:
+	    g_proc_loc = MIDDLE_PROCESS;
+	    p01->nbor = 0;
+	    p01->tr = FALSE;
+	    p12->nbor = 2;
+	    p12->tr = TRUE;
+	    p012->nbor = 0;
+	    p012->nbor2 = 2;
+	    break;
+	case 2:
+	    g_proc_loc = RIGHT_PROCESS;
+	    p01->nbor = -1;
+	    p01->tr = FALSE;
+	    p12->nbor = 1;
+	    p12->tr = FALSE;
+	    p012->nbor = 1;
+	    p012->nbor2 = -1;
+	    break;
+	}
+	g_left_rank = 0;
+	g_middle_rank = 1;
+	g_right_rank = 2;
+	break;
+    case 2:
+	switch (g_nIproc)
+	{
+	case 0:
+	    g_proc_loc = RIGHT_PROCESS;
+	    p01->nbor = -1;
+	    p01->tr = FALSE;
+	    p12->nbor = 2;
+	    p12->tr = FALSE;
+	    p012->nbor = 2;
+	    p012->nbor2 = -1;
+	    break;
+	case 1:
+	    g_proc_loc = LEFT_PROCESS;
+	    p01->nbor = 2;
+	    p01->tr = TRUE;
+	    p12->nbor = -1;
+	    p12->tr = FALSE;
+	    p012->nbor = 2;
+	    p012->nbor2 = -1;
+	    break;
+	case 2:
+	    g_proc_loc = MIDDLE_PROCESS;
+	    p01->nbor = 1;
+	    p01->tr = FALSE;
+	    p12->nbor = 0;
+	    p12->tr = TRUE;
+	    p012->nbor = 1;
+	    p012->nbor2 = 0;
+	    break;
+	}
+	g_left_rank = 1;
+	g_middle_rank = 2;
+	g_right_rank = 0;
+	break;
+    }
+
+    return 1;	
+}	
+
+void Sync(ArgStruct *p)
+{
+    MPI_Status status;
+    if (p->tr)
+    {
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+    }
+    else
+    {
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+    }
+}
+
+void Sync012(ArgStruct *p)
+{
+    MPI_Status status;
+    switch (g_proc_loc)
+    {
+    case LEFT_PROCESS:
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+	break;
+    case MIDDLE_PROCESS:
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor2, 1, MPI_COMM_WORLD);
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor2, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor2, 1, MPI_COMM_WORLD);
+	break;
+    case RIGHT_PROCESS:
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+	MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	break;
+    }
+}
+
+int DetermineLatencyReps(ArgStruct *p)
+{
+    MPI_Status status;
+    double t0, duration = 0;
+    int reps = 1, prev_reps = 0;
+    int i;
+
+    /* prime the send/receive pipes */
+    Sync(p);
+    Sync(p);
+    Sync(p);
+
+    /* test how long it takes to send n messages 
+     * where n = 1, 2, 4, 8, 16, 32, ...
+     */
+    t0 = MPI_Wtime();
+    t0 = MPI_Wtime();
+    t0 = MPI_Wtime();
+    while ( (duration < RUNTM) ||
+	    (duration < MAX_LAT_TIME && reps < 1000))
+    {
+	t0 = MPI_Wtime();
+	for (i=0; i<reps-prev_reps; i++)
+	{
+	    Sync(p);
+	}
+	duration += MPI_Wtime() - t0;
+	prev_reps = reps;
+	reps = reps * 2;
+
+	/* use duration from the root only */
+	if (p->tr)
+	    MPI_Send(&duration, 1, MPI_DOUBLE, p->nbor, 2, MPI_COMM_WORLD);
+	else
+	    MPI_Recv(&duration, 1, MPI_DOUBLE, p->nbor, 2, MPI_COMM_WORLD, &status);
+    }
+
+    return reps;
+}
+
+int DetermineLatencyReps012(ArgStruct *p)
+{
+    double t0, duration = 0;
+    int reps = 1, prev_reps = 0;
+    int i;
+
+    /* prime the send/receive pipes */
+    Sync012(p);
+    Sync012(p);
+    Sync012(p);
+
+    /* test how long it takes to send n messages 
+     * where n = 1, 2, 4, 8, 16, 32, ...
+     */
+    t0 = MPI_Wtime();
+    t0 = MPI_Wtime();
+    t0 = MPI_Wtime();
+    while ( (duration < RUNTM) ||
+	    (duration < MAX_LAT_TIME && reps < 1000))
+    {
+	t0 = MPI_Wtime();
+	for (i=0; i<reps-prev_reps; i++)
+	{
+	    Sync012(p);
+	}
+	duration += MPI_Wtime() - t0;
+	prev_reps = reps;
+	reps = reps * 2;
+
+	/* use duration from the root only */
+	MPI_Bcast(&duration, 1, MPI_DOUBLE, g_left_rank, MPI_COMM_WORLD);
+    }
+
+    return reps;
+}
+
+double TestLatency(ArgStruct *p)
+{
+    double latency, t0, min_latency = LONGTIME;
+    int i, j;
+    MPI_Status status;
+    char str[100];
+
+    /* calculate the latency between rank 0 and rank 1 */
+    p->latency_reps = DetermineLatencyReps(p);
+    if (/*p->latency_reps < 1024 &&*/ p->tr)
+    {
+	if (g_proc_loc == LEFT_PROCESS)
+	{
+	    sprintf(str, "%d <-> %d      ", p->iproc, p->nbor);
+	}
+	else
+	{
+	    sprintf(str, "      %d <-> %d", p->iproc, p->nbor);
+	}
+	/*printf("To determine %s latency, using %d reps\n", p->iproc == 0 ? "0 -> 1     " : "     1 -> 2", p->latency_reps);*/
+	printf("To determine %s latency, using %d reps.\n", str, p->latency_reps);
+	fflush(stdout);
+    }
+
+    for (j=0; j<TRIALS; j++)
+    {
+	Sync(p);
+	t0 = MPI_Wtime();
+	t0 = MPI_Wtime();
+	t0 = MPI_Wtime();
+	t0 = MPI_Wtime();
+	for (i = 0; i < p->latency_reps; i++)
+	{
+	    if (p->tr)
+	    {
+		MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+		MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+	    }
+	    else
+	    {
+		MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+		MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+	    }
+	}
+	latency = (MPI_Wtime() - t0)/(2 * p->latency_reps);
+	min_latency = MIN(min_latency, latency);
+    }
+
+    return min_latency;
+}
+
+double TestLatency012(ArgStruct *p)
+{
+    double latency, t0, min_latency = LONGTIME;
+    int i, j;
+    MPI_Status status;
+
+    g_latency012_reps = DetermineLatencyReps012(p);
+    if (g_proc_loc == MIDDLE_PROCESS)
+    {
+	printf("To determine %d <-- %d --> %d latency, using %d reps\n", p->nbor, p->iproc, p->nbor2, g_latency012_reps);
+	fflush(stdout);
+    }
+
+    for (j=0; j<TRIALS; j++)
+    {
+	Sync012(p);
+	t0 = MPI_Wtime();
+	t0 = MPI_Wtime();
+	t0 = MPI_Wtime();
+	t0 = MPI_Wtime();
+	for (i = 0; i < g_latency012_reps; i++)
+	{
+	    switch (g_proc_loc)
+	    {
+	    case LEFT_PROCESS:
+		MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+		MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+		break;
+	    case MIDDLE_PROCESS:
+		MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+		MPI_Send(NULL, 0, MPI_BYTE, p->nbor2, 1, MPI_COMM_WORLD);
+		MPI_Recv(NULL, 0, MPI_BYTE, p->nbor2, 1, MPI_COMM_WORLD, &status);
+		MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+		break;
+	    case RIGHT_PROCESS:
+		MPI_Recv(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD, &status);
+		MPI_Send(NULL, 0, MPI_BYTE, p->nbor, 1, MPI_COMM_WORLD);
+		break;
+	    }
+	}
+	latency = (MPI_Wtime() - t0)/(2 * g_latency012_reps);
+	min_latency = MIN(min_latency, latency);
+    }
+
+    return min_latency;
+}
+
+void SendTime(ArgStruct *p, double *t)
+{
+    MPI_Send(t, 1, MPI_DOUBLE, p->nbor, 2, MPI_COMM_WORLD);
+}
+
+void RecvTime(ArgStruct *p, double *t)
+{
+    MPI_Status status;
+    MPI_Recv(t, 1, MPI_DOUBLE, p->nbor, 2, MPI_COMM_WORLD, &status);
+}
+
+void SendReps(ArgStruct *p, int *rpt)
+{
+    MPI_Send(rpt, 1, MPI_INT, p->nbor, 2, MPI_COMM_WORLD);
+}
+
+void RecvReps(ArgStruct *p, int *rpt)
+{
+    MPI_Status status;
+    MPI_Recv(rpt, 1, MPI_INT, p->nbor, 2, MPI_COMM_WORLD, &status);
+}
Index: /mpich2/branches/dev/dkim/test/mpi/basic/sendrecv.vcproj
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/sendrecv.vcproj (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/sendrecv.vcproj (revision 100)
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="sendrecv"
+	ProjectGUID="{04B357E3-D9BB-436D-9125-800F2C9CB61A}"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Debug/sendrecv.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="4"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpich2d.lib odbc32.lib odbccp32.lib"
+				OutputFile=".\Debug/sendrecv.exe"
+				LinkIncremental="2"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\Debug/sendrecv.pdb"
+				SubSystem="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Debug/sendrecv.tlb"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\Release"
+			IntermediateDirectory=".\Release"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..\src\include,..\..\..\include\win32"
+				PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
+				StringPooling="TRUE"
+				RuntimeLibrary="4"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Release/sendrecv.pch"
+				AssemblerListingLocation=".\Release/"
+				ObjectFile=".\Release/"
+				ProgramDataBaseFileName=".\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="mpich2.lib odbc32.lib odbccp32.lib"
+				OutputFile=".\Release/sendrecv.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="..\..\..\lib"
+				ProgramDatabaseFile=".\Release/sendrecv.pdb"
+				SubSystem="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Release/sendrecv.tlb"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp">
+			<File
+				RelativePath=".\sendrecv.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;fi;fd">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/basic/netmpi.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/basic/netmpi.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/basic/netmpi.c (revision 100)
@@ -0,0 +1,742 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#ifdef HAVE_WINDOWS_H
+#include <winsock2.h>
+#include <windows.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi.h"
+#include "GetOpt.h"
+#include <string.h>
+
+#ifndef BOOL
+typedef int BOOL;
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define  TRIALS 	3
+#define  REPEAT 	1000
+int 	 g_NSAMP =	250;
+#define  PERT		3
+/*#define  LATENCYREPS	1000*/
+int      g_LATENCYREPS = 1000;
+#define  LONGTIME	1e99
+#define  CHARSIZE	8
+#define  PATIENCE	50
+#define  RUNTM		0.25
+double	 g_STOPTM = 	0.1;
+#define  MAXINT 	2147483647
+
+#define ABS(x)		(((x) < 0)?(-(x)):(x))
+#define MIN(x, y)	(((x) < (y))?(x):(y))
+#define MAX(x, y)	(((x) > (y))?(x):(y))
+
+int g_nIproc = 0, g_nNproc = 0;
+
+typedef struct protocolstruct ProtocolStruct;
+struct protocolstruct
+{
+    int nbor, iproc;
+};
+
+typedef struct argstruct ArgStruct;
+struct argstruct 
+{
+    /* This is the common information that is needed for all tests	*/
+    char    *host;	/* Name of receiving host			*/
+    char    *buff;	/* Transmitted buffer				*/
+    char    *buff1;	/* Transmitted buffer				*/
+    int     bufflen,	/* Length of transmitted buffer 		*/
+	    tr, 	/* Transmit flag 				*/
+	    nbuff;	/* Number of buffers to transmit		*/
+    
+    /* Now we work with a union of information for protocol dependent stuff */
+    ProtocolStruct prot;	/* Structure holding necessary info for TCP */
+};
+
+typedef struct data Data;
+struct data
+{
+    double t;
+    double bps;
+    double variance;
+    int    bits;
+    int    repeat;
+};
+
+double When(void);
+int Setup(ArgStruct *p);
+void Sync(ArgStruct *p);
+void SendData(ArgStruct *p);
+void RecvData(ArgStruct *p);
+void SendRecvData(ArgStruct *p);
+void SendTime(ArgStruct *p, double *t, int *rpt);
+void RecvTime(ArgStruct *p, double *t, int *rpt);
+int Establish(ArgStruct *p);
+int  CleanUp(ArgStruct *p);
+double TestLatency(ArgStruct *p);
+double TestSyncTime(ArgStruct *p);
+void PrintOptions(void);
+int DetermineLatencyReps(ArgStruct *p);
+
+void PrintOptions()
+{
+    printf("\n");
+    printf("Usage: netpipe flags\n");
+    printf(" flags:\n");
+    printf("       -reps #iterations\n");
+    printf("       -time stop_time\n");
+    printf("       -start initial_msg_size\n");
+    printf("       -end final_msg_size\n");
+    printf("       -out outputfile\n");
+    printf("       -nocache\n");
+    printf("       -headtohead\n");
+    printf("       -pert\n");
+    printf("       -noprint\n");
+    printf("       -onebuffer largest_buffer_size\n");
+    printf("Requires exactly two processes\n");
+    printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+    FILE *out=0;		/* Output data file 			*/
+    char s[255]; 		/* Generic string			*/
+    char *memtmp;
+    char *memtmp1;
+    
+    int i, j, n, nq,		/* Loop indices				*/
+	bufoffset = 0,		/* Align buffer to this			*/
+	bufalign = 16*1024,	/* Boundary to align buffer to		*/
+	nrepeat,		/* Number of time to do the transmission*/
+	nzero = 0,
+	len,			/* Number of bytes to be transmitted	*/
+	inc = 1,		/* Increment value			*/
+	detailflag = 0,		/* Set to examine the signature curve detail*/
+	pert,			/* Perturbation value			*/
+        ipert,                  /* index of the perturbation loop	*/
+	start = 0,		/* Starting value for signature curve 	*/
+	end = MAXINT,		/* Ending value for signature curve	*/
+	streamopt = 0,		/* Streaming mode flag			*/
+	printopt = 1;		/* Debug print statements flag		*/
+    int one_buffer = 0;
+    int onebuffersize = 100*1024*1024;
+    int quit = 0;
+    
+    ArgStruct	args;		/* Argumentsfor all the calls		*/
+    
+    double t, t0, t1, t2,	/* Time variables			*/
+	tlast,			/* Time for the last transmission	*/
+	tzero = 0,
+	latency,		/* Network message latency		*/
+	synctime;		/* Network synchronization time 	*/
+    
+    Data *bwdata;		/* Bandwidth curve data 		*/
+    
+    BOOL bNoCache = FALSE;
+    BOOL bHeadToHead = FALSE;
+    BOOL bSavePert = FALSE;
+    BOOL bUseMegaBytes = FALSE;
+
+    MPI_Init(&argc, &argv);
+    
+    MPI_Comm_size(MPI_COMM_WORLD, &g_nNproc);
+    MPI_Comm_rank(MPI_COMM_WORLD, &g_nIproc);
+    
+    if (g_nNproc != 2)
+    {
+	if (g_nIproc == 0)
+	    PrintOptions();
+	MPI_Finalize();
+	exit(0);
+    }
+    
+    GetOptDouble(&argc, &argv, "-time", &g_STOPTM);
+    GetOptInt(&argc, &argv, "-reps", &g_NSAMP);
+    GetOptInt(&argc, &argv, "-start", &start);
+    GetOptInt(&argc, &argv, "-end", &end);
+    one_buffer = GetOptInt(&argc, &argv, "-onebuffer", &onebuffersize);
+    if (one_buffer)
+    {
+	if (onebuffersize < 1)
+	{
+	    one_buffer = 0;
+	}
+	else
+	{
+	    onebuffersize += bufalign;
+	}
+    }
+    bNoCache = GetOpt(&argc, &argv, "-nocache");
+    bHeadToHead = GetOpt(&argc, &argv, "-headtohead");
+    bUseMegaBytes = GetOpt(&argc, &argv, "-mb");
+    if (GetOpt(&argc, &argv, "-noprint"))
+	printopt = 0;
+    bSavePert = GetOpt(&argc, &argv, "-pert");
+    
+    bwdata = malloc((g_NSAMP+1) * sizeof(Data));
+
+    if (g_nIproc == 0)
+	strcpy(s, "Netpipe.out");
+    GetOptString(&argc, &argv, "-out", s);
+    
+    if (start > end)
+    {
+	fprintf(stdout, "Start MUST be LESS than end\n");
+	exit(420132);
+    }
+    
+    args.nbuff = TRIALS;
+    
+    Setup(&args);
+    Establish(&args);
+    
+    if (args.tr)
+    {
+	if ((out = fopen(s, "w")) == NULL)
+	{
+	    fprintf(stdout,"Can't open %s for output\n", s);
+	    exit(1);
+	}
+    }
+    
+    latency = TestLatency(&args);
+    synctime = TestSyncTime(&args);
+ 
+    
+    if (args.tr)
+    {
+	SendTime(&args, &latency, &nzero);
+    }
+    else
+    {
+	RecvTime(&args, &latency, &nzero);
+    }
+    if (args.tr && printopt)
+    {
+	printf("Latency: %0.9f\n", latency);
+	fflush(stdout);
+	printf("Sync Time: %0.9f\n", synctime);
+	fflush(stdout);
+	printf("Now starting main loop\n");
+	fflush(stdout);
+    }
+    tlast = latency;
+    inc = (start > 1 && !detailflag) ? start/2: inc;
+    args.bufflen = start;
+
+    if (one_buffer)
+    {
+	args.buff = (char *)malloc(onebuffersize);
+	args.buff1 = (char*)malloc(onebuffersize);
+    }
+
+    /* Main loop of benchmark */
+    for (nq = n = 0, len = start; 
+         n < g_NSAMP && tlast < g_STOPTM && len <= end && !quit; 
+	 len = len + inc, nq++)
+    {
+	if (nq > 2 && !detailflag)
+	    inc = ((nq % 2))? inc + inc: inc;
+	
+	/* This is a perturbation loop to test nearby values */
+	for (ipert = 0, pert = (!detailflag && inc > PERT + 1)? -PERT: 0;
+	     pert <= PERT && !quit; 
+	     ipert++, n++, 
+		 pert += (!detailflag && inc > PERT + 1)? PERT: PERT + 1)
+	{
+	    
+	    /* Calculate howmany times to repeat the experiment. */
+	    if (args.tr)
+	    {
+		if (args.bufflen == 0)
+		    nrepeat = g_LATENCYREPS;
+		else
+		    nrepeat = (int)(MAX((RUNTM / ((double)args.bufflen /
+			           (args.bufflen - inc + 1.0) * tlast)), TRIALS));
+		SendTime(&args, &tzero, &nrepeat);
+	    }
+	    else
+	    {
+		nrepeat = 1; /* Just needs to be greater than zero */
+		RecvTime(&args, &tzero, &nrepeat);
+	    }
+	    
+	    /* Allocate the buffer */
+	    args.bufflen = len + pert;
+	    if (one_buffer)
+	    {
+		if (bNoCache)
+		{
+		    if (args.bufflen * nrepeat + bufalign > onebuffersize)
+		    {
+			fprintf(stdout, "Exceeded user specified buffer size\n");
+			fflush(stdout);
+			quit = 1;
+			break;
+		    }
+		}
+		else
+		{
+		    if (args.bufflen + bufalign > onebuffersize)
+		    {
+			fprintf(stdout, "Exceeded user specified buffer size\n");
+			fflush(stdout);
+			quit = 1;
+			break;
+		    }
+		}
+	    }
+	    else
+	    {
+		/* printf("allocating %d bytes\n", 
+		   args.bufflen * nrepeat + bufalign); */
+		if (bNoCache)
+		{
+		    if ((args.buff = (char *)malloc(args.bufflen * nrepeat + bufalign)) == (char *)NULL)
+		    {
+			fprintf(stdout,"Couldn't allocate memory\n");
+			fflush(stdout);
+			break;
+		    }
+		}
+		else
+		{
+		    if ((args.buff = (char *)malloc(args.bufflen + bufalign)) == (char *)NULL)
+		    {
+			fprintf(stdout,"Couldn't allocate memory\n");
+			fflush(stdout);
+			break;
+		    }
+		}
+		/* if ((args.buff1 = (char *)malloc(args.bufflen * nrepeat + bufalign)) == (char *)NULL) */
+		if ((args.buff1 = (char *)malloc(args.bufflen + bufalign)) == (char *)NULL)
+		{
+		    fprintf(stdout,"Couldn't allocate memory\n");
+		    fflush(stdout);
+		    break;
+		}
+	    }
+	    /* Possibly align the data buffer */
+	    memtmp = args.buff;
+	    memtmp1 = args.buff1;
+	    
+	    if (!bNoCache)
+	    {
+		if (bufalign != 0)
+		{
+		    args.buff += (bufalign - ((MPI_Aint)args.buff % bufalign) + bufoffset) % bufalign;
+		    /* args.buff1 += (bufalign - ((MPI_Aint)args.buff1 % bufalign) + bufoffset) % bufalign; */
+		}
+	    }
+	    args.buff1 += (bufalign - ((MPI_Aint)args.buff1 % bufalign) + bufoffset) % bufalign;
+	    
+	    if (args.tr && printopt)
+	    {
+		fprintf(stdout,"%3d: %9d bytes %4d times --> ",
+		    n, args.bufflen, nrepeat);
+		fflush(stdout);
+	    }
+	    
+	    /* Finally, we get to transmit or receive and time */
+	    if (args.tr)
+	    {
+		bwdata[n].t = LONGTIME;
+		t2 = t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args.buff = memtmp + ((bufalign - ((MPI_Aint)args.buff % bufalign) + bufoffset) % bufalign);
+			    /* args.buff1 = memtmp1 + ((bufalign - ((MPI_Aint)args.buff1 % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args.buff = memtmp;
+			    /* args.buff1 = memtmp1; */
+			}
+		    }
+		    
+		    Sync(&args);
+		    t0 = When();
+		    for (j = 0; j < nrepeat; j++)
+		    {
+			if (bHeadToHead)
+			    SendRecvData(&args);
+			else
+			{
+			    SendData(&args);
+			    if (!streamopt)
+			    {
+				RecvData(&args);
+			    }
+			}
+			if (bNoCache)
+			{
+			    args.buff += args.bufflen;
+			    /* args.buff1 += args.bufflen; */
+			}
+		    }
+		    t = (When() - t0)/((1 + !streamopt) * nrepeat);
+		    
+		    if (!streamopt)
+		    {
+			t2 += t*t;
+			t1 += t;
+			bwdata[n].t = MIN(bwdata[n].t, t);
+		    }
+		}
+		if (!streamopt)
+		    SendTime(&args, &bwdata[n].t, &nzero);
+		else
+		    RecvTime(&args, &bwdata[n].t, &nzero);
+		
+		if (!streamopt)
+		    bwdata[n].variance = t2/TRIALS - t1/TRIALS * t1/TRIALS;
+		
+	    }
+	    else
+	    {
+		bwdata[n].t = LONGTIME;
+		t2 = t1 = 0;
+		for (i = 0; i < TRIALS; i++)
+		{
+		    if (bNoCache)
+		    {
+			if (bufalign != 0)
+			{
+			    args.buff = memtmp + ((bufalign - ((MPI_Aint)args.buff % bufalign) + bufoffset) % bufalign);
+			    /* args.buff1 = memtmp1 + ((bufalign - ((MPI_Aint)args.buff1 % bufalign) + bufoffset) % bufalign); */
+			}
+			else
+			{
+			    args.buff = memtmp;
+			    /* args.buff1 = memtmp1; */
+			}
+		    }
+		    
+		    Sync(&args);
+		    t0 = When();
+		    for (j = 0; j < nrepeat; j++)
+		    {
+			if (bHeadToHead)
+			    SendRecvData(&args);
+			else
+			{
+			    RecvData(&args);
+			    if (!streamopt)
+				SendData(&args);
+			}
+			if (bNoCache)
+			{
+			    args.buff += args.bufflen;
+			    /* args.buff1 += args.bufflen; */
+			}
+		    }
+		    t = (When() - t0)/((1 + !streamopt) * nrepeat);
+		    
+		    if (streamopt)
+		    {
+			t2 += t*t;
+			t1 += t;
+			bwdata[n].t = MIN(bwdata[n].t, t);
+		    }
+		}
+		if (streamopt)
+		    SendTime(&args, &bwdata[n].t, &nzero);
+		else
+		    RecvTime(&args, &bwdata[n].t, &nzero);
+		
+		if (streamopt)
+		    bwdata[n].variance = t2/TRIALS - t1/TRIALS * t1/TRIALS;
+		
+	    }
+	    tlast = bwdata[n].t;
+	    bwdata[n].bits = args.bufflen * CHARSIZE;
+	    bwdata[n].bps = bwdata[n].bits / (bwdata[n].t * 1024 * 1024);
+	    bwdata[n].repeat = nrepeat;
+	    
+	    if (args.tr)
+	    {
+		if (bSavePert)
+		{
+		/* fprintf(out,"%f\t%f\t%d\t%d\t%f\n", bwdata[n].t, bwdata[n].bps,
+		    bwdata[n].bits, bwdata[n].bits / 8, bwdata[n].variance); */
+		    if (bUseMegaBytes)
+			fprintf(out,"%d\t%f\t%0.9f\n", bwdata[n].bits / 8, bwdata[n].bps / 8, bwdata[n].t);
+		    else
+			fprintf(out,"%d\t%f\t%0.9f\n", bwdata[n].bits / 8, bwdata[n].bps, bwdata[n].t);
+		    fflush(out);
+		}
+	    }
+	    if (!one_buffer)
+	    {
+		free(memtmp);
+		free(memtmp1);
+	    }
+	    if (args.tr && printopt)
+	    {
+		if (bUseMegaBytes)
+		    fprintf(stdout," %6.2f MBps in %0.9f sec\n", bwdata[n].bps / 8, tlast);
+		else
+		    fprintf(stdout," %6.2f Mbps in %0.9f sec\n", bwdata[n].bps, tlast);
+		fflush(stdout);
+	    }
+	} /* End of perturbation loop */	
+	if (!bSavePert && args.tr)
+	{
+	    /* if we didn't save all of the perturbation loops, find the max and save it */
+	    int index = 1;
+	    double dmax = bwdata[n-1].bps;
+	    for (; ipert > 1; ipert--)
+	    {
+		if (bwdata[n-ipert].bps > dmax)
+		{
+		    index = ipert;
+		    dmax = bwdata[n-ipert].bps;
+		}
+	    }
+	    if (bUseMegaBytes)
+		fprintf(out,"%d\t%f\t%0.9f\n", bwdata[n-index].bits / 8, bwdata[n-index].bps / 8, bwdata[n-index].t);
+	    else
+		fprintf(out,"%d\t%f\t%0.9f\n", bwdata[n-index].bits / 8, bwdata[n-index].bps, bwdata[n-index].t);
+	    fflush(out);
+	}
+    } /* End of main loop  */
+	
+    if (args.tr)
+	fclose(out);
+    /* THE_END:		 */
+    CleanUp(&args);
+    free(bwdata);
+    return 0;
+}
+
+
+/* Return the current time in seconds, using a double precision number. 	 */
+double When()
+{
+    return MPI_Wtime();
+}
+
+int Setup(ArgStruct *p)
+{
+    int nproc;
+    char s[255];
+    int len = 255;
+    
+    MPI_Comm_rank(MPI_COMM_WORLD, &p->prot.iproc);
+    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
+    
+    MPI_Get_processor_name(s, &len);
+    /*gethostname(s, len);*/
+    printf("%d: %s\n", p->prot.iproc, s);
+    fflush(stdout);
+    
+    if (p->prot.iproc == 0)
+	p->prot.nbor = 1;
+    else
+	p->prot.nbor = 0;
+    
+    if (nproc < 2)
+    {
+	printf("Need two processes\n");
+	printf("nproc: %i\n", nproc);
+	exit(-2);
+    }
+    
+    if (p->prot.iproc == 0)
+	p->tr = 1;
+    else
+	p->tr = 0;
+    return 1;	
+}	
+
+void Sync(ArgStruct *p)
+{
+    char ch;
+    MPI_Status status;
+    if (p->tr)
+    {
+	MPI_Send(&ch, 0, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
+	MPI_Recv(&ch, 0, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(&ch, 0, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
+    }
+    else
+    {
+	MPI_Recv(&ch, 0, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD, &status);
+	MPI_Send(&ch, 0, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
+	MPI_Recv(&ch, 0, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD, &status);
+    }
+}
+
+int DetermineLatencyReps(ArgStruct *p)
+{
+    MPI_Status status;
+    double t0, duration = 0;
+    int reps = 1, prev_reps = 0;
+    int i;
+
+    /* prime the send/receive pipes */
+    Sync(p);
+    Sync(p);
+    Sync(p);
+
+    /* test how long it takes to send n messages 
+     * where n = 1, 2, 4, 8, 16, 32, ...
+     */
+    t0 = When();
+    t0 = When();
+    t0 = When();
+    while ( (duration < 1) ||
+	    (duration < 3 && reps < 1000))
+    {
+	t0 = When();
+	for (i=0; i<reps-prev_reps; i++)
+	{
+	    Sync(p);
+	}
+	duration += When() - t0;
+	prev_reps = reps;
+	reps = reps * 2;
+
+	/* use duration from the root only */
+	if (p->prot.iproc == 0)
+	    MPI_Send(&duration, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD);
+	else
+	    MPI_Recv(&duration, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
+    }
+
+    return reps;
+}
+
+double TestLatency(ArgStruct *p)
+{
+    double latency, t0;
+    int i;
+
+    g_LATENCYREPS = DetermineLatencyReps(p);
+    if (g_LATENCYREPS < 1024 && p->prot.iproc == 0)
+    {
+	printf("Using %d reps to determine latency\n", g_LATENCYREPS);
+	fflush(stdout);
+    }
+
+    p->bufflen = 0;
+    p->buff = NULL; /*(char *)malloc(p->bufflen);*/
+    p->buff1 = NULL; /*(char *)malloc(p->bufflen);*/
+    Sync(p);
+    t0 = When();
+    t0 = When();
+    t0 = When();
+    t0 = When();
+    for (i = 0; i < g_LATENCYREPS; i++)
+    {
+	if (p->tr)
+	{
+	    SendData(p);
+	    RecvData(p);
+	}
+	else
+	{
+	    RecvData(p);
+	    SendData(p);
+	}
+    }
+    latency = (When() - t0)/(2 * g_LATENCYREPS);
+    /*
+    free(p->buff);
+    free(p->buff1);
+    */
+
+    return latency;
+}
+
+double TestSyncTime(ArgStruct *p)
+{
+    double synctime, t0;
+    int i;
+
+    t0 = When();
+    t0 = When();
+    t0 = When();
+    t0 = When();
+    t0 = When();
+    t0 = When();
+    for (i = 0; i < g_LATENCYREPS; i++)
+	Sync(p);
+    synctime = (When() - t0)/g_LATENCYREPS;
+
+    return synctime;
+}
+
+void SendRecvData(ArgStruct *p)
+{
+    MPI_Status status;
+    
+    /*MPI_Sendrecv(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1, p->buff1, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD, &status);*/
+
+    MPI_Request request;
+    MPI_Irecv(p->buff1, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD, &request);
+    MPI_Send(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
+    MPI_Wait(&request, &status);
+
+    /*
+    MPI_Send(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
+    MPI_Recv(p->buff1, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD, &status);
+    */
+}
+
+void SendData(ArgStruct *p)
+{
+    MPI_Send(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
+}
+
+void RecvData(ArgStruct *p)
+{
+    MPI_Status status;
+    MPI_Recv(p->buff1, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD, &status);
+}
+
+
+void SendTime(ArgStruct *p, double *t, int *rpt)
+{
+    if (*rpt > 0)
+	MPI_Send(rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD);
+    else
+	MPI_Send(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD);
+}
+
+void RecvTime(ArgStruct *p, double *t, int *rpt)
+{
+    MPI_Status status;
+    if (*rpt > 0)
+	MPI_Recv(rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
+    else
+	MPI_Recv(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
+}
+
+int Establish(ArgStruct *p)
+{
+    return 1;
+}
+
+int  CleanUp(ArgStruct *p)
+{
+  /*MPI_Barrier(MPI_COMM_WORLD);*/
+    MPI_Finalize();
+    return 1;
+}
+
Index: /mpich2/branches/dev/dkim/test/mpi/topo/dims2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/dims2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/dims2.c (revision 100)
@@ -0,0 +1,93 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int prodof( int, const int[] );
+/*
+ * Test edge cases of Dims_create
+ */
+int prodof( int ndims, const int dims[] )
+{
+    int i, prod=1;
+    for (i=0; i<ndims; i++) 
+	prod *= dims[i];
+    return prod;
+}
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int dims[4], nnodes;
+
+    MTest_Init( &argc, &argv );
+
+    /* 2 dimensional tests */
+    for (nnodes=1; nnodes <= 32; nnodes = nnodes * 2) {
+	dims[0] = 0;
+	dims[1] = nnodes;
+	
+	MPI_Dims_create( nnodes, 2, dims );
+	if (prodof(2, dims) != nnodes) {
+	    errs++;
+	    printf( "Dims_create returned the wrong decomposition.  " );
+	    printf( "Is [%d x %d], should be 1 x %d\n", dims[0], dims[1], 
+		    nnodes );
+	}
+	
+	/* Try calling Dims_create with nothing to do (all dimensions
+	   specified) */
+	dims[0] = 1;
+	dims[1] = nnodes;
+	MPI_Dims_create( nnodes, 2, dims );
+	if (prodof(2, dims) != nnodes) {
+	    errs++;
+	    printf( "Dims_create returned the wrong decomposition (all given).  " );
+	    printf( "Is [%d x %d], should be 1 x %d\n", dims[0], dims[1], 
+		    nnodes );
+	}
+
+    }
+
+    /* 4 dimensional tests */
+    for (nnodes=4; nnodes <= 32; nnodes = nnodes * 2) {
+	dims[0] = 0;
+	dims[1] = nnodes/2;
+	dims[2] = 0;
+	dims[3] = 2;
+	
+	MPI_Dims_create( nnodes, 4, dims );
+	if (prodof(4, dims) != nnodes) {
+	    errs++;
+	    printf( "Dims_create returned the wrong decomposition.  " );
+	    printf( "Is [%d x %d x %d x %d], should be 1 x %d x 1 x 2\n", 
+		    dims[0], dims[1], dims[2], dims[3],
+		    nnodes/2 );
+	}
+	
+	/* Try calling Dims_create with nothing to do (all dimensions
+	   specified) */
+	dims[0] = 1;
+	dims[1] = nnodes/2;
+	dims[2] = 1;
+	dims[3] = 2;
+	MPI_Dims_create( nnodes, 4, dims );
+	if (prodof(4, dims) != nnodes) {
+	    errs++;
+	    printf( "Dims_create returned the wrong decomposition (all given).  " );
+	    printf( "Is [%d x %d x %d x %d], should be 1 x %d x 1 x 2\n", 
+		    dims[0], dims[1], dims[2], dims[3],
+		    nnodes/2 );
+	}
+
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/cartcreates.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/cartcreates.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/cartcreates.c (revision 100)
@@ -0,0 +1,54 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int size, rank;
+    int dims[2], periods[2];
+    MPI_Comm comm;
+
+    MTest_Init( &argc, &argv );
+
+    /* Create a new cartesian communicator in a subset of the processes */
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    if (size < 2) {
+	fprintf( stderr, "This test needs at least 2 processes\n" );
+	MPI_Abort( MPI_COMM_WORLD, 1 );
+    }
+    dims[0]    = size-1;
+    periods[0] = 1;
+    MPI_Cart_create( MPI_COMM_WORLD, 1, dims, periods, 0, &comm );
+
+    if (comm != MPI_COMM_NULL) {
+	int csize;
+	MPI_Comm_size( comm, &csize );
+	if (csize != dims[0]) {
+	    errs++;
+	    fprintf( stderr, 
+	     "Sizes is wrong in cart communicator.  Is %d, should be %d\n", 
+	     csize, dims[0] ); 
+	}
+	MPI_Barrier( comm );
+
+	MPI_Comm_free( &comm );
+    } 
+    else if (rank < dims[0]) {
+	errs++;
+	fprintf( stderr, "Communicator returned is null!" );
+    }
+
+    MTest_Finalize( errs );
+
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/graphmap1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/graphmap1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/graphmap1.c (revision 100)
@@ -0,0 +1,40 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int newrank, merr, rank;
+    int index[2], edges[2];
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    /* Graph map where there are no nodes for this process */
+    MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+    /* Here is a singleton graph, containing only the root process */
+    index[0] = 0;
+    edges[0] = 0;
+    merr = MPI_Graph_map( MPI_COMM_WORLD, 1, index, edges, &newrank );
+    if (merr) {
+	errs++;
+	printf( "Graph map returned an error\n" );
+	MTestPrintError( merr );
+    }
+    if (rank != 0 && newrank != MPI_UNDEFINED) {
+	errs++;
+	printf( "Graph map with no local nodes did not return MPI_UNDEFINED\n" );
+    }
+    
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/topotest.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/topotest.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/topotest.c (revision 100)
@@ -0,0 +1,45 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int topo_type, size, dims[1], periods[1];
+    MPI_Comm comm;
+
+    MTest_Init( &argc, &argv );
+
+    /* Check that topo test returns the correct type, including 
+       MPI_UNDEFINED */
+
+    MPI_Topo_test( MPI_COMM_WORLD, &topo_type );
+    if (topo_type != MPI_UNDEFINED) {
+	errs++;
+	printf( "Topo type of comm world is not UNDEFINED\n" );
+    }
+
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    dims[0] = size;
+    periods[0] = 0;
+    MPI_Cart_create( MPI_COMM_WORLD, 1, dims, periods, 0, &comm );
+    MPI_Topo_test( comm, &topo_type );
+    if (topo_type != MPI_CART) {
+	errs++;
+	printf( "Topo type of cart comm is not CART\n" );
+    }
+
+    MPI_Comm_free( &comm );
+    /* FIXME: still need graph example */
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/graphcr.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/graphcr.c (revision 3859)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/graphcr.c (revision 3859)
@@ -0,0 +1,32 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Create a communicator with a graph that contains no processes";
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int *index = 0, *edges = 0;
+    MPI_Comm comm;
+
+    MTest_Init( &argc, &argv );
+
+    /* MPI 2.1, page 246, lines 29-30 make it clear that this is a valid
+       (not erroneous) call that must return MPI_COMM_NULL */
+    MPI_Graph_create( MPI_COMM_WORLD, 0, index, edges, 0, &comm );
+    if (comm != MPI_COMM_NULL) {
+	errs++;
+	fprintf( stderr, "Expected MPI_COMM_NULL from empty graph create\n" );
+    }
+	
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/cartmap1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/cartmap1.c (revision 1174)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/cartmap1.c (revision 1174)
@@ -0,0 +1,64 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int dims[2];
+    int periods[2];
+    int size, rank, newrank;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    
+    /* This defines a one dimensional cartision grid with a single point */
+    periods[0] = 1;
+    dims[0] = 1;
+
+    MPI_Cart_map( MPI_COMM_WORLD, 1, dims, periods, &newrank );
+    if (rank > 0) {
+	if (newrank != MPI_UNDEFINED) {
+	    errs++;
+	    printf( "rank outside of input communicator not UNDEFINED\n" );
+	}
+    }
+    else {
+	if (rank != newrank) {
+	    errs++;
+	    printf( "Newrank not defined and should be 0\n" );
+	}
+    }
+
+
+    /* As of MPI 2.1, a 0-dimensional topology is valid (its also a
+       point) */
+    MPI_Cart_map( MPI_COMM_WORLD, 0, dims, periods, &newrank );
+    if (rank > 0) {
+	if (newrank != MPI_UNDEFINED) {
+	    errs++;
+	    printf( "rank outside of input communicator not UNDEFINED\n" );
+	}
+    }
+    else {
+	/* rank == 0 */
+	if (rank != newrank) {
+	    errs++;
+	    printf( "Newrank not defined and should be 0\n" );
+	}
+    }
+
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/cartshift1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/cartshift1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/cartshift1.c (revision 100)
@@ -0,0 +1,96 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int size, rank;
+    int source, dest;
+    int dims[2], periods[2];
+    MPI_Comm comm;
+
+    MTest_Init( &argc, &argv );
+    
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    dims[0]    = size;
+    periods[0] = 1;
+    MPI_Cart_create( MPI_COMM_WORLD, 1, dims, periods, 0, &comm );
+    MPI_Cart_shift( comm, 0, 1, &source, &dest );
+    if (source != ((rank - 1 + size) % size)) {
+	errs++;
+	printf( "source for shift 1 is %d\n", source );
+    }
+    if (dest != ((rank + 1) % size)) {
+	errs++;
+	printf( "dest for shift 1 is %d\n", dest );
+    }
+    MPI_Cart_shift( comm, 0, 0, &source, &dest );
+    if (source != rank) {
+	errs++;
+	printf( "Source for shift 0 is %d\n", source );
+    }
+    if (dest != rank) {
+	errs++;
+	printf( "Dest for shift 0 is %d\n", dest );
+    }
+    MPI_Cart_shift( comm, 0, -1, &source, &dest );
+    if (source != ((rank + 1) % size)) {
+	errs++;
+	printf( "source for shift -1 is %d\n", source );
+    }
+    if (dest != ((rank - 1 + size) % size)) {
+	errs++;
+	printf( "dest for shift -1 is %d\n", dest );
+    }
+
+    /* Now, with non-periodic */
+    MPI_Comm_free( &comm );
+    periods[0] = 0;
+    MPI_Cart_create( MPI_COMM_WORLD, 1, dims, periods, 0, &comm );
+    MPI_Cart_shift( comm, 0, 1, &source, &dest );
+    if ((rank > 0 && source != (rank - 1)) || 
+	(rank == 0 && source != MPI_PROC_NULL)) {
+	errs++;
+	printf( "source for non-periodic shift 1 is %d\n", source );
+    }
+    if ((rank < size-1 && dest != rank + 1) || 
+	((rank == size-1) && dest != MPI_PROC_NULL)) {
+	errs++;
+	printf( "dest for non-periodic shift 1 is %d\n", dest );
+    }
+    MPI_Cart_shift( comm, 0, 0, &source, &dest );
+    if (source != rank) {
+	errs++;
+	printf( "Source for non-periodic shift 0 is %d\n", source );
+    }
+    if (dest != rank) {
+	errs++;
+	printf( "Dest for non-periodic shift 0 is %d\n", dest );
+    }
+    MPI_Cart_shift( comm, 0, -1, &source, &dest );
+    if ((rank < size - 1 && source != rank + 1) ||
+	(rank == size - 1 && source != MPI_PROC_NULL)) {
+	
+	errs++;
+	printf( "source for non-periodic shift -1 is %d\n", source );
+    }
+    if ((rank > 0 && dest != rank - 1) ||
+	(rank == 0 && dest != MPI_PROC_NULL)) {
+	errs++;
+	printf( "dest for non-periodic shift -1 is %d\n", dest );
+    }
+    MPI_Comm_free( &comm );
+    
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/graphcr2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/graphcr2.c (revision 1126)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/graphcr2.c (revision 1126)
@@ -0,0 +1,68 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Create a communicator with a graph that contains null edges and one that contains duplicate edges";
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int *index = 0, *edges = 0;
+    int rank, size, i, j, crank, csize;
+    MPI_Comm comm;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+
+    index = (int *)malloc( size*sizeof(int) );
+    edges = (int *)malloc( size*sizeof(int) );
+    for (i=0; i<size; i++) {
+	index[i] = 1;
+	edges[i] = i;
+    }
+    /* As of MPI 2.1, self edges are permitted */
+    MPI_Graph_create( MPI_COMM_WORLD, size, index, edges, 0, &comm );
+    MPI_Comm_rank( comm, &crank );
+    MPI_Comm_size( comm, &csize );
+    if (csize != size) {
+	errs ++;
+	fprintf( stderr, "Graph create with self links has size %d should be %d", csize, size );
+    }
+    free( index );
+    free( edges );
+    MPI_Comm_free( &comm );
+
+    /* Create a graph with duplicate links */
+    index = (int *)malloc( size * sizeof(int) );
+    edges = (int *)malloc( size * 2 * sizeof(int) );
+    j = 0;
+    for (i=0; i<size; i++) {
+	index[i]   = j + 2;
+	edges[j++] = (i + 1) % size;
+	edges[j++] = (i + 1) % size; 
+    }
+    /* As of MPI 2.1, duplicate edges are permitted */
+    MPI_Graph_create( MPI_COMM_WORLD, size, index, edges, 0, &comm );
+    MPI_Comm_rank( comm, &crank );
+    MPI_Comm_size( comm, &csize );
+    if (csize != size) {
+	errs ++;
+	fprintf( stderr, "Graph create with duplicate links has size %d should be %d", csize, size );
+    }
+    free( index );
+    free( edges );
+    MPI_Comm_free( &comm );
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/cartzero.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/cartzero.c (revision 1175)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/cartzero.c (revision 1175)
@@ -0,0 +1,92 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2008 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+/*  
+    Check that the MPI implementation properly handles zero-dimensional
+    Cartesian communicators - the original standard implies that these
+    should be consistent with higher dimensional topologies and thus 
+    these should work with any MPI implementation.  MPI 2.1 made this
+    requirement explicit.
+*/
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int size, rank, ndims;
+    MPI_Comm comm, newcomm;
+
+    MTest_Init( &argc, &argv );
+
+    /* Create a new cartesian communicator in a subset of the processes */
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    if (size < 2) {
+	fprintf( stderr, "This test needs at least 2 processes\n" );
+	MPI_Abort( MPI_COMM_WORLD, 1 );
+    }
+
+    MPI_Cart_create( MPI_COMM_WORLD, 0, NULL, NULL, 0, &comm );
+
+    if (comm != MPI_COMM_NULL) {
+	int csize;
+	MPI_Comm_size( comm, &csize );
+	if (csize != 1) {
+	    errs++;
+	    fprintf( stderr, 
+	     "Sizes is wrong in cart communicator.  Is %d, should be 1\n", 
+	     csize ); 
+	}
+
+	/* This function is not meaningful, but should not fail */
+	MPI_Dims_create(1, 0, NULL);
+
+	ndims = -1;
+	MPI_Cartdim_get(comm, &ndims);
+	if (ndims != 0) {
+	    errs++;
+	    fprintf(stderr, "MPI_Cartdim_get: ndims is %d, should be 0\n", ndims);
+	}
+
+	/* this function should not fail */
+	MPI_Cart_get(comm, 0, NULL, NULL, NULL);
+
+	MPI_Cart_rank(comm, NULL, &rank);
+	if (rank != 0) {
+	    errs++;
+	    fprintf(stderr, "MPI_Cart_rank: rank is %d, should be 0\n", rank);
+	}
+
+	/* this function should not fail */
+	MPI_Cart_coords(comm, 0, 0, NULL);
+
+	MPI_Cart_sub(comm, NULL, &newcomm);
+	ndims = -1;
+	MPI_Cartdim_get(newcomm, &ndims);
+	if (ndims != 0) {
+	    errs++;
+	    fprintf(stderr, 
+	       "MPI_Cart_sub did not return zero-dimensional communicator\n");
+	}
+
+	MPI_Barrier( comm );
+
+	MPI_Comm_free( &comm );
+	MPI_Comm_free( &newcomm );
+    } 
+    else if (rank == 0) {
+	errs++;
+	fprintf( stderr, "Communicator returned is null!" );
+    }
+
+    MTest_Finalize( errs );
+
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/Makefile.sm
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/Makefile.sm (revision 1126)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/Makefile.sm (revision 1126)
@@ -0,0 +1,25 @@
+INCLUDES = -I../include -I${srcdir}/../include
+LDADD = ../util/mtest.o 
+DEPADD = @MPILIBLOC@ ../util/mtest.o
+smvar_do_sharedlibs = 0
+
+cartmap1_SOURCES = cartmap1.c
+cartzero_SOURCES = cartzero.c
+cartshift1_SOURCES = cartshift1.c
+cartsuball_SOURCES = cartsuball.c
+cartcreates_SOURCES = cartcreates.c
+dims1_SOURCES = dims1.c
+dims2_SOURCES = dims2.c
+graphmap1_SOURCES = graphmap1.c
+topotest_SOURCES = topotest.c
+topodup_SOURCES = topodup.c
+graphcr_SOURCES = graphcr.c
+graphcr2_SOURCES = graphcr2.c
+
+../util/mtest.o: 
+	(cd ../util && make mtest.o)
+
+testing:
+	../runtests -srcdir=$(srcdir) -tests=testlist \
+			-mpiexec=$(bindir)/mpiexec \
+		   	-xmlfile=summary.xml
Index: /mpich2/branches/dev/dkim/test/mpi/topo/testlist
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/testlist (revision 1126)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/testlist (revision 1126)
@@ -0,0 +1,12 @@
+cartmap1 4
+cartzero 4
+cartshift1 4
+cartsuball 4
+cartcreates 4
+dims1 4
+dims2 1
+graphmap1 4
+topotest 4
+topodup 4
+graphcr 4
+graphcr2 4
Index: /mpich2/branches/dev/dkim/test/mpi/topo/topodup.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/topodup.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/topodup.c (revision 100)
@@ -0,0 +1,129 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0, i, k;
+    int dims[2], periods[2], wsize;
+    int outdims[2], outperiods[2], outcoords[2];
+    int topo_type;
+    int *index, *edges, *outindex, *outedges;
+    MPI_Comm comm1, comm2;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_size( MPI_COMM_WORLD, &wsize );
+
+    /* Create a cartesian topology, get its characteristics, then 
+       dup it and check that the new communicator has the same properties */
+    dims[0] = dims[1] = 0;
+    MPI_Dims_create( wsize, 2, dims );
+    periods[0] = periods[1] = 0;
+    MPI_Cart_create( MPI_COMM_WORLD, 2, dims, periods, 0, &comm1 );
+
+    MPI_Comm_dup( comm1, &comm2 );
+    MPI_Topo_test( comm2, &topo_type );
+    if (topo_type != MPI_CART) {
+	errs++;
+	printf( "Topo type of duped cart was not cart\n" );
+    }
+    else {
+	MPI_Cart_get( comm2, 2, outdims, outperiods, outcoords );
+	for (i=0; i<2; i++) {
+	    if (outdims[i] != dims[i]) {
+		errs++;
+		printf( "%d = outdims[%d] != dims[%d] = %d\n", outdims[i],
+			i, i, dims[i] );
+	    }
+	    if (outperiods[i] != periods[i]) {
+		errs++;
+		printf( "%d = outperiods[%d] != periods[%d] = %d\n", 
+			outperiods[i], i, i, periods[i] );
+	    }
+	}
+    }
+    MPI_Comm_free( &comm2 );
+    MPI_Comm_free( &comm1 );
+
+    /* Now do the same with a graph topology */
+    if (wsize >= 3) {
+	index = (int*)malloc(wsize * sizeof(int) );
+	edges = (int*)malloc(wsize * 2 * sizeof(int) );
+	if (!index || !edges) {
+	    printf( "Unable to allocate %d words for index or edges\n", 
+		    3 * wsize );
+	    MPI_Abort( MPI_COMM_WORLD, 1 );
+	}
+	index[0] = 2;
+	for (i=1; i<wsize; i++) {
+	    index[i] = 2 + index[i-1];
+	}
+	k=0;
+	for (i=0; i<wsize; i++) {
+	    edges[k++] = (i-1+wsize) % wsize;
+	    edges[k++] = (i+1) % wsize;
+	}
+	MPI_Graph_create( MPI_COMM_WORLD, wsize, index, edges, 0, &comm1 );
+	MPI_Comm_dup( comm1, &comm2 );
+	MPI_Topo_test( comm2, &topo_type );
+	if (topo_type != MPI_GRAPH) {
+	    errs++;
+	    printf( "Topo type of duped graph was not graph\n" );
+	}
+	else {
+	    int nnodes, nedges;
+	    MPI_Graphdims_get( comm2, &nnodes, &nedges );
+	    if (nnodes != wsize) {
+		errs++;
+		printf( "Nnodes = %d, should be %d\n", nnodes, wsize );
+	    }
+	    if (nedges != 2*wsize) {
+		errs++;
+		printf( "Nedges = %d, should be %d\n", nedges, 2*wsize );
+	    }
+	    outindex = (int*)malloc(wsize * sizeof(int) );
+	    outedges = (int*)malloc(wsize * 2 * sizeof(int) );
+	    if (!outindex || !outedges) {
+		printf( "Unable to allocate %d words for outindex or outedges\n", 
+			3 * wsize );
+		MPI_Abort( MPI_COMM_WORLD, 1 );
+	    }
+	    
+	    MPI_Graph_get( comm2, wsize, 2*wsize, outindex, outedges );
+	    for (i=0; i<wsize; i++) {
+		if (index[i] != outindex[i]) {
+		    printf( "%d = index[%d] != outindex[%d] = %d\n",
+			    index[i], i, i, outindex[i] );
+		    errs++;
+		}
+	    }
+	    for (i=0; i<2*wsize; i++) {
+		if (edges[i] != outedges[i]) {
+		    printf( "%d = edges[%d] != outedges[%d] = %d\n",
+			    edges[i], i, i, outedges[i] );
+		    errs++;
+		}
+	    }
+	    free( outindex );
+	    free( outedges );
+	}
+	free( index );
+	free( edges );
+
+	MPI_Comm_free( &comm2 );
+	MPI_Comm_free( &comm1 );
+    }
+    
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/cartsuball.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/cartsuball.c (revision 1184)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/cartsuball.c (revision 1184)
@@ -0,0 +1,54 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int size, dims[2], periods[2], remain[2];
+    int result, rank;
+    MPI_Comm comm, newcomm;
+
+    MTest_Init( &argc, &argv );
+
+    /* First, create a 1-dim cartesian communicator */
+    periods[0] = 0;
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+    dims[0] = size;
+    MPI_Cart_create( MPI_COMM_WORLD, 1, dims, periods, 0, &comm );
+    
+    /* Now, extract a communicator with no dimensions */
+    remain[0] = 0;
+    MPI_Cart_sub( comm, remain, &newcomm );
+
+    MPI_Comm_rank(comm, &rank);
+
+    if (rank == 0) {
+	/* This should be congruent to MPI_COMM_SELF */
+	MPI_Comm_compare( MPI_COMM_SELF, newcomm, &result );
+	if (result != MPI_CONGRUENT) {
+	    errs++;
+	    printf( "cart sub to size 0 did not give self\n" );
+	}
+	MPI_Comm_free( &newcomm );
+    }
+    else if (newcomm != MPI_COMM_NULL) {
+	errs++;
+	printf( "cart sub to size 0 did not give null\n" );
+    }
+
+    /* Free the new communicator so that storage leak tests will
+       be happy */
+    MPI_Comm_free( &comm );
+    
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/topo/dims1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/topo/dims1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/topo/dims1.c (revision 100)
@@ -0,0 +1,144 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+int prodof( int ndims, const int dims[] );
+int increasing( int ndims, const int dims[] );
+
+int prodof( int ndims, const int dims[] )
+{
+    int i, prod=1;
+    for (i=0; i<ndims; i++) 
+	prod *= dims[i];
+    return prod;
+}
+
+int increasing( int ndims, const int dims[] )
+{
+    int i, err=0;
+    for (i=1; i<ndims; i++) {
+	if (dims[i] > dims[i-1]) {
+	    printf ("%d = dims[%d] > dims[%d] = %d\n", dims[i], i, 
+		    i-1, dims[i-1] );
+	    err = 1;
+	}
+    }
+    return err;
+}
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int dims[4], nnodes, ndims;
+
+    MTest_Init( &argc, &argv );
+
+    /* Test multiple dims create values.  For each, make sure that the 
+       product of dims is the number of input nodes */
+    nnodes = 2*3*5*7*11;
+    ndims  = 2;
+    dims[0] = dims[1] = 0;
+    MPI_Dims_create( nnodes, ndims, dims );
+    if (prodof(ndims,dims) != nnodes) {
+	errs++;
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+    if (increasing( ndims, dims )) {
+	errs++;
+	printf( "dims create returned a decomposition with increasing dimensions (see MPI-1 standard section 6.5)\n" );
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+
+    /* Test multiple dims create values.  For each, make sure that the 
+       product of dims is the number of input nodes */
+    nnodes = 2*7;
+    ndims  = 2;
+    dims[0] = dims[1] = 0;
+    MPI_Dims_create( nnodes, ndims, dims );
+    if (prodof(ndims,dims) != nnodes) {
+	errs++;
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+    if (increasing( ndims, dims )) {
+	errs++;
+	printf( "dims create returned a decomposition with increasing dimensions (see MPI-1 standard section 6.5)\n" );
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+
+    nnodes = 2*2*3*3*5*7*11;
+    ndims  = 2;
+    dims[0] = dims[1] = 0;
+    MPI_Dims_create( nnodes, ndims, dims );
+    if (prodof(ndims,dims) != nnodes) {
+	errs++;
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+    if (increasing( ndims, dims )) {
+	errs++;
+	printf( "dims create returned a decomposition with increasing dimensions (see MPI-1 standard section 6.5)\n" );
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+
+    nnodes = 11;
+    ndims  = 2;
+    dims[0] = dims[1] = 0;
+    MPI_Dims_create( nnodes, ndims, dims );
+    if (prodof(ndims,dims) != nnodes) {
+	errs++;
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+    if (increasing( ndims, dims )) {
+	errs++;
+	printf( "dims create returned a decomposition with increasing dimensions (see MPI-1 standard section 6.5)\n" );
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+
+    nnodes = 5*7*11;
+    ndims  = 4;
+    dims[0] = dims[1] = dims[2] = dims[3] = 0;
+    MPI_Dims_create( nnodes, ndims, dims );
+    if (prodof(ndims,dims) != nnodes) {
+	errs++;
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+    if (increasing( ndims, dims )) {
+	errs++;
+	printf( "dims create returned a decomposition with increasing dimensions (see MPI-1 standard section 6.5)\n" );
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+
+    nnodes = 64;
+    ndims  = 4;
+    dims[0] = dims[1] = dims[2] = dims[3] = 0;
+    MPI_Dims_create( nnodes, ndims, dims );
+    if (prodof(ndims,dims) != nnodes) {
+	errs++;
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+    if (increasing( ndims, dims )) {
+	errs++;
+	printf( "dims create returned a decomposition with increasing dimensions (see MPI-1 standard section 6.5)\n" );
+	printf( "dims create returned the wrong decomposition for %d in %d dims\n",
+		nnodes, ndims );
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/runtests.wsf
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/runtests.wsf (revision 4104)
+++ /mpich2/branches/dev/dkim/test/mpi/runtests.wsf (revision 4104)
@@ -0,0 +1,171 @@
+<package>
+<job id="runtests">
+    <runtime>
+        <description>This script searches for runtests files and executes the tests described therein</description>
+        <named
+            name = "echo"
+            helpstring = "Echo each mpiexec command"
+            required = "false"
+        />
+        <named
+			name = "config"
+			helpstring = "test configuration, Debug or Release"
+			required = "false"
+		/>
+		<named
+			name = "out"
+			helpstring = "name of output file"
+			required = "false"
+		/>
+        <named
+            name = "channel"
+            helpstring = "name of channel"
+            required = "false"
+        />
+        <example>Example: runtests.wsf</example>
+    </runtime>
+<script language="VBScript">
+
+Dim WshShell
+Set WshShell = CreateObject("WScript.Shell")
+Set f = WScript.CreateObject("Scripting.FileSystemObject")
+Set cur_folder = f.GetFolder(".")
+Set files = CreateObject("Scripting.Dictionary")
+num_files = 0
+output = ""
+num_passed = 0
+num_failed = 0
+num_skipped = 0
+
+' check if we are running cscript or wscript
+bEcho = false
+If InStr(1, LCase(WScript.FullName), "cscript") > 0 Then
+	bEcho = true
+End If
+
+' check config option
+config = "Debug\"
+if WScript.Arguments.Named.Exists("config") then
+	config = WScript.Arguments.Named.Item("config") + "\"
+end if
+
+' check out option
+outfile_name = "summary.xml"
+if WScript.Arguments.Named.Exists("out") then
+	outfile_name = WScript.Arguments.Named.Item("out")
+end if
+
+' check channel option
+channel_name = "sock"
+if WScript.Arguments.Named.Exists("channel") then
+    channel_name = WScript.Arguments.Named.Item("channel")
+end if
+
+set ftmp = f.CreateTextFile(outfile_name)
+ftmp.WriteLine("<?xml version='1.0' ?>")
+ftmp.WriteLine("<?xml-stylesheet href=""TestResults.xsl"" type=""text/xsl"" ?>")
+ftmp.WriteLine("<MPITESTRESULTS>")
+ftmp.WriteLine("<DATE>" & Date)
+ftmp.WriteLine("</DATE>")
+ftmp.WriteLine("<MPISOURCE></MPISOURCE>")
+ftmp.Close()
+
+Function GetTestLists(folder)
+	For Each sub_folder in folder.SubFolders
+		GetTestLists(sub_folder)
+	Next
+	For Each file in folder.Files
+		If file.Name = "testlist" Then
+			files.Add num_files, file.Path
+			num_files = num_files + 1
+		End If
+	Next
+End Function
+
+Function RunTest(cmd_line)
+	Set oExec = WshShell.Exec("cmd /c " & cmd_line & " 2>&1") 'WshShell.Exec(cmd_line)
+	cmd_output = oExec.StdOut.ReadAll()
+	cmd_output = cmd_output & oExec.StdErr.ReadAll()
+	RunTest = cmd_output
+End Function
+
+Function RunTests(filename)
+	Set fin = f.OpenTextFile(filename)
+	while not fin.AtEndOfStream
+		line = fin.ReadLine()
+		line = Trim(line)
+		twostrings = split(line, " ", -1, 1)
+		if not IsNull(twostrings) then
+			count = 0
+			for each s in twostrings
+				count = count + 1
+			next
+			if count = 2 then
+			 if Left(twostrings(0), 1) <> "#" then
+			  if Len(twostrings(1)) > 0 then
+				exe = Replace( filename, "testlist", config + twostrings(0) + ".exe" )
+				cmd = "mpiexec -timeout 900 -n " + twostrings(1) + " -channel " + channel_name + " " + exe
+				if bEcho = true then
+			 		WScript.Echo cmd '+ vbCrLf
+				end if
+				set fout = f.OpenTextFile(outfile_name, 8, True)
+				'fout.Write( cmd + vbCrLf )
+				fout.WriteLine("<MPITEST>")
+				fout.WriteLine("<NAME>" & twostrings(0) & "</NAME>")
+				if f.FileExists(exe) then
+					result = RunTest(cmd)
+				else
+					result = "no executable, test skipped"
+					num_skipped = num_skipped + 1
+				end if
+				if bEcho = true then
+					WScript.Echo result '+ vbCrLf
+				end if
+				'fout.Write( result + vbCrLf )
+				if Instr(result, " No Errors") And len(result) < 14 Then
+					fout.WriteLine("<STATUS>pass</STATUS>")
+					num_passed = num_passed + 1
+				else
+					fout.WriteLine("<STATUS>fail</STATUS>")
+					fout.WriteLine("<TESTDIFF>")
+					result = cmd & vbCrLf & result
+					result = Replace( result, "&", "&amp;" )
+					result = Replace( result, "<", "&lt;" )
+					result = Replace( result, ">", "&gt;" )
+					fout.WriteLine(result)
+					fout.WriteLine("</TESTDIFF>")
+					if f.FileExists(exe) then
+						num_failed = num_failed + 1
+					end if
+				end if
+				fout.WriteLine("</MPITEST>")
+				fout.Close()
+			  end if
+			 end if
+			end if
+		end if
+	wend
+	fin.Close()
+End Function
+
+GetTestLists(cur_folder)
+a = files.Items
+If files.Count > 0 Then
+	For i = 0 to files.Count - 1
+		RunTests a(i)
+	Next
+End If
+
+set fout = f.OpenTextFile(outfile_name, 8, True)
+fout.WriteLine("</MPITESTRESULTS>")
+fout.Close()
+
+if bEcho = true then
+	WScript.Echo "num_passed = " & num_passed
+	WScript.Echo "num_failed = " & num_failed
+	WScript.Echo "num_skipped = " & num_skipped
+end if
+
+</script>
+</job>
+</package>
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/join.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/join.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/join.c (revision 100)
@@ -0,0 +1,172 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#ifdef HAVE_WINDOWS_H
+#include <winsock2.h>
+#include <ws2tcpip.h> /* socklen_t */
+#else
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#endif
+#include <string.h>
+
+static char MTEST_Descrip[] = "A simple test of Comm_join";
+
+#define COUNT 1024
+
+int main( int argc, char *argv[] )
+{
+    int sendbuf[COUNT], recvbuf[COUNT], i;
+    int err=0, rank, nprocs, errs=0;
+    MPI_Comm intercomm;
+    int listenfd, connfd, port, namelen;
+    struct sockaddr_in cliaddr, servaddr;
+    struct hostent *h;
+    char hostname[MPI_MAX_PROCESSOR_NAME];
+    socklen_t len, clilen;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_size(MPI_COMM_WORLD,&nprocs); 
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+    if (nprocs != 2) {
+        printf("Run this program with 2 processes\n");
+        MPI_Abort(MPI_COMM_WORLD,1);
+    }
+
+    if (rank == 1) {
+        /* server */
+        listenfd = socket(AF_INET, SOCK_STREAM, 0);
+        if (listenfd < 0) {
+            printf("server cannot open socket\n");
+            MPI_Abort(MPI_COMM_WORLD,1);
+        }
+        
+        memset(&servaddr, 0, sizeof(servaddr));
+        servaddr.sin_family = AF_INET;
+        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+        servaddr.sin_port = 0;
+
+        err = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
+        if (err < 0) {
+	    errs++;
+            printf("bind failed\n");
+            MPI_Abort(MPI_COMM_WORLD,1);
+        }
+
+        len = sizeof(servaddr);
+        err = getsockname(listenfd, (struct sockaddr *) &servaddr, &len);
+        if (err < 0) {
+	    errs++;
+            printf("getsockname failed\n");
+            MPI_Abort(MPI_COMM_WORLD,1);
+        }
+
+        port = ntohs(servaddr.sin_port);
+        MPI_Get_processor_name(hostname, &namelen);
+
+        err = listen(listenfd, 5);
+        if (err < 0) {
+	    errs++;
+            printf("listen failed\n");
+            MPI_Abort(MPI_COMM_WORLD, 1);
+        }
+
+        MPI_Send(hostname, namelen+1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+        MPI_Send(&port, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
+
+        clilen = sizeof(cliaddr);
+
+        connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
+        if (connfd < 0) {
+            printf("accept failed\n");
+            MPI_Abort(MPI_COMM_WORLD, 1);
+        }
+    }
+    else {
+        /* client */
+
+        MPI_Recv(hostname, MPI_MAX_PROCESSOR_NAME, MPI_CHAR, 1, 0, 
+                 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+        MPI_Recv(&port, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+
+        h = gethostbyname(hostname);
+        if (h == NULL) {
+            printf("gethostbyname failed\n");
+            MPI_Abort(MPI_COMM_WORLD, 1);
+        }
+
+        servaddr.sin_family = h->h_addrtype;
+        memcpy((char *) &servaddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
+        servaddr.sin_port = htons(port);
+
+        /* create socket */
+        connfd = socket(AF_INET, SOCK_STREAM, 0);
+        if (connfd < 0) {
+            printf("client cannot open socket\n");
+            MPI_Abort(MPI_COMM_WORLD, 1);
+        }
+
+        /* connect to server */
+        err = connect(connfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
+        if (err < 0) {
+	    errs++;
+            printf("client cannot connect\n");
+            MPI_Abort(MPI_COMM_WORLD, 1);
+        }
+    }
+
+    MPI_Barrier(MPI_COMM_WORLD);
+
+    /* To improve reporting of problems about operations, we
+       change the error handler to errors return */
+    MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+    err = MPI_Comm_join(connfd, &intercomm);
+    if (err) { errs++; printf("Error in MPI_Comm_join %d\n", err); }
+
+    /* To improve reporting of problems about operations, we
+       change the error handler to errors return */
+    MPI_Comm_set_errhandler( intercomm, MPI_ERRORS_RETURN );
+
+
+    for (i=0; i<COUNT; i++) {
+        recvbuf[i] = -1;
+        sendbuf[i] = i + COUNT*rank;
+    }
+
+    err = MPI_Sendrecv(sendbuf, COUNT, MPI_INT, 0, 0, recvbuf, COUNT, MPI_INT, 
+                       0, 0, intercomm, MPI_STATUS_IGNORE);
+    if (err != MPI_SUCCESS) {
+        errs++;
+	printf( "Error in MPI_Sendrecv on new communicator\n" );
+    }
+
+    for (i=0; i<COUNT; i++) {
+        if (recvbuf[i] != ((rank+1)%2) * COUNT + i)
+            errs++;
+    }
+
+    MPI_Barrier(MPI_COMM_WORLD);
+    err = MPI_Comm_disconnect(&intercomm);
+    if (err != MPI_SUCCESS) {
+        errs++;
+	printf( "Error in MPI_Comm_disconnect\n" );
+    }
+    
+    MTest_Finalize(errs);
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/selfconacc.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/selfconacc.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/selfconacc.c (revision 100)
@@ -0,0 +1,114 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void check_error( int, char * );
+
+void check_error(int error, char *fcname)
+{
+    char err_string[MPI_MAX_ERROR_STRING] = "";
+    int length;
+    if (error != MPI_SUCCESS)
+    {
+	MPI_Error_string(error, err_string, &length);
+	printf("%s failed: %s\n", fcname, err_string);
+	fflush(stdout);
+	MPI_Abort(MPI_COMM_WORLD, error);
+    }
+}
+
+int main( int argc, char *argv[] )
+{
+    int error;
+    int rank, size;
+    char port[MPI_MAX_PORT_NAME];
+    MPI_Status status;
+    MPI_Comm comm;
+    int verbose = 0;
+
+    if (getenv("MPITEST_VERBOSE"))
+    {
+	verbose = 1;
+    }
+
+    if (verbose) { printf("init.\n");fflush(stdout); }
+    error = MPI_Init(&argc, &argv);
+    check_error(error, "MPI_Init");
+
+    /* To improve reporting of problems about operations, we
+       change the error handler to errors return */
+    MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+    MPI_Comm_set_errhandler( MPI_COMM_SELF, MPI_ERRORS_RETURN );
+
+    if (verbose) { printf("size.\n");fflush(stdout); }
+    error = MPI_Comm_size(MPI_COMM_WORLD, &size);
+    check_error(error, "MPI_Comm_size");
+
+    if (verbose) { printf("rank.\n");fflush(stdout); }
+    error = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+    check_error(error, "MPI_Comm_rank");
+
+    if (size < 2)
+    {
+	printf("Two processes needed.\n");
+	MPI_Finalize();
+	return 0;
+    }
+
+    if (rank == 0)
+    {
+	if (verbose) { printf("open_port.\n");fflush(stdout); }
+	error = MPI_Open_port(MPI_INFO_NULL, port);
+	check_error(error, "MPI_Open_port");
+
+	if (verbose) { printf("0: opened port: <%s>\n", port);fflush(stdout); }
+	if (verbose) { printf("send.\n");fflush(stdout); }
+	error = MPI_Send(port, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
+	check_error(error, "MPI_Send");
+
+	if (verbose) { printf("accept.\n");fflush(stdout); }
+	error = MPI_Comm_accept(port, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm);
+	check_error(error, "MPI_Comm_accept");
+
+	if (verbose) { printf("close_port.\n");fflush(stdout); }
+	error = MPI_Close_port(port);
+	check_error(error, "MPI_Close_port");
+
+	if (verbose) { printf("disconnect.\n");fflush(stdout); }
+	error = MPI_Comm_disconnect(&comm);
+	check_error(error, "MPI_Comm_disconnect");
+    }
+    else if (rank == 1)
+    {
+	if (verbose) { printf("recv.\n");fflush(stdout); }
+	error = MPI_Recv(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
+	check_error(error, "MPI_Recv");
+
+	if (verbose) { printf("1: received port: <%s>\n", port);fflush(stdout); }
+	if (verbose) { printf("connect.\n");fflush(stdout); }
+	error = MPI_Comm_connect(port, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm);
+	check_error(error, "MPI_Comm_connect");
+
+	MPI_Comm_set_errhandler( comm, MPI_ERRORS_RETURN );
+
+	if (verbose) { printf("disconnect.\n");fflush(stdout); }
+	error = MPI_Comm_disconnect(&comm);
+	check_error(error, "MPI_Comm_disconnect");
+    }
+
+    error = MPI_Barrier(MPI_COMM_WORLD);
+    check_error(error, "MPI_Barrier");
+
+    if (rank == 0)
+    {
+	printf(" No Errors\n");
+    }
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawnminfo1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawnminfo1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawnminfo1.c (revision 100)
@@ -0,0 +1,154 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+/* Needed for getcwd */
+#include <unistd.h>
+#endif
+
+static char MTEST_Descrip[] = "A simple test of Comm_spawn_multiple with info";
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0, err;
+    int rank, size, rsize, i;
+    int np[2] = { 1, 1 }, sumnp = 2;
+    int errcodes[2];
+    MPI_Comm      parentcomm, intercomm;
+    MPI_Status    status;
+    MPI_Info      spawninfos[2];
+    char curdir[1024], wd[1024], childwd[1024];
+    char *commands[2] = { "spawnminfo1", "spawnminfo1" };
+
+    MTest_Init( &argc, &argv );
+
+    getcwd( curdir, sizeof(curdir) );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	char *p;
+	/* Create 2 more processes.  Make the working directory the
+	   directory above the current running directory */
+	strncpy( wd, curdir, sizeof(wd) );
+        /* Lop off the last element of the directory */
+	p = wd + strlen(wd) - 1;
+	while (p > wd && *p != '/' && *p != '\\') p--;
+	*p = 0;
+	
+	MPI_Info_create( &spawninfos[0] );
+	MPI_Info_set( spawninfos[0], "path", curdir );
+	MPI_Info_set( spawninfos[0], "wdir", wd );
+	MPI_Info_create( &spawninfos[1] );
+	MPI_Info_set( spawninfos[1], "path", curdir );
+	MPI_Info_set( spawninfos[1], "wdir", curdir );
+	MPI_Comm_spawn_multiple( 2, commands, MPI_ARGVS_NULL, np,
+			spawninfos, 0, MPI_COMM_WORLD,
+			&intercomm, errcodes );
+	MPI_Info_free( &spawninfos[0] );
+	MPI_Info_free( &spawninfos[1] );
+    }
+    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 != sumnp) {
+	    errs++;
+	    printf( "Did not create %d processes (got %d)\n", sumnp, 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;
+	    }
+	    for (i=0; i<rsize; i++) {
+		char *expected = 0;
+		MPI_Recv( childwd, sizeof(childwd), MPI_CHAR, i, 2, intercomm, 
+			  MPI_STATUS_IGNORE );
+		/* The first set uses wd the second set curdir */
+		if (i <np[0]) expected = wd;
+		else          expected = curdir;
+		if (strcmp( childwd, expected ) != 0) {
+		    printf( "Expected a working dir of %s but child is in %s for child rank %d\n",
+			    expected, childwd, i );
+		    errs ++;
+		}
+	    }
+	}
+    }
+    else {
+	/* Child */
+	char cname[MPI_MAX_OBJECT_NAME];
+	int rlen;
+
+	if (size != sumnp) {
+	    errs++;
+	    printf( "(Child) Did not create %d processes (got %d)\n", 
+		    sumnp, 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 our notion of the current directory to the parent */
+	MPI_Send( curdir, strlen(curdir)+1, MPI_CHAR, 0, 2, intercomm );
+
+	/* 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 */
+    MPI_Comm_free( &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 );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/multiple_ports2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/multiple_ports2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/multiple_ports2.c (revision 100)
@@ -0,0 +1,185 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpitest.h"
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+
+/* This test checks to make sure that two MPI_Comm_connects to two different 
+ * MPI ports
+ * match their corresponding MPI_Comm_accepts.  The root process opens two 
+ * MPI ports and
+ * sends the first port to process 1 and the second to process 2.  Then the 
+ * root process
+ * accepts a connection from the second port followed by the first port.  '
+ * Processes 1 and
+ * 2 both connect back to the root but process 2 first sleeps for three 
+ * seconds to give
+ * process 1 time to attempt to connect to the root.  The root should wait 
+ * until
+ * process 2 connects before accepting the connection from process 1.
+ */
+
+int main( int argc, char *argv[] )
+{
+    int num_errors = 0, total_num_errors = 0;
+    int rank, size;
+    char port1[MPI_MAX_PORT_NAME];
+    char port2[MPI_MAX_PORT_NAME];
+    char port3[MPI_MAX_PORT_NAME];
+    MPI_Status status;
+    MPI_Comm comm1, comm2, comm3;
+    int verbose = 0;
+    int data = 0;
+
+    if (getenv("MPITEST_VERBOSE"))
+    {
+	verbose = 1;
+    }
+
+    MPI_Init(&argc, &argv);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+    if (size < 4)
+    {
+	printf("Four processes needed to run this test.\n");
+	MPI_Finalize();
+	return 0;
+    }
+
+    if (rank == 0)
+    {
+	IF_VERBOSE(("0: opening ports.\n"));
+	MPI_Open_port(MPI_INFO_NULL, port1);
+	MPI_Open_port(MPI_INFO_NULL, port2);
+	MPI_Open_port(MPI_INFO_NULL, port3);
+
+	IF_VERBOSE(("0: opened port1: <%s>\n", port1));
+	IF_VERBOSE(("0: opened port2: <%s>\n", port2));
+	IF_VERBOSE(("0: opened port3: <%s>\n", port3));
+	IF_VERBOSE(("0: sending ports.\n"));
+	MPI_Send(port1, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
+	MPI_Send(port2, MPI_MAX_PORT_NAME, MPI_CHAR, 2, 0, MPI_COMM_WORLD);
+	MPI_Send(port3, MPI_MAX_PORT_NAME, MPI_CHAR, 3, 0, MPI_COMM_WORLD);
+
+	IF_VERBOSE(("0: accepting port3.\n"));
+	MPI_Comm_accept(port3, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm3);
+	IF_VERBOSE(("0: accepting port2.\n"));
+	MPI_Comm_accept(port2, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm2);
+	IF_VERBOSE(("0: accepting port1.\n"));
+	MPI_Comm_accept(port1, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm1);
+
+	IF_VERBOSE(("0: closing ports.\n"));
+	MPI_Close_port(port1);
+	MPI_Close_port(port2);
+	MPI_Close_port(port3);
+
+	IF_VERBOSE(("0: sending 1 to process 1.\n"));
+	data = 1;
+	MPI_Send(&data, 1, MPI_INT, 0, 0, comm1);
+
+	IF_VERBOSE(("0: sending 2 to process 2.\n"));
+	data = 2;
+	MPI_Send(&data, 1, MPI_INT, 0, 0, comm2);
+
+	IF_VERBOSE(("0: sending 3 to process 3.\n"));
+	data = 3;
+	MPI_Send(&data, 1, MPI_INT, 0, 0, comm3);
+
+	IF_VERBOSE(("0: disconnecting.\n"));
+	MPI_Comm_disconnect(&comm1);
+	MPI_Comm_disconnect(&comm2);
+	MPI_Comm_disconnect(&comm3);
+    }
+    else if (rank == 1)
+    {
+	IF_VERBOSE(("1: receiving port.\n"));
+	MPI_Recv(port1, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
+
+	IF_VERBOSE(("1: received port1: <%s>\n", port1));
+	IF_VERBOSE(("1: connecting.\n"));
+	MPI_Comm_connect(port1, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm1);
+
+	MPI_Recv(&data, 1, MPI_INT, 0, 0, comm1, &status);
+	if (data != 1)
+	{
+	    printf("Received %d from root when expecting 1\n", data);
+	    fflush(stdout);
+	    num_errors++;
+	}
+
+	IF_VERBOSE(("1: disconnecting.\n"));
+	MPI_Comm_disconnect(&comm1);
+    }
+    else if (rank == 2)
+    {
+	IF_VERBOSE(("2: receiving port.\n"));
+	MPI_Recv(port2, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
+
+	IF_VERBOSE(("2: received port2: <%s>\n", port2));
+	/* make sure process 1 has time to do the connect before this process 
+	   attempts to connect */
+	MTestSleep(2);
+	IF_VERBOSE(("2: connecting.\n"));
+	MPI_Comm_connect(port2, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm2);
+
+	MPI_Recv(&data, 1, MPI_INT, 0, 0, comm2, &status);
+	if (data != 2)
+	{
+	    printf("Received %d from root when expecting 2\n", data);
+	    fflush(stdout);
+	    num_errors++;
+	}
+
+	IF_VERBOSE(("2: disconnecting.\n"));
+	MPI_Comm_disconnect(&comm2);
+    }
+    else if (rank == 3)
+    {
+	IF_VERBOSE(("3: receiving port.\n"));
+	MPI_Recv(port3, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
+
+	IF_VERBOSE(("2: received port2: <%s>\n", port2));
+	/* make sure process 1 and 2 have time to do the connect before this 
+	   process attempts to connect */
+	MTestSleep(4);
+	IF_VERBOSE(("3: connecting.\n"));
+	MPI_Comm_connect(port3, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm3);
+
+	MPI_Recv(&data, 1, MPI_INT, 0, 0, comm3, &status);
+	if (data != 3)
+	{
+	    printf("Received %d from root when expecting 3\n", data);
+	    fflush(stdout);
+	    num_errors++;
+	}
+
+	IF_VERBOSE(("3: disconnecting.\n"));
+	MPI_Comm_disconnect(&comm3);
+    }
+
+    MPI_Barrier(MPI_COMM_WORLD);
+
+    MPI_Reduce(&num_errors, &total_num_errors, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
+    if (rank == 0)
+    {
+	if (total_num_errors)
+	{
+	    printf(" Found %d errors\n", total_num_errors);
+	}
+	else
+	{
+	    printf(" No Errors\n");
+	}
+	fflush(stdout);
+    }
+    MPI_Finalize();
+    return total_num_errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spaiccreate2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spaiccreate2.c (revision 3141)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spaiccreate2.c (revision 3141)
@@ -0,0 +1,84 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Use Spawn to create an intercomm, then create a new intercomm between processes from mixed worlds.";
+
+/*
+ * This test is a regression test for ticket#114 based on a bug reported by Brad
+ * Penoff.  The specific bug only occurred when MPI_Intercomm_create was called
+ * with a local communicator argument that contained one or more processes from
+ * a different MPI_COMM_WORLD.
+ */
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int wrank, wsize, mrank, msize, inter_rank;
+    int np = 2;
+    int errcodes[2];
+    MPI_Comm      parentcomm, intercomm, intercomm2, even_odd_comm, merged_world;
+
+    MTest_Init( &argc, &argv );
+
+    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( "./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 */
+    int rrank = -1;
+    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 );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawnmanyarg.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawnmanyarg.c (revision 3857)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawnmanyarg.c (revision 3857)
@@ -0,0 +1,175 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2008 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static char MTEST_Descrip[] = "A simple test of Comm_spawn, with many arguments";
+
+#define MAX_ARGV 1024
+int worker( int argc, char *argv[], 
+	    MPI_Comm intercomm, char *outargv[], int np );
+
+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;
+    char *inargv[MAX_ARGV];
+    char *outargv[MAX_ARGV];
+    int narg = 40;
+    char *saveArgp = 0;
+    char *saveoutArgp = 0;
+
+    MTest_Init( &argc, &argv );
+
+    /* Initialize the argument vectors */
+    for (i=0; i<MAX_ARGV; i++) {
+      char *p;
+      p = (char *)malloc( 9 );
+      if (!p) {
+	  fprintf( stderr, "Unable to allocated memory\n" );
+	  MPI_Abort( MPI_COMM_WORLD, 1 );
+      }
+      strcpy( p, "01234567" );
+      inargv[i] = p;
+      p = (char *)malloc( 9 );
+      if (!p) {
+	  fprintf( stderr, "Unable to allocated memory\n" );
+	  MPI_Abort( MPI_COMM_WORLD, 1 );
+      }
+      strcpy( p, "01234567" );
+      outargv[i] = p;
+    }
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	for (narg=16; narg < 512; narg += narg) {
+	    /* Create 2 more processes */
+	    /* Set a null at argument length narg */
+	    saveArgp = inargv[narg];
+	    inargv[narg] = 0;
+	    /* ./ is unix specific .
+	       The more generic approach would be to specify "spawnmanyarg" as 
+	       the executable and pass an info with ("path", ".") */
+	    MPI_Comm_spawn( "./spawnmanyarg", inargv, np,
+			    MPI_INFO_NULL, 0, MPI_COMM_WORLD,
+			    &intercomm, errcodes );
+	    inargv[narg] = saveArgp;
+	    /* We now have a valid intercomm */
+	    
+	    /* Master */
+	    MPI_Comm_remote_size( intercomm, &rsize );
+	    MPI_Comm_size( intercomm, &size );
+	    MPI_Comm_rank( intercomm, &rank );
+	    
+	    if (rsize != np) {
+		errs++;
+		printf( "Did not create %d processes (got %d)\n", np, rsize );
+	    }
+	    /* Send the expected rank */
+	    for (i=0; i<rsize; i++) {
+		MPI_Send( &i, 1, MPI_INT, i, 0, intercomm );
+	    }
+	    /* Send the number of arguments */
+	    for (i=0; i<rsize; i++) {
+		MPI_Send( &narg, 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;
+	    }
+	    
+	    /* Free the intercomm before the next round of spawns */
+	    MPI_Comm_free( &intercomm );
+	}
+    }
+    else {
+	/* Note that worker also send errs to the parent */
+	errs += worker( argc, argv, parentcomm, outargv, np );
+	MPI_Comm_free( &parentcomm );
+	MPI_Finalize();
+	return 0;
+    }
+
+    /* Note that the MTest_Finalize get errs only over COMM_WORLD */
+    if (parentcomm == MPI_COMM_NULL) {
+	MTest_Finalize( errs );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
+
+/* Call this routine if this process is the spawned child */
+int worker( int argc, char *argv[], 
+	    MPI_Comm intercomm, char *outargv[], int np )
+{
+    int i, narg;
+    int rsize, size, rank;
+    int errs = 0;
+    char *saveoutArgp = 0;
+    MPI_Status status;
+
+    MPI_Comm_remote_size( intercomm, &rsize );
+    MPI_Comm_size( intercomm, &size );
+    MPI_Comm_rank( intercomm, &rank );
+
+    /* Child */
+    /* FIXME: This assumes that stdout is handled for the children
+       (the error count will still be reported to the parent) */
+    if (size != np) {
+	errs++;
+	printf( "(Child) Did not create %d processes (got %d)\n", 
+		np, size );
+    }
+    MPI_Recv( &i, 1, MPI_INT, 0, 0, intercomm, &status );
+    if (i != rank) {
+	errs++;
+	printf( "Unexpected rank on child %d (%d)\n", rank, i );
+    }
+    MPI_Recv( &narg, 1, MPI_INT, 0, 0, intercomm, MPI_STATUS_IGNORE );
+    saveoutArgp = outargv[narg];
+    outargv[narg] = 0;
+    /* Check the command line */
+    for (i=1; i<argc; i++) {
+	if (!outargv[i-1]) {
+	    errs++;
+	    printf( "Wrong number of arguments (%d)\n", argc );
+	    break;
+	}
+	if (strcmp( argv[i], outargv[i-1] ) != 0) {
+	    errs++;
+	    printf( "Found arg %s but expected %s\n", argv[i],
+		    outargv[i-1] );
+	}
+    }
+    if (outargv[i-1]) {
+	/* We had too few args in the spawned command */
+	errs++;
+	printf( "Too few arguments to spawned command (only %d)\n", i );
+    }
+    /* Restore the argument vector (not necessary in this case, since the 
+       worker will exit) */
+    outargv[narg] = saveoutArgp;
+    /* Send the errs back to the master process */
+    MPI_Ssend( &errs, 1, MPI_INT, 0, 1, intercomm );
+
+   return errs;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawnargv.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawnargv.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawnargv.c (revision 100)
@@ -0,0 +1,114 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static char MTEST_Descrip[] = "A simple test of Comm_spawn, with complex arguments";
+
+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;
+    char * inargv[]  = { "a", "b=c", "d e", "-pf", " Ss", 0 };
+    char * outargv[] = { "a", "b=c", "d e", "-pf", " Ss", 0 };
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	/* Create 2 more processes */
+	/* ./ is unix specific .
+	   The more generic approach would be to specify "spawnargv" as the 
+	   executable and pass an info with ("path", ".") */
+	MPI_Comm_spawn( "./spawnargv", inargv, 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 );
+	}
+	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 */
+	/* FIXME: This assumes that stdout is handled for the children
+	   (the error count will still be reported to the parent) */
+	if (size != np) {
+	    errs++;
+	    printf( "(Child) Did not create %d processes (got %d)\n", 
+		    np, size );
+	}
+	MPI_Recv( &i, 1, MPI_INT, 0, 0, intercomm, &status );
+	if (i != rank) {
+	    errs++;
+	    printf( "Unexpected rank on child %d (%d)\n", rank, i );
+	}
+	/* Check the command line */
+	for (i=1; i<argc; i++) {
+	    if (!outargv[i-1]) {
+		errs++;
+		printf( "Wrong number of arguments (%d)\n", argc );
+		break;
+	    }
+	    if (strcmp( argv[i], outargv[i-1] ) != 0) {
+		errs++;
+		printf( "Found arg %s but expected %s\n", argv[i],
+			outargv[i-1] );
+	    }
+	}
+	if (outargv[i-1]) {
+	    /* We had too few args in the spawned command */
+	    errs++;
+	    printf( "Too few arguments to spawned command\n" );
+	}
+	/* 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 */
+    MPI_Comm_free( &intercomm );
+
+    /* Note that the MTest_Finalize get errs only over COMM_WORLD */
+    if (parentcomm == MPI_COMM_NULL) {
+	MTest_Finalize( errs );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawn1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawn1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawn1.c (revision 100)
@@ -0,0 +1,118 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static char MTEST_Descrip[] = "A simple test of Comm_spawn";
+
+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;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	/* Create 2 more processes */
+	MPI_Comm_spawn( "./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 );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawn2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawn2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawn2.c (revision 100)
@@ -0,0 +1,158 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <string.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "A simple test of Comm_spawn, called twice";
+
+/*
+ * One bug report indicated that two calls to Spawn failed, even when 
+ * one succeeded.  This test makes sure that an MPI program can make
+ * multiple calls to spawn.
+ */
+
+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, intercomm2;
+    MPI_Status    status;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	/* Create 2 more processes */
+	/* This uses a Unix name for the program; 
+	   Windows applications may need to use just spawn2 or
+	   spawn2.exe.  We can't rely on using info to place . in the
+	   path, since info is not required to be followed. */
+	MPI_Comm_spawn( "./spawn2", 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 );
+    }
+
+    if (parentcomm == MPI_COMM_NULL) {
+	/* Create 2 more processes */
+	/* This uses a Unix name for the program; 
+	   Windows applications may need to use just spawn2 or
+	   spawn2.exe.  We can't rely on using info to place . in the
+	   path, since info is not required to be followed. */
+	MPI_Comm_spawn( "./spawn2", MPI_ARGV_NULL, np,
+			MPI_INFO_NULL, 0, MPI_COMM_WORLD,
+			&intercomm2, MPI_ERRCODES_IGNORE );
+    }
+    else 
+	intercomm2 = parentcomm;
+
+    /* We now have a valid intercomm */
+
+    MPI_Comm_remote_size( intercomm2, &rsize );
+    MPI_Comm_size( intercomm2, &size );
+    MPI_Comm_rank( intercomm2, &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, intercomm2 );
+	    }
+	    /* We could use intercomm2 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, intercomm2, MPI_STATUS_IGNORE );
+		errs += err;
+	    }
+	}
+
+	MPI_Comm_free( &intercomm2 );
+    }
+
+    /* It isn't necessary to free the intercomm, but it should not hurt */
+    MPI_Comm_free( &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 );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/Makefile.sm
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/Makefile.sm (revision 3857)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/Makefile.sm (revision 3857)
@@ -0,0 +1,40 @@
+INCLUDES = -I../include -I${srcdir}/../include
+LDADD = ../util/mtest.o 
+DEPADD = @MPILIBLOC@ ../util/mtest.o
+smvar_do_sharedlibs = 0
+
+namepub_SOURCES = namepub.c
+spawn1_SOURCES = spawn1.c
+spawninfo1_SOURCES = spawninfo1.c
+spawnminfo1_SOURCES = spawnminfo1.c
+spawn2_SOURCES = spawn2.c
+spawnintra_SOURCES = spawnintra.c
+spawnargv_SOURCES = spawnargv.c
+spawnmanyarg_SOURCES = spawnmanyarg.c
+spaconacc_SOURCES = spaconacc.c
+spaconacc2_SOURCES = spaconacc2.c
+selfconacc_SOURCES = selfconacc.c
+spawnmult2_SOURCES = spawnmult2.c
+taskmaster_SOURCES = taskmaster.c
+join_SOURCES = join.c
+disconnect_reconnect_SOURCES = disconnect_reconnect.c
+disconnect_reconnect2_SOURCES = disconnect_reconnect2.c
+disconnect_reconnect3_SOURCES = disconnect_reconnect3.c
+multiple_ports_SOURCES = multiple_ports.c
+multiple_ports2_SOURCES = multiple_ports2.c
+spaiccreate_SOURCES = spaiccreate.c
+spaiccreate2_SOURCES = spaiccreate2.c
+disconnect_SOURCES = disconnect.c
+disconnect2_SOURCES = disconnect2.c
+disconnect3_SOURCES = disconnect3.c
+concurrent_spawns_SOURCES = concurrent_spawns.c
+
+../util/mtest.o:
+	(cd ../util && $(MAKE) mtest.o)
+
+testing:
+	../runtests -srcdir=$(srcdir) -tests=testlist \
+			-mpiexec=$(bindir)/mpiexec \
+		   	-xmlfile=summary.xml
+clean-local:
+	-rm -f summary.xml
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect2.c (revision 100)
@@ -0,0 +1,146 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+#define DATA_VALUE 123
+#define DATA_TAG 100
+#define SENDER_RANK 0
+#define RECEIVER_RANK 1
+
+static char MTEST_Descrip[] = "A simple test of Comm_disconnect";
+
+int main(int argc, char *argv[])
+{
+    int errs = 0;
+    int rank, size, rsize, i, data = -1;
+    int np = 3;
+    MPI_Comm      parentcomm, intercomm;
+    MPI_Status    status;
+    int verbose = 0;
+    char *env;
+
+    env = getenv("MPITEST_VERBOSE");
+    if (env)
+    {
+	if (*env != '0')
+	    verbose = 1;
+    }
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL)
+    {
+	IF_VERBOSE(("spawning %d processes\n", np));
+	/* Create 3 more processes */
+	MPI_Comm_spawn("./disconnect2", 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 (rank == SENDER_RANK)
+	{
+	    IF_VERBOSE(("sending int\n"));
+	    i = DATA_VALUE;
+	    MPI_Send(&i, 1, MPI_INT, RECEIVER_RANK, DATA_TAG, intercomm);
+	    MPI_Recv(&data, 1, MPI_INT, RECEIVER_RANK, DATA_TAG, intercomm, 
+		     &status);
+	    if (data != i)
+	    {
+		errs++;
+	    }
+	}
+	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 (rank == RECEIVER_RANK)
+	{
+	    IF_VERBOSE(("receiving int\n"));
+	    i = -1;
+	    MPI_Recv(&i, 1, MPI_INT, SENDER_RANK, DATA_TAG, intercomm, &status);
+	    if (i != DATA_VALUE)
+	    {
+		errs++;
+		printf("expected %d but received %d\n", DATA_VALUE, i);
+		fflush(stdout);
+		MPI_Abort(intercomm, 1);
+	    }
+	    MPI_Send(&i, 1, MPI_INT, SENDER_RANK, DATA_TAG, intercomm);
+	}
+
+	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 );
+    }
+
+    IF_VERBOSE(("calling finalize\n"));
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect2.c (revision 1266)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect2.c (revision 1266)
@@ -0,0 +1,255 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Note: In this program, the return codes from the MPI routines are checked.
+   Since the error handlers for the communicators are not set to 
+   MPI_ERRORS_RETURN, any error should cause an abort rather than a return.
+   The test on the return value is an extra safety check; note that a 
+   return value of other than MPI_SUCCESS in these routines indicates an
+   error in the error handling by the MPI implementation */
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+void check_error(int, char *);
+
+void check_error(int error, char *fcname)
+{
+    char err_string[MPI_MAX_ERROR_STRING] = "";
+    int length;
+    if (error != MPI_SUCCESS)
+    {
+	MPI_Error_string(error, err_string, &length);
+	printf("%s failed: %s\n", fcname, err_string);
+	fflush(stdout);
+	MPI_Abort(MPI_COMM_WORLD, error);
+    }
+}
+
+/* This test spawns two child jobs and has them open a port and connect to 
+ * each other.
+ * The two children repeatedly connect, accept, and disconnect from each other.
+ */
+int main(int argc, char *argv[])
+{
+    int error;
+    int rank, size;
+    int numprocs = 3;
+    char *argv1[2] = { "connector", NULL };
+    char *argv2[2] = { "acceptor", NULL };
+    MPI_Comm comm_connector, comm_acceptor, comm_parent, comm;
+    char port[MPI_MAX_PORT_NAME] = {0};
+    MPI_Status status;
+    MPI_Info spawn_path = MPI_INFO_NULL;
+    int i, num_loops = 100;
+    int data;
+    int verbose = 0;
+
+    if (getenv("MPITEST_VERBOSE"))
+    {
+	verbose = 1;
+    }
+
+    IF_VERBOSE(("init.\n"));
+    error = MPI_Init(&argc, &argv);
+    check_error(error, "MPI_Init");
+
+    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, "path", "." );
+
+	IF_VERBOSE(("spawn connector.\n"));
+	error = MPI_Comm_spawn("disconnect_reconnect2", argv1, numprocs, spawn_path, 0, 
+			       MPI_COMM_WORLD, &comm_connector, 
+			       MPI_ERRCODES_IGNORE);
+	check_error(error, "MPI_Comm_spawn");
+
+	IF_VERBOSE(("spawn acceptor.\n"));
+	error = MPI_Comm_spawn("disconnect_reconnect2", argv2, numprocs, spawn_path, 0, 
+			       MPI_COMM_WORLD, &comm_acceptor, 
+			       MPI_ERRCODES_IGNORE);
+	check_error(error, "MPI_Comm_spawn");
+	MPI_Info_free( &spawn_path );
+
+	if (rank == 0)
+	{
+	    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");
+
+	if (rank == 0)
+	{
+	    printf(" No Errors\n");
+	    fflush(stdout);
+	}
+    }
+    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 (rank == 0)
+	{
+	    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");
+	}
+
+	for (i=0; i<num_loops; i++)
+	{
+	    IF_VERBOSE(("accept.\n"));
+	    error = MPI_Comm_accept(port, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &comm);
+	    check_error(error, "MPI_Comm_accept");
+
+	    if (rank == 0)
+	    {
+		data = i;
+		error = MPI_Send(&data, 1, MPI_INT, 0, 0, comm);
+		check_error(error, "MPI_Send");
+		error = MPI_Recv(&data, 1, MPI_INT, 0, 0, comm, &status);
+		check_error(error, "MPI_Recv");
+		if (data != i)
+		{
+		    printf("expected %d but received %d\n", i, data);
+		    fflush(stdout);
+		    MPI_Abort(MPI_COMM_WORLD, 1);
+		}
+	    }
+
+	    IF_VERBOSE(("disconnect.\n"));
+	    error = MPI_Comm_disconnect(&comm);
+	    check_error(error, "MPI_Comm_disconnect");
+	}
+
+	if (rank == 0)
+	{
+	    IF_VERBOSE(("close_port.\n"));
+	    error = MPI_Close_port(port);
+	    check_error(error, "MPI_Close_port");
+	}
+
+	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 (rank == 0)
+	{
+	    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));
+	}
+
+	for (i=0; i<num_loops; i++)
+	{
+	    IF_VERBOSE(("connect.\n"));
+	    error = MPI_Comm_connect(port, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &comm);
+	    check_error(error, "MPI_Comm_connect");
+
+	    if (rank == 0)
+	    {
+		data = -1;
+		error = MPI_Recv(&data, 1, MPI_INT, 0, 0, comm, &status);
+		check_error(error, "MPI_Recv");
+		if (data != i)
+		{
+		    printf("expected %d but received %d\n", i, data);
+		    fflush(stdout);
+		    MPI_Abort(MPI_COMM_WORLD, 1);
+		}
+		error = MPI_Send(&data, 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
+    {
+	printf("invalid command line.\n");fflush(stdout);
+	{
+	    int i;
+	    for (i=0; i<argc; i++)
+	    {
+		printf("argv[%d] = <%s>\n", i, argv[i]);
+	    }
+	}
+	fflush(stdout);
+	MPI_Abort(MPI_COMM_WORLD, -2);
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawnmult2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawnmult2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawnmult2.c (revision 100)
@@ -0,0 +1,121 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * This tests spawn_mult by using the same executable and no command-line
+ * options.  The attribute MPI_APPNUM is used to determine which
+ * executable is running.
+ */
+
+int main( int argc, char *argv[] )
+{
+    MPI_Comm parentcomm, intercomm;
+    int i, size, rsize, rank;
+    int err, errs = 0;
+    MPI_Status status;
+    int flag;
+    static int np[2] = { 1, 1 };
+    int *appnum_ptr;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+    if (parentcomm == MPI_COMM_NULL) {
+	/* Create 2 more processes */
+	static char *cmds[2] = { "./spawnmult2", "./spawnmult2" };
+	static MPI_Info infos[2] = { MPI_INFO_NULL, MPI_INFO_NULL };
+	int errcodes[2];
+
+	MPI_Comm_spawn_multiple( 2, cmds, MPI_ARGVS_NULL, np, infos, 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) {
+	/* This is the master process */
+	if (rsize != np[0] + np[1]) { 
+	    errs++;
+	    printf( "Did not create %d processes (got %d)\n",
+		    np[0] + np[1], rsize );
+	}
+	if (rank == 0) {
+	    /* Tell each child process what rank we think they are */
+	    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 process */
+	/* FIXME: This assumes that stdout is handled for the children
+	 * (the error count will still be reported to the parent) */
+	if (size != 2) {
+	    int wsize;
+	    errs++;
+	    printf( "(Child) Did not create 2 processes (got %d)\n", size);
+	    MPI_Comm_size( MPI_COMM_WORLD, &wsize );
+	    if (wsize == 2) {
+		errs++;
+                printf( "(Child) world size is 2 but local intercomm size is not 2\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 );
+	}
+
+	/* Check for correct APPNUM */
+	MPI_Comm_get_attr( MPI_COMM_WORLD, MPI_APPNUM, &appnum_ptr, &flag );
+	/* My appnum should be my rank in comm world */
+	if (flag) {
+            if (*appnum_ptr != rank) {
+                errs++;
+                printf( "appnum is %d but should be %d\n", *appnum_ptr, rank );
+	    }
+	}
+	else {
+             errs++;
+             printf( "appnum was not set\n" );
+	}
+
+	/* 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 */
+    MPI_Comm_free( &intercomm );
+
+    /* Note that the MTest_Finalize get errs only over COMM_WORLD  */
+    if (parentcomm == MPI_COMM_NULL) {
+	MTest_Finalize( errs );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect3.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect3.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect3.c (revision 100)
@@ -0,0 +1,146 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+#define DATA_VALUE 123
+#define DATA_TAG 100
+#define SENDER_RANK 1
+#define RECEIVER_RANK 2
+
+static char MTEST_Descrip[] = "A simple test of Comm_disconnect";
+
+int main(int argc, char *argv[])
+{
+    int errs = 0;
+    int rank, size, rsize, i, data = -1;
+    int np = 3;
+    MPI_Comm      parentcomm, intercomm;
+    MPI_Status    status;
+    int verbose = 0;
+    char *env;
+
+    env = getenv("MPITEST_VERBOSE");
+    if (env)
+    {
+	if (*env != '0')
+	    verbose = 1;
+    }
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL)
+    {
+	IF_VERBOSE(("spawning %d processes\n", np));
+	/* Create 3 more processes */
+	MPI_Comm_spawn("./disconnect3", 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 (rank == SENDER_RANK)
+	{
+	    IF_VERBOSE(("sending int\n"));
+	    i = DATA_VALUE;
+	    MPI_Send(&i, 1, MPI_INT, RECEIVER_RANK, DATA_TAG, intercomm);
+	    MPI_Recv(&data, 1, MPI_INT, RECEIVER_RANK, DATA_TAG, intercomm, 
+		     &status);
+	    if (data != i)
+	    {
+		errs++;
+	    }
+	}
+	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 (rank == RECEIVER_RANK)
+	{
+	    IF_VERBOSE(("receiving int\n"));
+	    i = -1;
+	    MPI_Recv(&i, 1, MPI_INT, SENDER_RANK, DATA_TAG, intercomm, &status);
+	    if (i != DATA_VALUE)
+	    {
+		errs++;
+		printf("expected %d but received %d\n", DATA_VALUE, i);
+		fflush(stdout);
+		MPI_Abort(intercomm, 1);
+	    }
+	    MPI_Send(&i, 1, MPI_INT, SENDER_RANK, DATA_TAG, intercomm);
+	}
+
+	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 );
+    }
+
+    IF_VERBOSE(("calling finalize\n"));
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect3.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect3.c (revision 1198)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect3.c (revision 1198)
@@ -0,0 +1,196 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/*
+ * This test tests the disconnect code for processes that span process groups.
+ *
+ * This test spawns a group of processes and then merges them into a single 
+ * communicator.
+ * Then the single communicator is split into two communicators, one containing
+ * the even ranks and the other the odd ranks.
+ * Then the two new communicators do MPI_Comm_accept/connect/disconnect calls 
+ * in a loop.
+ * The even group does the accepting while the odd group does the connecting.
+ *
+ */
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+
+static char MTEST_Descrip[] = "A simple test of Comm_connect/accept/disconnect";
+
+int main(int argc, char *argv[])
+{
+    int errs = 0;
+    int rank, rsize, i, j, data, num_loops = 100;
+    int np = 4;
+    MPI_Comm parentcomm, intercomm, intracomm, comm;
+    MPI_Status status;
+    char port[MPI_MAX_PORT_NAME] = {0};
+    int even_odd;
+    int verbose = 0;
+    int do_messages = 1;
+    char *env;
+
+    env = getenv("MPITEST_VERBOSE");
+    if (env)
+    {
+	if (*env != '0')
+	    verbose = 1;
+    }
+
+    MTest_Init( &argc, &argv );
+
+    /* command line arguments can change the number of loop iterations and 
+       whether or not messages are sent over the new communicators */
+    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]);
+    }
+
+    /* Spawn the child processes and merge them into a single communicator */
+    MPI_Comm_get_parent( &parentcomm );
+    if (parentcomm == MPI_COMM_NULL)
+    {
+	IF_VERBOSE(("spawning %d processes\n", np));
+	/* Create 4 more processes */
+	MPI_Comm_spawn("./disconnect_reconnect3", /*MPI_ARGV_NULL*/&argv[1], np,
+			MPI_INFO_NULL, 0, MPI_COMM_WORLD,
+			&intercomm, MPI_ERRCODES_IGNORE);
+	MPI_Intercomm_merge(intercomm, 0, &intracomm);
+    }
+    else
+    {
+	intercomm = parentcomm;
+	MPI_Intercomm_merge(intercomm, 1, &intracomm);
+    }
+
+    /* We now have a valid intracomm containing all processes */
+
+    MPI_Comm_rank(intracomm, &rank);
+
+    /* Split the communicator so that the even ranks are in one communicator 
+       and the odd ranks are in another */
+    even_odd = rank % 2;
+    MPI_Comm_split(intracomm, even_odd, rank, &comm);
+
+    /* Open a port on rank zero of the even communicator */
+    /* rank 0 on intracomm == rank 0 on even communicator */
+    if (rank == 0)
+    {
+	MPI_Open_port(MPI_INFO_NULL, port);
+	IF_VERBOSE(("port = %s\n", port));
+    }
+    /* Broadcast the port to everyone.  This makes the logic easier than 
+       trying to figure out which process in the odd communicator to send it 
+       to */
+    MPI_Bcast(port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, intracomm);
+
+    IF_VERBOSE(("disconnecting parent/child communicator\n"));
+    MPI_Comm_disconnect(&intercomm);
+    MPI_Comm_disconnect(&intracomm);
+
+    MPI_Comm_rank(comm, &rank);
+
+    if (!even_odd)
+    {
+	/* The even group does the accepting */
+	for (i=0; i<num_loops; i++)
+	{
+	    IF_VERBOSE(("accepting connection\n"));
+	    MPI_Comm_accept(port, MPI_INFO_NULL, 0, comm, &intercomm);
+	    MPI_Comm_remote_size(intercomm, &rsize);
+	    if (do_messages && (rank == 0))
+	    {
+		j = 0;
+		for (j=0; j<rsize; j++)
+		{
+		    data = i;
+		    IF_VERBOSE(("sending int to odd_communicator process %d\n", j));
+		    MPI_Send(&data, 1, MPI_INT, j, 100, intercomm);
+		    IF_VERBOSE(("receiving int from odd_communicator process %d\n", j));
+		    data = i-1;
+		    MPI_Recv(&data, 1, MPI_INT, j, 100, intercomm, &status);
+		    if (data != i)
+		    {
+			errs++;
+		    }
+		}
+	    }
+	    IF_VERBOSE(("disconnecting 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
+    {
+	/* The odd group does the connecting */
+	for (i=0; i<num_loops; i++)
+	{
+	    IF_VERBOSE(("connecting to port\n"));
+	    MPI_Comm_connect(port, MPI_INFO_NULL, 0, comm, &intercomm);
+	    if (do_messages)
+	    {
+		IF_VERBOSE(("receiving int from even_communicator process 0\n"));
+		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(("sending int back to even_communicator process 0\n"));
+		MPI_Send(&data, 1, MPI_INT, 0, 100, intercomm);
+	    }
+	    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 );*/
+    }
+
+    MPI_Comm_free( &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 );
+    }
+
+    IF_VERBOSE(("calling finalize\n"));
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spaconacc2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spaconacc2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spaconacc2.c (revision 100)
@@ -0,0 +1,213 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Note: In this program, the return codes from the MPI routines are checked.
+   Since the error handlers for the communicators are not set to 
+   MPI_ERRORS_RETURN, any error should cause an abort rather than a return.
+   The test on the return value is an extra safety check; note that a 
+   return value of other than MPI_SUCCESS in these routines indicates an
+   error in the error handling by the MPI implementation */
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+
+void check_error(int error, char *fcname)
+{
+    char err_string[MPI_MAX_ERROR_STRING] = "";
+    int length;
+    if (error != MPI_SUCCESS)
+    {
+	MPI_Error_string(error, err_string, &length);
+	printf("%s failed: %s\n", fcname, err_string);
+	fflush(stdout);
+	MPI_Abort(MPI_COMM_WORLD, error);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    int error;
+    int rank, size, i;
+    char *argv1[2] = { "connector", NULL };
+    char *argv2[2] = { "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;
+
+    if (getenv("MPITEST_VERBOSE"))
+    {
+	verbose = 1;
+    }
+
+    IF_VERBOSE(("init.\n"));
+    error = MPI_Init(&argc, &argv);
+    check_error(error, "MPI_Init");
+
+    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, "path", "." );
+
+	IF_VERBOSE(("spawn connector.\n"));
+	error = MPI_Comm_spawn("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("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 i;
+	    for (i=0; i<argc; i++)
+	    {
+		printf("argv[%d] = <%s>\n", i, argv[i]);
+	    }
+	}
+	fflush(stdout);
+	MPI_Abort(MPI_COMM_WORLD, -2);
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/concurrent_spawns.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/concurrent_spawns.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/concurrent_spawns.c (revision 100)
@@ -0,0 +1,136 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/* #include <fcntl.h> */
+
+/* This test tests the ability to handle multiple simultaneous calls to 
+ * MPI_Comm_spawn.
+ * The first process spawns MAX_NUM_SPAWNS processes and tells them to spawn 
+ * MAX_NUM_SPAWNS -1 processes.
+ * This repeats until no processes are spawned.  For MAX_NUM_SPAWNS = 4 this 
+ * results in 64 processes 
+ * created.  Hopefully this will result in concurrent handling of 
+ * MPI_Comm_spawn calls from multiple processes.
+ */
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+
+static char MTEST_Descrip[] = "A test of concurrent MPI_Comm_spawn calls";
+
+#define MAX_NUM_SPAWNS 4
+
+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;
+
+    env = getenv("MPITEST_VERBOSE");
+    if (env)
+    {
+	if (*env != '0')
+	    verbose = 1;
+    }
+
+    MTest_Init( &argc, &argv );
+
+    /* 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 0
+    { int fd1 = open("concurrent_spawns",O_RDONLY);
+    printf( "fd = %d\n", fd1 ); fflush(stdout); close(fd1); }
+#endif
+    /* 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("./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_free( &parentcomm );
+    }
+    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 );
+    }
+
+    IF_VERBOSE(("calling finalize\n"));
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/taskmaster.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/taskmaster.c (revision 3304)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/taskmaster.c (revision 3304)
@@ -0,0 +1,141 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <mpi.h>
+
+#define DEFAULT_TASKS 128
+#define DEFAULT_TASK_WINDOW 2
+/* #define USE_THREADS */
+
+int comm_world_rank;
+int comm_world_size;
+
+#define CHECK_SUCCESS(status) \
+{ \
+    if (status != MPI_SUCCESS) { \
+	fprintf(stderr, "Routine on line %d returned with error status\n", __LINE__); \
+	MPI_Abort(MPI_COMM_WORLD, -1); \
+    } \
+}
+
+void process_spawn(MPI_Comm * comm, int thread_id)
+{
+    CHECK_SUCCESS(MPI_Comm_spawn("./taskmaster", (char **) NULL, 1, MPI_INFO_NULL, 0,
+				 MPI_COMM_WORLD, comm, NULL));
+}
+
+void process_disconnect(MPI_Comm * comm, int thread_id)
+{
+    if (comm_world_rank == 0) {
+	CHECK_SUCCESS(MPI_Recv(NULL, 0, MPI_CHAR, 0, 1, *comm, MPI_STATUS_IGNORE));
+	CHECK_SUCCESS(MPI_Send(NULL, 0, MPI_CHAR, 0, 1, *comm));
+    }
+
+    CHECK_SUCCESS(MPI_Comm_disconnect(comm));
+}
+
+#ifdef USE_THREADS
+static void * main_thread(void * arg)
+{
+    MPI_Comm child_comm;
+    int thread_id = *((int *) arg);
+
+    process_spawn(&child_comm, thread_id);
+    CHECK_SUCCESS(MPI_Comm_set_errhandler(child_comm, MPI_ERRORS_RETURN));
+    process_disconnect(&child_comm, thread_id);
+
+    return NULL;
+}
+#endif /* USE_THREADS */
+
+int main(int argc, char *argv[])
+{
+    int tasks = 0, provided, i, j;
+    MPI_Comm parent;
+#ifdef USE_THREADS
+    pthread_t * threads;
+#else
+    MPI_Comm * child;
+#endif /* USE_THREADS */
+
+    CHECK_SUCCESS(MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided));
+    if (provided != MPI_THREAD_MULTIPLE) {
+	fprintf(stderr, "MPI does not provide THREAD_MULTIPLE support\n");
+	MPI_Abort(MPI_COMM_WORLD, -1);
+    }
+
+    CHECK_SUCCESS(MPI_Comm_get_parent(&parent));
+
+    if (parent == MPI_COMM_NULL) { /* Parent communicator */
+	if (argc == 2) {
+	    tasks = atoi(argv[1]);
+	}
+	else if (argc == 1) {
+	    tasks = DEFAULT_TASKS;
+	}
+	else {
+	    fprintf(stderr, "Usage: %s {number_of_tasks}\n", argv[0]);
+	    MPI_Abort(MPI_COMM_WORLD, -1);
+	}
+
+	CHECK_SUCCESS(MPI_Comm_rank(MPI_COMM_WORLD, &comm_world_rank));
+	CHECK_SUCCESS(MPI_Comm_size(MPI_COMM_WORLD, &comm_world_size));
+
+#ifdef USE_THREADS
+	threads = (pthread_t *) malloc(tasks * sizeof(pthread_t));
+	if (!threads) {
+	    fprintf(stderr, "Unable to allocate memory for threads\n");
+	    MPI_Abort(MPI_COMM_WORLD, -1);
+	}
+#else
+	child = (MPI_Comm *) malloc(tasks * sizeof(MPI_Comm));
+	if (!child) {
+	    fprintf(stderr, "Unable to allocate memory for child communicators\n");
+	    MPI_Abort(MPI_COMM_WORLD, -1);
+	}
+#endif /* USE_THREADS */
+
+#ifdef USE_THREADS
+	/* Create a thread for each task. Each thread will spawn a
+	 * child process to perform its task. */
+	for (i = 0; i < tasks;) {
+	    for (j = 0; j < DEFAULT_TASK_WINDOW; j++)
+		pthread_create(&threads[j], NULL, main_thread, &j);
+	    for (j = 0; j < DEFAULT_TASK_WINDOW; j++)
+		pthread_join(threads[j], NULL);
+	    i += DEFAULT_TASK_WINDOW;
+	}
+#else
+	/* Directly spawn a child process to perform each task */
+	for (i = 0; i < tasks;) {
+	    for (j = 0; j < DEFAULT_TASK_WINDOW; j++)
+		process_spawn(&child[j], -1);
+	    for (j = 0; j < DEFAULT_TASK_WINDOW; j++)
+		process_disconnect(&child[j], -1);
+	    i += DEFAULT_TASK_WINDOW;
+	}
+#endif /* USE_THREADS */
+
+	CHECK_SUCCESS(MPI_Barrier(MPI_COMM_WORLD));
+
+	if (comm_world_rank == 0)
+	    printf(" No Errors\n");
+    }
+    else { /* Child communicator */
+	/* Do some work here and send a message to the root process in
+	 * the parent communicator. */
+	CHECK_SUCCESS(MPI_Send(NULL, 0, MPI_CHAR, 0, 1, parent));
+	CHECK_SUCCESS(MPI_Recv(NULL, 0, MPI_CHAR, 0, 1, parent, MPI_STATUS_IGNORE));
+	CHECK_SUCCESS(MPI_Comm_disconnect(&parent));
+    }
+
+fn_exit:
+    MPI_Finalize();
+
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/multiple_ports.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/multiple_ports.c (revision 982)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/multiple_ports.c (revision 982)
@@ -0,0 +1,145 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpitest.h"
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+
+/* This test checks to make sure that two MPI_Comm_connects to two different MPI
+ * ports match their corresponding MPI_Comm_accepts.  The root process opens two
+ * MPI ports and sends the first port to process 1 and the second to process 2.
+ * Then the root process accepts a connection from the second port followed by
+ * the first port.  Processes 1 and 2 both connect back to the root but process
+ * 2 first sleeps for three seconds to give process 1 time to attempt to connect
+ * to the root.  The root should wait until process 2 connects before accepting
+ * the connection from process 1.
+ */
+
+int main( int argc, char *argv[] )
+{
+    int num_errors = 0, total_num_errors = 0;
+    int rank, size;
+    char port1[MPI_MAX_PORT_NAME];
+    char port2[MPI_MAX_PORT_NAME];
+    MPI_Status status;
+    MPI_Comm comm1, comm2;
+    int verbose = 0;
+    int data = 0;
+
+    if (getenv("MPITEST_VERBOSE"))
+    {
+	verbose = 1;
+    }
+
+    MPI_Init(&argc, &argv);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+    if (size < 3)
+    {
+	printf("Three processes needed to run this test.\n");
+	MPI_Finalize();
+	return 0;
+    }
+
+    if (rank == 0)
+    {
+	IF_VERBOSE(("0: opening ports.\n"));
+	MPI_Open_port(MPI_INFO_NULL, port1);
+	MPI_Open_port(MPI_INFO_NULL, port2);
+
+	IF_VERBOSE(("0: opened port1: <%s>\n", port1));
+	IF_VERBOSE(("0: opened port2: <%s>\n", port2));
+	IF_VERBOSE(("0: sending ports.\n"));
+	MPI_Send(port1, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
+	MPI_Send(port2, MPI_MAX_PORT_NAME, MPI_CHAR, 2, 0, MPI_COMM_WORLD);
+
+	IF_VERBOSE(("0: accepting port2.\n"));
+	MPI_Comm_accept(port2, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm2);
+	IF_VERBOSE(("0: accepting port1.\n"));
+	MPI_Comm_accept(port1, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm1);
+
+	IF_VERBOSE(("0: closing ports.\n"));
+	MPI_Close_port(port1);
+	MPI_Close_port(port2);
+
+	IF_VERBOSE(("0: sending 1 to process 1.\n"));
+	data = 1;
+	MPI_Send(&data, 1, MPI_INT, 0, 0, comm1);
+
+	IF_VERBOSE(("0: sending 2 to process 2.\n"));
+	data = 2;
+	MPI_Send(&data, 1, MPI_INT, 0, 0, comm2);
+
+	IF_VERBOSE(("0: disconnecting.\n"));
+	MPI_Comm_disconnect(&comm1);
+	MPI_Comm_disconnect(&comm2);
+    }
+    else if (rank == 1)
+    {
+	IF_VERBOSE(("1: receiving port.\n"));
+	MPI_Recv(port1, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
+
+	IF_VERBOSE(("1: received port1: <%s>\n", port1));
+	IF_VERBOSE(("1: connecting.\n"));
+	MPI_Comm_connect(port1, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm1);
+
+	MPI_Recv(&data, 1, MPI_INT, 0, 0, comm1, &status);
+	if (data != 1)
+	{
+	    printf("Received %d from root when expecting 1\n", data);
+	    fflush(stdout);
+	    num_errors++;
+	}
+
+	IF_VERBOSE(("1: disconnecting.\n"));
+	MPI_Comm_disconnect(&comm1);
+    }
+    else if (rank == 2)
+    {
+	IF_VERBOSE(("2: receiving port.\n"));
+	MPI_Recv(port2, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
+
+	IF_VERBOSE(("2: received port2: <%s>\n", port2));
+	/* make sure process 1 has time to do the connect before this process 
+	   attempts to connect */
+	MTestSleep(3);
+	IF_VERBOSE(("2: connecting.\n"));
+	MPI_Comm_connect(port2, MPI_INFO_NULL, 0, MPI_COMM_SELF, &comm2);
+
+	MPI_Recv(&data, 1, MPI_INT, 0, 0, comm2, &status);
+	if (data != 2)
+	{
+	    printf("Received %d from root when expecting 2\n", data);
+	    fflush(stdout);
+	    num_errors++;
+	}
+
+	IF_VERBOSE(("2: disconnecting.\n"));
+	MPI_Comm_disconnect(&comm2);
+    }
+
+    MPI_Barrier(MPI_COMM_WORLD);
+
+    MPI_Reduce(&num_errors, &total_num_errors, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
+    if (rank == 0)
+    {
+	if (total_num_errors)
+	{
+	    printf(" Found %d errors\n", total_num_errors);
+	}
+	else
+	{
+	    printf(" No Errors\n");
+	}
+	fflush(stdout);
+    }
+    MPI_Finalize();
+    return total_num_errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spaiccreate.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spaiccreate.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spaiccreate.c (revision 100)
@@ -0,0 +1,93 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Use Spawn to create an intercomm, then create a new intercomm that includes processes not in the initial spawn intercomm";
+
+/*
+ * This test ensures that spawned processes are able to communicate with 
+ * processes that were not in the communicator from which they were spawned.
+ */
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int wrank, wsize;
+    int np = 2;
+    int errcodes[2];
+    MPI_Comm      parentcomm, intercomm, intercomm2;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
+    MPI_Comm_size( MPI_COMM_WORLD, &wsize );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	/* Create 2 more processes, from process 0 in the original 
+	   comm world */
+	if (wrank == 0) {
+	    MPI_Comm_spawn( "./spaiccreate", MPI_ARGV_NULL, np,
+			    MPI_INFO_NULL, 0, MPI_COMM_SELF,
+			    &intercomm, errcodes );
+	}
+	else {
+	    intercomm = MPI_COMM_NULL;
+	}
+    }
+    else 
+	intercomm = parentcomm;
+
+    /* We now have a valid intercomm.  Use it to create a NEW intercomm
+       that includes all processes */
+    MPI_Intercomm_create( MPI_COMM_WORLD, 0, intercomm, 0, 123, &intercomm2 );
+    
+    /* Have the spawned processes send to rank 1 in the comm world of the 
+       parent */
+    if (parentcomm == MPI_COMM_NULL) {
+	MPI_Send( &wrank, 1, MPI_INT, 1, wrank, intercomm2 );
+    }
+    else {
+	if (wrank == 1) {
+	    int i, rsize, rrank;
+	    MPI_Status status;
+
+	    MPI_Comm_remote_size( intercomm2, &rsize );
+	    for (i=0; i<rsize; i++) {
+		MPI_Recv( &rrank, 1, MPI_INT, i, i, intercomm2, &status );
+		if (rrank != i) {
+		    errs++;
+		    printf( "Received %d from %d; expected %d\n",
+			    rrank, i, i );
+		}
+	    }
+	}
+    }
+
+    /*    printf( "%sAbout to barrier on intercomm2\n", 
+	    (parentcomm == MPI_COMM_NULL) ? "<orig>" : "<spawned>" ); 
+	    fflush(stdout);*/
+    MPI_Barrier( intercomm2 );
+    
+    /* It isn't necessary to free the intercomms, but it should not hurt */
+    if (intercomm != MPI_COMM_NULL) 
+	MPI_Comm_free( &intercomm );
+    MPI_Comm_free( &intercomm2 );
+
+    /* 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 );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawninfo1.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawninfo1.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawninfo1.c (revision 100)
@@ -0,0 +1,145 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2005 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+/* Needed for getcwd */
+#include <unistd.h>
+#endif
+
+static char MTEST_Descrip[] = "A simple test of Comm_spawn with info";
+
+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;
+    MPI_Info      spawninfo;
+    char curdir[1024], wd[1024], childwd[1024];
+
+    MTest_Init( &argc, &argv );
+
+    getcwd( curdir, sizeof(curdir) );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	char *p;
+	/* Create 2 more processes.  Make the working directory the
+	   directory above the current running directory */
+	strncpy( wd, curdir, sizeof(wd) );
+        /* Lop off the last element of the directory */
+	p = wd + strlen(wd) - 1;
+	while (p > wd && *p != '/' && *p != '\\') p--;
+	*p = 0;
+	
+	MPI_Info_create( &spawninfo );
+	MPI_Info_set( spawninfo, "path", curdir );
+	MPI_Info_set( spawninfo, "wdir", wd );
+	MPI_Comm_spawn( "spawninfo1", MPI_ARGV_NULL, np,
+			spawninfo, 0, MPI_COMM_WORLD,
+			&intercomm, errcodes );
+	MPI_Info_free( &spawninfo );
+    }
+    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;
+	    }
+	    for (i=0; i<rsize; i++) {
+		MPI_Recv( childwd, sizeof(childwd), MPI_CHAR, i, 2, intercomm, 
+			  MPI_STATUS_IGNORE );
+		if (strcmp( childwd, wd ) != 0) {
+		    printf( "Expected a working dir of %s but child is in %s\n",
+			    wd, childwd );
+		    errs ++;
+		}
+	    }
+	}
+    }
+    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 our notion of the current directory to the parent */
+	MPI_Send( curdir, strlen(curdir)+1, MPI_CHAR, 0, 2, intercomm );
+
+	/* 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 */
+    MPI_Comm_free( &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 );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spawnintra.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spawnintra.c (revision 3251)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spawnintra.c (revision 3251)
@@ -0,0 +1,194 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "A simple test of Comm_spawn, followed by intercomm merge";
+
+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, intracomm, intracomm2, intracomm3;
+    int           isChild = 0;
+    MPI_Status    status;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL) {
+	/* Create 2 more processes */
+	MPI_Comm_spawn( "./spawnintra", 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 );
+	    }
+	}
+    }
+    else {
+	/* Child */
+	isChild = 1;
+	if (size != np) {
+	    errs++;
+	    printf( "(Child) Did not create %d processes (got %d)\n", 
+		    np, size );
+	}
+	MPI_Recv( &i, 1, MPI_INT, 0, 0, intercomm, &status );
+	if (i != rank) {
+	    errs++;
+	    printf( "Unexpected rank on child %d (%d)\n", rank, i );
+	}
+    }
+
+    /* At this point, try to form the intracommunicator */
+    MPI_Intercomm_merge( intercomm, isChild, &intracomm );
+
+    /* Check on the intra comm */
+    {
+	int icsize, icrank, wrank;
+
+	MPI_Comm_size( intracomm, &icsize );
+	MPI_Comm_rank( intracomm, &icrank );
+	MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
+
+	if (icsize != rsize + size) {
+	    errs++;
+	    printf( "Intracomm rank %d thinks size is %d, not %d\n",
+		    icrank, icsize, rsize + size );
+	}
+	/* Make sure that the processes are ordered correctly */
+	if (isChild) {
+	    int psize;
+	    MPI_Comm_remote_size( parentcomm, &psize );
+	    if (icrank != psize + wrank ) {
+		errs++;
+		printf( "Intracomm rank %d (from child) should have rank %d\n",
+			icrank, psize + wrank );
+	    }
+	}
+	else {
+	    if (icrank != wrank) {
+		errs++;
+		printf( "Intracomm rank %d (from parent) should have rank %d\n",
+			icrank, wrank );
+	    }
+	}
+    }
+
+    /* At this point, try to form the intracommunicator, with the other 
+     processes first */
+    MPI_Intercomm_merge( intercomm, !isChild, &intracomm2 );
+
+    /* Check on the intra comm */
+    {
+	int icsize, icrank, wrank;
+
+	MPI_Comm_size( intracomm2, &icsize );
+	MPI_Comm_rank( intracomm2, &icrank );
+	MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
+
+	if (icsize != rsize + size) {
+	    errs++;
+	    printf( "(2)Intracomm rank %d thinks size is %d, not %d\n",
+		    icrank, icsize, rsize + size );
+	}
+	/* Make sure that the processes are ordered correctly */
+	if (isChild) {
+	    if (icrank != wrank ) {
+		errs++;
+		printf( "(2)Intracomm rank %d (from child) should have rank %d\n",
+			icrank, wrank );
+	    }
+	}
+	else {
+	    int csize;
+	    MPI_Comm_remote_size( intercomm, &csize );
+	    if (icrank != wrank + csize) {
+		errs++;
+		printf( "(2)Intracomm rank %d (from parent) should have rank %d\n",
+			icrank, wrank + csize );
+	    }
+	}
+    }
+
+    /* At this point, try to form the intracommunicator, with an 
+       arbitrary choice for the first group of processes */
+    MPI_Intercomm_merge( intercomm, 0, &intracomm3 );
+    /* Check on the intra comm */
+    {
+	int icsize, icrank, wrank;
+
+	MPI_Comm_size( intracomm3, &icsize );
+	MPI_Comm_rank( intracomm3, &icrank );
+	MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
+
+	if (icsize != rsize + size) {
+	    errs++;
+	    printf( "(3)Intracomm rank %d thinks size is %d, not %d\n",
+		    icrank, icsize, rsize + size );
+	}
+	/* Eventually, we should test that the processes are ordered 
+	   correctly, by groups (must be one of the two cases above) */
+    }
+
+    /* Update error count */
+    if (isChild) {
+	/* Send the errs back to the master process */
+	MPI_Ssend( &errs, 1, MPI_INT, 0, 1, intercomm );
+    }
+    else {
+	if (rank == 0) {
+	    /* 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;
+	    }
+	}
+    }
+
+    /* It isn't necessary to free the intracomms, but it should not hurt */
+    MPI_Comm_free( &intracomm );
+    MPI_Comm_free( &intracomm2 );
+    MPI_Comm_free( &intracomm3 );
+
+    /* It isn't necessary to free the intercomm, but it should not hurt */
+    MPI_Comm_free( &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 );
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/namepub.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/namepub.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/namepub.c (revision 100)
@@ -0,0 +1,100 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <string.h>
+#include "mpitest.h"
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    char port_name[MPI_MAX_PORT_NAME], port_name_out[MPI_MAX_PORT_NAME];
+    char serv_name[256];
+    int merr, mclass;
+    char errmsg[MPI_MAX_ERROR_STRING];
+    int msglen;
+    int rank;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+    /* Note that according to the MPI standard, port_name must
+       have been created by MPI_Open_port.  For current testing
+       purposes, we'll use a fake name.  This test should eventually use
+       a valid name from Open_port */
+
+    strcpy( port_name, "otherhost:122" );
+    strcpy( serv_name, "MyTest" );
+
+    MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+    if (rank == 0)
+    {
+	merr = MPI_Publish_name( serv_name, MPI_INFO_NULL, port_name );
+	if (merr) {
+	    errs++;
+	    MPI_Error_string( merr, errmsg, &msglen );
+	    printf( "Error in Publish_name: \"%s\"\n", errmsg );
+	}
+
+	MPI_Barrier(MPI_COMM_WORLD);
+	MPI_Barrier(MPI_COMM_WORLD);
+	
+	merr = MPI_Unpublish_name( serv_name, MPI_INFO_NULL, port_name );
+	if (merr) {
+	    errs++;
+	    MPI_Error_string( merr, errmsg, &msglen );
+	    printf( "Error in Unpublish name: \"%s\"\n", errmsg );
+	}
+
+    }
+    else
+    {
+	MPI_Barrier(MPI_COMM_WORLD);
+	
+	merr = MPI_Lookup_name( serv_name, MPI_INFO_NULL, port_name_out );
+	if (merr) {
+	    errs++;
+	    MPI_Error_string( merr, errmsg, &msglen );
+	    printf( "Error in Lookup name: \"%s\"\n", errmsg );
+	}
+	else {
+	    if (strcmp( port_name, port_name_out )) {
+		errs++;
+		printf( "Lookup name returned the wrong value (%s)\n", 
+			port_name_out );
+	    }
+	}
+
+	MPI_Barrier(MPI_COMM_WORLD);
+    }
+
+
+    MPI_Barrier(MPI_COMM_WORLD);
+    
+    merr = MPI_Lookup_name( serv_name, MPI_INFO_NULL, port_name_out );
+    if (!merr) {
+	errs++;
+	printf( "Lookup name returned name after it was unpublished\n" );
+    }
+    else {
+	/* Must be class MPI_ERR_NAME */
+	MPI_Error_class( merr, &mclass );
+	if (mclass != MPI_ERR_NAME) {
+	    errs++;
+	    MPI_Error_string( merr, errmsg, &msglen );
+	    printf( "Lookup name returned the wrong error class (%d), msg: \"%s\"\n", 
+		    mclass, errmsg );
+	}
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+  
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect.c (revision 1198)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect_reconnect.c (revision 1198)
@@ -0,0 +1,187 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+
+static char MTEST_Descrip[] = "A simple test of Comm_connect/accept/disconnect";
+
+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;
+
+    env = getenv("MPITEST_VERBOSE");
+    if (env)
+    {
+	if (*env != '0')
+	    verbose = 1;
+    }
+
+    MTest_Init( &argc, &argv );
+
+    /* 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("./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 );
+    }
+
+    IF_VERBOSE(("[%d] calling finalize\n",rank));
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/disconnect.c (revision 100)
@@ -0,0 +1,114 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+
+static char MTEST_Descrip[] = "A simple test of Comm_disconnect";
+
+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;
+
+    env = getenv("MPITEST_VERBOSE");
+    if (env)
+    {
+	if (*env != '0')
+	    verbose = 1;
+    }
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Comm_get_parent( &parentcomm );
+
+    if (parentcomm == MPI_COMM_NULL)
+    {
+	IF_VERBOSE(("spawning %d processes\n", np));
+	/* Create 3 more processes */
+	MPI_Comm_spawn("./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 );
+    }
+
+    IF_VERBOSE(("calling finalize\n"));
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/spaconacc.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/spaconacc.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/spaconacc.c (revision 100)
@@ -0,0 +1,204 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define IF_VERBOSE(a) if (verbose) { printf a ; fflush(stdout); }
+void check_error(int, char *);
+
+void check_error(int error, char *fcname)
+{
+    char err_string[MPI_MAX_ERROR_STRING] = "";
+    int length;
+    if (error != MPI_SUCCESS)
+    {
+	MPI_Error_string(error, err_string, &length);
+	printf("%s failed: %s\n", fcname, err_string);
+	fflush(stdout);
+	MPI_Abort(MPI_COMM_WORLD, error);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    int error;
+    int rank, size;
+    char *argv1[2] = { "connector", NULL };
+    char *argv2[2] = { "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;
+
+    if (getenv("MPITEST_VERBOSE"))
+    {
+	verbose = 1;
+    }
+
+    IF_VERBOSE(("init.\n"));
+    error = MPI_Init(&argc, &argv);
+    check_error(error, "MPI_Init");
+
+    /* To improve reporting of problems about operations, we
+       change the error handler to errors return */
+    MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+    MPI_Comm_set_errhandler( MPI_COMM_SELF, MPI_ERRORS_RETURN );
+
+    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) */
+	error = MPI_Info_create( &spawn_path );
+	check_error( error, "MPI_Info_create" );
+	error = MPI_Info_set( spawn_path, "path", "." );
+	check_error( error, "MPI_Info_set" );
+
+	IF_VERBOSE(("spawn connector.\n"));
+	error = MPI_Comm_spawn("spaconacc", 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("spaconacc", argv2, 1, spawn_path, 0, 
+			       MPI_COMM_SELF, &comm_acceptor, 
+			       MPI_ERRCODES_IGNORE);
+	check_error(error, "MPI_Comm_spawn");
+	error = MPI_Info_free( &spawn_path );
+	check_error( error, "MPI_Info_free" );
+
+	MPI_Comm_set_errhandler( comm_connector, MPI_ERRORS_RETURN );
+	MPI_Comm_set_errhandler( comm_acceptor, MPI_ERRORS_RETURN );
+
+	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");
+
+	MPI_Comm_set_errhandler( comm_parent, MPI_ERRORS_RETURN );
+
+	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");
+
+	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);
+	}
+
+	MPI_Comm_set_errhandler( comm_parent, MPI_ERRORS_RETURN );
+	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");
+
+	MPI_Comm_set_errhandler( comm, MPI_ERRORS_RETURN );
+	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 i;
+	    for (i=0; i<argc; i++)
+	    {
+		printf("argv[%d] = <%s>\n", i, argv[i]);
+	    }
+	}
+	fflush(stdout);
+	MPI_Abort(MPI_COMM_WORLD, -2);
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/spawn/testlist
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/spawn/testlist (revision 3857)
+++ /mpich2/branches/dev/dkim/test/mpi/spawn/testlist (revision 3857)
@@ -0,0 +1,30 @@
+namepub 2
+spawn1 1
+spawn2 1
+spawninfo1 1
+spawnminfo1 1
+spawnintra 1
+spawnintra 2
+spawnargv 1
+spawnmanyarg 1
+spawnmult2 2
+spaconacc 1
+spaconacc2 1
+selfconacc 2
+spaiccreate 2
+taskmaster 1
+join 2
+disconnect_reconnect 3
+disconnect_reconnect2 3
+disconnect_reconnect3 3
+multiple_ports 3
+multiple_ports2 4
+disconnect 3
+disconnect2 3
+disconnect3 3
+# The concurrent_spawns test can overtax the process manager, so
+# we set a shorter time limit in case it hangs.
+# There's a problem with mpd that causes concurrent_spawns to cause problems
+# with mpd, leading to many runaway concurrent_spawn processes.  This 
+# test is being disabled until mpd is fixed.
+concurrent_spawns 1 timeLimit=30
Index: /mpich2/branches/dev/dkim/test/mpi/project_f.txt
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/project_f.txt (revision 4104)
+++ /mpich2/branches/dev/dkim/test/mpi/project_f.txt (revision 4104)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject ProjectCreator="Intel Fortran" Keyword="Console Application" Version="8.00" ProjectIdGuid="{UUID1}">
+	<Platforms>
+		<Platform Name="PLATFORM_NAME"/></Platforms>
+	<Configurations>
+		<Configuration Name="Debug|PLATFORM_NAME" DeleteExtensionsOnClean="*.obj;*.mod;*.pdb;*.asm;*.map;*.dyn;*.dpi;*.tmp;*.log;*.ilk;*.exe;$(TargetPath)" MustRebuild="true" Command="$(TargetPath)">
+				<Tool Name="VFMidlTool" SwitchesHaveChanged="true" SuppressStartupBanner="true" HeaderFileName="$(InputName).h" TypeLibraryName="$(IntDir)/$(InputName).tlb"/>
+				<Tool Name="VFPreBuildEventTool"/>
+				<Tool Name="VFFortranCompilerTool" SwitchesHaveChanged="true" SuppressStartupBanner="true" DebugInformationFormat="debugEnabled" Optimization="optimizeDisabled" AdditionalIncludeDirectories="DOTDOTS..\..\src\include;DOTDOTSTARGET_HEADER" ModulePath="$(INTDIR)/" ObjectFile="$(INTDIR)/" Traceback="true" BoundsCheck="true" RuntimeLibrary="rtSingleThreadedDebug" CompileOnly="true"/>
+				<Tool Name="VFPostBuildEventTool"/>
+				<Tool Name="VFCustomBuildTool"/>
+				<Tool Name="VFLinkerTool" SwitchesHaveChanged="true" MustRebuild="true" OutputFile="Debug/PROJECTNAME.exe" LinkIncremental="linkIncrementalNo" SuppressStartupBanner="true" AdditionalLibraryDirectories="DOTDOTS..\..\lib" GenerateDebugInformation="true" ProgramDatabaseFile="$(OUTDIR)/PROJECTNAME.pdb" SubSystem="subSystemConsole" AdditionalDependencies="fmpich2d.lib mpid.lib"/>
+				<Tool Name="VFResourceCompilerTool" ResourceOutputFileName="$(IntDir)/$(InputName).res"/>
+				<Tool Name="VFPreLinkEventTool"/></Configuration>
+		<Configuration Name="Release|PLATFORM_NAME" DeleteExtensionsOnClean="*.obj;*.mod;*.pdb;*.asm;*.map;*.dyn;*.dpi;*.tmp;*.log;*.ilk;*.exe;$(TargetPath)" MustRebuild="true" Command="$(TargetPath)">
+				<Tool Name="VFMidlTool" SwitchesHaveChanged="true" SuppressStartupBanner="true" HeaderFileName="$(InputName).h" TypeLibraryName="$(IntDir)/$(InputName).tlb"/>
+				<Tool Name="VFPreBuildEventTool"/>
+				<Tool Name="VFFortranCompilerTool" SwitchesHaveChanged="true" SuppressStartupBanner="true" AdditionalIncludeDirectories="DOTDOTS..\..\src\include;DOTDOTSTARGET_HEADER" ModulePath="$(INTDIR)/" ObjectFile="$(INTDIR)/" CompileOnly="true"/>
+				<Tool Name="VFPostBuildEventTool"/>
+				<Tool Name="VFCustomBuildTool"/>
+				<Tool Name="VFLinkerTool" SwitchesHaveChanged="true" MustRebuild="true" OutputFile="Release/PROJECTNAME.exe" LinkIncremental="linkIncrementalNo" SuppressStartupBanner="true" AdditionalLibraryDirectories="DOTDOTS..\..\lib" SubSystem="subSystemConsole" AdditionalDependencies="fmpich2.lib mpi.lib"/>
+				<Tool Name="VFResourceCompilerTool" ResourceOutputFileName="$(IntDir)/$(InputName).res"/>
+				<Tool Name="VFPreLinkEventTool"/></Configuration></Configurations>
+	<Files>
+		<Filter Name="Source Files" Filter="f90;for;f;fpp;ftn;def;odl;idl">
+		<File RelativePath="PROJECTNAME.FORTFILEEXTN"/>
+		<File RelativePath="..\util\mtestFORTFILEEXTN.FORTFILEEXTN"/></Filter>
+		<Filter Name="Header Files" Filter="fi;fd"/>
+		<Filter Name="Resource Files" Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"/></Files>
+	<Globals/></VisualStudioProject>
Index: /mpich2/branches/dev/dkim/test/mpi/coll/red4.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/red4.c (revision 3681)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/red4.c (revision 3681)
@@ -0,0 +1,254 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Test MPI_Reduce with non-commutative user-define operations and arbitrary root";
+
+/*
+ * This tests that the reduce operation respects the noncommutative flag.
+ * and that can distinguish between P_{root} P_{root+1} 
+ * ... P_{root-1} and P_0 ... P_{size-1} .  The MPI standard clearly
+ * specifies that the result is P_0 ... P_{size-1}, independent of the root 
+ * (see 4.9.4 in MPI-1)
+ */
+
+/* This implements a simple matrix-matrix multiply.  This is an associative
+   but not commutative operation.  The matrix size is set in matSize;
+   the number of matrices is the count argument. The matrix is stored
+   in C order, so that
+     c(i,j) is cin[j+i*matSize]
+ */
+#define MAXCOL 256
+static int matSize = 0;  /* Must be < MAXCOL */
+
+void uop( void *cinPtr, void *coutPtr, int *count, MPI_Datatype *dtype )
+{
+    const int *cin;
+    int       *cout;
+    int       i, j, k, nmat;
+    int       tempCol[MAXCOL];
+
+    if (*count != 1) printf( "Panic!\n" );
+    for (nmat = 0; nmat < *count; nmat++) {
+	cin  = (const int *)cinPtr;
+	cout = (int *)coutPtr;
+	for (j=0; j<matSize; j++) {
+	    for (i=0; i<matSize; i++) {
+		tempCol[i] = 0;
+		for (k=0; k<matSize; k++) {
+		    /* col[i] += cin(i,k) * cout(k,j) */
+		    tempCol[i] += cin[k+i*matSize] * cout[j+k*matSize];
+		}
+	    }
+	    for (i=0; i<matSize; i++) {
+		cout[j+i*matSize] = tempCol[i];
+	    }
+	}
+	cinPtr = (int *)cinPtr + matSize*matSize;
+	coutPtr = (int *)coutPtr + matSize*matSize;
+    }
+}
+
+/* Initialize the integer matrix as a permutation of rank with rank+1.
+   If we call this matrix P_r, we know that product of P_0 P_1 ... P_{size-1}
+   is the matrix with rows ordered as
+   1,size,2,3,4,...,size-1
+   (The matrix is basically a circular shift right, 
+   shifting right n-1 steps for an n x n dimensional matrix, with the last
+   step swapping rows 1 and size)
+*/   
+
+static void initMat( MPI_Comm comm, int mat[] )
+{
+    int i, size, rank;
+    
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+
+    /* Remember the matrix size */
+    matSize = size;
+
+    for (i=0; i<matSize*matSize; i++) mat[i] = 0;
+
+    for (i=0; i<matSize; i++) {
+	if (i == rank)                   
+	    mat[((i+1)%matSize) + i * matSize] = 1;
+	else if (i == ((rank + 1)%matSize)) 
+	    mat[((i+matSize-1)%matSize) + i * matSize] = 1;
+	else                             
+	    mat[i+i*matSize] = 1;
+    }
+}
+
+/* Compare a matrix with the identity matrix */
+static int isIdentity( MPI_Comm comm, int mat[] )
+{
+    int i, j, size, rank, errs = 0;
+    
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+
+    for (i=0; i<size; i++) {
+	for (j=0; j<size; j++) {
+	    if (j == i) {
+		if (mat[j+i*size] != 1) {
+		    printf( "mat(%d,%d) = %d, should = 1\n", 
+			    i, j, mat[j+i*size] );
+		    errs++;
+		}
+	    }
+	    else {
+		if (mat[j+i*size] != 0) {
+		    printf( "mat(%d,%d) = %d, should = 0\n",
+			    i, j, mat[j+i*size] );
+		    errs++;
+		}
+	    }
+	}
+    }
+    return errs;
+}
+
+/* Compare a matrix with the identity matrix with rows permuted to as rows
+   1,size,2,3,4,5,...,size-1 */
+static int isPermutedIdentity( MPI_Comm comm, int mat[] )
+{
+    int i, j, size, rank, errs = 0;
+    
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+
+    /* Check the first two last rows */
+    i = 0;
+    for (j=0; j<size; j++) {
+	if (j==0) { 
+	    if (mat[j] != 1) {
+		printf( "mat(%d,%d) = %d, should = 1\n", 
+			i, j, mat[j] );
+		errs++;
+	    }
+	}
+	else {
+	    if (mat[j] != 0) {
+		printf( "mat(%d,%d) = %d, should = 0\n", 
+			i, j, mat[j] );
+		errs++;
+	    }
+	}
+    }
+    i = 1;
+    for (j=0; j<size; j++) {
+	if (j==size-1) { 
+	    if (mat[j+i*size] != 1) {
+		printf( "mat(%d,%d) = %d, should = 1\n", 
+			i, j, mat[j+i*size] );
+		errs++;
+	    }
+	}
+	else {
+	    if (mat[j+i*size] != 0) {
+		printf( "mat(%d,%d) = %d, should = 0\n", 
+			i, j, mat[j+i*size] );
+		errs++;
+	    }
+	}
+    }
+    /* The remaint rows are shifted down by one */
+    for (i=2; i<size; i++) {
+	for (j=0; j<size; j++) {
+	    if (j == i-1) {
+		if (mat[j+i*size] != 1) {
+		    printf( "mat(%d,%d) = %d, should = 1\n", 
+			    i, j, mat[j+i*size] );
+		    errs++;
+		}
+	    }
+	    else {
+		if (mat[j+i*size] != 0) {
+		    printf( "mat(%d,%d) = %d, should = 0\n",
+			    i, j, mat[j+i*size] );
+		    errs++;
+		}
+	    }
+	}
+    }
+    return errs;
+}
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int rank, size, root;
+    int minsize = 2, count; 
+    MPI_Comm      comm;
+    int *buf, *bufout;
+    MPI_Op op;
+    MPI_Datatype mattype;
+
+    MTest_Init( &argc, &argv );
+
+    MPI_Op_create( uop, 0, &op );
+    
+    while (MTestGetIntracommGeneral( &comm, minsize, 1 )) {
+	if (comm == MPI_COMM_NULL) continue;
+	MPI_Comm_size( comm, &size );
+	MPI_Comm_rank( comm, &rank );
+
+	if (size > MAXCOL) {
+	    /* Skip because there are too many processes */
+	    MTestFreeComm( &comm );
+	    continue;
+	}
+
+	/* Only one matrix for now */
+	count = 1;
+
+	/* A single matrix, the size of the communicator */
+	MPI_Type_contiguous( size*size, MPI_INT, &mattype );
+	MPI_Type_commit( &mattype );
+	
+	buf = (int *)malloc( count * size * size * sizeof(int) );
+	if (!buf) MPI_Abort( MPI_COMM_WORLD, 1 );
+	bufout = (int *)malloc( count * size * size * sizeof(int) );
+	if (!bufout) MPI_Abort( MPI_COMM_WORLD, 1 );
+
+	for (root = 0; root < size; root ++) {
+	    initMat( comm, buf );
+	    MPI_Reduce( buf, bufout, count, mattype, op, root, comm );
+	    if (rank == root) {
+		errs += isPermutedIdentity( comm, bufout );
+	    }
+
+	    /* Try the same test, but using MPI_IN_PLACE */
+	    initMat( comm, bufout );
+	    if (rank == root) {
+		MPI_Reduce( MPI_IN_PLACE, bufout, count, mattype, op, root, comm );
+	    }
+	    else {
+		MPI_Reduce( bufout, NULL, count, mattype, op, root, comm );
+	    }
+	    if (rank == root) {
+		errs += isPermutedIdentity( comm, bufout );
+	    }
+	}
+	MPI_Type_free( &mattype );
+
+	free( buf );
+	free( bufout );
+
+	MTestFreeComm( &comm );
+    }
+
+    MPI_Op_free( &op );
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/allred.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/allred.c (revision 3899)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/allred.c (revision 3899)
@@ -0,0 +1,343 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi.h"
+
+int count, size, rank;
+int cerrcnt, gerrcnt;
+
+struct int_test { int a; int b; };
+struct long_test { long a; int b; };
+struct short_test { short a; int b; };
+struct float_test { float a; int b; };
+struct double_test { double a; int b; };
+
+#define mpi_type2str(type)                                 \
+    ((type == MPI_INT) ? "MPI_INT" :                       \
+     (type == MPI_LONG) ? "MPI_LONG" :                     \
+     (type == MPI_SHORT) ? "MPI_SHORT" :                   \
+     (type == MPI_UNSIGNED_SHORT) ? "MPI_UNSIGNED_SHORT" : \
+     (type == MPI_UNSIGNED) ? "MPI_UNSIGNED" :             \
+     (type == MPI_UNSIGNED_LONG) ? "MPI_UNSIGNED_LONG" :   \
+     (type == MPI_FLOAT) ? "MPI_FLOAT" :                   \
+     (type == MPI_DOUBLE) ? "MPI_DOUBLE" :                 \
+     (type == MPI_2INT) ? "MPI_2INT" :                     \
+     (type == MPI_LONG_INT) ? "MPI_LONG_INT" :             \
+     (type == MPI_SHORT_INT) ? "MPI_SHORT_INT" :           \
+     (type == MPI_FLOAT_INT) ? "MPI_FLOAT_INT" :           \
+     (type == MPI_DOUBLE_INT) ? "MPI_DOUBLE_INT" :         \
+     "MPI_NULL_DATATYPE")
+
+#define mpi_op2str(op)                   \
+    ((op == MPI_SUM) ? "MPI_SUM" :       \
+     (op == MPI_PROD) ? "MPI_PROD" :     \
+     (op == MPI_MAX) ? "MPI_MAX" :       \
+     (op == MPI_MIN) ? "MPI_MIN" :       \
+     (op == MPI_LOR) ? "MPI_LOR" :       \
+     (op == MPI_LXOR) ? "MPI_LXOR" :     \
+     (op == MPI_LAND) ? "MPI_LAND" :     \
+     (op == MPI_BOR) ? "MPI_BOR" :       \
+     (op == MPI_BAND) ? "MPI_BAND" :     \
+     (op == MPI_BXOR) ? "MPI_BXOR" :     \
+     (op == MPI_MAXLOC) ? "MPI_MAXLOC" : \
+     (op == MPI_MINLOC) ? "MPI_MINLOC" : \
+     "MPI_NO_OP")
+
+#define DECL_MALLOC_IN_OUT_SOL(type)                 \
+    type *in, *out, *sol;                            \
+    in = (type *) malloc(count * sizeof(type));      \
+    out = (type *) malloc(count * sizeof(type));     \
+    sol = (type *) malloc(count * sizeof(type));
+
+#define SET_INDEX_CONST(arr, val)               \
+    {                                           \
+        int i;                                  \
+        for (i = 0; i < count; i++)             \
+            arr[i] = val;                       \
+    }
+
+#define SET_INDEX_SUM(arr, val)                 \
+    {                                           \
+        int i;                                  \
+        for (i = 0; i < count; i++)             \
+            arr[i] = i + val;                   \
+    }
+
+#define SET_INDEX_FACTOR(arr, val)              \
+    {                                           \
+        int i;                                  \
+        for (i = 0; i < count; i++)             \
+            arr[i] = i * (val);                 \
+    }
+
+#define SET_INDEX_POWER(arr, val)               \
+    {                                           \
+        int i, j;                               \
+        for (i = 0; i < count; i++) {           \
+            (arr)[i] = 1;                       \
+            for (j = 0; j < (val); j++)         \
+                arr[i] *= i;                    \
+        }                                       \
+    }
+
+#define ERROR_CHECK_AND_FREE(lerrcnt, mpi_type, mpi_op)                 \
+    {                                                                   \
+        if (lerrcnt) {                                                  \
+            fprintf(stderr, "(%d) Error for type %s and op %s\n",       \
+                    rank, mpi_type2str(mpi_type), mpi_op2str(mpi_op));  \
+        }                                                               \
+        free(in); free(out); free(sol);                                 \
+    }
+
+#define ALLREDUCE_AND_FREE(mpi_type, mpi_op, in, out, sol)              \
+    {                                                                   \
+        int i, lerrcnt = 0;                                             \
+        MPI_Allreduce(in, out, count, mpi_type, mpi_op, MPI_COMM_WORLD); \
+        for (i = 0; i < count; i++) {                                   \
+            if (out[i] != sol[i]) {                                     \
+                cerrcnt++;                                              \
+                lerrcnt++;                                              \
+            }                                                           \
+        }                                                               \
+        ERROR_CHECK_AND_FREE(lerrcnt, mpi_type, mpi_op);                \
+    }
+
+#define STRUCT_ALLREDUCE_AND_FREE(mpi_type, mpi_op, in, out, sol)       \
+    {                                                                   \
+        int i, lerrcnt = 0;                                             \
+        MPI_Allreduce(in, out, count, mpi_type, mpi_op, MPI_COMM_WORLD); \
+        for (i = 0; i < count; i++) {                                   \
+            if ((out[i].a != sol[i].a) || (out[i].b != sol[i].b)) {     \
+                cerrcnt++;                                              \
+                lerrcnt++;                                              \
+            }                                                           \
+        }                                                               \
+        ERROR_CHECK_AND_FREE(lerrcnt, mpi_type, mpi_op);                \
+    }
+
+#define SET_INDEX_STRUCT_CONST(arr, val, el)                    \
+    {                                                           \
+        int i;                                                  \
+        for (i = 0; i < count; i++)                             \
+            arr[i].el = val;                                    \
+    }
+
+#define SET_INDEX_STRUCT_SUM(arr, val, el)                      \
+    {                                                           \
+        int i;                                                  \
+        for (i = 0; i < count; i++)                             \
+            arr[i].el = i + (val);                              \
+    }
+
+#define sum_test1(type, mpi_type)                                       \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        SET_INDEX_SUM(in, 0);                                           \
+        SET_INDEX_FACTOR(sol, size);                                    \
+        SET_INDEX_CONST(out, 0);                                        \
+        ALLREDUCE_AND_FREE(mpi_type, MPI_SUM, in, out, sol);            \
+    }
+
+#define prod_test1(type, mpi_type)                                      \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        SET_INDEX_SUM(in, 0);                                           \
+        SET_INDEX_POWER(sol, size);                                     \
+        SET_INDEX_CONST(out, 0);                                        \
+        ALLREDUCE_AND_FREE(mpi_type, MPI_PROD, in, out, sol);           \
+    }
+
+#define max_test1(type, mpi_type)                                       \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        SET_INDEX_SUM(in, rank);                                        \
+        SET_INDEX_SUM(sol, size - 1);                                   \
+        SET_INDEX_CONST(out, 0);                                        \
+        ALLREDUCE_AND_FREE(mpi_type, MPI_MAX, in, out, sol);            \
+    }
+
+#define min_test1(type, mpi_type)                                       \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        SET_INDEX_SUM(in, rank);                                        \
+        SET_INDEX_SUM(sol, 0);                                          \
+        SET_INDEX_CONST(out, 0);                                        \
+        ALLREDUCE_AND_FREE(mpi_type, MPI_MIN, in, out, sol);            \
+    }
+
+#define const_test(type, mpi_type, mpi_op, val1, val2, val3)            \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        SET_INDEX_CONST(in, (val1));                                    \
+        SET_INDEX_CONST(sol, (val2));                                   \
+        SET_INDEX_CONST(out, (val3));                                   \
+        ALLREDUCE_AND_FREE(mpi_type, mpi_op, in, out, sol);             \
+    }
+
+#define lor_test1(type, mpi_type)                                       \
+    const_test(type, mpi_type, MPI_LOR, (rank & 0x1), (size > 1), 0)
+#define lor_test2(type, mpi_type)                       \
+    const_test(type, mpi_type, MPI_LOR, 0, 0, 0)
+#define lxor_test1(type, mpi_type)                                      \
+    const_test(type, mpi_type, MPI_LXOR, (rank == 1), (size > 1), 0)
+#define lxor_test2(type, mpi_type)                      \
+    const_test(type, mpi_type, MPI_LXOR, 0, 0, 0)
+#define lxor_test3(type, mpi_type)                      \
+    const_test(type, mpi_type, MPI_LXOR, 1, 0, 0)
+#define land_test1(type, mpi_type)                              \
+    const_test(type, mpi_type, MPI_LAND, (rank & 0x1), 0, 0)
+#define land_test2(type, mpi_type)                      \
+    const_test(type, mpi_type, MPI_LAND, 1, 1, 0)
+#define bor_test1(type, mpi_type)                                       \
+    const_test(type, mpi_type, MPI_BOR, (rank & 0x3), ((size < 3) ? size - 1 : 0x3), 0)
+#define bxor_test1(type, mpi_type)                                      \
+    const_test(type, mpi_type, MPI_BXOR, (rank == 1) * 0xf0, (size > 1) * 0xf0, 0)
+#define bxor_test2(type, mpi_type)                      \
+    const_test(type, mpi_type, MPI_BXOR, 0, 0, 0)
+#define bxor_test3(type, mpi_type)                      \
+    const_test(type, mpi_type, MPI_BXOR, ~0, 0, 0)
+
+#define band_test1(type, mpi_type)                                      \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        if (rank == size-1) {                                           \
+            SET_INDEX_SUM(in, 0);                                       \
+        }                                                               \
+        else {                                                          \
+            SET_INDEX_CONST(in, ~0);                                    \
+        }                                                               \
+        SET_INDEX_SUM(sol, 0);                                          \
+        SET_INDEX_CONST(out, 0);                                        \
+        ALLREDUCE_AND_FREE(mpi_type, MPI_BAND, in, out, sol);           \
+    }
+
+#define band_test2(type, mpi_type)                                      \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        if (rank == size-1) {                                           \
+            SET_INDEX_SUM(in, 0);                                       \
+        }                                                               \
+        else {                                                          \
+            SET_INDEX_CONST(in, 0);                                     \
+        }                                                               \
+        SET_INDEX_CONST(sol, 0);                                        \
+        SET_INDEX_CONST(out, 0);                                        \
+        ALLREDUCE_AND_FREE(mpi_type, MPI_BAND, in, out, sol);           \
+    }
+
+#define maxloc_test(type, mpi_type)                                     \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        SET_INDEX_STRUCT_SUM(in, rank, a);                              \
+        SET_INDEX_STRUCT_CONST(in, rank, b);                            \
+        SET_INDEX_STRUCT_SUM(sol, size - 1, a);                         \
+        SET_INDEX_STRUCT_CONST(sol, size - 1, b);                       \
+        SET_INDEX_STRUCT_CONST(out, 0, a);                              \
+        SET_INDEX_STRUCT_CONST(out, -1, b);                             \
+        STRUCT_ALLREDUCE_AND_FREE(mpi_type, MPI_MAXLOC, in, out, sol);   \
+    }
+
+#define minloc_test(type, mpi_type)                                     \
+    {                                                                   \
+        DECL_MALLOC_IN_OUT_SOL(type);                                   \
+        SET_INDEX_STRUCT_SUM(in, rank, a);                              \
+        SET_INDEX_STRUCT_CONST(in, rank, b);                            \
+        SET_INDEX_STRUCT_SUM(sol, 0, a);                                \
+        SET_INDEX_STRUCT_CONST(sol, 0, b);                              \
+        SET_INDEX_STRUCT_CONST(out, 0, a);                              \
+        SET_INDEX_STRUCT_CONST(out, -1, b);                             \
+        STRUCT_ALLREDUCE_AND_FREE(mpi_type, MPI_MINLOC, in, out, sol);  \
+    }
+
+#define test_types_set1(op, post)                                   \
+    {                                                               \
+        op##_test##post(int, MPI_INT);                              \
+        op##_test##post(long, MPI_LONG);                            \
+        op##_test##post(short, MPI_SHORT);                          \
+        op##_test##post(unsigned short, MPI_UNSIGNED_SHORT);        \
+        op##_test##post(unsigned, MPI_UNSIGNED);                    \
+        op##_test##post(unsigned long, MPI_UNSIGNED_LONG);          \
+        op##_test##post(unsigned char, MPI_UNSIGNED_CHAR);          \
+    }
+
+#define test_types_set2(op, post)               \
+    {                                           \
+        test_types_set1(op, post);              \
+        op##_test##post(float, MPI_FLOAT);      \
+        op##_test##post(double, MPI_DOUBLE);    \
+    }
+
+#define test_types_set3(op, post)                                   \
+    {                                                               \
+        op##_test##post(unsigned char, MPI_BYTE);                   \
+    }
+
+int main( int argc, char **argv )
+{
+    MPI_Init(&argc, &argv);
+
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+    count = 10;
+
+    test_types_set2(sum, 1);
+    test_types_set2(prod, 1);
+    test_types_set2(max, 1);
+    test_types_set2(min, 1);
+
+    test_types_set1(lor, 1);
+    test_types_set1(lor, 2);
+
+    test_types_set1(lxor, 1);
+    test_types_set1(lxor, 2);
+    test_types_set1(lxor, 3);
+
+    test_types_set1(land, 1);
+    test_types_set1(land, 2);
+
+    test_types_set1(bor, 1);
+    test_types_set1(band, 1);
+    test_types_set1(band, 2);
+
+    test_types_set1(bxor, 1);
+    test_types_set1(bxor, 2);
+    test_types_set1(bxor, 3);
+
+    test_types_set3(bor, 1);
+    test_types_set3(band, 1);
+    test_types_set3(band, 2);
+
+    test_types_set3(bxor, 1);
+    test_types_set3(bxor, 2);
+    test_types_set3(bxor, 3);
+
+    maxloc_test(struct int_test, MPI_2INT);
+    maxloc_test(struct long_test, MPI_LONG_INT);
+    maxloc_test(struct short_test, MPI_SHORT_INT);
+    maxloc_test(struct float_test, MPI_FLOAT_INT);
+    maxloc_test(struct double_test, MPI_DOUBLE_INT);
+
+    minloc_test(struct int_test, MPI_2INT);
+    minloc_test(struct long_test, MPI_LONG_INT);
+    minloc_test(struct short_test, MPI_SHORT_INT);
+    minloc_test(struct float_test, MPI_FLOAT_INT);
+    minloc_test(struct double_test, MPI_DOUBLE_INT);
+
+    MPI_Allreduce(&cerrcnt, &gerrcnt, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+    if (rank == 0) {
+        if (gerrcnt)
+            printf(" Found %d errors\n", gerrcnt);
+        else
+            printf(" No Errors\n");
+        fflush(stdout);
+    }
+
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/gather.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/gather.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/gather.c (revision 100)
@@ -0,0 +1,74 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Gather data from a vector to contiguous */
+
+int main( int argc, char **argv )
+{
+    MPI_Datatype vec;
+    MPI_Comm     comm;
+    double *vecin, *vecout;
+    int    minsize = 2, count;
+    int    root, i, n, stride, errs = 0;
+    int    rank, size;
+
+    MTest_Init( &argc, &argv );
+
+    while (MTestGetIntracommGeneral( &comm, minsize, 1 )) {
+	if (comm == MPI_COMM_NULL) continue;
+	/* Determine the sender and receiver */
+	MPI_Comm_rank( comm, &rank );
+	MPI_Comm_size( comm, &size );
+	
+	for (root=0; root<size; root++) {
+	    for (count = 1; count < 65000; count = count * 2) {
+		n = 12;
+		stride = 10;
+		vecin = (double *)malloc( n * stride * size * sizeof(double) );
+		vecout = (double *)malloc( size * n * sizeof(double) );
+		
+		MPI_Type_vector( n, 1, stride, MPI_DOUBLE, &vec );
+		MPI_Type_commit( &vec );
+		
+		for (i=0; i<n*stride; i++) vecin[i] =-2;
+		for (i=0; i<n; i++) vecin[i*stride] = rank * n + i;
+		
+		MPI_Gather( vecin, 1, vec, vecout, n, MPI_DOUBLE, root, comm );
+		
+		if (rank == root) {
+		    for (i=0; i<n*size; i++) {
+			if (vecout[i] != i) {
+			    errs++;
+			    if (errs < 10) {
+				fprintf( stderr, "vecout[%d]=%d\n",
+					 i, (int)vecout[i] );
+			    }
+			}
+		    }
+		}
+		MPI_Type_free( &vec );
+		free( vecin );
+		free( vecout );
+	    }
+	}
+	MTestFreeComm( &comm );
+    }
+
+    /* do a zero length gather */
+    MPI_Gather( NULL, 0, MPI_BYTE, NULL, 0, MPI_BYTE, 0, MPI_COMM_WORLD );
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
+
+
Index: /mpich2/branches/dev/dkim/test/mpi/coll/coll3.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/coll3.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/coll3.c (revision 100)
@@ -0,0 +1,93 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+
+#define MAX_PROCESSES 10
+
+int main( int argc, char **argv )
+{
+    int              rank, size, i,j;
+    int              table[MAX_PROCESSES][MAX_PROCESSES];
+    int              errors=0;
+    int              participants;
+    int              displs[MAX_PROCESSES];
+    int              recv_counts[MAX_PROCESSES];
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+
+    /* A maximum of MAX_PROCESSES processes can participate */
+    if ( size > MAX_PROCESSES ) participants = MAX_PROCESSES;
+    else              participants = size;
+    /* while (MAX_PROCESSES % participants) participants--; */
+    if (MAX_PROCESSES % participants) {
+	fprintf( stderr, "Number of processors must divide %d\n",
+		MAX_PROCESSES );
+	MPI_Abort( MPI_COMM_WORLD, 1 );
+	}
+    if ( (rank < participants) ) {
+
+      /* Determine what rows are my responsibility */
+      int block_size = MAX_PROCESSES / participants;
+      int begin_row  = rank * block_size;
+      int end_row    = (rank+1) * block_size;
+      int send_count = block_size * MAX_PROCESSES;
+      
+      /* Fill in the displacements and recv_counts */
+      for (i=0; i<participants; i++) {
+	displs[i]      = i * block_size * MAX_PROCESSES;
+	recv_counts[i] = send_count;
+      }
+
+      /* Paint my rows my color */
+      for (i=begin_row; i<end_row ;i++)
+	for (j=0; j<MAX_PROCESSES; j++)
+	  table[i][j] = rank + 10;
+      
+      /* Gather everybody's result together - sort of like an */
+      /* inefficient allgather */
+      for (i=0; i<participants; i++) {
+	MPI_Gatherv(&table[begin_row][0], send_count, MPI_INT, 
+		    &table[0][0], recv_counts, displs, MPI_INT, 
+		    i, MPI_COMM_WORLD);
+      }
+
+
+      /* Everybody should have the same table now.
+
+	 The entries are:
+	 Table[i][j] = (i/block_size) + 10;
+       */
+      for (i=0; i<MAX_PROCESSES;i++) 
+	if ( (table[i][0] - table[i][MAX_PROCESSES-1] !=0) ) 
+	  errors++;
+      for (i=0; i<MAX_PROCESSES;i++) {
+	  for (j=0; j<MAX_PROCESSES;j++) {
+	      if (table[i][j] != (i/block_size) + 10) errors++;
+	      }
+	  }
+      if (errors) {
+	  /* Print out table if there are any errors */
+	  for (i=0; i<MAX_PROCESSES;i++) {
+	      printf("\n");
+	      for (j=0; j<MAX_PROCESSES; j++)
+		  printf("  %d",table[i][j]);
+	      }
+	  printf("\n");
+	  }
+    } 
+
+    MPI_Finalize();
+    if (errors)
+        printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
+    else {
+	if (rank == 0)  
+	    printf(" No Errors\n");
+    }
+    return errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/icallreduce.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/icallreduce.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/icallreduce.c (revision 100)
@@ -0,0 +1,83 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Simple intercomm allreduce test";
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0, err;
+    int *sendbuf = 0, *recvbuf = 0;
+    int leftGroup, i, count, rank, rsize;
+    MPI_Comm comm;
+    MPI_Datatype datatype;
+
+    MTest_Init( &argc, &argv );
+
+    datatype = MPI_INT;
+    /* Get an intercommunicator */
+    while (MTestGetIntercomm( &comm, &leftGroup, 4 )) {
+	if (comm == MPI_COMM_NULL) continue;
+	MPI_Comm_rank( comm, &rank );
+	MPI_Comm_remote_size( comm, &rsize );
+
+	/* To improve reporting of problems about operations, we
+	   change the error handler to errors return */
+	MPI_Errhandler_set( comm, MPI_ERRORS_RETURN );
+
+	for (count = 1; count < 65000; count = 2 * count) {
+	    /* printf( "rank = %d(%d)\n", rank, leftGroup ); fflush(stdout); */
+	    sendbuf = (int *)malloc( count * sizeof(int) );
+	    recvbuf = (int *)malloc( count * sizeof(int) );
+	    if (leftGroup) {
+		for (i=0; i<count; i++) sendbuf[i] = i;
+	    }
+	    else {
+		for (i=0; i<count; i++) sendbuf[i] = -i;
+	    }
+	    for (i=0; i<count; i++) recvbuf[i] = 0;
+	    err = MPI_Allreduce( sendbuf, recvbuf, count, datatype, 
+				 MPI_SUM, comm );
+	    if (err) {
+		errs++;
+		MTestPrintError( err );
+	    }
+	    /* In each process should be the sum of the values from the
+	       other process */
+	    if (leftGroup) {
+		for (i=0; i<count; i++) {
+		    if (recvbuf[i] != -i * rsize) {
+			errs++;
+			if (errs < 10) {
+			    fprintf( stderr, "recvbuf[%d] = %d\n", i, recvbuf[i] );
+			}
+		    }
+		}
+	    }
+	    else {
+		for (i=0; i<count; i++) {
+		    if (recvbuf[i] != i * rsize) {
+			errs++;
+			if (errs < 10) {
+			    fprintf( stderr, "recvbuf[%d] = %d\n", i, recvbuf[i] );
+			}
+		    }
+		}
+	    }
+            free( sendbuf );
+            free( recvbuf );
+	}
+	MTestFreeComm( &comm );
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/coll5.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/coll5.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/coll5.c (revision 100)
@@ -0,0 +1,58 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+
+#define MAX_PROCESSES 10
+
+int main( int argc, char **argv )
+{
+    int              rank, size, i,j;
+    int              table[MAX_PROCESSES][MAX_PROCESSES];
+    int              row[MAX_PROCESSES];
+    int              errors=0;
+    int              participants;
+    int              displs[MAX_PROCESSES];
+    int              send_counts[MAX_PROCESSES];
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+
+    /* A maximum of MAX_PROCESSES processes can participate */
+    if ( size > MAX_PROCESSES ) participants = MAX_PROCESSES;
+    else              participants = size;
+    if ( (rank < participants) ) {
+      int recv_count = MAX_PROCESSES;
+      
+      /* If I'm the root (process 0), then fill out the big table */
+      /* and setup  send_counts and displs arrays */
+      if (rank == 0) 
+	for ( i=0; i<participants; i++) {
+	  send_counts[i] = recv_count;
+	  displs[i] = i * MAX_PROCESSES;
+	  for ( j=0; j<MAX_PROCESSES; j++ ) 
+	    table[i][j] = i+j;
+	}
+      
+      /* Scatter the big table to everybody's little table */
+      MPI_Scatterv(&table[0][0], send_counts, displs, MPI_INT, 
+		   &row[0]     , recv_count, MPI_INT, 0, MPI_COMM_WORLD);
+
+      /* Now see if our row looks right */
+      for (i=0; i<MAX_PROCESSES; i++) 
+	if ( row[i] != i+rank ) errors++;
+    } 
+
+    MPI_Finalize();
+    if (errors)
+        printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
+    else {
+	if (rank == 0) 
+	    printf(" No Errors\n");
+	}
+    return errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/scantst.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/scantst.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/scantst.c (revision 100)
@@ -0,0 +1,117 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+
+void addem ( int *, int *, int *, MPI_Datatype * );
+void assoc ( int *, int *, int *, MPI_Datatype * );
+
+void addem( int *invec, int *inoutvec, int *len, MPI_Datatype *dtype)
+{
+  int i;
+  for ( i=0; i<*len; i++ ) 
+    inoutvec[i] += invec[i];
+}
+
+#define BAD_ANSWER 100000
+
+/*
+    The operation is inoutvec[i] = invec[i] op inoutvec[i] 
+    (see 4.9.4).  The order is important.
+
+    Note that the computation is in process rank (in the communicator)
+    order, independant of the root.
+ */
+void assoc( int *invec, int *inoutvec, int *len, MPI_Datatype *dtype)
+{
+  int i;
+  for ( i=0; i<*len; i++ )  {
+    if (inoutvec[i] <= invec[i] ) {
+      int rank;
+      MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+      fprintf( stderr, "[%d] inout[0] = %d, in[0] = %d\n", 
+	      rank, inoutvec[0], invec[0] );
+      inoutvec[i] = BAD_ANSWER;
+      }
+    else 
+      inoutvec[i] = invec[i];
+  }
+}
+
+int main( int argc, char **argv )
+{
+    int              rank, size, i;
+    int              data;
+    int              errors=0;
+    int              result = -100;
+    int              correct_result;
+    MPI_Op           op_assoc, op_addem;
+    MPI_Comm comm=MPI_COMM_WORLD;
+    
+    MPI_Init( &argc, &argv );
+    MPI_Op_create( (MPI_User_function *)assoc, 0, &op_assoc );
+    MPI_Op_create( (MPI_User_function *)addem, 1, &op_addem );
+
+    /* Run this for a variety of communicator sizes */
+
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+
+    data = rank;
+	
+    correct_result = 0;
+    for (i=0;i<=rank;i++)
+        correct_result += i;
+    
+    MPI_Scan ( &data, &result, 1, MPI_INT, MPI_SUM, comm );
+    if (result != correct_result) {
+        fprintf( stderr, "[%d] Error suming ints with scan\n", rank );
+        errors++;
+    }
+
+    MPI_Scan ( &data, &result, 1, MPI_INT, MPI_SUM, comm );
+    if (result != correct_result) {
+        fprintf( stderr, "[%d] Error summing ints with scan (2)\n", rank );
+        errors++;
+    }
+    
+    data = rank;
+    result = -100;
+    MPI_Scan ( &data, &result, 1, MPI_INT, op_addem, comm );
+    if (result != correct_result) {
+        fprintf( stderr, "[%d] Error summing ints with scan (userop)\n", 
+                 rank );
+        errors++;
+    }
+    
+    MPI_Scan ( &data, &result, 1, MPI_INT, op_addem, comm );
+    if (result != correct_result) {
+        fprintf( stderr, "[%d] Error summing ints with scan (userop2)\n", 
+                 rank );
+        errors++;
+    }
+    result = -100;
+    data = rank;
+    MPI_Scan ( &data, &result, 1, MPI_INT, op_assoc, comm );
+    if (result == BAD_ANSWER) {
+        fprintf( stderr, "[%d] Error scanning with non-commutative op\n",
+                 rank );
+        errors++;
+    }
+
+    MPI_Op_free( &op_assoc );
+    MPI_Op_free( &op_addem );
+    
+    MPI_Finalize();
+    if (errors)
+        printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
+    else {
+	if (rank == 0) 
+	    printf(" No Errors\n");
+    }
+
+    return errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/coll7.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/coll7.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/coll7.c (revision 100)
@@ -0,0 +1,66 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+
+#define MAX_PROCESSES 10
+
+int main( int argc, char **argv )
+{
+    int              rank, size, i,j;
+    int              table[MAX_PROCESSES][MAX_PROCESSES];
+    int              errors=0;
+    int              participants;
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+
+    /* A maximum of MAX_PROCESSES processes can participate */
+    if ( size > MAX_PROCESSES ) participants = MAX_PROCESSES;
+    else              participants = size;
+    if (MAX_PROCESSES % participants) {
+	fprintf( stderr, "Number of processors must divide %d\n",
+		MAX_PROCESSES );
+	MPI_Abort( MPI_COMM_WORLD, 1 );
+	}
+    /* while (MAX_PROCESSES % participants) participants--; */
+    if ( (rank < participants) ) {
+
+      /* Determine what rows are my responsibility */
+      int block_size = MAX_PROCESSES / participants;
+      int begin_row  = rank * block_size;
+      int end_row    = (rank+1) * block_size;
+      int send_count = block_size * MAX_PROCESSES;
+      int recv_count = send_count;
+
+      /* Paint my rows my color */
+      for (i=begin_row; i<end_row ;i++)
+	for (j=0; j<MAX_PROCESSES; j++)
+	  table[i][j] = rank + 10;
+
+      /* Everybody gets the gathered table */
+      MPI_Allgather(&table[begin_row][0], send_count, MPI_INT, 
+		   &table[0][0],          recv_count, MPI_INT, MPI_COMM_WORLD);
+
+      /* Everybody should have the same table now,  */
+      /* This test does not in any way guarantee there are no errors */
+      /* Print out a table or devise a smart test to make sure it's correct */
+      for (i=0; i<MAX_PROCESSES;i++) {
+	if ( (table[i][0] - table[i][MAX_PROCESSES-1] !=0) ) 
+	  errors++;
+      }
+    } 
+
+    MPI_Finalize();
+    if (errors)
+        printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
+    else {
+	if (rank == 0) 
+	    printf(" No Errors\n");
+    }
+    return errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/icalltoall.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/icalltoall.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/icalltoall.c (revision 100)
@@ -0,0 +1,83 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Simple intercomm alltoall test";
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0, err;
+    int *sendbuf = 0, *recvbuf = 0;
+    int leftGroup, i, j, idx, count, rank, rsize;
+    MPI_Comm comm;
+    MPI_Datatype datatype;
+
+    MTest_Init( &argc, &argv );
+
+    datatype = MPI_INT;
+    while (MTestGetIntercomm( &comm, &leftGroup, 4 )) {
+	if (comm == MPI_COMM_NULL) continue;
+	for (count = 1; count < 66000; count = 2 * count) {
+	    /* Get an intercommunicator */
+	    MPI_Comm_remote_size( comm, &rsize );
+	    MPI_Comm_rank( comm, &rank );
+	    sendbuf = (int *)malloc( rsize * count * sizeof(int) );
+	    recvbuf = (int *)malloc( rsize * count * sizeof(int) );
+	    for (i=0; i<rsize*count; i++) recvbuf[i] = -1;
+	    if (leftGroup) {
+		idx = 0;
+		for (j=0; j<rsize; j++) {
+		    for (i=0; i<count; i++) {
+			sendbuf[idx++] = i + rank;
+		    }
+		}
+		err = MPI_Alltoall( sendbuf, count, datatype, 
+				    NULL, 0, datatype, comm );
+		if (err) {
+		    errs++;
+		    MTestPrintError( err );
+		}
+	    }
+	    else {
+		int rank, size;
+
+		MPI_Comm_rank( comm, &rank );
+		MPI_Comm_size( comm, &size );
+
+		/* In the right group */
+		err = MPI_Alltoall( NULL, 0, datatype, 
+				    recvbuf, count, datatype, comm );
+		if (err) {
+		    errs++;
+		    MTestPrintError( err );
+		}
+		/* Check that we have received the correct data */
+		idx = 0;
+		for (j=0; j<rsize; j++) {
+		    for (i=0; i<count; i++) {
+			if (recvbuf[idx++] != i + j) {
+			    errs++;
+			    if (errs < 10) 
+				fprintf( stderr, "buf[%d] = %d on %d\n", 
+					 i, recvbuf[i], rank );
+			}
+		    }
+		}
+	    }
+	    free( recvbuf );
+	    free( sendbuf );
+	}
+	MTestFreeComm( &comm );
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/coll9.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/coll9.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/coll9.c (revision 100)
@@ -0,0 +1,49 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+
+void addem ( int *, int *, int *, MPI_Datatype * );
+
+void addem(int *invec, int *inoutvec, int *len, MPI_Datatype *dtype)
+{
+  int i;
+  for ( i=0; i<*len; i++ ) 
+    inoutvec[i] += invec[i];
+}
+
+int main( int argc, char **argv )
+{
+    int              rank, size, i;
+    int              data;
+    int              errors=0;
+    int              result = -100;
+    int              correct_result;
+    MPI_Op           op;
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+
+    data = rank;
+    MPI_Op_create( (MPI_User_function *)addem, 1, &op );
+    MPI_Reduce ( &data, &result, 1, MPI_INT, op, 0, MPI_COMM_WORLD );
+    MPI_Bcast  ( &result, 1, MPI_INT, 0, MPI_COMM_WORLD );
+    MPI_Op_free( &op );
+    correct_result = 0;
+    for(i=0;i<size;i++) 
+      correct_result += i;
+    if (result != correct_result) errors++;
+
+    MPI_Finalize();
+    if (errors)
+      printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
+    else {
+	if (rank == 0) 
+	    printf(" No Errors\n");
+    }
+    return errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/opmaxloc.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/opmaxloc.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/opmaxloc.c (revision 100)
@@ -0,0 +1,279 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitestconf.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Test MPI_MAXLOC operations on datatypes dupported by MPICH2";
+
+/*
+ * This test looks at the handling of char and types that  are not required 
+ * integers (e.g., long long).  MPICH2 allows
+ * these as well.  A strict MPI test should not include this test.
+ *
+ * The rule on max loc is that if there is a tie in the value, the minimum
+ * rank is used (see 4.9.3 in the MPI-1 standard)
+ */
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int rank, size;
+    MPI_Comm      comm;
+
+    MTest_Init( &argc, &argv );
+
+    comm = MPI_COMM_WORLD;
+
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+
+    /* 2 int */
+    {
+	struct twoint { int val; int loc; } cinbuf[3], coutbuf[3];
+ 	
+	cinbuf[0].val = 1;
+	cinbuf[0].loc = rank;
+	cinbuf[1].val = 0;
+	cinbuf[1].loc = rank;
+	cinbuf[2].val = rank;
+	cinbuf[2].loc = rank;
+	
+	coutbuf[0].val = 0;
+	coutbuf[0].loc = -1;
+	coutbuf[1].val = 1;
+	coutbuf[1].loc = -1;
+	coutbuf[2].val = 1;
+	coutbuf[2].loc = -1;
+	MPI_Reduce( cinbuf, coutbuf, 3, MPI_2INT, MPI_MAXLOC, 0, comm );
+	if (rank == 0) {
+	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
+		errs++;
+		fprintf( stderr, "2int MAXLOC(1) test failed\n" );
+	    }
+	    if (coutbuf[1].val != 0) {
+		errs++;
+		fprintf( stderr, "2int MAXLOC(0) test failed, value = %d, should be zero\n", coutbuf[1].val );
+	    }
+	    if (coutbuf[1].loc != 0) {
+		errs++;
+		fprintf( stderr, "2int MAXLOC(0) test failed, location of max = %d, should be zero\n", coutbuf[1].loc );
+	    }
+	    if (coutbuf[2].val != size-1 || coutbuf[2].loc != size-1) {
+		errs++;
+		fprintf( stderr, "2int MAXLOC(>) test failed\n" );
+	    }
+	}
+    }
+
+    /* float int */
+    {
+	struct floatint { float val; int loc; } cinbuf[3], coutbuf[3];
+ 	
+	cinbuf[0].val = 1;
+	cinbuf[0].loc = rank;
+	cinbuf[1].val = 0;
+	cinbuf[1].loc = rank;
+	cinbuf[2].val = (float)rank;
+	cinbuf[2].loc = rank;
+	
+	coutbuf[0].val = 0;
+	coutbuf[0].loc = -1;
+	coutbuf[1].val = 1;
+	coutbuf[1].loc = -1;
+	coutbuf[2].val = 1;
+	coutbuf[2].loc = -1;
+	MPI_Reduce( cinbuf, coutbuf, 3, MPI_FLOAT_INT, MPI_MAXLOC, 0, comm );
+	if (rank == 0) {
+	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
+		errs++;
+		fprintf( stderr, "float-int MAXLOC(1) test failed\n" );
+	    }
+	    if (coutbuf[1].val != 0) {
+		errs++;
+		fprintf( stderr, "float-int MAXLOC(0) test failed, value = %f, should be zero\n", coutbuf[1].val );
+	    }
+	    if (coutbuf[1].loc != 0) {
+		errs++;
+		fprintf( stderr, "float-int MAXLOC(0) test failed, location of max = %d, should be zero\n", coutbuf[1].loc );
+	    }
+	    if (coutbuf[2].val != size-1 || coutbuf[2].loc != size-1) {
+		errs++;
+		fprintf( stderr, "float-int MAXLOC(>) test failed\n" );
+	    }
+	}
+    }
+    
+    /* long int */
+    {
+	struct longint { long val; int loc; } cinbuf[3], coutbuf[3];
+ 	
+	cinbuf[0].val = 1;
+	cinbuf[0].loc = rank;
+	cinbuf[1].val = 0;
+	cinbuf[1].loc = rank;
+	cinbuf[2].val = rank;
+	cinbuf[2].loc = rank;
+	
+	coutbuf[0].val = 0;
+	coutbuf[0].loc = -1;
+	coutbuf[1].val = 1;
+	coutbuf[1].loc = -1;
+	coutbuf[2].val = 1;
+	coutbuf[2].loc = -1;
+	MPI_Reduce( cinbuf, coutbuf, 3, MPI_LONG_INT, MPI_MAXLOC, 0, comm );
+	if (rank == 0) {
+	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
+		errs++;
+		fprintf( stderr, "long-int MAXLOC(1) test failed\n" );
+	    }
+	    if (coutbuf[1].val != 0) {
+		errs++;
+		fprintf( stderr, "long-int MAXLOC(0) test failed, value = %ld, should be zero\n", coutbuf[1].val );
+	    }
+	    if (coutbuf[1].loc != 0) {
+		errs++;
+		fprintf( stderr, "long-int MAXLOC(0) test failed, location of max = %d, should be zero\n", coutbuf[1].loc );
+	    }
+	    if (coutbuf[2].val != size-1 || coutbuf[2].loc != size-1) {
+		errs++;
+		fprintf( stderr, "long-int MAXLOC(>) test failed\n" );
+	    }
+	}
+    }
+
+    /* short int */
+    {
+	struct shortint { short val; int loc; } cinbuf[3], coutbuf[3];
+ 	
+	cinbuf[0].val = 1;
+	cinbuf[0].loc = rank;
+	cinbuf[1].val = 0;
+	cinbuf[1].loc = rank;
+	cinbuf[2].val = rank;
+	cinbuf[2].loc = rank;
+	
+	coutbuf[0].val = 0;
+	coutbuf[0].loc = -1;
+	coutbuf[1].val = 1;
+	coutbuf[1].loc = -1;
+	coutbuf[2].val = 1;
+	coutbuf[2].loc = -1;
+	MPI_Reduce( cinbuf, coutbuf, 3, MPI_SHORT_INT, MPI_MAXLOC, 0, comm );
+	if (rank == 0) {
+	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
+		errs++;
+		fprintf( stderr, "short-int MAXLOC(1) test failed\n" );
+	    }
+	    if (coutbuf[1].val != 0) {
+		errs++;
+		fprintf( stderr, "short-int MAXLOC(0) test failed, value = %d, should be zero\n", coutbuf[1].val );
+	    }
+	    if (coutbuf[1].loc != 0) {
+		errs++;
+		fprintf( stderr, "short-int MAXLOC(0) test failed, location of max = %d, should be zero\n", coutbuf[1].loc );
+	    }
+	    if (coutbuf[2].val != size-1) {
+		errs++;
+		fprintf( stderr, "short-int MAXLOC(>) test failed, value = %d, should be %d\n", coutbuf[2].val, size-1 );
+	    }
+	    if (coutbuf[2].loc != size -1) {
+		errs++;
+		fprintf( stderr, "short-int MAXLOC(>) test failed, location of max = %d, should be %d\n", coutbuf[2].loc, size-1 );
+	    }
+	}
+    }
+    
+    /* double int */
+    {
+	struct doubleint { double val; int loc; } cinbuf[3], coutbuf[3];
+ 	
+	cinbuf[0].val = 1;
+	cinbuf[0].loc = rank;
+	cinbuf[1].val = 0;
+	cinbuf[1].loc = rank;
+	cinbuf[2].val = rank;
+	cinbuf[2].loc = rank;
+	
+	coutbuf[0].val = 0;
+	coutbuf[0].loc = -1;
+	coutbuf[1].val = 1;
+	coutbuf[1].loc = -1;
+	coutbuf[2].val = 1;
+	coutbuf[2].loc = -1;
+	MPI_Reduce( cinbuf, coutbuf, 3, MPI_DOUBLE_INT, MPI_MAXLOC, 0, comm );
+	if (rank == 0) {
+	    if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
+		errs++;
+		fprintf( stderr, "double-int MAXLOC(1) test failed\n" );
+	    }
+	    if (coutbuf[1].val != 0) {
+		errs++;
+		fprintf( stderr, "double-int MAXLOC(0) test failed, value = %lf, should be zero\n", coutbuf[1].val );
+	    }
+	    if (coutbuf[1].loc != 0) {
+		errs++;
+		fprintf( stderr, "double-int MAXLOC(0) test failed, location of max = %d, should be zero\n", coutbuf[1].loc );
+	    }
+	    if (coutbuf[2].val != size-1 || coutbuf[2].loc != size-1) {
+		errs++;
+		fprintf( stderr, "double-int MAXLOC(>) test failed\n" );
+	    }
+	}
+    }
+    
+#ifdef HAVE_LONG_DOUBLE
+    /* long double int */
+    {
+	struct longdoubleint { long double val; int loc; } cinbuf[3], coutbuf[3];
+ 	
+	cinbuf[0].val = 1;
+	cinbuf[0].loc = rank;
+	cinbuf[1].val = 0;
+	cinbuf[1].loc = rank;
+	cinbuf[2].val = rank;
+	cinbuf[2].loc = rank;
+	
+	coutbuf[0].val = 0;
+	coutbuf[0].loc = -1;
+	coutbuf[1].val = 1;
+	coutbuf[1].loc = -1;
+	coutbuf[2].val = 1;
+	coutbuf[2].loc = -1;
+	if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL) {
+	    MPI_Reduce( cinbuf, coutbuf, 3, MPI_LONG_DOUBLE_INT, MPI_MAXLOC, 
+			0, comm );
+	    if (rank == 0) {
+		if (coutbuf[0].val != 1 || coutbuf[0].loc != 0) {
+		    errs++;
+		    fprintf( stderr, "long double-int MAXLOC(1) test failed\n" );
+		}
+		if (coutbuf[1].val != 0) {
+		    errs++;
+		    fprintf( stderr, "long double-int MAXLOC(0) test failed, value = %lf, should be zero\n", (double)coutbuf[1].val );
+		}
+		if (coutbuf[1].loc != 0) {
+		    errs++;
+		    fprintf( stderr, "long double-int MAXLOC(0) test failed, location of max = %d, should be zero\n", coutbuf[1].loc );
+		}
+		if (coutbuf[2].val != size-1) {
+		    errs++;
+		    fprintf( stderr, "long double-int MAXLOC(>) test failed, value = %lf, should be %d\n", (double)coutbuf[2].val, size-1 );
+		}
+		if (coutbuf[2].loc != size-1) {
+		    errs++;
+		    fprintf( stderr, "long double-int MAXLOC(>) test failed, location of max = %d, should be %d\n", coutbuf[2].loc, size-1 );
+		}
+	    }
+	}
+    }
+#endif
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/opmin.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/opmin.c (revision 3503)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/opmin.c (revision 3503)
@@ -0,0 +1,178 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitestconf.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Test MPI_MIN operations on optional datatypes dupported by MPICH2";
+
+/*
+ * This test looks at the handling of char and types that  are not required 
+ * integers (e.g., long long).  MPICH2 allows
+ * these as well.  A strict MPI test should not include this test.
+ */
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int rank, size;
+    MPI_Comm      comm;
+    char cinbuf[3], coutbuf[3];
+    signed char scinbuf[3], scoutbuf[3];
+    unsigned char ucinbuf[3], ucoutbuf[3];
+
+    MTest_Init( &argc, &argv );
+
+    comm = MPI_COMM_WORLD;
+
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+
+#ifndef USE_STRICT_MPI
+    /* char */
+    MTestPrintfMsg( 10, "Reduce of MPI_CHAR\n" );
+    cinbuf[0] = 1;
+    cinbuf[1] = 0;
+    cinbuf[2] = (rank & 0x7f);
+
+    coutbuf[0] = 0;
+    coutbuf[1] = 1;
+    coutbuf[2] = 1;
+    MPI_Reduce( cinbuf, coutbuf, 3, MPI_CHAR, MPI_MIN, 0, comm );
+    if (rank == 0) {
+	if (coutbuf[0] != 1) {
+	    errs++;
+	    fprintf( stderr, "char MIN(1) test failed\n" );
+	}
+	if (coutbuf[1] != 0) {
+	    errs++;
+	    fprintf( stderr, "char MIN(0) test failed\n" );
+	}
+	if (coutbuf[2] != 0) {
+	    errs++;
+	    fprintf( stderr, "char MIN(>) test failed\n" );
+	}
+    }
+#endif /* USE_STRICT_MPI */
+
+    /* signed char */
+    MTestPrintfMsg( 10, "Reduce of MPI_SIGNED_CHAR\n" );
+    scinbuf[0] = 1;
+    scinbuf[1] = 0;
+    scinbuf[2] = (rank & 0x7f);
+
+    scoutbuf[0] = 0;
+    scoutbuf[1] = 1;
+    scoutbuf[2] = 1;
+    MPI_Reduce( scinbuf, scoutbuf, 3, MPI_SIGNED_CHAR, MPI_MIN, 0, comm );
+    if (rank == 0) {
+	if (scoutbuf[0] != 1) {
+	    errs++;
+	    fprintf( stderr, "signed char MIN(1) test failed\n" );
+	}
+	if (scoutbuf[1] != 0) {
+	    errs++;
+	    fprintf( stderr, "signed char MIN(0) test failed\n" );
+	}
+	if (scoutbuf[2] != 0) {
+	    errs++;
+	    fprintf( stderr, "signed char MIN(>) test failed\n" );
+	}
+    }
+
+    /* unsigned char */
+    MTestPrintfMsg( 10, "Reduce of MPI_UNSIGNED_CHAR\n" );
+    ucinbuf[0] = 1;
+    ucinbuf[1] = 0;
+    ucinbuf[2] = (rank & 0x7f);
+
+    ucoutbuf[0] = 0;
+    ucoutbuf[1] = 1;
+    ucoutbuf[2] = 1;
+    MPI_Reduce( ucinbuf, ucoutbuf, 3, MPI_UNSIGNED_CHAR, MPI_MIN, 0, comm );
+    if (rank == 0) {
+	if (ucoutbuf[0] != 1) {
+	    errs++;
+	    fprintf( stderr, "unsigned char MIN(1) test failed\n" );
+	}
+	if (ucoutbuf[1]) {
+	    errs++;
+	    fprintf( stderr, "unsigned char MIN(0) test failed\n" );
+	}
+	if (ucoutbuf[2] != 0) {
+	    errs++;
+	    fprintf( stderr, "unsigned char MIN(>) test failed\n" );
+	}
+    }
+
+#ifdef HAVE_LONG_DOUBLE
+    { long double ldinbuf[3], ldoutbuf[3];
+    /* long double */
+    ldinbuf[0] = 1;
+    ldinbuf[1] = 0;
+    ldinbuf[2] = rank;
+
+    ldoutbuf[0] = 0;
+    ldoutbuf[1] = 1;
+    ldoutbuf[2] = 1;
+    if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL) {
+	MTestPrintfMsg( 10, "Reduce of MPI_LONG_DOUBLE\n" );
+	MPI_Reduce( ldinbuf, ldoutbuf, 3, MPI_LONG_DOUBLE, MPI_MIN, 0, comm );
+	if (rank == 0) {
+	    if (ldoutbuf[0] != 1) {
+		errs++;
+		fprintf( stderr, "long double MIN(1) test failed\n" );
+	    }
+	    if (ldoutbuf[1] != 0.0) {
+		errs++;
+		fprintf( stderr, "long double MIN(0) test failed\n" );
+	    }
+	    if (ldoutbuf[2] != 0.0) {
+		errs++;
+		fprintf( stderr, "long double MIN(>) test failed\n" );
+	    }
+	}
+    }
+    }
+#endif /* HAVE_LONG_DOUBLE */
+
+#ifdef HAVE_LONG_LONG
+    {
+	long long llinbuf[3], lloutbuf[3];
+    /* long long */
+    llinbuf[0] = 1;
+    llinbuf[1] = 0;
+    llinbuf[2] = rank;
+
+    lloutbuf[0] = 0;
+    lloutbuf[1] = 1;
+    lloutbuf[2] = 1;
+    if (MPI_LONG_LONG != MPI_DATATYPE_NULL) {
+	MTestPrintfMsg( 10, "Reduce of MPI_LONG_LONG\n" );
+	MPI_Reduce( llinbuf, lloutbuf, 3, MPI_LONG_LONG, MPI_MIN, 0, comm );
+	if (rank == 0) {
+	    if (lloutbuf[0] != 1) {
+		errs++;
+		fprintf( stderr, "long long MIN(1) test failed\n" );
+	    }
+	    if (lloutbuf[1] != 0) {
+		errs++;
+		fprintf( stderr, "long long MIN(0) test failed\n" );
+	    }
+	    if (lloutbuf[2] != 0) {
+		errs++;
+		fprintf( stderr, "long long MIN(>) test failed\n" );
+	    }
+	}
+    }
+    }
+#endif /* HAVE_LONG_LONG */
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/icreduce.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/icreduce.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/icreduce.c (revision 100)
@@ -0,0 +1,91 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Simple intercomm reduce test";
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0, err;
+    int *sendbuf = 0, *recvbuf=0;
+    int leftGroup, i, count, rank, rsize;
+    MPI_Comm comm;
+    MPI_Datatype datatype;
+
+    MTest_Init( &argc, &argv );
+
+    datatype = MPI_INT;
+    /* Get an intercommunicator */
+    while (MTestGetIntercomm( &comm, &leftGroup, 4 )) {
+	MPI_Comm_rank( comm, &rank );
+	MPI_Comm_remote_size( comm, &rsize );
+
+	/* To improve reporting of problems about operations, we
+	   change the error handler to errors return */
+	MPI_Comm_set_errhandler( comm, MPI_ERRORS_RETURN );
+
+	for (count = 1; count < 65000; count = 2 * count) {
+	    sendbuf = (int *)malloc( count * sizeof(int) );
+	    recvbuf = (int *)malloc( count * sizeof(int) );
+	    for (i=0; i<count; i++) {
+		sendbuf[i] = -1;
+		recvbuf[i] = -1;
+	    }
+	    if (leftGroup) {
+		err = MPI_Reduce( sendbuf, recvbuf, count, datatype, MPI_SUM,
+				 (rank == 0) ? MPI_ROOT : MPI_PROC_NULL,
+				 comm );
+		if (err) {
+		    errs++;
+		    MTestPrintError( err );
+		}
+		/* Test that no other process in this group received the 
+		   broadcast, and that we got the right answers */
+		if (rank == 0) {
+		    for (i=0; i<count; i++) {
+			if (recvbuf[i] != i * rsize) {
+			    errs++;
+			}
+		    }
+		}
+		else {
+		    for (i=0; i<count; i++) {
+			if (recvbuf[i] != -1) {
+			    errs++;
+			}
+		    }
+		}
+	    }
+	    else {
+		/* In the right group */
+		for (i=0; i<count; i++) sendbuf[i] = i;
+		err = MPI_Reduce( sendbuf, recvbuf, count, datatype, MPI_SUM, 
+				  0, comm );
+		if (err) {
+		    errs++;
+		    MTestPrintError( err );
+		}
+		/* Check that we have received no data */
+		for (i=0; i<count; i++) {
+		    if (recvbuf[i] != -1) {
+			errs++;
+		    }
+		}
+	    }
+	free( sendbuf ); 
+	free( recvbuf );
+	}
+	MTestFreeComm( &comm );
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/opmax.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/opmax.c (revision 3503)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/opmax.c (revision 3503)
@@ -0,0 +1,178 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitestconf.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Test MPI_MAX operations on optional datatypes dupported by MPICH2";
+
+/*
+ * This test looks at the handling of char and types that  are not required 
+ * integers (e.g., long long).  MPICH2 allows
+ * these as well.  A strict MPI test should not include this test.
+ */
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int rank, size;
+    MPI_Comm      comm;
+    char cinbuf[3], coutbuf[3];
+    signed char scinbuf[3], scoutbuf[3];
+    unsigned char ucinbuf[3], ucoutbuf[3];
+
+    MTest_Init( &argc, &argv );
+
+    comm = MPI_COMM_WORLD;
+
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+
+#ifndef USE_STRICT_MPI
+    /* char */
+    MTestPrintfMsg( 10, "Reduce of MPI_CHAR\n" );
+    cinbuf[0] = 1;
+    cinbuf[1] = 0;
+    cinbuf[2] = rank;
+
+    coutbuf[0] = 0;
+    coutbuf[1] = 1;
+    coutbuf[2] = 1;
+    MPI_Reduce( cinbuf, coutbuf, 3, MPI_CHAR, MPI_MAX, 0, comm );
+    if (rank == 0) {
+	if (coutbuf[0] != 1) {
+	    errs++;
+	    fprintf( stderr, "char MAX(1) test failed\n" );
+	}
+	if (coutbuf[1] != 0) {
+	    errs++;
+	    fprintf( stderr, "char MAX(0) test failed\n" );
+	}
+	if (size < 128 && coutbuf[2] != size - 1) {
+	    errs++;
+	    fprintf( stderr, "char MAX(>) test failed\n" );
+	}
+    }
+#endif /* USE_STRICT_MPI */
+
+    /* signed char */
+    MTestPrintfMsg( 10, "Reduce of MPI_SIGNED_CHAR\n" );
+    scinbuf[0] = 1;
+    scinbuf[1] = 0;
+    scinbuf[2] = rank;
+
+    scoutbuf[0] = 0;
+    scoutbuf[1] = 1;
+    scoutbuf[2] = 1;
+    MPI_Reduce( scinbuf, scoutbuf, 3, MPI_SIGNED_CHAR, MPI_MAX, 0, comm );
+    if (rank == 0) {
+	if (scoutbuf[0] != 1) {
+	    errs++;
+	    fprintf( stderr, "signed char MAX(1) test failed\n" );
+	}
+	if (scoutbuf[1] != 0) {
+	    errs++;
+	    fprintf( stderr, "signed char MAX(0) test failed\n" );
+	}
+	if (size < 128 && scoutbuf[2] != size - 1) {
+	    errs++;
+	    fprintf( stderr, "signed char MAX(>) test failed\n" );
+	}
+    }
+
+    /* unsigned char */
+    MTestPrintfMsg( 10, "Reduce of MPI_UNSIGNED_CHAR\n" );
+    ucinbuf[0] = 1;
+    ucinbuf[1] = 0;
+    ucinbuf[2] = rank;
+
+    ucoutbuf[0] = 0;
+    ucoutbuf[1] = 1;
+    ucoutbuf[2] = 1;
+    MPI_Reduce( ucinbuf, ucoutbuf, 3, MPI_UNSIGNED_CHAR, MPI_MAX, 0, comm );
+    if (rank == 0) {
+	if (ucoutbuf[0] != 1) {
+	    errs++;
+	    fprintf( stderr, "unsigned char MAX(1) test failed\n" );
+	}
+	if (ucoutbuf[1]) {
+	    errs++;
+	    fprintf( stderr, "unsigned char MAX(0) test failed\n" );
+	}
+	if (size < 256 && ucoutbuf[2] != size - 1) {
+	    errs++;
+	    fprintf( stderr, "unsigned char MAX(>) test failed\n" );
+	}
+    }
+
+#ifdef HAVE_LONG_DOUBLE
+    { long double ldinbuf[3], ldoutbuf[3];
+    /* long double */
+    ldinbuf[0] = 1;
+    ldinbuf[1] = 0;
+    ldinbuf[2] = rank;
+
+    ldoutbuf[0] = 0;
+    ldoutbuf[1] = 1;
+    ldoutbuf[2] = 1;
+    if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL) {
+	MTestPrintfMsg( 10, "Reduce of MPI_LONG_DOUBLE\n" );
+	MPI_Reduce( ldinbuf, ldoutbuf, 3, MPI_LONG_DOUBLE, MPI_MAX, 0, comm );
+	if (rank == 0) {
+	    if (ldoutbuf[0] != 1) {
+		errs++;
+		fprintf( stderr, "long double MAX(1) test failed\n" );
+	    }
+	    if (ldoutbuf[1] != 0.0) {
+		errs++;
+		fprintf( stderr, "long double MAX(0) test failed\n" );
+	    }
+	    if (ldoutbuf[2] != size - 1) {
+		errs++;
+		fprintf( stderr, "long double MAX(>) test failed\n" );
+	    }
+	}
+    }
+    }
+#endif /* HAVE_LONG_DOUBLE */
+
+#ifdef HAVE_LONG_LONG
+    {
+	long long llinbuf[3], lloutbuf[3];
+    /* long long */
+    llinbuf[0] = 1;
+    llinbuf[1] = 0;
+    llinbuf[2] = rank;
+
+    lloutbuf[0] = 0;
+    lloutbuf[1] = 1;
+    lloutbuf[2] = 1;
+    if (MPI_LONG_LONG != MPI_DATATYPE_NULL) {
+	MTestPrintfMsg( 10, "Reduce of MPI_LONG_LONG\n" );
+	MPI_Reduce( llinbuf, lloutbuf, 3, MPI_LONG_LONG, MPI_MAX, 0, comm );
+	if (rank == 0) {
+	    if (lloutbuf[0] != 1) {
+		errs++;
+		fprintf( stderr, "long long MAX(1) test failed\n" );
+	    }
+	    if (lloutbuf[1] != 0) {
+		errs++;
+		fprintf( stderr, "long long MAX(0) test failed\n" );
+	    }
+	    if (lloutbuf[2] != size - 1) {
+		errs++;
+		fprintf( stderr, "long long MAX(>) test failed\n" );
+	    }
+	}
+    }
+    }
+#endif /* HAVE_LONG_LONG */
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/coll10.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/coll10.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/coll10.c (revision 100)
@@ -0,0 +1,66 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#define BAD_ANSWER 100000
+
+int assoc ( int *, int *, int *, MPI_Datatype * );
+
+/*
+    The operation is inoutvec[i] = invec[i] op inoutvec[i] 
+    (see 4.9.4).  The order is important.
+
+    Note that the computation is in process rank (in the communicator)
+    order, independant of the root.
+ */
+int assoc(int *invec, int *inoutvec, int *len, MPI_Datatype *dtype)
+{
+  int i;
+  for ( i=0; i<*len; i++ )  {
+    if (inoutvec[i] <= invec[i] ) {
+      int rank;
+      MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+      fprintf( stderr, "[%d] inout[0] = %d, in[0] = %d\n", 
+	       rank, inoutvec[0], invec[0] );
+      inoutvec[i] = BAD_ANSWER;
+      }
+    else 
+      inoutvec[i] = invec[i];
+  }
+  return (1);
+}
+
+int main( int argc, char **argv )
+{
+    int              rank, size;
+    int              data;
+    int              errors=0;
+    int              result = -100;
+    MPI_Op           op;
+
+    MPI_Init( &argc, &argv );
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    MPI_Comm_size( MPI_COMM_WORLD, &size );
+
+    data = rank;
+
+    MPI_Op_create( (MPI_User_function*)assoc, 0, &op );
+    MPI_Reduce ( &data, &result, 1, MPI_INT, op, size-1, MPI_COMM_WORLD );
+    MPI_Bcast  ( &result, 1, MPI_INT, size-1, MPI_COMM_WORLD );
+    MPI_Op_free( &op );
+    if (result == BAD_ANSWER) errors++;
+
+    if (errors)
+      printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
+    else {
+	if (rank == 0) 
+	    printf(" No Errors\n");
+    }
+
+    MPI_Finalize();
+
+    return errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/gather2.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/gather2.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/gather2.c (revision 100)
@@ -0,0 +1,89 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Gather data from a vector to contiguous.  Use IN_PLACE */
+
+int main( int argc, char **argv )
+{
+    MPI_Datatype vec;
+    double *vecin, *vecout;
+    MPI_Comm comm;
+    int    count, minsize = 2;
+    int    root, i, n, stride, errs = 0;
+    int    rank, size;
+
+    MTest_Init( &argc, &argv );
+
+    while (MTestGetIntracommGeneral( &comm, minsize, 1 )) {
+	if (comm == MPI_COMM_NULL) continue;
+	/* Determine the sender and receiver */
+	MPI_Comm_rank( comm, &rank );
+	MPI_Comm_size( comm, &size );
+	
+	for (root=0; root<size; root++) {
+	    for (count = 1; count < 65000; count = count * 2) {
+		n = 12;
+		stride = 10;
+		vecin = (double *)malloc( n * stride * size * sizeof(double) );
+		vecout = (double *)malloc( size * n * sizeof(double) );
+		
+		MPI_Type_vector( n, 1, stride, MPI_DOUBLE, &vec );
+		MPI_Type_commit( &vec );
+		
+		for (i=0; i<n*stride; i++) vecin[i] =-2;
+		for (i=0; i<n; i++) vecin[i*stride] = rank * n + i;
+		
+		if (rank == root) {
+		    for (i=0; i<n; i++) {
+			vecout[rank*n+i] = rank*n+i;
+		    }
+		    MPI_Gather( MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, 
+				vecout, n, MPI_DOUBLE, root, comm );
+		}
+		else {
+		    MPI_Gather( vecin, 1, vec, NULL, -1, MPI_DATATYPE_NULL, 
+				root, comm );
+		}
+		if (rank == root) {
+		    for (i=0; i<n*size; i++) {
+			if (vecout[i] != i) {
+			    errs++;
+			    if (errs < 10) {
+				fprintf( stderr, "vecout[%d]=%d\n",
+					 i, (int)vecout[i] );
+			    }
+			}
+		    }
+		}
+		MPI_Type_free( &vec );
+		free( vecin );
+		free( vecout );
+	    }
+	}
+	MTestFreeComm( &comm );
+    }
+
+    /* do a zero length gather */
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    if ( rank == 0 ) {
+	MPI_Gather( MPI_IN_PLACE, -1, MPI_DATATYPE_NULL, NULL, 0, MPI_BYTE, 0,
+		    MPI_COMM_WORLD );
+    } else {
+	MPI_Gather( NULL, 0, MPI_BYTE, NULL, 0, MPI_BYTE, 0, MPI_COMM_WORLD );
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
+
+
Index: /mpich2/branches/dev/dkim/test/mpi/coll/coll12.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/coll12.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/coll12.c (revision 100)
@@ -0,0 +1,80 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include <stdio.h>
+#include "mpi.h"
+
+#define TABLE_SIZE 2
+
+int main( int argc, char **argv )
+{
+  int    rank, size;
+  double a[TABLE_SIZE];
+  struct { double a; int b; } in[TABLE_SIZE], out[TABLE_SIZE];
+  int    i;
+  int    errors = 0, toterrors;
+
+  /* Initialize the environment and some variables */
+  MPI_Init( &argc, &argv );
+  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+  MPI_Comm_size( MPI_COMM_WORLD, &size );
+
+  /* Initialize the maxloc data */
+  for ( i=0; i<TABLE_SIZE; i++ ) a[i] = 0;
+  for ( i=rank; i<TABLE_SIZE; i++ ) a[i] = (double)rank + 1.0;
+
+  /* Copy data to the "in" buffer */
+  for (i=0; i<TABLE_SIZE; i++) { 
+	in[i].a = a[i];
+	in[i].b = rank;
+  }
+
+  /* Reduce it! */
+  MPI_Reduce( in, out, TABLE_SIZE, MPI_DOUBLE_INT, MPI_MAXLOC, 0, MPI_COMM_WORLD );
+  MPI_Bcast ( out, TABLE_SIZE, MPI_DOUBLE_INT, 0, MPI_COMM_WORLD );
+
+  /* Check to see that we got the right answers */
+  for (i=0; i<TABLE_SIZE; i++) 
+	if (i % size == rank)
+	  if (out[i].b != rank) {
+        printf("MAX (ranks[%d] = %d != %d\n", i, out[i].b, rank );
+		errors++;
+      }
+
+  /* Initialize the minloc data */
+  for ( i=0; i<TABLE_SIZE; i++ ) a[i] = 0;
+  for ( i=rank; i<TABLE_SIZE; i++ ) a[i] = -(double)rank - 1.0;
+
+  /* Copy data to the "in" buffer */
+  for (i=0; i<TABLE_SIZE; i++)  {
+	in[i].a = a[i];
+	in[i].b = rank;
+  }
+
+  /* Reduce it! */
+  MPI_Allreduce( in, out, TABLE_SIZE, MPI_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD );
+
+  /* Check to see that we got the right answers */
+  for (i=0; i<TABLE_SIZE; i++) 
+	if (i % size == rank)
+	  if (out[i].b != rank) {
+        printf("MIN (ranks[%d] = %d != %d\n", i, out[i].b, rank );
+		errors++;
+      }
+
+  /* Finish up! */
+  MPI_Allreduce( &errors, &toterrors, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
+  if (toterrors) {
+      if (errors)
+	  printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
+  }
+  else {
+      if (rank == 0) printf( " No Errors\n" );
+  }
+      
+  MPI_Finalize();
+  return errors;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/icbarrier.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/icbarrier.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/icbarrier.c (revision 100)
@@ -0,0 +1,54 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Simple intercomm barrier test";
+
+/* This only checks that the Barrier operation accepts intercommunicators.
+   It does not check for the semantics of a intercomm barrier (all processes
+   in the local group can exit when (but not before) all processes in the 
+   remote group enter the barrier */
+int main( int argc, char *argv[] )
+{
+    int errs = 0, err;
+    int leftGroup;
+    MPI_Comm comm;
+    MPI_Datatype datatype;
+
+    MTest_Init( &argc, &argv );
+
+    datatype = MPI_INT;
+    while (MTestGetIntercomm( &comm, &leftGroup, 4 )) {
+	/* Get an intercommunicator */
+	/* To improve reporting of problems about operations, we
+	   change the error handler to errors return */
+	MPI_Comm_set_errhandler( comm, MPI_ERRORS_RETURN );
+	if (leftGroup) {
+	    err = MPI_Barrier( comm );
+	    if (err) {
+		errs++;
+		MTestPrintError( err );
+	    }
+	}
+	else {
+	    /* In the right group */
+	    err = MPI_Barrier( comm );
+	    if (err) {
+		errs++;
+		MTestPrintError( err );
+	    }
+	}
+	MTestFreeComm( &comm );
+    }
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/opprod.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/opprod.c (revision 3503)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/opprod.c (revision 3503)
@@ -0,0 +1,233 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitestconf.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Test MPI_PROD operations on optional datatypes dupported by MPICH2";
+
+typedef struct { double r, i; } d_complex;
+
+/*
+ * This test looks at the handling of logical and for types that are not 
+ * integers or are not required integers (e.g., long long).  MPICH2 allows
+ * these as well.  A strict MPI test should not include this test.
+ */
+int main( int argc, char *argv[] )
+{
+    int errs = 0;
+    int rank, size, maxsize, result[6] = { 1, 1, 2, 6, 24, 120 };
+    MPI_Comm      comm;
+    char cinbuf[3], coutbuf[3];
+    signed char scinbuf[3], scoutbuf[3];
+    unsigned char ucinbuf[3], ucoutbuf[3];
+    d_complex dinbuf[3], doutbuf[3];
+
+    MTest_Init( &argc, &argv );
+
+    comm = MPI_COMM_WORLD;
+
+    MPI_Comm_rank( comm, &rank );
+    MPI_Comm_size( comm, &size );
+    if (size > 5) maxsize = 5;
+    else          maxsize = size;
+
+    /* General forumula: If we multiple the values from 1 to n, the 
+       product is n!.  This grows very fast, so we'll only use the first 
+       five (1! = 1, 2! = 2, 3! = 6, 4! = 24, 5! = 120), with n!
+       stored in the array result[n] */
+
+#ifndef USE_STRICT_MPI
+    /* char */
+    MTestPrintfMsg( 10, "Reduce of MPI_CHAR\n" );
+    cinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
+    cinbuf[1] = 0;
+    cinbuf[2] = (rank > 1);
+
+    coutbuf[0] = 0;
+    coutbuf[1] = 1;
+    coutbuf[2] = 1;
+    MPI_Reduce( cinbuf, coutbuf, 3, MPI_CHAR, MPI_PROD, 0, comm );
+    if (rank == 0) {
+	if (coutbuf[0] != (char)result[maxsize-1]) {
+	    errs++;
+	    fprintf( stderr, "char PROD(rank) test failed (%d!=%d)\n",
+		     (int)coutbuf[0], (int)result[maxsize]);
+	}
+	if (coutbuf[1]) {
+	    errs++;
+	    fprintf( stderr, "char PROD(0) test failed\n" );
+	}
+	if (size > 1 && coutbuf[2]) {
+	    errs++;
+	    fprintf( stderr, "char PROD(>) test failed\n" );
+	}
+    }
+#endif /* USE_STRICT_MPI */
+
+    /* signed char */
+    MTestPrintfMsg( 10, "Reduce of MPI_SIGNED_CHAR\n" );
+    scinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
+    scinbuf[1] = 0;
+    scinbuf[2] = (rank > 1);
+
+    scoutbuf[0] = 0;
+    scoutbuf[1] = 1;
+    scoutbuf[2] = 1;
+    MPI_Reduce( scinbuf, scoutbuf, 3, MPI_SIGNED_CHAR, MPI_PROD, 0, comm );
+    if (rank == 0) {
+	if (scoutbuf[0] != (signed char)result[maxsize-1]) {
+	    errs++;
+	    fprintf( stderr, "signed char PROD(rank) test failed (%d!=%d)\n",
+		     (int)scoutbuf[0], (int)result[maxsize]);
+	}
+	if (scoutbuf[1]) {
+	    errs++;
+	    fprintf( stderr, "signed char PROD(0) test failed\n" );
+	}
+	if (size > 1 && scoutbuf[2]) {
+	    errs++;
+	    fprintf( stderr, "signed char PROD(>) test failed\n" );
+	}
+    }
+
+    /* unsigned char */
+    MTestPrintfMsg( 10, "Reduce of MPI_UNSIGNED_CHAR\n" );
+    ucinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
+    ucinbuf[1] = 0;
+    ucinbuf[2] = (rank > 0);
+
+    ucoutbuf[0] = 0;
+    ucoutbuf[1] = 1;
+    ucoutbuf[2] = 1;
+    MPI_Reduce( ucinbuf, ucoutbuf, 3, MPI_UNSIGNED_CHAR, MPI_PROD, 0, comm );
+    if (rank == 0) {
+	if (ucoutbuf[0] != (unsigned char)result[maxsize-1]) {
+	    errs++;
+	    fprintf( stderr, "unsigned char PROD(rank) test failed\n" );
+	}
+	if (ucoutbuf[1]) {
+	    errs++;
+	    fprintf( stderr, "unsigned char PROD(0) test failed\n" );
+	}
+	if (size > 1 && ucoutbuf[2]) {
+	    errs++;
+	    fprintf( stderr, "unsigned char PROD(>) test failed\n" );
+	}
+    }
+
+#ifndef USE_STRICT_MPI
+    /* For some reason, complex is not allowed for sum and prod */
+    if (MPI_DOUBLE_COMPLEX != MPI_DATATYPE_NULL) {
+	/* double complex; may be null if we do not have Fortran support */
+	dinbuf[0].r = (rank < maxsize && rank > 0) ? rank : 1;
+	dinbuf[1].r = 0;
+	dinbuf[2].r = (rank > 0);
+	dinbuf[0].i = 0;
+	dinbuf[1].i = 1;
+	dinbuf[2].i = -(rank > 0);
+	
+	doutbuf[0].r = 0;
+	doutbuf[1].r = 1;
+	doutbuf[2].r = 1;
+	doutbuf[0].i = 0;
+	doutbuf[1].i = 1;
+	doutbuf[2].i = 1;
+	MPI_Reduce( dinbuf, doutbuf, 3, MPI_DOUBLE_COMPLEX, MPI_PROD, 0, comm );
+	if (rank == 0) {
+	    double imag, real;
+	    if (doutbuf[0].r != (double)result[maxsize-1] || doutbuf[0].i != 0) {
+		errs++;
+		fprintf( stderr, "double complex PROD(rank) test failed\n" );
+	    }
+	    /* Multiplying the imaginary part depends on size mod 4 */
+	    imag = 1.0; real = 0.0; /* Make compiler happy */
+	    switch (size % 4) {
+	    case 1: imag = 1.0; real = 0.0; break;
+	    case 2: imag = 0.0; real = -1.0; break;
+	    case 3: imag =-1.0; real = 0.0; break;
+	    case 0: imag = 0.0; real = 1.0; break; 
+	    }
+	    if (doutbuf[1].r != real || doutbuf[1].i != imag) {
+		errs++;
+		fprintf( stderr, "double complex PROD(i) test failed (%f,%f)!=(%f,%f)\n",
+			 doutbuf[1].r,doutbuf[1].i,real,imag);
+	    }
+	    if (doutbuf[2].r != 0 || doutbuf[2].i != 0) {
+		errs++;
+		fprintf( stderr, "double complex PROD(>) test failed\n" );
+	    }
+	}
+    }
+#endif /* USE_STRICT_MPI */
+
+#ifdef HAVE_LONG_DOUBLE
+    { long double ldinbuf[3], ldoutbuf[3];
+    /* long double */
+    ldinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
+    ldinbuf[1] = 0;
+    ldinbuf[2] = (rank > 0);
+
+    ldoutbuf[0] = 0;
+    ldoutbuf[1] = 1;
+    ldoutbuf[2] = 1;
+    if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL) {
+	MPI_Reduce( ldinbuf, ldoutbuf, 3, MPI_LONG_DOUBLE, MPI_PROD, 0, comm );
+	if (rank == 0) {
+	    if (ldoutbuf[0] != (long double)result[maxsize-1]) {
+		errs++;
+		fprintf( stderr, "long double PROD(rank) test failed\n" );
+	    }
+	    if (ldoutbuf[1]) {
+		errs++;
+		fprintf( stderr, "long double PROD(0) test failed\n" );
+	    }
+	    if (size > 1 && ldoutbuf[2] != 0) {
+		errs++;
+		fprintf( stderr, "long double PROD(>) test failed\n" );
+	    }
+	}
+    }
+    }
+#endif /* HAVE_LONG_DOUBLE */
+
+#ifdef HAVE_LONG_LONG
+    {
+	long long llinbuf[3], lloutbuf[3];
+    /* long long */
+    llinbuf[0] = (rank < maxsize && rank > 0) ? rank : 1;
+    llinbuf[1] = 0;
+    llinbuf[2] = (rank > 0);
+
+    lloutbuf[0] = 0;
+    lloutbuf[1] = 1;
+    lloutbuf[2] = 1;
+    if (MPI_LONG_LONG != MPI_DATATYPE_NULL) {
+	MPI_Reduce( llinbuf, lloutbuf, 3, MPI_LONG_LONG, MPI_PROD, 0, comm );
+	if (rank == 0) {
+	    if (lloutbuf[0] != (long long)result[maxsize-1]) {
+		errs++;
+		fprintf( stderr, "long long PROD(rank) test failed\n" );
+	    }
+	    if (lloutbuf[1]) {
+		errs++;
+		fprintf( stderr, "long long PROD(0) test failed\n" );
+	    }
+	    if (size > 1 && lloutbuf[2]) {
+		errs++;
+		fprintf( stderr, "long long PROD(>) test failed\n" );
+	    }
+	}
+    }
+    }
+#endif /* HAVE_LONG_LONG */
+
+    MTest_Finalize( errs );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/icalltoallv.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/icalltoallv.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/icalltoallv.c (revision 100)
@@ -0,0 +1,99 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitest.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+  This program tests MPI_Alltoallv by having processor i send different
+  amounts of data to each processor.
+
+  Because there are separate send and receive types to alltoallv,
+  there need to be tests to rearrange data on the fly.  Not done yet.
+  
+  The first test sends i items to processor i from all processors.
+
+  Currently, the test uses only MPI_INT; this is adequate for testing systems
+  that use point-to-point operations
+ */
+
+int main( int argc, char **argv )
+{
+    MPI_Comm comm;
+    int      *sbuf, *rbuf;
+    int      rank, size, lsize, asize;
+    int      *sendcounts, *recvcounts, *rdispls, *sdispls;
+    int      i, j, *p, err;
+    int      leftGroup;
+
+    MTest_Init( &argc, &argv );
+    err = 0;
+
+    while (MTestGetIntercomm( &comm, &leftGroup, 4 )) {
+      if (comm == MPI_COMM_NULL) continue;
+
+      /* Create the buffer */
+      MPI_Comm_size( comm, &lsize );
+      MPI_Comm_remote_size( comm, &size );
+      asize = (lsize > size) ? lsize : size;
+      MPI_Comm_rank( comm, &rank );
+      sbuf = (int *)malloc( size * size * sizeof(int) );
+      rbuf = (int *)malloc( asize * asize * sizeof(int) );
+      if (!sbuf || !rbuf) {
+	fprintf( stderr, "Could not allocated buffers!\n" );
+	MPI_Abort( comm, 1 );
+      }
+
+      /* Load up the buffers */
+      for (i=0; i<size*size; i++) {
+	sbuf[i] = i + 100*rank;
+	rbuf[i] = -i;
+      }
+
+      /* Create and load the arguments to alltoallv */
+      sendcounts = (int *)malloc( size * sizeof(int) );
+      recvcounts = (int *)malloc( size * sizeof(int) );
+      rdispls    = (int *)malloc( size * sizeof(int) );
+      sdispls    = (int *)malloc( size * sizeof(int) );
+      if (!sendcounts || !recvcounts || !rdispls || !sdispls) {
+	fprintf( stderr, "Could not allocate arg items!\n" );
+	MPI_Abort( comm, 1 );
+      }
+      for (i=0; i<size; i++) {
+	sendcounts[i] = i;
+	sdispls[i]    = (i * (i+1))/2;
+	recvcounts[i] = rank;
+	rdispls[i] = i * rank;
+      }
+      MPI_Alltoallv( sbuf, sendcounts, sdispls, MPI_INT,
+		     rbuf, recvcounts, rdispls, MPI_INT, comm );
+
+      /* Check rbuf */
+      for (i=0; i<size; i++) {
+	p = rbuf + rdispls[i];
+	for (j=0; j<rank; j++) {
+	  if (p[j] != i * 100 + (rank*(rank+1))/2 + j) {
+	    fprintf( stderr, "[%d] got %d expected %d for %dth\n",
+		     rank, p[j],(i*(i+1))/2 + j, j );
+	    err++;
+	  }
+	}
+      }
+
+      free( sdispls );
+      free( rdispls );
+      free( recvcounts );
+      free( sendcounts );
+      free( rbuf );
+      free( sbuf );
+      MTestFreeComm( &comm );
+    }
+
+    MTest_Finalize( err );
+    MPI_Finalize();
+    return 0;
+}
Index: /mpich2/branches/dev/dkim/test/mpi/coll/icscatterv.c
===================================================================
--- /mpich2/branches/dev/dkim/test/mpi/coll/icscatterv.c (revision 100)
+++ /mpich2/branches/dev/dkim/test/mpi/coll/icscatterv.c (revision 100)
@@ -0,0 +1,105 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2003 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+static char MTEST_Descrip[] = "Simple intercomm scatterv test";
+
+int main( int argc, char *argv[] )
+{
+    int errs = 0, err;
+    int *buf = 0;
+    int *sendcounts;
+    int *senddispls;
+    int leftGroup, i, count, rank, rsize, size;
+    MPI_Comm comm;
+    MPI_Datatype datatype;
+
+    MTest_Init( &argc, &argv );
+
+    datatype = MPI_INT;
+    /* Get an intercommunicator */
+    while (MTestGetIntercomm( &comm, &leftGroup, 4 )) {
+	if (comm == MPI_COMM_NULL) continue;
+	MPI_Comm_remote_size( comm, &rsize );
+	MPI_Comm_rank( comm, &rank );
+	MPI_Comm_size( comm, &size );
+
+	/* To improve reporting of problems about operations, we
+	   change the error handler to errors return */
+	MPI_Comm_set_errhandler( comm, MPI_ERRORS_RETURN );
+
+	for (count = 1; count < 65000; count = 2 * count) {
+	    buf = 0;
+	    sendcounts = (int *)malloc( rsize * sizeof(int) );
+	    senddispls = (int *)malloc( rsize * sizeof(int) );
+	    for (i=0; i<rsize; i++) {
+		sendcounts[i] = count;
+		senddispls[i] = count * i;
+	    }
+	    if (leftGroup) {
+		buf = (int *)malloc( count * rsize * sizeof(int) );
+		if (rank == 0) {
+		    for (i=0; i<count*rsize; i++) buf[i] = i;
+		}
+		else {
+		    for (i=0; i<count*rsize; i++) buf[i] = -1;
+		}
+		err = MPI_Scatterv( buf, sendcounts, senddispls, datatype, 
+				    NULL, 0, datatype,
+				    (rank == 0) ? MPI_ROOT : MPI_PROC_NULL,
+				    comm );
+		if (err) {
+		    errs++;
+		    MTestPrintError( err );
+		}
+		/* Test that no other process in this group received the 
+		   scatter */
+		if (rank != 0) {
+		    for (i=0; i<count*rsize; i++) {
+			if (buf[i] != -1) {
+			    if (errs < 10) {
+				fprintf( stderr, "Received data on root group!\n" );
+			    }
+			    errs++;
+			}
+		    }
+		}
+	    }
+	    else {
+		buf = (int *)malloc( count * sizeof(int) );
+		/* In the right group */
+		for (i=0; i<count; i++) buf[i] = -1;
+		err = MPI_