All pastes #1270077 Raw Edit

Parallel::MPI OpenMPI patch

public text v1 · immutable
#1270077 ·published 2008-11-29 07:56 UTC
rendered paste body
diff -ur Parallel-MPI-0.03~/MPI.pm Parallel-MPI-0.03/MPI.pm
--- Parallel-MPI-0.03~/MPI.pm	2000-07-19 14:10:13.000000000 +0900
+++ Parallel-MPI-0.03/MPI.pm	2008-11-29 16:44:23.610555872 +0900
@@ -19,54 +19,54 @@
 
 @ISA = qw(Exporter DynaLoader);
 
-my %constants = qw(MPI_2COMPLEX            MPI_Datatype
-		   MPI_2DOUBLE_COMPLEX     MPI_Datatype
-		   MPI_2DOUBLE_PRECISION   MPI_Datatype
-		   MPI_2INT                MPI_Datatype
-		   MPI_2INTEGER            MPI_Datatype
-		   MPI_2REAL               MPI_Datatype
-		   MPI_COMPLEX             MPI_Datatype
-		   MPI_DATATYPE_NULL       MPI_Datatype
-		   MPI_DOUBLE              MPI_Datatype
-		   MPI_DOUBLE_COMPLEX      MPI_Datatype
-		   MPI_DOUBLE_INT          MPI_Datatype
-		   MPI_DOUBLE_PRECISION    MPI_Datatype
-		   MPI_FLOAT               MPI_Datatype
-		   MPI_FLOAT_INT           MPI_Datatype
-		   MPI_INT                 MPI_Datatype
-		   MPI_INTEGER             MPI_Datatype
-		   MPI_BYTE                MPI_Datatype
-		   MPI_CHAR                MPI_Datatype
-		   MPI_CHARACTER           MPI_Datatype
-		   MPI_LOGICAL             MPI_Datatype
-		   MPI_LONG                MPI_Datatype
-		   MPI_LONG_DOUBLE         MPI_Datatype
-		   MPI_LONG_DOUBLE_INT     MPI_Datatype
-		   MPI_LONG_INT            MPI_Datatype
-		   MPI_LONG_LONG_INT       MPI_Datatype
-		   MPI_REAL                MPI_Datatype
-		   MPI_SHORT               MPI_Datatype
-		   MPI_SHORT_INT           MPI_Datatype
-                   MPI_STRING              MPI_Datatype
-		   MPI_UNSIGNED            MPI_Datatype
-		   MPI_UNSIGNED_CHAR       MPI_Datatype
-		   MPI_UNSIGNED_LONG       MPI_Datatype
-		   MPI_UNSIGNED_SHORT      MPI_Datatype
+my %constants = qw(MPI_2COMPLEX            undef
+		   MPI_2DOUBLE_COMPLEX     undef
+		   MPI_2DOUBLE_PRECISION   undef
+		   MPI_2INT                undef
+		   MPI_2INTEGER            undef
+		   MPI_2REAL               undef
+		   MPI_COMPLEX             undef
+		   MPI_DATATYPE_NULL       undef
+		   MPI_DOUBLE              undef
+		   MPI_DOUBLE_COMPLEX      undef
+		   MPI_DOUBLE_INT          undef
+		   MPI_DOUBLE_PRECISION    undef
+		   MPI_FLOAT               undef
+		   MPI_FLOAT_INT           undef
+		   MPI_INT                 undef
+		   MPI_INTEGER             undef
+		   MPI_BYTE                undef
+		   MPI_CHAR                undef
+		   MPI_CHARACTER           undef
+		   MPI_LOGICAL             undef
+		   MPI_LONG                undef
+		   MPI_LONG_DOUBLE         undef
+		   MPI_LONG_DOUBLE_INT     undef
+		   MPI_LONG_INT            undef
+		   MPI_LONG_LONG_INT       undef
+		   MPI_REAL                undef
+		   MPI_SHORT               undef
+		   MPI_SHORT_INT           undef
+           MPI_STRING              undef
+		   MPI_UNSIGNED            undef
+		   MPI_UNSIGNED_CHAR       undef
+		   MPI_UNSIGNED_LONG       undef
+		   MPI_UNSIGNED_SHORT      undef
 		   MPI_ANY_SOURCE          MPI_Status
 		   MPI_ANY_TAG             MPI_Status
-		   MPI_BAND                MPI_Op
-		   MPI_BOR                 MPI_Op
-		   MPI_BXOR                MPI_Op
-		   MPI_LAND                MPI_Op
-		   MPI_LOR                 MPI_Op
-		   MPI_LXOR                MPI_Op
-		   MPI_MAX                 MPI_Op
-		   MPI_MAXLOC              MPI_Op
-		   MPI_MIN                 MPI_Op
-		   MPI_MINLOC              MPI_Op
-		   MPI_OP_NULL             MPI_Op
-		   MPI_PROD                MPI_Op
-		   MPI_SUM                 MPI_Op
+		   MPI_BAND                undef
+		   MPI_BOR                 undef
+		   MPI_BXOR                undef
+		   MPI_LAND                undef
+		   MPI_LOR                 undef
+		   MPI_LXOR                undef
+		   MPI_MAX                 undef
+		   MPI_MAXLOC              undef
+		   MPI_MIN                 undef
+		   MPI_MINLOC              undef
+		   MPI_OP_NULL             undef
+		   MPI_PROD                undef
+		   MPI_SUM                 undef
 		   MPI_COMM_NULL           MPI_Comm
 		   MPI_COMM_SELF           MPI_Comm
 		   MPI_COMM_WORLD          MPI_Comm
diff -ur Parallel-MPI-0.03~/MPI.xs Parallel-MPI-0.03/MPI.xs
--- Parallel-MPI-0.03~/MPI.xs	2002-04-12 11:45:14.000000000 +0900
+++ Parallel-MPI-0.03/MPI.xs	2008-11-29 16:54:06.901101027 +0900
@@ -3,8 +3,7 @@
 #include "XSUB.h"
 #include <mpi.h>
 
-#define MPI_STRING ((MPI_Datatype)34)
-/*#define  ARGV_DEBUG*/
+/* #define  ARGV_DEBUG */
 
 #ifdef FLOAT_HACK
 # undef MPI_FLOAT
@@ -88,27 +87,23 @@
  
         /* argc = $#ARGV+1  +1 for argv[0] */
 	argc = av_len(args_av)+2;
-	if (argc == 1) {
-	    croak("MPI_Init: no arguments found in the argv");
-	} else {
-            /* build up argv by setting argv[0] from $0
-	       and the rest from @ARGV
+	/* build up argv by setting argv[0] from $0
+	   and the rest from @ARGV
 
-               We add an extra NULL to prevent a coredump
-               during global destruction
-	    */
-	    argv = (char**) malloc((argc+1) * sizeof(char*));
-            argv[0] = strdup(SvPV(argv0, PL_na));
-	    for(i=1; i<argc; i++) {
-	        sv_tmp = av_fetch(args_av,i-1,0);
-	        if (sv_tmp == NULL) {
-		    argv[i] = NULL;
-	        } else {
-		    argv[i] = strdup(SvPV(*sv_tmp, PL_na));
-	        }
-            }
-            argv[argc] = NULL; /* prevents coredumps */
+	   We add an extra NULL to prevent a coredump
+	   during global destruction
+	*/
+	argv = (char**) malloc((argc+1) * sizeof(char*));
+	argv[0] = strdup(SvPV(argv0, PL_na));
+	for(i=1; i<argc; i++) {
+	    sv_tmp = av_fetch(args_av,i-1,0);
+	    if (sv_tmp == NULL) {
+		argv[i] = NULL;
+	    } else {
+		argv[i] = strdup(SvPV(*sv_tmp, PL_na));
+	    }
 	}
+	argv[argc] = NULL; /* prevents coredumps */
 
 	/* debug */
 #ifdef ARGV_DEBUG
@@ -172,7 +167,7 @@
 MPI_Send(ref, count, datatype, dest, tag, comm)
     SV* ref
     int count
-    MPI_Datatype datatype
+    enum MPIpm_type_const datatype
     int	dest
     int	tag
     MPI_Comm comm
@@ -216,19 +211,19 @@
 	}
 	printf("\n");
 #endif /* SEND_DEBUG */
-        if(datatype == MPI_STRING)
+        if(datatype == TYPE_VALUE_MPI_STRING)
 	    MPIpm_errhandler("MPI_Send",
 		             MPI_Send(&len, 1, MPI_INT, dest, tag, comm));
 	MPIpm_errhandler("MPI_Send",
 	                 MPI_Send(buf, len, MPI_CHAR, dest, tag, comm));
     } else {
 	count = 1;
-        if (datatype == MPI_CHAR)
+        if (datatype == TYPE_VALUE_MPI_CHAR)
 	    count = (SvCUR(SvRV(ref)) + 1) * sizeof(char);
 	buf = (void*) malloc(MPIpm_bufsize(datatype,SvRV(ref),count));
 	MPIpm_packscalar(buf,SvRV(ref),datatype);
 
-	ret = MPI_Send(buf,count,datatype,dest,tag,comm);
+	ret = MPI_Send(buf,count,MPIpm_datatype(datatype),dest,tag,comm);
 
 	free(buf);
 	MPIpm_errhandler("MPI_Send",ret);
@@ -239,7 +234,7 @@
 MPI_Recv(ref, count, datatype, source, tag, comm)
 	SV *	ref
 	int     count
-	MPI_Datatype	datatype
+	enum MPIpm_type_const datatype
 	int	source
 	int	tag
 	MPI_Comm comm
@@ -260,18 +255,18 @@
 	    int len;
 	    AV *stuff = (AV*) SvRV(ref);
             switch(datatype) {
-	      case MPI_STRING:
+	      case TYPE_VALUE_MPI_STRING:
 	        MPI_Recv(&len, 1, MPI_INT, source, tag, comm, &status);
 		break;
-	      case MPI_INT:
+	      case TYPE_VALUE_MPI_INT:
                 len = count * sizeof(int);
                 break;
 #ifndef FLOAT_HACK
-	      case MPI_FLOAT:
+	      case TYPE_VALUE_MPI_FLOAT:
                 len = count * sizeof(float);
                 break;
 #endif
-	      case MPI_DOUBLE:
+	      case TYPE_VALUE_MPI_DOUBLE:
                 len = count * sizeof(double);
                 break;
             }
@@ -292,14 +287,14 @@
 	    MPIpm_errhandler("MPI_Recv",ret);
 	    /* return the status as a 4 element array:
 	     * (count,MPI_SOURCE,MPI_TAG,MPI_ERROR) */
-	    XPUSHs(sv_2mortal(newSViv(status.count)));
+	    XPUSHs(sv_2mortal(newSViv(status._count)));
 	    XPUSHs(sv_2mortal(newSViv(status.MPI_SOURCE)));
 	    XPUSHs(sv_2mortal(newSViv(status.MPI_TAG)));
 	    XPUSHs(sv_2mortal(newSViv(status.MPI_ERROR)));
 	} else {
 	  buf = (void*) malloc(MPIpm_bufsize(datatype,NULL,count));
 
-	  ret = MPI_Recv(buf,count,datatype,source,tag,comm,&status);
+	  ret = MPI_Recv(buf,count,MPIpm_datatype(datatype),source,tag,comm,&status);
 
 	  MPIpm_unpackscalar(buf,SvRV(ref),datatype);
 	  free(buf);
@@ -307,7 +302,7 @@
 
 	  /* return the status as a 4 element array:
 	   * (count,MPI_SOURCE,MPI_TAG,MPI_ERROR) */
-	  XPUSHs(sv_2mortal(newSViv(status.count)));
+	  XPUSHs(sv_2mortal(newSViv(status._count)));
 	  XPUSHs(sv_2mortal(newSViv(status.MPI_SOURCE)));
 	  XPUSHs(sv_2mortal(newSViv(status.MPI_TAG)));
 	  XPUSHs(sv_2mortal(newSViv(status.MPI_ERROR)));
@@ -325,7 +320,7 @@
 MPI_Bcast(ref, count, datatype, root, comm)
 	SV *    ref
 	int     count
-        MPI_Datatype 	datatype
+    enum MPIpm_type_const datatype
 	int	root
 	MPI_Comm	comm
       PREINIT:
@@ -345,7 +340,7 @@
 	    else
 		buf = (void*) malloc(MPIpm_bufsize(datatype,SvRV(ref),count));
 
-	    ret = MPI_Bcast(buf,count,datatype,root,comm);
+	    ret = MPI_Bcast(buf,count,MPIpm_datatype(datatype),root,comm);
 	    if(rank != root)
 		MPIpm_unpackarray(buf,&array,datatype, count);
 	    MPIpm_errhandler("MPI_Bcast",ret);
@@ -356,7 +351,7 @@
 	    buf = (void*) malloc(MPIpm_bufsize(datatype,SvRV(ref),count));
 	    MPIpm_packscalar(buf,SvRV(ref),datatype);
 
-	    ret = MPI_Bcast(buf,count,datatype,root,comm);
+	    ret = MPI_Bcast(buf,count,MPIpm_datatype(datatype),root,comm);
 
 	    MPIpm_unpackscalar(buf,SvRV(ref),datatype);
 	    free(buf);
@@ -396,8 +391,8 @@
 	SV *	sendref
 	SV *	recvref
 	int	count
-	MPI_Datatype	datatype
-	MPI_Op	op
+	enum MPIpm_type_const datatype
+	enum MPIpm_op_const	op
 	int	root
 	MPI_Comm	comm
       PREINIT:
@@ -415,7 +410,7 @@
 	  recvbuf = (void*)malloc(MPIpm_bufsize(datatype,SvRV(recvref),count));
 	  MPIpm_packscalar(sendbuf,SvRV(sendref),datatype);
 
-	  ret = MPI_Reduce(sendbuf,recvbuf,count,datatype,op,root,comm);
+	  ret = MPI_Reduce(sendbuf,recvbuf,count,MPIpm_datatype(datatype),MPIpm_op(op),root,comm);
 
 	  MPIpm_unpackscalar(recvbuf,SvRV(recvref),datatype);
 	  free(sendbuf);
@@ -429,8 +424,8 @@
 	SV *	sendref
 	SV *	recvref
 	int	count
-	MPI_Datatype	datatype
-	MPI_Op	op
+	enum MPIpm_type_const datatype
+	enum MPIpm_op_const	op
 	MPI_Comm	comm
       PREINIT:
         void* sendbuf, *recvbuf;
@@ -447,7 +442,7 @@
 	  recvbuf = (void*)malloc(MPIpm_bufsize(datatype,SvRV(recvref),count));
 	  MPIpm_packscalar(sendbuf,SvRV(sendref),datatype);
 
-	  ret = MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm);
+	  ret = MPI_Allreduce(sendbuf,recvbuf,count,MPIpm_datatype(datatype),MPIpm_op(op),comm);
 
 	  MPIpm_unpackscalar(recvbuf,SvRV(recvref),datatype);
 	  free(sendbuf);
@@ -460,10 +455,10 @@
 MPI_Scatter(sendref, sendcnt, sendtype, recvref, recvcnt, recvtype, root, comm)
 	SV *    sendref
         int     sendcnt
-        MPI_Datatype 	sendtype
+        enum MPIpm_type_const 	sendtype
 	SV *    recvref
         int     recvcnt
-        MPI_Datatype 	recvtype
+        enum MPIpm_type_const 	recvtype
 	int	root
 	MPI_Comm	comm
       PREINIT:
@@ -480,7 +475,7 @@
             if(rank == root)
 		len = MPIpm_packarray(&sendbuf, (AV*)SvRV(sendref), sendtype,0);
 	    recvbuf = (void*) malloc(MPIpm_bufsize(recvtype,(SV*)SvRV(sendref),recvcnt));
-	    ret = MPI_Scatter(sendbuf,sendcnt,sendtype,recvbuf,recvcnt,recvtype,root,comm); 
+	    ret = MPI_Scatter(sendbuf,sendcnt,MPIpm_datatype(sendtype),recvbuf,recvcnt,MPIpm_datatype(recvtype),root,comm); 
 	    if(SvTYPE(SvRV(recvref)) == SVt_PVAV) {
 		AV *recv = (AV*) SvRV(recvref);
 		MPIpm_unpackarray(recvbuf,&recv,recvtype,recvcnt);
@@ -494,7 +489,7 @@
 	  recvbuf = (void*)calloc(MPIpm_bufsize(recvtype,SvRV(recvref),recvcnt)+1,1);
 	  MPIpm_packscalar(sendbuf,SvRV(sendref),sendtype);
 
-	  ret = MPI_Scatter(sendbuf,sendcnt,sendtype,recvbuf,recvcnt,recvtype,root,comm); 
+	  ret = MPI_Scatter(sendbuf,sendcnt,MPIpm_datatype(sendtype),recvbuf,recvcnt,MPIpm_datatype(recvtype),root,comm); 
 	  MPIpm_unpackscalar(recvbuf,SvRV(recvref),recvtype);
 #ifdef WHY_DOES_THIS_MAKE_IT_SEGFAULT
 	  free(sendbuf);
@@ -506,12 +501,12 @@
 
 int
 MPI_Gather(sendref, sendcnt, sendtype, recvref, recvcnt, recvtype, root, comm)
-	SV *    sendref
+    SV *    sendref
         int     sendcnt
-        MPI_Datatype 	sendtype
+        enum MPIpm_type_const 	sendtype
 	SV *    recvref
         int     recvcnt
-        MPI_Datatype 	recvtype
+        enum MPIpm_type_const 	recvtype
 	int	root
 	MPI_Comm	comm
       PREINIT:
@@ -530,7 +525,7 @@
 	  recvbuf = (void*)malloc(MPIpm_bufsize(recvtype,SvRV(recvref),recvcnt));
 	  MPIpm_packscalar(sendbuf,SvRV(sendref),sendtype);
 
-	  ret = MPI_Gather(sendbuf,sendcnt,sendtype,recvbuf,recvcnt,recvtype,root,comm);
+	  ret = MPI_Gather(sendbuf,sendcnt,MPIpm_datatype(sendtype),recvbuf,recvcnt,MPIpm_datatype(recvtype),root,comm);
 
 	  MPIpm_unpackscalar(recvbuf,SvRV(recvref),recvtype);
 	  free(sendbuf);
@@ -542,12 +537,12 @@
 MPI_Sendrecv(sendref, sendcount, sendtype, dest, sendtag, recvref, recvcount, recvtype, source, recvtag, comm)
 	SV *	sendref
 	int	sendcount
-	MPI_Datatype	sendtype
+	enum MPIpm_type_const sendtype
 	int	dest
 	int	sendtag
 	SV *	recvref
 	int	recvcount
-	MPI_Datatype	recvtype
+	enum MPIpm_type_const recvtype
 	int	source
 	int	recvtag
 	MPI_Comm	comm
@@ -566,8 +561,8 @@
 	    int len;
 	    recvbuf = malloc(MPIpm_bufsize(recvtype, SvRV(recvref), recvcount));
 	    len = MPIpm_packarray(&sendbuf, (AV*)SvRV(sendref), sendtype, sendcount);
-	    ret = MPI_Sendrecv(sendbuf, sendcount, sendtype, dest, sendtag,
-                               recvbuf, recvcount, recvtype, source, recvtag,
+	    ret = MPI_Sendrecv(sendbuf, sendcount, MPIpm_datatype(sendtype), dest, sendtag,
+                               recvbuf, recvcount, MPIpm_datatype(recvtype), source, recvtag,
                                comm, &status);
 
 	    MPIpm_unpackarray(recvbuf,&array,recvtype,recvcount);
@@ -578,8 +573,8 @@
 	  MPIpm_packscalar(sendbuf,SvRV(sendref),sendtype);
           MPIpm_packscalar(recvbuf,SvRV(recvref),recvtype);
 	  
-	  ret = MPI_Sendrecv(sendbuf, sendcount, sendtype, dest,
-                             sendtag, recvbuf, recvcount, recvtype,
+	  ret = MPI_Sendrecv(sendbuf, sendcount, MPIpm_datatype(sendtype), dest,
+                             sendtag, recvbuf, recvcount, MPIpm_datatype(recvtype),
 			     source, recvtag, comm, &status);
 
 	  MPIpm_unpackscalar(recvbuf,SvRV(recvref),recvtype);
@@ -590,7 +585,7 @@
 
 	/* return the status as a 4 element array:
 	 * (count,MPI_SOURCE,MPI_TAG,MPI_ERROR) */
-	XPUSHs(sv_2mortal(newSViv(status.count)));
+	XPUSHs(sv_2mortal(newSViv(status._count)));
 	XPUSHs(sv_2mortal(newSViv(status.MPI_SOURCE)));
 	XPUSHs(sv_2mortal(newSViv(status.MPI_TAG)));
 	XPUSHs(sv_2mortal(newSViv(status.MPI_ERROR)));
diff -ur Parallel-MPI-0.03~/typemap Parallel-MPI-0.03/typemap
--- Parallel-MPI-0.03~/typemap	1999-04-28 08:54:33.000000000 +0900
+++ Parallel-MPI-0.03/typemap	2008-11-29 16:24:41.687056196 +0900
@@ -1,3 +1,3 @@
-MPI_Datatype					T_PTROBJ
+enum MPIpm_type_const		T_INT
 MPI_Comm					T_PTROBJ
-MPI_Op						T_PTROBJ
+enum MPIpm_op_const 	T_INT
diff -ur Parallel-MPI-0.03~/utils.c Parallel-MPI-0.03/utils.c
--- Parallel-MPI-0.03~/utils.c	2000-07-19 13:56:23.000000000 +0900
+++ Parallel-MPI-0.03/utils.c	2008-11-29 16:53:42.023058753 +0900
@@ -1,392 +1,535 @@
+#include <stddef.h>
+
 /* This is included into MPI.xs.  It's just here to unclutter MPI.xs a bit */
 
-static double
-constant(name, arg)
+enum MPIpm_type_const {
+  TYPE_VALUE_NONE = 0,
+  TYPE_VALUE_MPI_2COMPLEX,
+  TYPE_VALUE_MPI_2DOUBLE_COMPLEX,
+  TYPE_VALUE_MPI_2DOUBLE_PRECISION,
+  TYPE_VALUE_MPI_2INT,
+  TYPE_VALUE_MPI_2INTEGER,
+  TYPE_VALUE_MPI_2REAL,
+  TYPE_VALUE_MPI_BYTE,
+  TYPE_VALUE_MPI_CHAR,
+  TYPE_VALUE_MPI_CHARACTER,
+  TYPE_VALUE_MPI_COMPLEX,
+  TYPE_VALUE_MPI_DATATYPE_NULL,
+  TYPE_VALUE_MPI_DOUBLE,
+  TYPE_VALUE_MPI_DOUBLE_COMPLEX,
+  TYPE_VALUE_MPI_DOUBLE_INT,
+  TYPE_VALUE_MPI_DOUBLE_PRECISION,
+  TYPE_VALUE_MPI_FLOAT,
+  TYPE_VALUE_MPI_FLOAT_INT,
+  TYPE_VALUE_MPI_INT,
+  TYPE_VALUE_MPI_INTEGER,
+  TYPE_VALUE_MPI_LOGICAL,
+  TYPE_VALUE_MPI_LONG,
+  TYPE_VALUE_MPI_LONG_DOUBLE,
+  TYPE_VALUE_MPI_LONG_DOUBLE_INT,
+  TYPE_VALUE_MPI_LONG_INT,
+  TYPE_VALUE_MPI_LONG_LONG_INT,
+  TYPE_VALUE_MPI_LB,
+  TYPE_VALUE_MPI_PACKED,
+  TYPE_VALUE_MPI_REAL,
+  TYPE_VALUE_MPI_SHORT,
+  TYPE_VALUE_MPI_SHORT_INT,
+  TYPE_VALUE_MPI_STRING,
+  TYPE_VALUE_MPI_UB,
+  TYPE_VALUE_MPI_UNSIGNED,
+  TYPE_VALUE_MPI_UNSIGNED_CHAR,
+  TYPE_VALUE_MPI_UNSIGNED_LONG,
+  TYPE_VALUE_MPI_UNSIGNED_SHORT,
+  TYPE_VALUE_LAST
+};
+
+static enum MPIpm_type_const
+type_constant(name, arg)
 char *name;
 int arg;
 {
-  errno = 0;
   if (strEQ(name, "MPI_2COMPLEX"))
 #ifdef MPI_2COMPLEX
-    return MPI_2COMPLEX;
+    return TYPE_VALUE_MPI_2COMPLEX;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_2DOUBLE_COMPLEX"))
 #ifdef MPI_2DOUBLE_COMPLEX
-    return MPI_2DOUBLE_COMPLEX;
+    return TYPE_VALUE_MPI_2DOUBLE_COMPLEX;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_2DOUBLE_PRECISION"))
 #ifdef MPI_2DOUBLE_PRECISION
-    return MPI_2DOUBLE_PRECISION;
+    return TYPE_VALUE_MPI_2DOUBLE_PRECISION;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_2INT"))
 #ifdef MPI_2INT
-    return MPI_2INT;
+    return TYPE_VALUE_MPI_2INT;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_2INTEGER"))
 #ifdef MPI_2INTEGER
-    return MPI_2INTEGER;
+    return TYPE_VALUE_MPI_2INTEGER;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_2REAL"))
 #ifdef MPI_2REAL
-    return MPI_2REAL;
+    return TYPE_VALUE_MPI_2REAL;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_ANY_SOURCE"))
-#ifdef MPI_ANY_SOURCE
-    return MPI_ANY_SOURCE;
+  if (strEQ(name, "MPI_BYTE"))
+#ifdef MPI_BYTE
+    return TYPE_VALUE_MPI_BYTE;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_ANY_TAG"))
-#ifdef MPI_ANY_TAG
-    return MPI_ANY_TAG;
+  if (strEQ(name, "MPI_CHAR"))
+#ifdef MPI_CHAR
+    return TYPE_VALUE_MPI_CHAR;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_BAND"))
-#ifdef MPI_BAND
-    return MPI_BAND;
+  if (strEQ(name, "MPI_CHARACTER"))
+#ifdef MPI_CHARACTER
+    return TYPE_VALUE_MPI_CHARACTER;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_BOR"))
-#ifdef MPI_BOR
-    return MPI_BOR;
+  if (strEQ(name, "MPI_COMPLEX"))
+#ifdef MPI_COMPLEX
+    return TYPE_VALUE_MPI_COMPLEX;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_BSEND_OVERHEAD"))
-#ifdef MPI_BSEND_OVERHEAD
-    return MPI_BSEND_OVERHEAD;
-#else
-      goto not_there;
-#endif
-  if (strEQ(name, "MPI_BXOR"))
-#ifdef MPI_BXOR
-    return MPI_BXOR;
+  if (strEQ(name, "MPI_DATATYPE_NULL"))
+#ifdef MPI_DATATYPE_NULL
+    return TYPE_VALUE_MPI_DATATYPE_NULL;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_BYTE"))
-#ifdef MPI_BYTE
-    return MPI_BYTE;
+  if (strEQ(name, "MPI_DOUBLE"))
+#ifdef MPI_DOUBLE
+    return TYPE_VALUE_MPI_DOUBLE;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_CART"))
-#ifdef MPI_CART
-    return MPI_CART;
+  if (strEQ(name, "MPI_DOUBLE_COMPLEX"))
+#ifdef MPI_DOUBLE_COMPLEX
+    return TYPE_VALUE_MPI_DOUBLE_COMPLEX;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_CHAR"))
-#ifdef MPI_CHAR
-    return MPI_CHAR;
+  if (strEQ(name, "MPI_DOUBLE_INT"))
+#ifdef MPI_DOUBLE_INT
+    return TYPE_VALUE_MPI_DOUBLE_INT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_CHARACTER"))
-#ifdef MPI_CHARACTER
-    return MPI_CHARACTER;
+  if (strEQ(name, "MPI_DOUBLE_PRECISION"))
+#ifdef MPI_DOUBLE_PRECISION
+    return TYPE_VALUE_MPI_DOUBLE_PRECISION;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_COMM_NULL"))
-#ifdef MPI_COMM_NULL
-    return MPI_COMM_NULL;
+  if (strEQ(name, "MPI_FLOAT"))
+#ifdef MPI_FLOAT
+    return TYPE_VALUE_MPI_FLOAT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_COMM_SELF"))
-#ifdef MPI_COMM_SELF
-    return MPI_COMM_SELF;
+  if (strEQ(name, "MPI_FLOAT_INT"))
+#ifdef MPI_FLOAT_INT
+    return TYPE_VALUE_MPI_FLOAT_INT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_COMM_WORLD"))
-#ifdef MPI_COMM_WORLD
-    return MPI_COMM_WORLD;
+  if (strEQ(name, "MPI_INT"))
+#ifdef MPI_INT
+    return TYPE_VALUE_MPI_INT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_COMPLEX"))
-#ifdef MPI_COMPLEX
-    return MPI_COMPLEX;
+  if (strEQ(name, "MPI_INTEGER"))
+#ifdef MPI_INTEGER
+    return TYPE_VALUE_MPI_INTEGER;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_CONGRUENT"))
-#ifdef MPI_CONGRUENT
-    return MPI_CONGRUENT;
+  if (strEQ(name, "MPI_LOGICAL"))
+#ifdef MPI_LOGICAL
+    return TYPE_VALUE_MPI_LOGICAL;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_DATATYPE_NULL"))
-#ifdef MPI_DATATYPE_NULL
-    return MPI_DATATYPE_NULL;
+  if (strEQ(name, "MPI_LONG"))
+#ifdef MPI_LONG
+    return TYPE_VALUE_MPI_LONG;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_DOUBLE"))
-#ifdef MPI_DOUBLE
-    return MPI_DOUBLE;
+  if (strEQ(name, "MPI_LONG_DOUBLE"))
+#ifdef MPI_LONG_DOUBLE
+    return TYPE_VALUE_MPI_LONG_DOUBLE;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_DOUBLE_COMPLEX"))
-#ifdef MPI_DOUBLE_COMPLEX
-    return MPI_DOUBLE_COMPLEX;
+  if (strEQ(name, "MPI_LONG_DOUBLE_INT"))
+#ifdef MPI_LONG_DOUBLE_INT
+    return TYPE_VALUE_MPI_LONG_DOUBLE_INT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_DOUBLE_INT"))
-#ifdef MPI_DOUBLE_INT
-    return MPI_DOUBLE_INT;
+  if (strEQ(name, "MPI_LONG_INT"))
+#ifdef MPI_LONG_INT
+    return TYPE_VALUE_MPI_LONG_INT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_DOUBLE_PRECISION"))
-#ifdef MPI_DOUBLE_PRECISION
-    return MPI_DOUBLE_PRECISION;
+  if (strEQ(name, "MPI_LONG_LONG_INT"))
+#ifdef MPI_LONG_LONG_INT
+    return TYPE_VALUE_MPI_LONG_LONG_INT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_ERRHANDLER_NULL"))
-#ifdef MPI_ERRHANDLER_NULL
-    return MPI_ERRHANDLER_NULL;
+  if (strEQ(name, "MPI_LB"))
+#ifdef MPI_LB
+    return TYPE_VALUE_MPI_LB;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_ERRORS_ARE_FATAL"))
-#ifdef MPI_ERRORS_ARE_FATAL
-    return MPI_ERRORS_ARE_FATAL;
+  if (strEQ(name, "MPI_PACKED"))
+#ifdef MPI_PACKED
+    return TYPE_VALUE_MPI_PACKED;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_ERRORS_RETURN"))
-#ifdef MPI_ERRORS_RETURN
-    return MPI_ERRORS_RETURN;
+  if (strEQ(name, "MPI_REAL"))
+#ifdef MPI_REAL
+    return TYPE_VALUE_MPI_REAL;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_FLOAT"))
-#ifdef MPI_FLOAT
-    return MPI_FLOAT;
+  if (strEQ(name, "MPI_SHORT"))
+#ifdef MPI_SHORT
+    return TYPE_VALUE_MPI_SHORT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_FLOAT_INT"))
-#ifdef MPI_FLOAT_INT
-    return MPI_FLOAT_INT;
+  if (strEQ(name, "MPI_SHORT_INT"))
+#ifdef MPI_SHORT_INT
+    return TYPE_VALUE_MPI_SHORT_INT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_GRAPH"))
-#ifdef MPI_GRAPH
-    return MPI_GRAPH;
+  if (strEQ(name, "MPI_STRING"))
+#ifdef MPI_STRING
+    return TYPE_VALUE_MPI_STRING;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_GROUP_EMPTY"))
-#ifdef MPI_GROUP_EMPTY
-    return MPI_GROUP_EMPTY;
+  if (strEQ(name, "MPI_UB"))
+#ifdef MPI_UB
+    return TYPE_VALUE_MPI_UB;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_GROUP_NULL"))
-#ifdef MPI_GROUP_NULL
-    return MPI_GROUP_NULL;
+  if (strEQ(name, "MPI_UNSIGNED"))
+#ifdef MPI_UNSIGNED
+    return TYPE_VALUE_MPI_UNSIGNED;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_HOST"))
-#ifdef MPI_HOST
-    return MPI_HOST;
+  if (strEQ(name, "MPI_UNSIGNED_CHAR"))
+#ifdef MPI_UNSIGNED_CHAR
+    return TYPE_VALUE_MPI_UNSIGNED_CHAR;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_IDENT"))
-#ifdef MPI_IDENT
-    return MPI_IDENT;
+  if (strEQ(name, "MPI_UNSIGNED_LONG"))
+#ifdef MPI_UNSIGNED_LONG
+    return TYPE_VALUE_MPI_UNSIGNED_LONG;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_INT"))
-#ifdef MPI_INT
-    return MPI_INT;
+  if (strEQ(name, "MPI_UNSIGNED_SHORT"))
+#ifdef MPI_UNSIGNED_SHORT
+    return TYPE_VALUE_MPI_UNSIGNED_SHORT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_INTEGER"))
-#ifdef MPI_INTEGER
-    return MPI_INTEGER;
+not_there:
+  return TYPE_VALUE_NONE;
+}
+
+enum MPIpm_op_const {
+  OP_VALUE_NONE = 0,
+  OP_VALUE_MPI_BAND,
+  OP_VALUE_MPI_BOR,
+  OP_VALUE_MPI_BXOR,
+  OP_VALUE_MPI_LAND,
+  OP_VALUE_MPI_MIN,
+  OP_VALUE_MPI_MINLOC,
+  OP_VALUE_MPI_OP_NULL,
+  OP_VALUE_MPI_PROD,
+  OP_VALUE_MPI_SUM,
+  OP_VALUE_MPI_LOR,
+  OP_VALUE_MPI_LXOR,
+  OP_VALUE_MPI_MAX,
+  OP_VALUE_MPI_MAXLOC,
+  OP_VALUE_LAST
+};
+
+static enum MPIpm_op_const op_constant(name, arg)
+char *name;
+int arg;
+{
+  if (strEQ(name, "MPI_BAND"))
+#ifdef MPI_BAND
+    return OP_VALUE_MPI_BAND;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_IO"))
-#ifdef MPI_IO
-    return MPI_IO;
+  if (strEQ(name, "MPI_BOR"))
+#ifdef MPI_BOR
+    return OP_VALUE_MPI_BOR;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_KEYVAL_INVALID"))
-#ifdef MPI_KEYVAL_INVALID
-    return MPI_KEYVAL_INVALID;
+  if (strEQ(name, "MPI_BXOR"))
+#ifdef MPI_BXOR
+    return OP_VALUE_MPI_BXOR;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_LAND"))
 #ifdef MPI_LAND
-    return MPI_LAND;
-#else
-    goto not_there;
-#endif
-  if (strEQ(name, "MPI_LB"))
-#ifdef MPI_LB
-    return MPI_LB;
-#else
-    goto not_there;
-#endif
-  if (strEQ(name, "MPI_LOGICAL"))
-#ifdef MPI_LOGICAL
-    return MPI_LOGICAL;
+    return OP_VALUE_MPI_LAND;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_LONG"))
-#ifdef MPI_LONG
-    return MPI_LONG;
+  if (strEQ(name, "MPI_MIN"))
+#ifdef MPI_MIN
+    return OP_VALUE_MPI_MIN;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_LONG_DOUBLE"))
-#ifdef MPI_LONG_DOUBLE
-    return MPI_LONG_DOUBLE;
+  if (strEQ(name, "MPI_MINLOC"))
+#ifdef MPI_MINLOC
+    return OP_VALUE_MPI_MINLOC;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_LONG_DOUBLE_INT"))
-#ifdef MPI_LONG_DOUBLE_INT
-    return MPI_LONG_DOUBLE_INT;
+  if (strEQ(name, "MPI_OP_NULL"))
+#ifdef MPI_OP_NULL
+    return OP_VALUE_MPI_OP_NULL;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_LONG_INT"))
-#ifdef MPI_LONG_INT
-    return MPI_LONG_INT;
+  if (strEQ(name, "MPI_PROD"))
+#ifdef MPI_PROD
+    return OP_VALUE_MPI_PROD;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_LONG_LONG_INT"))
-#ifdef MPI_LONG_LONG_INT
-    return MPI_LONG_LONG_INT;
+  if (strEQ(name, "MPI_SUM"))
+#ifdef MPI_SUM
+    return OP_VALUE_MPI_SUM;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_LOR"))
 #ifdef MPI_LOR
-    return MPI_LOR;
+    return OP_VALUE_MPI_LOR;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_LXOR"))
 #ifdef MPI_LXOR
-    return MPI_LXOR;
+    return OP_VALUE_MPI_LXOR;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_MAX"))
 #ifdef MPI_MAX
-    return MPI_MAX;
+    return OP_VALUE_MPI_MAX;
 #else
     goto not_there;
 #endif
   if (strEQ(name, "MPI_MAXLOC"))
 #ifdef MPI_MAXLOC
-    return MPI_MAXLOC;
+    return OP_VALUE_MPI_MAXLOC;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_MAX_ERROR_STRING"))
-#ifdef MPI_MAX_ERROR_STRING
-    return MPI_MAX_ERROR_STRING;
+not_there:
+  return OP_VALUE_NONE;
+}
+
+static uintptr_t handle_constant(name, arg)
+char *name;
+int arg;
+{
+  if (strEQ(name, "MPI_COMM_NULL"))
+#ifdef MPI_COMM_NULL
+    return (uintptr_t)MPI_COMM_NULL;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_MAX_NAME_STRING"))
-#ifdef MPI_MAX_NAME_STRING
-    return MPI_MAX_NAME_STRING;
+  if (strEQ(name, "MPI_COMM_SELF"))
+#ifdef MPI_COMM_SELF
+    return (uintptr_t)MPI_COMM_SELF;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_MAX_PROCESSOR_NAME"))
-#ifdef MPI_MAX_PROCESSOR_NAME
-    return MPI_MAX_PROCESSOR_NAME;
+  if (strEQ(name, "MPI_COMM_WORLD"))
+#ifdef MPI_COMM_WORLD
+    return (uintptr_t)MPI_COMM_WORLD;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_ERRHANDLER_NULL"))
+#ifdef MPI_ERRHANDLER_NULL
+    return (uintptr_t)MPI_ERRHANDLER_NULL;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_ERRORS_ARE_FATAL"))
+#ifdef MPI_ERRORS_ARE_FATAL
+    return (uintptr_t)MPI_ERRORS_ARE_FATAL;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_ERRORS_RETURN"))
+#ifdef MPI_ERRORS_RETURN
+    return (uintptr_t)MPI_ERRORS_RETURN;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_GROUP_EMPTY"))
+#ifdef MPI_GROUP_EMPTY
+    return (uintptr_t)MPI_GROUP_EMPTY;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_GROUP_NULL"))
+#ifdef MPI_GROUP_NULL
+    return (uintptr_t)MPI_GROUP_NULL;
+#else
+    goto not_there;
+#endif
+not_there:
+  return 0;
+}
+
+static double
+constant(name, arg)
+char *name;
+int arg;
+{
+  errno = 0;
+  {
+    enum MPIpm_type_const t = type_constant(name);
+    if (TYPE_VALUE_NONE != t)
+      return t;
+  }
+  {
+    enum MPIpm_op_const t = op_constant(name);
+    if (OP_VALUE_NONE != t)
+      return t;
+  }
+  {
+    uintptr_t t = handle_constant(name);
+    if (t)
+      return t;
+  }
+  if (strEQ(name, "MPI_ANY_SOURCE"))
+#ifdef MPI_ANY_SOURCE
+    return MPI_ANY_SOURCE;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_ANY_TAG"))
+#ifdef MPI_ANY_TAG
+    return MPI_ANY_TAG;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_BSEND_OVERHEAD"))
+#ifdef MPI_BSEND_OVERHEAD
+    return MPI_BSEND_OVERHEAD;
+#else
+      goto not_there;
+#endif
+  if (strEQ(name, "MPI_CART"))
+#ifdef MPI_CART
+    return MPI_CART;
+#else
+    goto not_there;
+#endif
+  if (strEQ(name, "MPI_CONGRUENT"))
+#ifdef MPI_CONGRUENT
+    return MPI_CONGRUENT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_MIN"))
-#ifdef MPI_MIN
-    return MPI_MIN;
+  if (strEQ(name, "MPI_GRAPH"))
+#ifdef MPI_GRAPH
+    return MPI_GRAPH;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_MINLOC"))
-#ifdef MPI_MINLOC
-    return MPI_MINLOC;
+  if (strEQ(name, "MPI_HOST"))
+#ifdef MPI_HOST
+    return MPI_HOST;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_OP_NULL"))
-#ifdef MPI_OP_NULL
-    return MPI_OP_NULL;
+  if (strEQ(name, "MPI_IDENT"))
+#ifdef MPI_IDENT
+    return MPI_IDENT;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_PACKED"))
-#ifdef MPI_PACKED
-    return MPI_PACKED;
+  if (strEQ(name, "MPI_IO"))
+#ifdef MPI_IO
+    return MPI_IO;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_PROC_NULL"))
-#ifdef MPI_PROC_NULL
-    return MPI_PROC_NULL;
+  if (strEQ(name, "MPI_KEYVAL_INVALID"))
+#ifdef MPI_KEYVAL_INVALID
+    return MPI_KEYVAL_INVALID;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_PROD"))
-#ifdef MPI_PROD
-    return MPI_PROD;
+  if (strEQ(name, "MPI_MAX_ERROR_STRING"))
+#ifdef MPI_MAX_ERROR_STRING
+    return MPI_MAX_ERROR_STRING;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_REAL"))
-#ifdef MPI_REAL
-    return MPI_REAL;
+  if (strEQ(name, "MPI_MAX_NAME_STRING"))
+#ifdef MPI_MAX_NAME_STRING
+    return MPI_MAX_NAME_STRING;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_SHORT"))
-#ifdef MPI_SHORT
-    return MPI_SHORT;
+  if (strEQ(name, "MPI_MAX_PROCESSOR_NAME"))
+#ifdef MPI_MAX_PROCESSOR_NAME
+    return MPI_MAX_PROCESSOR_NAME;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_SHORT_INT"))
-#ifdef MPI_SHORT_INT
-    return MPI_SHORT_INT;
+  if (strEQ(name, "MPI_PROC_NULL"))
+#ifdef MPI_PROC_NULL
+    return MPI_PROC_NULL;
 #else
     goto not_there;
 #endif
@@ -396,36 +539,18 @@
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_STRING"))
-#ifdef MPI_STRING
-    return MPI_STRING;
-#else
-    goto not_there;
-#endif
   if (strEQ(name, "MPI_SUBVERSION"))
 #ifdef MPI_SUBVERSION
     return MPI_SUBVERSION;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_SUM"))
-#ifdef MPI_SUM
-    return MPI_SUM;
-#else
-    goto not_there;
-#endif
   if (strEQ(name, "MPI_TAG_UB"))
 #ifdef MPI_TAG_UB
     return MPI_TAG_UB;
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_UB"))
-#ifdef MPI_UB
-    return MPI_UB;
-#else
-    goto not_there;
-#endif
   if (strEQ(name, "MPI_UNDEFINED"))
 #ifdef MPI_UNDEFINED
     return MPI_UNDEFINED;
@@ -444,30 +569,6 @@
 #else
     goto not_there;
 #endif
-  if (strEQ(name, "MPI_UNSIGNED"))
-#ifdef MPI_UNSIGNED
-    return MPI_UNSIGNED;
-#else
-    goto not_there;
-#endif
-  if (strEQ(name, "MPI_UNSIGNED_CHAR"))
-#ifdef MPI_UNSIGNED_CHAR
-    return MPI_UNSIGNED_CHAR;
-#else
-    goto not_there;
-#endif
-  if (strEQ(name, "MPI_UNSIGNED_LONG"))
-#ifdef MPI_UNSIGNED_LONG
-    return MPI_UNSIGNED_LONG;
-#else
-    goto not_there;
-#endif
-  if (strEQ(name, "MPI_UNSIGNED_SHORT"))
-#ifdef MPI_UNSIGNED_SHORT
-    return MPI_UNSIGNED_SHORT;
-#else
-    goto not_there;
-#endif
   if (strEQ(name, "MPI_VERSION"))
 #ifdef MPI_VERSION
     return MPI_VERSION;
@@ -490,54 +591,54 @@
   return 0;
 }
 
-int MPIpm_bufsize(MPI_Datatype datatype, SV* scalar, int count) {
+int MPIpm_bufsize(enum MPIpm_type_const datatype, SV* scalar, int count) {
   switch (datatype) {
 
-  case MPI_INT:
-  case MPI_INTEGER:
+  case TYPE_VALUE_MPI_INT:
+  case TYPE_VALUE_MPI_INTEGER:
     return count * sizeof(int);
     break;
 
-  case MPI_DOUBLE:
+  case TYPE_VALUE_MPI_DOUBLE:
     return count * sizeof(double);
     break;
 
 #ifndef FLOAT_HACK    
-  case MPI_FLOAT:
+  case TYPE_VALUE_MPI_FLOAT:
     return count * sizeof(float);
     break;
 #endif
 
-  case MPI_CHAR:
+  case TYPE_VALUE_MPI_CHAR:
     return (count + 1) * sizeof(char);
     break;
 
-  case MPI_STRING:
-  case MPI_2COMPLEX:
-  case MPI_2DOUBLE_COMPLEX:
-  case MPI_2DOUBLE_PRECISION:
-  case MPI_2INT:
-  case MPI_2INTEGER: 
-  case MPI_2REAL:
-  case MPI_BYTE:
-  case MPI_COMPLEX:
-  case MPI_DATATYPE_NULL:
-  case MPI_DOUBLE_COMPLEX:
-  case MPI_DOUBLE_INT:
-  case MPI_DOUBLE_PRECISION:
-  case MPI_FLOAT_INT:
-  case MPI_LONG:
-  case MPI_LONG_DOUBLE:
-  case MPI_LONG_DOUBLE_INT:
-  case MPI_LONG_INT:
-  case MPI_LONG_LONG_INT:
-  case MPI_REAL:
-  case MPI_SHORT:
-  case MPI_SHORT_INT:     
-  case MPI_UNSIGNED:
-  case MPI_UNSIGNED_CHAR:
-  case MPI_UNSIGNED_LONG:
-  case MPI_UNSIGNED_SHORT:
+  case TYPE_VALUE_MPI_STRING:
+  case TYPE_VALUE_MPI_2COMPLEX:
+  case TYPE_VALUE_MPI_2DOUBLE_COMPLEX:
+  case TYPE_VALUE_MPI_2DOUBLE_PRECISION:
+  case TYPE_VALUE_MPI_2INT:
+  case TYPE_VALUE_MPI_2INTEGER: 
+  case TYPE_VALUE_MPI_2REAL:
+  case TYPE_VALUE_MPI_BYTE:
+  case TYPE_VALUE_MPI_COMPLEX:
+  case TYPE_VALUE_MPI_DATATYPE_NULL:
+  case TYPE_VALUE_MPI_DOUBLE_COMPLEX:
+  case TYPE_VALUE_MPI_DOUBLE_INT:
+  case TYPE_VALUE_MPI_DOUBLE_PRECISION:
+  case TYPE_VALUE_MPI_FLOAT_INT:
+  case TYPE_VALUE_MPI_LONG:
+  case TYPE_VALUE_MPI_LONG_DOUBLE:
+  case TYPE_VALUE_MPI_LONG_DOUBLE_INT:
+  case TYPE_VALUE_MPI_LONG_INT:
+  case TYPE_VALUE_MPI_LONG_LONG_INT:
+  case TYPE_VALUE_MPI_REAL:
+  case TYPE_VALUE_MPI_SHORT:
+  case TYPE_VALUE_MPI_SHORT_INT:     
+  case TYPE_VALUE_MPI_UNSIGNED:
+  case TYPE_VALUE_MPI_UNSIGNED_CHAR:
+  case TYPE_VALUE_MPI_UNSIGNED_LONG:
+  case TYPE_VALUE_MPI_UNSIGNED_SHORT:
     croak("Unsupported datatype %d in MPIpm_bufsize()", datatype);
     break;
    
@@ -548,7 +649,7 @@
   return(-1);
 }
 
-int MPIpm_packarray(void** buf, AV* array, MPI_Datatype datatype, int count) {
+int MPIpm_packarray(void** buf, AV* array, enum MPIpm_type_const datatype, int count) {
     int i,len=0,avl;
     SV** sv_tmp;
     char* t;
@@ -563,7 +664,7 @@
     }
 
     switch(datatype) {
-      case MPI_STRING:
+      case TYPE_VALUE_MPI_STRING:
 	for(i=0 ; i<=avl ; i++) {
 	    sv_tmp = av_fetch(array, i, 0);
             if(sv_tmp != NULL)
@@ -582,8 +683,8 @@
 	}
 	return(len);
 	break;
-      case MPI_INT:
-      case MPI_INTEGER:
+      case TYPE_VALUE_MPI_INT:
+      case TYPE_VALUE_MPI_INTEGER:
         len = (avl+1) * sizeof(int);
 	t = *buf = (void*) malloc(len);
 
@@ -596,7 +697,7 @@
 	}
 	return(len);
 #ifndef FLOAT_HACK    
-      case MPI_FLOAT:
+      case TYPE_VALUE_MPI_FLOAT:
         len = (avl+1) * sizeof(float);
 	t = *buf = (void*) malloc(len);
 
@@ -609,7 +710,7 @@
 	}
 	return(len);
 #endif
-      case MPI_DOUBLE:
+      case TYPE_VALUE_MPI_DOUBLE:
         len = (avl+1) * sizeof(double);
 	t = *buf = (void*) malloc(len);
 
@@ -629,19 +730,21 @@
     return(-1);
 }
 
-void MPIpm_unpackarray(void* buf, AV** array, MPI_Datatype datatype, int count) 
+void MPIpm_unpackarray(void* buf, AV** array, enum MPIpm_type_const datatype, int count) 
 {
     int i;
     char* t = buf;
 
     av_clear(*array);
     switch(datatype) {
-      case MPI_STRING:
+#ifdef MPI_STRING
+      case TYPE_VALUE_MPI_STRING:
+#endif
 	croak("Unrecognized or unsupported datatype %d in MPIpm_packscalar()",
 	      datatype);
         break;
-      case MPI_INT:
-      case MPI_INTEGER:
+      case TYPE_VALUE_MPI_INT:
+      case TYPE_VALUE_MPI_INTEGER:
         av_extend(*array, count);
         for(i=0;i<count;i++) {
             int u;
@@ -654,10 +757,10 @@
 	}
 	break;
 #ifndef FLOAT_HACK
-      case MPI_FLOAT:
+      case TYPE_VALUE_MPI_FLOAT:
 	break;
 #endif
-      case MPI_DOUBLE:
+      case TYPE_VALUE_MPI_DOUBLE:
         av_extend(*array, count);
         for(i=0;i<count;i++) {
             double u;
@@ -676,54 +779,54 @@
     } 
 }
 
-void MPIpm_packscalar(char* buf, SV* scalar, MPI_Datatype datatype) {
+void MPIpm_packscalar(char* buf, SV* scalar, enum MPIpm_type_const datatype) {
   switch (datatype) {
 
-  case MPI_INT:
-  case MPI_INTEGER:
+  case TYPE_VALUE_MPI_INT:
+  case TYPE_VALUE_MPI_INTEGER:
     *(int*)buf = SvIV(scalar);
     break;
 
-  case MPI_DOUBLE:
+  case TYPE_VALUE_MPI_DOUBLE:
     *(double*)buf = SvNV(scalar);
     break;
 
 #ifndef FLOAT_HACK        
-  case MPI_FLOAT:
+  case TYPE_VALUE_MPI_FLOAT:
     *(float*)buf = (float)SvNV(scalar);
     break;
 #endif
 
-  case MPI_CHAR:
+  case TYPE_VALUE_MPI_CHAR:
     memcpy(buf, SvPV(scalar, PL_na), SvCUR(scalar));
     *(char*)(buf + SvCUR(scalar)) = '\0';
     break;
 
-  case MPI_2COMPLEX:
-  case MPI_2DOUBLE_COMPLEX:
-  case MPI_2DOUBLE_PRECISION:
-  case MPI_2INT:
-  case MPI_2INTEGER: 
-  case MPI_2REAL:
-  case MPI_BYTE:
-  case MPI_COMPLEX:
-  case MPI_DATATYPE_NULL:
-  case MPI_DOUBLE_COMPLEX:
-  case MPI_DOUBLE_INT:
-  case MPI_DOUBLE_PRECISION:
-  case MPI_FLOAT_INT:
-  case MPI_LONG:
-  case MPI_LONG_DOUBLE:
-  case MPI_LONG_DOUBLE_INT:
-  case MPI_LONG_INT:
-  case MPI_LONG_LONG_INT:
-  case MPI_REAL:
-  case MPI_SHORT:
-  case MPI_SHORT_INT:     
-  case MPI_UNSIGNED:
-  case MPI_UNSIGNED_CHAR:
-  case MPI_UNSIGNED_LONG:
-  case MPI_UNSIGNED_SHORT:
+  case TYPE_VALUE_MPI_2COMPLEX:
+  case TYPE_VALUE_MPI_2DOUBLE_COMPLEX:
+  case TYPE_VALUE_MPI_2DOUBLE_PRECISION:
+  case TYPE_VALUE_MPI_2INT:
+  case TYPE_VALUE_MPI_2INTEGER: 
+  case TYPE_VALUE_MPI_2REAL:
+  case TYPE_VALUE_MPI_BYTE:
+  case TYPE_VALUE_MPI_COMPLEX:
+  case TYPE_VALUE_MPI_DATATYPE_NULL:
+  case TYPE_VALUE_MPI_DOUBLE_COMPLEX:
+  case TYPE_VALUE_MPI_DOUBLE_INT:
+  case TYPE_VALUE_MPI_DOUBLE_PRECISION:
+  case TYPE_VALUE_MPI_FLOAT_INT:
+  case TYPE_VALUE_MPI_LONG:
+  case TYPE_VALUE_MPI_LONG_DOUBLE:
+  case TYPE_VALUE_MPI_LONG_DOUBLE_INT:
+  case TYPE_VALUE_MPI_LONG_INT:
+  case TYPE_VALUE_MPI_LONG_LONG_INT:
+  case TYPE_VALUE_MPI_REAL:
+  case TYPE_VALUE_MPI_SHORT:
+  case TYPE_VALUE_MPI_SHORT_INT:     
+  case TYPE_VALUE_MPI_UNSIGNED:
+  case TYPE_VALUE_MPI_UNSIGNED_CHAR:
+  case TYPE_VALUE_MPI_UNSIGNED_LONG:
+  case TYPE_VALUE_MPI_UNSIGNED_SHORT:
     croak("Unsupported datatype %d in MPIpm_packscalar()", datatype);
     break;
    
@@ -734,53 +837,53 @@
 
 }
 
-void MPIpm_unpackscalar(void* buf, SV* scalar, MPI_Datatype datatype) {
+void MPIpm_unpackscalar(void* buf, SV* scalar, enum MPIpm_type_const datatype) {
   switch (datatype) {
 
-  case MPI_INT:
-  case MPI_INTEGER:
+  case TYPE_VALUE_MPI_INT:
+  case TYPE_VALUE_MPI_INTEGER:
     sv_setiv(scalar, *(int*)buf);
     break;
 
-  case MPI_DOUBLE:
+  case TYPE_VALUE_MPI_DOUBLE:
     sv_setnv(scalar, *(double*)buf);
     break;
 
 #ifndef FLOAT_HACK        
-  case MPI_FLOAT:
+  case TYPE_VALUE_MPI_FLOAT:
     sv_setnv(scalar, (double)*(float*)buf);    
     break;
 #endif
 
-  case MPI_CHAR:
+  case TYPE_VALUE_MPI_CHAR:
     sv_setpv(scalar, buf);
     break;
 
-  case MPI_2COMPLEX:
-  case MPI_2DOUBLE_COMPLEX:
-  case MPI_2DOUBLE_PRECISION:
-  case MPI_2INT:
-  case MPI_2INTEGER: 
-  case MPI_2REAL:
-  case MPI_BYTE:
-  case MPI_COMPLEX:
-  case MPI_DATATYPE_NULL:
-  case MPI_DOUBLE_COMPLEX:
-  case MPI_DOUBLE_INT:
-  case MPI_DOUBLE_PRECISION:
-  case MPI_FLOAT_INT:
-  case MPI_LONG:
-  case MPI_LONG_DOUBLE:
-  case MPI_LONG_DOUBLE_INT:
-  case MPI_LONG_INT:
-  case MPI_LONG_LONG_INT:
-  case MPI_REAL:
-  case MPI_SHORT:
-  case MPI_SHORT_INT:     
-  case MPI_UNSIGNED:
-  case MPI_UNSIGNED_CHAR:
-  case MPI_UNSIGNED_LONG:
-  case MPI_UNSIGNED_SHORT:
+  case TYPE_VALUE_MPI_2COMPLEX:
+  case TYPE_VALUE_MPI_2DOUBLE_COMPLEX:
+  case TYPE_VALUE_MPI_2DOUBLE_PRECISION:
+  case TYPE_VALUE_MPI_2INT:
+  case TYPE_VALUE_MPI_2INTEGER: 
+  case TYPE_VALUE_MPI_2REAL:
+  case TYPE_VALUE_MPI_BYTE:
+  case TYPE_VALUE_MPI_COMPLEX:
+  case TYPE_VALUE_MPI_DATATYPE_NULL:
+  case TYPE_VALUE_MPI_DOUBLE_COMPLEX:
+  case TYPE_VALUE_MPI_DOUBLE_INT:
+  case TYPE_VALUE_MPI_DOUBLE_PRECISION:
+  case TYPE_VALUE_MPI_FLOAT_INT:
+  case TYPE_VALUE_MPI_LONG:
+  case TYPE_VALUE_MPI_LONG_DOUBLE:
+  case TYPE_VALUE_MPI_LONG_DOUBLE_INT:
+  case TYPE_VALUE_MPI_LONG_INT:
+  case TYPE_VALUE_MPI_LONG_LONG_INT:
+  case TYPE_VALUE_MPI_REAL:
+  case TYPE_VALUE_MPI_SHORT:
+  case TYPE_VALUE_MPI_SHORT_INT:     
+  case TYPE_VALUE_MPI_UNSIGNED:
+  case TYPE_VALUE_MPI_UNSIGNED_CHAR:
+  case TYPE_VALUE_MPI_UNSIGNED_LONG:
+  case TYPE_VALUE_MPI_UNSIGNED_SHORT:
     croak("Unsupported datatype %d in MPIpm_unpackscalar()", datatype);
     break;
    
@@ -869,3 +972,217 @@
     die(buf);
   }
 }
+
+MPI_Datatype MPIpm_datatype(type)
+enum MPIpm_type_const type;
+{
+  switch (type) {
+#ifdef MPI_2COMPLEX
+  case TYPE_VALUE_MPI_2COMPLEX:
+    return MPI_2COMPLEX;
+#endif
+#ifdef MPI_2DOUBLE_COMPLEX
+  case TYPE_VALUE_MPI_2DOUBLE_COMPLEX:
+    return MPI_2DOUBLE_COMPLEX;
+#endif
+#ifdef MPI_2DOUBLE_PRECISION
+  case TYPE_VALUE_MPI_2DOUBLE_PRECISION:
+    return MPI_2DOUBLE_PRECISION;
+#endif
+#ifdef MPI_2INT
+  case TYPE_VALUE_MPI_2INT:
+    return MPI_2INT;
+#endif
+#ifdef MPI_2INTEGER
+  case TYPE_VALUE_MPI_2INTEGER:
+    return MPI_2INTEGER;
+#endif
+#ifdef MPI_2REAL
+  case TYPE_VALUE_MPI_2REAL:
+    return MPI_2REAL;
+#endif
+#ifdef MPI_BYTE
+  case TYPE_VALUE_MPI_BYTE:
+    return MPI_BYTE;
+#endif
+#ifdef MPI_CHAR
+  case TYPE_VALUE_MPI_CHAR:
+    return MPI_CHAR;
+#endif
+#ifdef MPI_CHARACTER
+  case TYPE_VALUE_MPI_CHARACTER:
+    return MPI_CHARACTER;
+#endif
+#ifdef MPI_COMPLEX
+  case TYPE_VALUE_MPI_COMPLEX:
+    return MPI_COMPLEX;
+#endif
+#ifdef MPI_DATATYPE_NULL
+  case TYPE_VALUE_MPI_DATATYPE_NULL:
+    return MPI_DATATYPE_NULL;
+#endif
+#ifdef MPI_DOUBLE
+  case TYPE_VALUE_MPI_DOUBLE:
+    return MPI_DOUBLE;
+#endif
+#ifdef MPI_DOUBLE_COMPLEX
+  case TYPE_VALUE_MPI_DOUBLE_COMPLEX:
+    return MPI_DOUBLE_COMPLEX;
+#endif
+#ifdef MPI_DOUBLE_INT
+  case TYPE_VALUE_MPI_DOUBLE_INT:
+    return MPI_DOUBLE_INT;
+#endif
+#ifdef MPI_DOUBLE_PRECISION
+  case TYPE_VALUE_MPI_DOUBLE_PRECISION:
+    return MPI_DOUBLE_PRECISION;
+#endif
+#ifdef MPI_FLOAT
+  case TYPE_VALUE_MPI_FLOAT:
+    return MPI_FLOAT;
+#endif
+#ifdef MPI_FLOAT_INT
+  case TYPE_VALUE_MPI_FLOAT_INT:
+    return MPI_FLOAT_INT;
+#endif
+#ifdef MPI_INT
+  case TYPE_VALUE_MPI_INT:
+    return MPI_INT;
+#endif
+#ifdef MPI_INTEGER
+  case TYPE_VALUE_MPI_INTEGER:
+    return MPI_INTEGER;
+#endif
+#ifdef MPI_LOGICAL
+  case TYPE_VALUE_MPI_LOGICAL:
+    return MPI_LOGICAL;
+#endif
+#ifdef MPI_LONG
+  case TYPE_VALUE_MPI_LONG:
+    return MPI_LONG;
+#endif
+#ifdef MPI_LONG_DOUBLE
+  case TYPE_VALUE_MPI_LONG_DOUBLE:
+    return MPI_LONG_DOUBLE;
+#endif
+#ifdef MPI_LONG_DOUBLE_INT
+  case TYPE_VALUE_MPI_LONG_DOUBLE_INT:
+    return MPI_LONG_DOUBLE_INT;
+#endif
+#ifdef MPI_LONG_INT
+  case TYPE_VALUE_MPI_LONG_INT:
+    return MPI_LONG_INT;
+#endif
+#ifdef MPI_LONG_LONG_INT
+  case TYPE_VALUE_MPI_LONG_LONG_INT:
+    return MPI_LONG_LONG_INT;
+#endif
+#ifdef MPI_LB
+  case TYPE_VALUE_MPI_LB:
+    return MPI_LB;
+#endif
+#ifdef MPI_PACKED
+  case TYPE_VALUE_MPI_PACKED:
+    return MPI_PACKED;
+#endif
+#ifdef MPI_REAL
+  case TYPE_VALUE_MPI_REAL:
+    return MPI_REAL;
+#endif
+#ifdef MPI_SHORT
+  case TYPE_VALUE_MPI_SHORT:
+    return MPI_SHORT;
+#endif
+#ifdef MPI_SHORT_INT
+  case TYPE_VALUE_MPI_SHORT_INT:
+    return MPI_SHORT_INT;
+#endif
+#ifdef MPI_STRING
+  case TYPE_VALUE_MPI_STRING:
+    return MPI_STRING;
+#endif
+#ifdef MPI_UB
+  case TYPE_VALUE_MPI_UB:
+    return MPI_UB;
+#endif
+#ifdef MPI_UNSIGNED
+  case TYPE_VALUE_MPI_UNSIGNED:
+    return MPI_UNSIGNED;
+#endif
+#ifdef MPI_UNSIGNED_CHAR
+  case TYPE_VALUE_MPI_UNSIGNED_CHAR:
+    return MPI_UNSIGNED_CHAR;
+#endif
+#ifdef MPI_UNSIGNED_LONG
+  case TYPE_VALUE_MPI_UNSIGNED_LONG:
+    return MPI_UNSIGNED_LONG;
+#endif
+#ifdef MPI_UNSIGNED_SHORT
+  case TYPE_VALUE_MPI_UNSIGNED_SHORT:
+    return MPI_UNSIGNED_SHORT;
+#endif
+  }
+  return NULL;
+}
+
+MPI_Op MPIpm_op(type)
+enum MPIpm_op_const type;
+{
+  switch (type) {
+#ifdef MPI_BAND
+  case OP_VALUE_MPI_BAND:
+    return MPI_BAND;
+#endif
+#ifdef MPI_BOR
+  case OP_VALUE_MPI_BOR:
+    return MPI_BOR;
+#endif
+#ifdef MPI_BXOR
+  case OP_VALUE_MPI_BXOR:
+    return MPI_BXOR;
+#endif
+#ifdef MPI_LAND
+  case OP_VALUE_MPI_LAND:
+    return MPI_LAND;
+#endif
+#ifdef MPI_MIN
+  case OP_VALUE_MPI_MIN:
+    return MPI_MIN;
+#endif
+#ifdef MPI_MINLOC
+  case OP_VALUE_MPI_MINLOC:
+    return MPI_MINLOC;
+#endif
+#ifdef MPI_OP_NULL
+  case OP_VALUE_MPI_OP_NULL:
+    return MPI_OP_NULL;
+#endif
+#ifdef MPI_PROD
+  case OP_VALUE_MPI_PROD:
+    return MPI_PROD;
+#endif
+#ifdef MPI_SUM
+  case OP_VALUE_MPI_SUM:
+    return MPI_SUM;
+#endif
+#ifdef MPI_LOR
+  case OP_VALUE_MPI_LOR:
+    return MPI_LOR;
+#endif
+#ifdef MPI_LXOR
+  case OP_VALUE_MPI_LXOR:
+    return MPI_LXOR;
+#endif
+#ifdef MPI_MAX
+  case OP_VALUE_MPI_MAX:
+    return MPI_MAX;
+#endif
+#ifdef MPI_MAXLOC
+  case OP_VALUE_MPI_MAXLOC:
+    return MPI_MAXLOC;
+#endif
+  }
+  return NULL;
+}
+
+