[mpich2-commits] r4137 - mpich2/trunk/src/mpi/coll

goodell at mcs.anl.gov goodell at mcs.anl.gov
Thu Mar 19 21:47:27 CDT 2009


Author: goodell
Date: 2009-03-19 21:47:27 -0500 (Thu, 19 Mar 2009)
New Revision: 4137

Added:
   mpich2/trunk/src/mpi/coll/oputil.h
Modified:
   mpich2/trunk/src/mpi/coll/opband.c
   mpich2/trunk/src/mpi/coll/opbor.c
   mpich2/trunk/src/mpi/coll/opbxor.c
   mpich2/trunk/src/mpi/coll/opland.c
   mpich2/trunk/src/mpi/coll/oplor.c
   mpich2/trunk/src/mpi/coll/oplxor.c
   mpich2/trunk/src/mpi/coll/opmax.c
   mpich2/trunk/src/mpi/coll/opmin.c
   mpich2/trunk/src/mpi/coll/opprod.c
   mpich2/trunk/src/mpi/coll/opsum.c
Log:
Refactor predefined reduction operations.

This version should greatly reduce the chances of a copy-paste error creeping
into the code and should make adding new predefined reduction types easier.

Reviewed by buntinas at .

Modified: mpich2/trunk/src/mpi/coll/opband.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opband.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opband.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,218 +6,74 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran integer,
- * and byte data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer, Fortran integer,
+ * and byte types (5.9.2 Predefined reduce operations)
  */
 #ifndef MPIR_LBAND
 #define MPIR_LBAND(a,b) ((a)&(b))
 #endif
-void MPIR_BAND ( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_BAND
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_BAND (
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_BAND";
     int i, len = *Len;
-    
+
     switch (*type) {
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LBAND)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(BYTE)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BAND" );
+            break;
+        }
+        /* --END ERROR HANDLING-- */
     }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-    case MPI_BYTE: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBAND(a[i],b[i]);
-        break;
-    }
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BAND" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_BAND_check_dtype
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_BAND_check_dtype ( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_BAND_check_dtype";
     switch (type) {
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: case MPI_INTEGER: 
-#endif
-    case MPI_INT: 
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_BYTE: 
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BAND" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(BYTE)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BAND" );
+        /* --END ERROR HANDLING-- */
     }
 }
 

Modified: mpich2/trunk/src/mpi/coll/opbor.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opbor.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opbor.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,218 +6,74 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran integer,
- * and byte data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer, Fortran integer,
+ * and byte data items (5.9.2 Predefined reduce operations)
  */
 #ifndef MPIR_LBOR
 #define MPIR_LBOR(a,b) ((a)|(b))
 #endif
-void MPIR_BOR ( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_BOR
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_BOR (
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_BOR";
     int i, len = *Len;
-    
+
     switch (*type) {
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LBOR)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(BYTE)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BOR" );
+            break;
+        }
+        /* --END ERROR HANDLING-- */
     }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-    case MPI_BYTE: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBOR(a[i],b[i]);
-        break;
-    }
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BOR" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_BAND_check_dtype
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_BOR_check_dtype ( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_BOR_check_dtype";
-    
     switch (type) {
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: case MPI_INTEGER: 
-#endif
-    case MPI_INT: 
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_BYTE: 
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BOR" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(BYTE)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BOR" );
+        /* --END ERROR HANDLING-- */
     }
 }
 

Modified: mpich2/trunk/src/mpi/coll/opbxor.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opbxor.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opbxor.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,218 +6,73 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran integer,
- * and byte data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer, Fortran integer,
+ * and byte data items (5.9.2 Predefined reduce operations)
  */
 #ifndef MPIR_LBXOR
 #define MPIR_LBXOR(a,b) ((a)^(b))
 #endif
-void MPIR_BXOR ( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_BXOR
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_BXOR (
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_BXOR";
     int i, len = *Len;
-    
+
     switch (*type) {
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_BYTE: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LBXOR(a[i],b[i]);
-        break;
-    }
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LBXOR)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(BYTE)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
 	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BXOR" );
-        break;
-    }
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BXOR" );
+            break;
+        }
 	/* --END ERROR HANDLING-- */
     }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_BXOR
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_BXOR_check_dtype ( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_BXOR_check_dtype";
-    
     switch (type) {
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: case MPI_INTEGER: 
-#endif
-    case MPI_INT: 
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_BYTE: 
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-        return MPI_SUCCESS;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(BYTE)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
 	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BXOR" );
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_BXOR" );
 	/* --END ERROR HANDLING-- */
     }
 }

Modified: mpich2/trunk/src/mpi/coll/opland.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opland.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opland.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,302 +6,107 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 #ifdef HAVE_FORTRAN_BINDING
 #include "mpi_fortlogical.h"
 #endif
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran logical
- * data items (4.9.2 Predefined reduce operations)
+
+/*
+ * In MPI-2.1, this operation is valid only for C integer and Logical
+ * types (5.9.2 Predefined reduce operations)
  */
 #ifndef MPIR_LLAND
 #define MPIR_LLAND(a,b) ((a)&&(b))
 #endif
-void MPIR_LAND ( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_LAND
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_LAND (
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_LAND";
     int i, len = *Len;
-    
+
     switch (*type) {
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LLAND)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+
+        /* MPI_LOGICAL requires special handling (MPIR_{TO,FROM}_FLOG) */
+#if defined(HAVE_FORTRAN_BINDING)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
+#  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_, c_type_)          \
+    case (mpi_type_): {                                                \
+            c_type_ * restrict a = (c_type_ *)inoutvec;                \
+            c_type_ * restrict b = (c_type_ *)invec;                   \
+            for (i=0; i<len; i++)                                      \
+                a[i] = MPIR_TO_FLOG(MPIR_LLAND(MPIR_FROM_FLOG(a[i]),   \
+                                               MPIR_FROM_FLOG(b[i]))); \
+            break;                                                     \
     }
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
+        /* expand logicals (which may include MPI_C_BOOL, a non-Fortran type) */
+        MPIR_OP_TYPE_GROUP(LOGICAL)
+        /* now revert _HAVE_FORTRAN macro to default */
+#  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
+#  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_, c_type_) MPIR_OP_TYPE_MACRO(mpi_type_, c_type_)
+#else
+        /* if we don't have Fortran support then we don't have to jump through
+           any hoops, simply expand the group */
+        MPIR_OP_TYPE_GROUP(LOGICAL)
 #endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
+
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        /* We previously supported floating point types, although I question
+           their utility in logical boolean ops [goodell@ 2009-03-16] */
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LAND" );
+            break;
+        }
+        /* --END ERROR HANDLING-- */
     }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-	/* FIXME: This assume C float = Fortran real */
-    case MPI_REAL: 
-#endif
-    {
-        float * restrict a = (float *)inoutvec; 
-        float * restrict b = (float *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = (float)MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-	/* FIXME: This assume C double = Fortran double precision */
-    case MPI_DOUBLE_PRECISION: 
-#endif
-    {
-        double * restrict a = (double *)inoutvec; 
-        double * restrict b = (double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4: {
-        MPIR_REAL4_CTYPE * restrict a = (MPIR_REAL4_CTYPE *)inoutvec; 
-        MPIR_REAL4_CTYPE * restrict b = (MPIR_REAL4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8: {
-        MPIR_REAL8_CTYPE * restrict a = (MPIR_REAL8_CTYPE *)inoutvec; 
-        MPIR_REAL8_CTYPE * restrict b = (MPIR_REAL8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16: {
-        MPIR_REAL16_CTYPE * restrict a = (MPIR_REAL16_CTYPE *)inoutvec; 
-        MPIR_REAL16_CTYPE * restrict b = (MPIR_REAL16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: {
-        long double * restrict a = (long double *)inoutvec; 
-        long double * restrict b = (long double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for (i=0; i<len; i++) 
-            a[i] = MPIR_TO_FLOG(MPIR_LLAND(MPIR_FROM_FLOG(a[i]),
-                                           MPIR_FROM_FLOG(b[i])));
-        break;
-    }
-    case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLAND(a[i],b[i]);
-        break;
-    }
-#endif
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LAND" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_LAND
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_LAND_check_dtype ( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_LAND_check_dtype";
-    
     switch (type) {
-    case MPI_INT: 
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: 
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: 
-    case MPI_INTEGER: 
-#endif
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4:
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8:
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16:
-#endif
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LAND" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(LOGICAL) /* no special handling needed in check_dtype code */
+
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        /* We previously supported floating point types, although I question
+           their utility in logical boolean ops [goodell@ 2009-03-16] */
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LAND" );
+        /* --END ERROR HANDLING-- */
     }
 }
 

Modified: mpich2/trunk/src/mpi/coll/oplor.c
===================================================================
--- mpich2/trunk/src/mpi/coll/oplor.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/oplor.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,301 +6,107 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 #ifdef HAVE_FORTRAN_BINDING
 #include "mpi_fortlogical.h"
 #endif
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran logical
- * data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer and Logical
+ * types (5.9.2 Predefined reduce operations)
  */
 #ifndef MPIR_LLOR
 #define MPIR_LLOR(a,b) ((a)||(b))
 #endif
-void MPIR_LOR ( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_LOR
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_LOR (
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_LOR";
     int i, len = *Len;
-    
+
     switch (*type) {
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LLOR)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+
+        /* MPI_LOGICAL requires special handling (MPIR_{TO,FROM}_FLOG) */
+#if defined(HAVE_FORTRAN_BINDING)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
+#  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_, c_type_)              \
+        case (mpi_type_): {                                                \
+                c_type_ * restrict a = (c_type_ *)inoutvec;                \
+                c_type_ * restrict b = (c_type_ *)invec;                   \
+                for (i=0; i<len; i++)                                      \
+                    a[i] = MPIR_TO_FLOG(MPIR_LLOR(MPIR_FROM_FLOG(a[i]),    \
+                                                   MPIR_FROM_FLOG(b[i]))); \
+                break;                                                     \
+        }
+        /* expand logicals (which may include MPI_C_BOOL, a non-Fortran type) */
+        MPIR_OP_TYPE_GROUP(LOGICAL)
+        /* now revert _HAVE_FORTRAN macro to default */
+#  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
+#  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_, c_type_) MPIR_OP_TYPE_MACRO(mpi_type_, c_type_)
+#else
+        /* if we don't have Fortran support then we don't have to jump through
+           any hoops, simply expand the group */
+        MPIR_OP_TYPE_GROUP(LOGICAL)
 #endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    {
-        float * restrict a = (float *)inoutvec; 
-        float * restrict b = (float *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = (float)MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-	/* FIXME : This assumes Fortran double precision == C double */
-    case MPI_DOUBLE_PRECISION: 
-#endif
-    {
-        double * restrict a = (double *)inoutvec; 
-        double * restrict b = (double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: {
-        long double * restrict a = (long double *)inoutvec; 
-        long double * restrict b = (long double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for (i=0; i<len; i++) 
-            a[i] = MPIR_TO_FLOG(MPIR_LLOR(MPIR_FROM_FLOG(a[i]),
-                                          MPIR_FROM_FLOG(b[i])));
-        break;
-    }
-    case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for (i=0; i<len; i++) 
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4: {
-        MPIR_REAL4_CTYPE * restrict a = (MPIR_REAL4_CTYPE *)inoutvec; 
-        MPIR_REAL4_CTYPE * restrict b = (MPIR_REAL4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8: {
-        MPIR_REAL8_CTYPE * restrict a = (MPIR_REAL8_CTYPE *)inoutvec; 
-        MPIR_REAL8_CTYPE * restrict b = (MPIR_REAL8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16: {
-        MPIR_REAL16_CTYPE * restrict a = (MPIR_REAL16_CTYPE *)inoutvec; 
-        MPIR_REAL16_CTYPE * restrict b = (MPIR_REAL16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLOR(a[i],b[i]);
-        break;
-    }
-#endif
+
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        /* We previously supported floating point types, although I question
+           their utility in logical boolean ops [goodell@ 2009-03-16] */
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
 	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LOR" );
-        break;
-    }
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LOR" );
+            break;
+        }
 	/* --END ERROR HANDLING-- */
     }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_LOR
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_LOR_check_dtype ( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_LOR_check_dtype";
-
     switch (type) {
-    case MPI_INT: 
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-	/* FIXME : This assumes Fortran double precision == C double */
-    case MPI_DOUBLE_PRECISION: 
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: 
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: 
-    case MPI_INTEGER: 
-#endif
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4:
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8:
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16:
-#endif
-        return MPI_SUCCESS;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(LOGICAL) /* no special handling needed in check_dtype code */
+
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        /* We previously supported floating point types, although I question
+           their utility in logical boolean ops [goodell@ 2009-03-16] */
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
 	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LOR" );
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LOR" );
 	/* --END ERROR HANDLING-- */
     }
 }
+

Modified: mpich2/trunk/src/mpi/coll/oplxor.c
===================================================================
--- mpich2/trunk/src/mpi/coll/oplxor.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/oplxor.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,302 +6,107 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 #ifdef HAVE_FORTRAN_BINDING
 #include "mpi_fortlogical.h"
 #endif
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran logical
- * data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer and Logical
+ * types (5.9.2 Predefined reduce operations)
  */
 #ifndef MPIR_LLXOR
 #define MPIR_LLXOR(a,b) (((a)&&(!b))||((!a)&&(b)))
 #endif
-void MPIR_LXOR ( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_LXOR
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_LXOR (
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_LXOR";
     int i, len = *Len;
-    
+
     switch (*type) {
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LLXOR)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+
+        /* MPI_LOGICAL requires special handling (MPIR_{TO,FROM}_FLOG) */
+#if defined(HAVE_FORTRAN_BINDING)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
+#  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_, c_type_)              \
+        case (mpi_type_): {                                                \
+                c_type_ * restrict a = (c_type_ *)inoutvec;                \
+                c_type_ * restrict b = (c_type_ *)invec;                   \
+                for (i=0; i<len; i++)                                      \
+                    a[i] = MPIR_TO_FLOG(MPIR_LLXOR(MPIR_FROM_FLOG(a[i]),   \
+                                                   MPIR_FROM_FLOG(b[i]))); \
+                break;                                                     \
+        }
+        /* expand logicals (which may include MPI_C_BOOL, a non-Fortran type) */
+        MPIR_OP_TYPE_GROUP(LOGICAL)
+        /* now revert _HAVE_FORTRAN macro to default */
+#  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
+#  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_, c_type_) MPIR_OP_TYPE_MACRO(mpi_type_, c_type_)
+#else
+        /* if we don't have Fortran support then we don't have to jump through
+           any hoops, simply expand the group */
+        MPIR_OP_TYPE_GROUP(LOGICAL)
 #endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
+
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        /* We previously supported floating point types, although I question
+           their utility in logical boolean ops [goodell@ 2009-03-16] */
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LXOR" );
+            break;
+        }
+        /* --END ERROR HANDLING-- */
     }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-	/* FIXME: This assumes C float = Fortran real */
-#endif
-    {
-        float * restrict a = (float *)inoutvec; 
-        float * restrict b = (float *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = (float)MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-	/* FIXME: This assumes C double = Fortran double precision */
-#endif
-    {
-        double * restrict a = (double *)inoutvec; double * restrict b = (double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: {
-        long double * restrict a = (long double *)inoutvec; 
-        long double * restrict b = (long double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for (i=0; i<len; i++) 
-            a[i] = MPIR_TO_FLOG(MPIR_LLXOR(MPIR_FROM_FLOG(a[i]),
-                                           MPIR_FROM_FLOG(b[i])));
-        break;
-    }
-    case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for (i=0; i<len; i++) 
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4: {
-        MPIR_REAL4_CTYPE * restrict a = (MPIR_REAL4_CTYPE *)inoutvec; 
-        MPIR_REAL4_CTYPE * restrict b = (MPIR_REAL4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8: {
-        MPIR_REAL8_CTYPE * restrict a = (MPIR_REAL8_CTYPE *)inoutvec; 
-        MPIR_REAL8_CTYPE * restrict b = (MPIR_REAL8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16: {
-        MPIR_REAL16_CTYPE * restrict a = (MPIR_REAL16_CTYPE *)inoutvec; 
-        MPIR_REAL16_CTYPE * restrict b = (MPIR_REAL16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LLXOR(a[i],b[i]);
-        break;
-    }
-#endif
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LXOR" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_LXOR
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_LXOR_check_dtype ( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_LXOR_check_dtype";
-    
     switch (type) {
-    case MPI_INT: 
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: 
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_LOGICAL: 
-    case MPI_INTEGER: 
-#endif
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4:
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8:
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16:
-#endif
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LXOR" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(LOGICAL) /* no special handling needed in check_dtype code */
+
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        /* We previously supported floating point types, although I question
+           their utility in logical boolean ops [goodell@ 2009-03-16] */
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_LXOR" );
+        /* --END ERROR HANDLING-- */
     }
 }
 

Modified: mpich2/trunk/src/mpi/coll/opmax.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opmax.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opmax.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,287 +6,70 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran integer,
- * and floating point data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer, Fortran integer,
+ * and floating point types (5.9.2 Predefined reduce operations)
  */
-void MPIR_MAXF( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_MAXF
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_MAXF(
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_MAXF";
     int i, len = *Len;
-    
+
     switch (*type) {
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_MAX)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MAX" );
+            break;
+        }
+        /* --END ERROR HANDLING-- */
     }
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4: {
-        MPIR_REAL4_CTYPE * restrict a = (MPIR_REAL4_CTYPE *)inoutvec; 
-        MPIR_REAL4_CTYPE * restrict b = (MPIR_REAL4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8: {
-        MPIR_REAL8_CTYPE * restrict a = (MPIR_REAL8_CTYPE *)inoutvec; 
-        MPIR_REAL8_CTYPE * restrict b = (MPIR_REAL8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16: {
-        MPIR_REAL16_CTYPE * restrict a = (MPIR_REAL16_CTYPE *)inoutvec; 
-        MPIR_REAL16_CTYPE * restrict b = (MPIR_REAL16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED: {
-        unsigned int * restrict a = (unsigned int *)inoutvec; 
-        unsigned int * restrict b = (unsigned int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-	/* FIXME: This assumes C float = Fortran real */
-#endif
-    {
-        float * restrict a = (float *)inoutvec; 
-        float * restrict b = (float *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-	/* FIXME: This assumes C double = Fortran double precision */
-#endif
-    {
-        double * restrict a = (double *)inoutvec; 
-        double * restrict b = (double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: {
-        long double * restrict a = (long double *)inoutvec; 
-        long double * restrict b = (long double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MAX(a[i],b[i]);
-        break;
-    }
-#endif
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MAX" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_MAXF_check_dtype
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_MAXF_check_dtype( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_MAXF_check_dtype";
-    
     switch (type) {
-    case MPI_INT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER: 
-#endif
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: 
-#endif
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4:
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8:
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16:
-#endif
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MAX" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MAX" );
+        /* --END ERROR HANDLING-- */
     }
 }

Modified: mpich2/trunk/src/mpi/coll/opmin.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opmin.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opmin.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,287 +6,69 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran integer,
- * and floating point data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer, Fortran integer,
+ * and floating point types (5.9.2 Predefined reduce operations)
  */
-void MPIR_MINF ( 
-	void *invec, 
-	void *inoutvec, 
-	int *Len, 
-	MPI_Datatype *type )
+#undef FUNCNAME
+#define FUNCNAME MPIR_MINF
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_MINF (
+    void *invec,
+    void *inoutvec,
+    int *Len,
+    MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_MINF";
     int i, len = *Len;
-    
+
     switch (*type) {
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_MIN)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MIN" );
+            break;
+        }
+        /* --END ERROR HANDLING-- */
     }
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4: {
-        MPIR_REAL4_CTYPE * restrict a = (MPIR_REAL4_CTYPE *)inoutvec; 
-        MPIR_REAL4_CTYPE * restrict b = (MPIR_REAL4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8: {
-        MPIR_REAL8_CTYPE * restrict a = (MPIR_REAL8_CTYPE *)inoutvec; 
-        MPIR_REAL8_CTYPE * restrict b = (MPIR_REAL8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16: {
-        MPIR_REAL16_CTYPE * restrict a = (MPIR_REAL16_CTYPE *)inoutvec; 
-        MPIR_REAL16_CTYPE * restrict b = (MPIR_REAL16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-	/* FIXME: This assumes C float = Fortran real */
-#endif
-    {
-        float * restrict a = (float *)inoutvec; 
-        float * restrict b = (float *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-	/* FIXME: This assumes C double = Fortran double precision */
-#endif
-    {
-        double * restrict a = (double *)inoutvec; 
-        double * restrict b = (double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: {
-        long double * restrict a = (long double *)inoutvec; 
-        long double * restrict b = (long double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_MIN(a[i],b[i]);
-        break;
-    }
-#endif
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MIN" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
+#undef FUNCNAME
+#define FUNCNAME MPIR_MINF_check_dtype
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
 int MPIR_MINF_check_dtype ( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_MINF_check_dtype";
-    
     switch (type) {
-    case MPI_INT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER: 
-#endif
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: 
-#endif
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4:
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8:
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16:
-#endif
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MIN" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MIN" );
+        /* --END ERROR HANDLING-- */
     }
 }

Modified: mpich2/trunk/src/mpi/coll/opprod.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opprod.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opprod.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,383 +6,93 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran integer,
- * floating point, and complex data items (4.9.2 Predefined reduce operations)
+/*
+ * In MPI-2.1, this operation is valid only for C integer, Fortran integer,
+ * Floating point, and Complex types (5.9.2 Predefined reduce operations)
  */
 #define MPIR_LPROD(a,b) ((a)*(b))
 
-void MPIR_PROD ( 
-    void *invec, 
-    void *inoutvec, 
-    int *Len, 
+#undef FUNCNAME
+#define FUNCNAME MPIR_PROD
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_PROD (
+    void *invec,
+    void *inoutvec,
+    int *Len,
     MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_PROD";
     int i, len = *Len;
-    
-#if defined(HAVE_FORTRAN_BINDING) || defined(HAVE_CXX_COMPLEX)
-    typedef struct { 
-        float re;
-        float im; 
-    } s_complex;
 
-    typedef struct { 
-        double re;
-        double im; 
-    } d_complex;
-#endif
-#if defined(HAVE_LONG_DOUBLE) && defined(HAVE_CXX_COMPLEX)
-    typedef struct {
-	long double re;
-	long double im;
-    } ld_complex;
-#endif
-
     switch (*type) {
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4: {
-        MPIR_REAL4_CTYPE * restrict a = (MPIR_REAL4_CTYPE *)inoutvec; 
-        MPIR_REAL4_CTYPE * restrict b = (MPIR_REAL4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8: {
-        MPIR_REAL8_CTYPE * restrict a = (MPIR_REAL8_CTYPE *)inoutvec; 
-        MPIR_REAL8_CTYPE * restrict b = (MPIR_REAL8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16: {
-        MPIR_REAL16_CTYPE * restrict a = (MPIR_REAL16_CTYPE *)inoutvec; 
-        MPIR_REAL16_CTYPE * restrict b = (MPIR_REAL16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    {
-        float * restrict a = (float *)inoutvec; 
-        float * restrict b = (float *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-    {
-        double * restrict a = (double *)inoutvec; 
-        double * restrict b = (double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: {
-        long double * restrict a = (long double *)inoutvec; 
-        long double * restrict b = (long double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LPROD(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_COMPLEX8:
-    case MPI_COMPLEX: {
-        s_complex * restrict a = (s_complex *)inoutvec; 
-        s_complex * restrict b = (s_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            s_complex c;
-            c.re = a[i].re; c.im = a[i].im;
-            a[i].re = c.re*b[i].re - c.im*b[i].im;
-            a[i].im = c.im*b[i].re + c.re*b[i].im;
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LPROD)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+
+        /* complex multiplication is slightly different than scalar multiplication */
+        /* adding the C99 {float,double} _Complex types will require redefining an additional macro */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_)          \
+        case (mpi_type_): {                             \
+            c_type_ * restrict a = (c_type_ *)inoutvec; \
+            c_type_ * restrict b = (c_type_ *)invec;    \
+            for ( i=0; i<len; i++ ) {                   \
+                c_type_ c;                              \
+                c.re = a[i].re; c.im = a[i].im;         \
+                a[i].re = c.re*b[i].re - c.im*b[i].im;  \
+                a[i].im = c.im*b[i].re + c.re*b[i].im;  \
+            }                                           \
+            break;                                      \
         }
-        break;
-    }
-    case MPI_COMPLEX16:
-    case MPI_DOUBLE_COMPLEX: {
-        d_complex * restrict a = (d_complex *)inoutvec; 
-        d_complex * restrict b = (d_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            d_complex c;
-            c.re = a[i].re; c.im = a[i].im;
-            a[i].re = c.re*b[i].re - c.im*b[i].im;
-            a[i].im = c.im*b[i].re + c.re*b[i].im;
+        MPIR_OP_TYPE_GROUP(COMPLEX)
+        MPIR_OP_TYPE_GROUP(COMPLEX_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_PROD" );
+            break;
         }
-        break;
+        /* --END ERROR HANDLING-- */
     }
-#endif /* HAVE_FORTRAN_BINDING */
-#ifdef HAVE_CXX_COMPLEX
-    case MPIR_CXX_COMPLEX_VALUE: {
-        s_complex * restrict a = (s_complex *)inoutvec; 
-        s_complex const * restrict b = (s_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            s_complex c;
-            c.re = a[i].re; c.im = a[i].im;
-            a[i].re = c.re*b[i].re - c.im*b[i].im;
-            a[i].im = c.im*b[i].re + c.re*b[i].im;
-        }
-        break;
-    }
-    case MPIR_CXX_DOUBLE_COMPLEX_VALUE: {
-        d_complex * restrict a = (d_complex *)inoutvec; 
-        d_complex const * restrict b = (d_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            d_complex c;
-            c.re = a[i].re; c.im = a[i].im;
-            a[i].re = c.re*b[i].re - c.im*b[i].im;
-            a[i].im = c.im*b[i].re + c.re*b[i].im;
-        }
-        break;
-    }
-#ifdef HAVE_LONG_DOUBLE
-    case MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE: {
-        ld_complex * restrict a = (ld_complex *)inoutvec; 
-        ld_complex const * restrict b = (ld_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            ld_complex c;
-            c.re = a[i].re; c.im = a[i].im;
-            a[i].re = c.re*b[i].re - c.im*b[i].im;
-            a[i].im = c.im*b[i].re + c.re*b[i].im;
-        }
-        break;
-    }
-#endif /* HAVE_LONG_DOUBLE */
-#endif /* HAVE_CXX_COMPLEX */
-
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_PROD" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
-int MPIR_PROD_check_dtype ( MPI_Datatype type )
+#undef FUNCNAME
+#define FUNCNAME MPIR_PROD_check_dtype
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_PROD_check_dtype( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_PROD_check_dtype";
     switch (type) {
-    case MPI_INT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER: 
-#endif
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: 
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_COMPLEX: 
-    case MPI_DOUBLE_COMPLEX: 
-#endif
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4:
-    case MPI_COMPLEX8:
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8:
-    case MPI_COMPLEX16:
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16:
-    case MPI_COMPLEX32:
-#endif
-#ifdef HAVE_CXX_COMPLEX
-    case MPIR_CXX_COMPLEX_VALUE:
-    case MPIR_CXX_DOUBLE_COMPLEX_VALUE:
-#ifdef HAVE_LONG_DOUBLE
-    case MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE:
-#endif
-#endif /* HAVE_CXX_COMPLEX */
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_PROD" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+
+        MPIR_OP_TYPE_GROUP(COMPLEX)
+        MPIR_OP_TYPE_GROUP(COMPLEX_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_PROD" );
+        /* --END ERROR HANDLING-- */
     }
 }
 

Modified: mpich2/trunk/src/mpi/coll/opsum.c
===================================================================
--- mpich2/trunk/src/mpi/coll/opsum.c	2009-03-20 02:46:22 UTC (rev 4136)
+++ mpich2/trunk/src/mpi/coll/opsum.c	2009-03-20 02:47:27 UTC (rev 4137)
@@ -6,379 +6,91 @@
  */
 
 #include "mpiimpl.h"
+#include "oputil.h"
 
-/* 
- * In MPI-1, this operation is valid only for  C integer, Fortran integer,
- * floating point, and complex data items (4.9.2 Predefined reduce operations)
- *
- * In MPI-2, it is valid for more operations.  
- * Of particular interest are the C++ operations that may not correspond
- * to C or Fortran counterparts.  MPI::COMPLEX (C++ Complex) (and the long
- * version) may fall into this category.
+/*
+ * In MPI-2.1, this operation is valid only for C integer, Fortran integer,
+ * Floating point, and Complex types (5.9.2 Predefined reduce operations)
  */
 #define MPIR_LSUM(a,b) ((a)+(b))
 
-void MPIR_SUM ( 
-	void *invec, 
-	void *inoutvec, 
-	int *Len, 
-	MPI_Datatype *type )
+#undef FUNCNAME
+#define FUNCNAME MPIR_SUM
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+void MPIR_SUM (
+    void *invec,
+    void *inoutvec,
+    int *Len,
+    MPI_Datatype *type )
 {
-    static const char FCNAME[] = "MPIR_SUM";
     int i, len = *Len;
 
-#if defined(HAVE_FORTRAN_BINDING) || defined(HAVE_CXX_COMPLEX)
-    typedef struct { 
-        float re;
-        float im; 
-    } s_complex;
-
-    typedef struct { 
-        double re;
-        double im; 
-    } d_complex;
-#endif
-#if defined(HAVE_LONG_DOUBLE) && defined(HAVE_CXX_COMPLEX)
-    typedef struct {
-	long double re;
-	long double im;
-    } ld_complex;
-#endif
-
     switch (*type) {
-    case MPI_INT: {
-        int * restrict a = (int *)inoutvec; 
-        int * restrict b = (int *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER: {
-        MPI_Fint * restrict a = (MPI_Fint *)inoutvec; 
-        MPI_Fint * restrict b = (MPI_Fint *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1: {
-        MPIR_INTEGER1_CTYPE * restrict a = (MPIR_INTEGER1_CTYPE *)inoutvec; 
-        MPIR_INTEGER1_CTYPE * restrict b = (MPIR_INTEGER1_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2: {
-        MPIR_INTEGER2_CTYPE * restrict a = (MPIR_INTEGER2_CTYPE *)inoutvec; 
-        MPIR_INTEGER2_CTYPE * restrict b = (MPIR_INTEGER2_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4: {
-        MPIR_INTEGER4_CTYPE * restrict a = (MPIR_INTEGER4_CTYPE *)inoutvec; 
-        MPIR_INTEGER4_CTYPE * restrict b = (MPIR_INTEGER4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8: {
-        MPIR_INTEGER8_CTYPE * restrict a = (MPIR_INTEGER8_CTYPE *)inoutvec; 
-        MPIR_INTEGER8_CTYPE * restrict b = (MPIR_INTEGER8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16: {
-        MPIR_INTEGER16_CTYPE * restrict a = (MPIR_INTEGER16_CTYPE *)inoutvec; 
-        MPIR_INTEGER16_CTYPE * restrict b = (MPIR_INTEGER16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4: {
-        MPIR_REAL4_CTYPE * restrict a = (MPIR_REAL4_CTYPE *)inoutvec; 
-        MPIR_REAL4_CTYPE * restrict b = (MPIR_REAL4_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8: {
-        MPIR_REAL8_CTYPE * restrict a = (MPIR_REAL8_CTYPE *)inoutvec; 
-        MPIR_REAL8_CTYPE * restrict b = (MPIR_REAL8_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16: {
-        MPIR_REAL16_CTYPE * restrict a = (MPIR_REAL16_CTYPE *)inoutvec; 
-        MPIR_REAL16_CTYPE * restrict b = (MPIR_REAL16_CTYPE *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-    case MPI_UNSIGNED: {
-        unsigned * restrict a = (unsigned *)inoutvec; 
-        unsigned * restrict b = (unsigned *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_LONG: {
-        long * restrict a = (long *)inoutvec; 
-        long * restrict b = (long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: {
-	/* case MPI_LONG_LONG_INT: defined to be the same as long_long */
-        long long * restrict a = (long long *)inoutvec; 
-        long long * restrict b = (long long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-    
-    case MPI_UNSIGNED_LONG: {
-        unsigned long * restrict a = (unsigned long *)inoutvec; 
-        unsigned long * restrict b = (unsigned long *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_SHORT: {
-        short * restrict a = (short *)inoutvec; 
-        short * restrict b = (short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_SHORT: {
-        unsigned short * restrict a = (unsigned short *)inoutvec; 
-        unsigned short * restrict b = (unsigned short *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    {
-        char * restrict a = (char *)inoutvec; 
-        char * restrict b = (char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_SIGNED_CHAR: {
-        signed char * restrict a = (signed char *)inoutvec; 
-        signed char * restrict b = (signed char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_UNSIGNED_CHAR: {
-        unsigned char * restrict a = (unsigned char *)inoutvec; 
-        unsigned char * restrict b = (unsigned char *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    {
-        float * restrict a = (float *)inoutvec; 
-        float * restrict b = (float *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-    {
-        double * restrict a = (double *)inoutvec; 
-        double * restrict b = (double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: {
-        long double * restrict a = (long double *)inoutvec; 
-        long double * restrict b = (long double *)invec;
-        for ( i=0; i<len; i++ )
-            a[i] = MPIR_LSUM(a[i],b[i]);
-        break;
-    }
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_COMPLEX8:
-    case MPI_COMPLEX: {
-        s_complex * restrict a = (s_complex *)inoutvec; 
-        s_complex const * restrict b = (s_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            a[i].re = MPIR_LSUM(a[i].re ,b[i].re);
-            a[i].im = MPIR_LSUM(a[i].im ,b[i].im);
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_, c_type_, MPIR_LSUM)
+        /* no semicolons by necessity */
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+
+        /* complex multiplication is slightly different than scalar multiplication */
+        /* adding the C99 {float,double} _Complex types will require redefining an additional macro */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_)             \
+        case (mpi_type_): {                                \
+            c_type_ * restrict a = (c_type_ *)inoutvec;    \
+            const c_type_ * restrict b = (c_type_ *)invec; \
+            for ( i=0; i<len; i++ ) {                      \
+                a[i].re = MPIR_LSUM(a[i].re ,b[i].re);     \
+                a[i].im = MPIR_LSUM(a[i].im ,b[i].im);     \
+            }                                              \
+            break;                                         \
         }
-        break;
-    }
-    case MPI_COMPLEX16:
-    case MPI_DOUBLE_COMPLEX: {
-        d_complex * restrict a = (d_complex *)inoutvec; 
-        d_complex const * restrict b = (d_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            a[i].re = MPIR_LSUM(a[i].re ,b[i].re);
-            a[i].im = MPIR_LSUM(a[i].im ,b[i].im);
+        MPIR_OP_TYPE_GROUP(COMPLEX)
+        MPIR_OP_TYPE_GROUP(COMPLEX_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+        /* --BEGIN ERROR HANDLING-- */
+        default: {
+            MPIU_THREADPRIV_DECL;
+            MPIU_THREADPRIV_GET;
+            MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_SUM" );
+            break;
         }
-        break;
+        /* --END ERROR HANDLING-- */
     }
-	/* FIXME: Need complex8, 16, and 32 */
-#endif /* HAVE_FORTRAN_BINDING */
-#ifdef HAVE_CXX_COMPLEX
-    case MPIR_CXX_COMPLEX_VALUE: {
-        s_complex * restrict a = (s_complex *)inoutvec; 
-        s_complex const * restrict b = (s_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            a[i].re = MPIR_LSUM(a[i].re ,b[i].re);
-            a[i].im = MPIR_LSUM(a[i].im ,b[i].im);
-        }
-        break;
-    }
-    case MPIR_CXX_DOUBLE_COMPLEX_VALUE: {
-        d_complex * restrict a = (d_complex *)inoutvec; 
-        d_complex const * restrict b = (d_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            a[i].re = MPIR_LSUM(a[i].re ,b[i].re);
-            a[i].im = MPIR_LSUM(a[i].im ,b[i].im);
-        }
-        break;
-    }
-#ifdef HAVE_LONG_DOUBLE
-    case MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE: {
-        ld_complex * restrict a = (ld_complex *)inoutvec; 
-        ld_complex const * restrict b = (ld_complex *)invec;
-        for ( i=0; i<len; i++ ) {
-            a[i].re = MPIR_LSUM(a[i].re ,b[i].re);
-            a[i].im = MPIR_LSUM(a[i].im ,b[i].im);
-        }
-        break;
-    }
-#endif /* HAVE_LONG_DOUBLE */
-#endif /* HAVE_CXX_COMPLEX */
-	/* --BEGIN ERROR HANDLING-- */
-    default: {
-	MPIU_THREADPRIV_DECL;
-	MPIU_THREADPRIV_GET;
-        MPIU_THREADPRIV_FIELD(op_errno) = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_SUM" );
-        break;
-    }
-	/* --END ERROR HANDLING-- */
-    }
 }
 
 
-int MPIR_SUM_check_dtype ( MPI_Datatype type )
+#undef FUNCNAME
+#define FUNCNAME MPIR_SUM_check_dtype
+#undef FCNAME
+#define FCNAME MPIU_QUOTE(FUNCNAME)
+int MPIR_SUM_check_dtype( MPI_Datatype type )
 {
-    static const char FCNAME[] = "MPIR_SUM_check_dtype";
-    
     switch (type) {
-    case MPI_INT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_INTEGER:
-#endif
-    case MPI_UNSIGNED: 
-    case MPI_LONG: 
-#if defined(HAVE_LONG_LONG_INT)
-    case MPI_LONG_LONG: 
-#endif
-    case MPI_UNSIGNED_LONG: 
-    case MPI_SHORT: 
-    case MPI_UNSIGNED_SHORT: 
-    case MPI_CHAR: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_CHARACTER: 
-#endif
-    case MPI_SIGNED_CHAR: 
-    case MPI_UNSIGNED_CHAR: 
-    case MPI_FLOAT: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_REAL: 
-#endif
-    case MPI_DOUBLE: 
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_DOUBLE_PRECISION: 
-#endif
-#if defined(HAVE_LONG_DOUBLE)
-    case MPI_LONG_DOUBLE: 
-#endif
-#ifdef HAVE_FORTRAN_BINDING
-    case MPI_COMPLEX: 
-    case MPI_DOUBLE_COMPLEX: 
-#endif
-/* The length type can be provided without Fortran, so we do so */
-#ifdef MPIR_INTEGER1_CTYPE
-    case MPI_INTEGER1:
-#endif
-#ifdef MPIR_INTEGER2_CTYPE
-    case MPI_INTEGER2:
-#endif
-#ifdef MPIR_INTEGER4_CTYPE
-    case MPI_INTEGER4:
-#endif
-#ifdef MPIR_INTEGER8_CTYPE
-    case MPI_INTEGER8:
-#endif
-#ifdef MPIR_INTEGER16_CTYPE
-    case MPI_INTEGER16:
-#endif
-#ifdef MPIR_REAL4_CTYPE
-    case MPI_REAL4:
-    case MPI_COMPLEX8:
-#endif
-#ifdef MPIR_REAL8_CTYPE
-    case MPI_REAL8:
-    case MPI_COMPLEX16:
-#endif
-#ifdef MPIR_REAL16_CTYPE
-    case MPI_REAL16:
-    case MPI_COMPLEX32:
-#endif
-#ifdef HAVE_CXX_COMPLEX
-    case MPIR_CXX_COMPLEX_VALUE:
-    case MPIR_CXX_DOUBLE_COMPLEX_VALUE:
-#ifdef HAVE_LONG_DOUBLE
-    case MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE:
-#endif
-#endif /* HAVE_CXX_COMPLEX */
-        return MPI_SUCCESS;
-	/* --BEGIN ERROR HANDLING-- */
-    default: 
-        return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_SUM" );
-	/* --END ERROR HANDLING-- */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_, c_type_) case (mpi_type_):
+        MPIR_OP_TYPE_GROUP(C_INTEGER)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT)
+        /* extra types that are not required to be supported by the MPI Standard */
+        MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA)
+        MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)
+
+        MPIR_OP_TYPE_GROUP(COMPLEX)
+        MPIR_OP_TYPE_GROUP(COMPLEX_EXTRA)
+#undef MPIR_OP_TYPE_MACRO
+            return MPI_SUCCESS;
+        /* --BEGIN ERROR HANDLING-- */
+        default:
+            return MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_SUM" );
+        /* --END ERROR HANDLING-- */
     }
 }
+

Added: mpich2/trunk/src/mpi/coll/oputil.h
===================================================================
--- mpich2/trunk/src/mpi/coll/oputil.h	                        (rev 0)
+++ mpich2/trunk/src/mpi/coll/oputil.h	2009-03-20 02:47:27 UTC (rev 4137)
@@ -0,0 +1,251 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *
+ *  (C) 2009 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+/* The MPI Standard (MPI-2.1, sec 5.9.2) defines which predfined reduction
+   operators are valid by groups of types:
+     C integer
+     Fortran integer
+     Floating point
+     Logical
+     Complex
+     Byte
+
+   We define an "x-macro" for each type group.  Immediately prior to
+   instantiating any of these macros you should define a valid
+   MPIR_OP_TYPE_MACRO(mpi_type_,c_type_).  The primary use for this is to expand
+   a given group's list into a sequence of case statements.  The macro
+   MPIR_OP_TYPE_REDUCE_CASE is available as a convenience to generate a case
+   block that performs a reduction with the given operator.  */
+
+#if 0 /* sample usage: */
+#undef MPIR_OP_TYPE_MACRO
+#define MPIR_OP_TYPE_MACRO(mpi_type_,c_type_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_,c_type_,MPIR_MAX)
+/* or */
+#define MPIR_OP_TYPE_MACRO(mpi_type_,c_type_) case (mpi_type_):
+
+MPIR_OP_TYPE_GROUP(C_INTEGER)
+MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
+#undef MPIR_OP_TYPE_MACRO
+#endif
+
+
+/* op_macro_ is a 2-arg macro or function that preforms the reduction
+   operation on a single element */
+#define MPIR_OP_TYPE_REDUCE_CASE(mpi_type_,c_type_,op_macro_) \
+    case (mpi_type_): {                                       \
+        c_type_ * restrict a = (c_type_ *)inoutvec;           \
+        const c_type_ * restrict b = (c_type_ *)invec;        \
+        for ( i=0; i<len; i++ )                               \
+            a[i] = op_macro_(a[i],b[i]);                      \
+        break;                                                \
+    }
+
+/* helps enforce consistent naming */
+#define MPIR_OP_TYPE_GROUP(group) MPIR_OP_TYPE_GROUP_##group
+
+/* -------------------------------------------------------------------- */
+/* These macros are used to disable non-existent types.  They evaluate to
+   nothing if the particular feature test is false, otherwise they evaluate to
+   the standard macro to be expanded like any other type. */
+
+/* first define all wrapper macros as empty for possibly non-existent types */
+#define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(mpi_type_,c_type_)
+#define MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(mpi_type_,c_type_)
+
+/* then redefine them to be valid based on other preprocessor definitions */
+#if defined(HAVE_FORTRAN_BINDING)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
+#  undef MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8
+#  undef MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16
+#  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+/* These two shouldn't really be gated on HAVE_FORTRAN_BINDING alone.  There
+   should instead be an individual test like HAVE_LONG_DOUBLE, etc. */
+#  define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#  define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+
+#if defined(HAVE_LONG_LONG_INT)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG
+#  define MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+
+#if defined(HAVE_LONG_DOUBLE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE
+#  define MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+
+/* Fortran fixed width integer type support */
+#if defined(MPIR_INTEGER1_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+#if defined(MPIR_INTEGER2_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+#if defined(MPIR_INTEGER4_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+#if defined(MPIR_INTEGER8_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+#if defined(MPIR_INTEGER16_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+
+/* Fortran fixed width floating point type support */
+#if defined(MPIR_REAL4_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+#if defined(MPIR_REAL8_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+#if defined(MPIR_REAL16_CTYPE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE
+#  define MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+
+/* C++ complex types */
+#if defined(MPIR_CXX_COMPLEX_VALUE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX
+#  define MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+#if defined(MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE)
+#  undef MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX
+#  define MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(mpi_type_,c_type_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_)
+#endif
+
+/* C types needed to support some of the complex types.
+
+   FIXME These are a hack in most cases, but they seem to work in practice
+   and it's what we were doing prior to the oputil.h refactoring. */
+typedef struct {
+    float re;
+    float im;
+} s_complex;
+
+typedef struct {
+    double re;
+    double im;
+} d_complex;
+
+#if defined(HAVE_LONG_DOUBLE)
+typedef struct {
+    long double re;
+    long double im;
+} ld_complex;
+#endif
+
+/* -------------------------------------------------------------------- */
+/* type group macros
+
+   Implementation note: it is important that no MPI type show up more than once
+   among all the lists.  Otherwise it will be easy to end up with two case
+   statements with the same value, which is erroneous in C.  Duplicate C types
+   in this list are not a problem. */
+
+/* c integer group */
+#define MPIR_OP_TYPE_GROUP_C_INTEGER                       \
+    MPIR_OP_TYPE_MACRO(MPI_INT, int)                       \
+    MPIR_OP_TYPE_MACRO(MPI_LONG, long)                     \
+    MPIR_OP_TYPE_MACRO(MPI_SHORT, short)                   \
+    MPIR_OP_TYPE_MACRO(MPI_UNSIGNED_SHORT, unsigned short) \
+    MPIR_OP_TYPE_MACRO(MPI_UNSIGNED, unsigned)             \
+    MPIR_OP_TYPE_MACRO(MPI_UNSIGNED_LONG, unsigned long)   \
+    MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(MPI_LONG_LONG, long long) \
+    MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(MPI_UNSIGNED_LONG_LONG, unsigned long long) \
+    MPIR_OP_TYPE_MACRO(MPI_SIGNED_CHAR, signed char)       \
+    MPIR_OP_TYPE_MACRO(MPI_UNSIGNED_CHAR, unsigned char)
+/* The MPI Standard doesn't include these types in the C integer group for
+   predefined operations but MPICH2 supports them when possible. */
+#define MPIR_OP_TYPE_GROUP_C_INTEGER_EXTRA                  \
+    MPIR_OP_TYPE_MACRO(MPI_CHAR, char)
+
+/* fortran integer group */
+#define MPIR_OP_TYPE_GROUP_FORTRAN_INTEGER                 \
+    MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_INTEGER, MPI_Fint)
+/* The MPI Standard doesn't include these types in the Fortran integer group for
+   predefined operations but MPICH2 supports them when possible. */
+#define MPIR_OP_TYPE_GROUP_FORTRAN_INTEGER_EXTRA                                 \
+    MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_CHARACTER, char)                         \
+    MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE(MPI_INTEGER1, MPIR_INTEGER1_CTYPE)    \
+    MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE(MPI_INTEGER2, MPIR_INTEGER2_CTYPE)    \
+    MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE(MPI_INTEGER4, MPIR_INTEGER4_CTYPE)    \
+    MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE(MPI_INTEGER8, MPIR_INTEGER8_CTYPE)    \
+    MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE(MPI_INTEGER16, MPIR_INTEGER16_CTYPE)
+
+/* floating point group */
+#define MPIR_OP_TYPE_GROUP_FLOATING_POINT                             \
+    MPIR_OP_TYPE_MACRO(MPI_FLOAT, float)                              \
+    MPIR_OP_TYPE_MACRO(MPI_DOUBLE, double)                            \
+    MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_REAL, float)                  \
+    MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_DOUBLE_PRECISION, double)     \
+    MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE(MPI_LONG_DOUBLE, long double) \
+/* The MPI Standard doesn't include these types in the floating point group for
+   predefined operations but MPICH2 supports them when possible. */
+#define MPIR_OP_TYPE_GROUP_FLOATING_POINT_EXTRA                         \
+    MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE(MPI_REAL4, MPIR_REAL4_CTYPE)    \
+    MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE(MPI_REAL8, MPIR_REAL8_CTYPE)    \
+    MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE(MPI_REAL16, MPIR_REAL16_CTYPE)
+
+/* logical group */
+/* FIXME Is MPI_Fint really OK here? */
+#define MPIR_OP_TYPE_GROUP_LOGICAL                         \
+    MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_LOGICAL, MPI_Fint)
+#define MPIR_OP_TYPE_GROUP_LOGICAL_EXTRA /* empty, provided for consistency */
+
+/* complex group */
+#define MPIR_OP_TYPE_GROUP_COMPLEX                          \
+    MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_COMPLEX, s_complex)
+#define MPIR_OP_TYPE_GROUP_COMPLEX_EXTRA                                                            \
+    MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8(MPI_COMPLEX8, s_complex)                                       \
+    MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16(MPI_COMPLEX16, d_complex)                                     \
+    MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPIR_CXX_COMPLEX_VALUE, s_complex)                          \
+    MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPIR_CXX_DOUBLE_COMPLEX_VALUE, d_complex)                   \
+    MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE, ld_complex)
+
+/* byte group */
+#define MPIR_OP_TYPE_GROUP_BYTE                 \
+    MPIR_OP_TYPE_MACRO(MPI_BYTE, unsigned char)
+#define MPIR_OP_TYPE_GROUP_BYTE_EXTRA /* empty, provided for consistency */
+
+/* convenience macro that just is all non-extra groups concatenated */
+#define MPIR_OP_TYPE_GROUP_ALL_BASIC    \
+    MPIR_OP_TYPE_GROUP(C_INTEGER)       \
+    MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER) \
+    MPIR_OP_TYPE_GROUP(FLOATING_POINT)  \
+    MPIR_OP_TYPE_GROUP(LOGICAL)         \
+    MPIR_OP_TYPE_GROUP(COMPLEX)         \
+    MPIR_OP_TYPE_GROUP(BYTE)
+
+/* this macro includes just the extra type groups */
+#define MPIR_OP_TYPE_GROUP_ALL_EXTRA          \
+    MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)       \
+    MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA) \
+    MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)  \
+    MPIR_OP_TYPE_GROUP(LOGICAL_EXTRA)         \
+    MPIR_OP_TYPE_GROUP(COMPLEX_EXTRA)         \
+    MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
+



More information about the mpich2-commits mailing list