EMAN2
mympimodule.c
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2005 The Regents of the University of California
00003 All Rights Reserved
00004 Permission to use, copy, modify and distribute any part of this
00005         Continuity 6 for educational, research and non-profit purposes,
00006         without fee, and without a written agreement is hereby granted,
00007         provided that the above copyright notice, this paragraph and the
00008         following three paragraphs appear in all copies.
00009 Those desiring to incorporate this software into commercial products or
00010         use for commercial purposes should contact the Technology
00011         Transfer & Intellectual Property Services, University of
00012         California, San Diego, 9500 Gilman Drive, Mail Code 0910, La
00013         Jolla, CA 92093-0910, Ph: (858) 534-5815, FAX: (858) 534-7345,
00014         E-MAIL:invent@ucsd.edu.
00015 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY
00016         PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
00017         CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF
00018         THE USE OF THIS SOFTWARE  EVEN IF THE UNIVERSITY OF
00019         CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00020 THE SOFTWARE PROVIDED HEREIN IS ON AN AS IS BASIS, AND THE
00021         UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
00022         MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00023         THE UNIVERSITY OF CALIFORNIA MAKES NO REPRESENTATIONS AND
00024         EXTENDS NO WARRANTIES OF ANY KIND, EITHER IMPLIED OR EXPRESS,
00025         INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00026         MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT THE
00027         USE OF THE Continuity WILL NOT INFRINGE ANY PATENT, TRADEMARK OR
00028         OTHER RIGHTS.";
00029 */
00030 
00031 
00032 /*
00033 $Date: 2009/12/06 01:15:37 $
00034 $Revision: 1.4 $
00035 $Source: /usr/local/CVS/CVS/eman2/sparx/test/bootstrap/mympimodule.c,v $
00036 */
00037 
00038 /************** numpy or Numeric? **************/
00039 
00040 
00041 /* if NUMPY is defined then we look for arrayobject.h
00042    in <arrayobject.h>.  If not then in <Numeric/arrayobject.h>
00043 
00044    The second case would be the norm if you are linking against
00045    Numeric instead of numpy.
00046 
00047    We default to Numeric but this might change in the future.
00048 
00049    You can see the which was used at run time by printing
00050    mpi.ARRAY_LIBRARY.
00051 
00052 */
00053 
00054 /************** numpy or Numeric **************/
00055 char DATE_SRC[]="$Date: 2009/12/06 01:15:37 $";
00056 
00057 #define VERSION "1.13.0"
00058 #define COPYWRITE "Copyright (c) 2005 The Regents of the University of California All Rights Reserved.  print mpi.copywrite() for details."
00059 #undef DO_UNSIGED
00060 #define DATA_TYPE long
00061 #define COM_TYPE long
00062 #define ARG_ARRAY
00063 /* #define ARG_STR */
00064 /* #define SIZE_RANK */
00065 #include <Python.h>
00066 #include "documentation.h"
00067 
00068 #ifdef NUMPY
00069 #include <arrayobject.h>
00070 #define LIBRARY "NUMPY"
00071 #else
00072 #include <Numeric/arrayobject.h>
00073 #define LIBRARY "Numeric"
00074 #endif
00075 
00076 #include <sys/types.h>
00077 #include <sys/stat.h>
00078 #include <sys/mman.h>
00079 #include <fcntl.h>
00080 #include <unistd.h>
00081 #include <sys/time.h>
00082 #include <time.h>
00083 #include <stdio.h>
00084 #include <stdlib.h>
00085 #ifndef PyMODINIT_FUNC
00086 #define PyMODINIT_FUNC void
00087 #endif
00088 
00089 #include <string.h>
00090 #include <mpi.h>
00091 
00092 static int calls = 0;
00093 static int errs = 0;
00094 MPI_Errhandler newerr;
00095 static MPI_Comm mycomm;
00096 
00097 
00098 
00099 #ifdef MPI_VERSION
00100 #if (MPI_VERSION == 2)
00101 #define MPI2
00102 #endif
00103 #else
00104 #define MPI_VERSION 1
00105 #endif
00106 
00107 #ifndef MPI_SUBVERSION
00108 #define MPI_SUBVERSION 0
00109 #endif
00110 
00111 char cw[2160];
00112 
00113 #define com_ray_size 20
00114 MPI_Comm com_ray[com_ray_size];
00115 char errstr[256];
00116 char version[8];
00117 
00118 #ifdef MPI2
00119 int *array_of_errcodes=NULL;
00120 int array_of_errcodes_size=0;
00121 #endif
00122 
00123 MPI_Status status;
00124 int ierr;
00125 void char_func (char *ret, int retl, char *str, int slen, char *str2, int slen2, int *offset);
00126 void the_date(double *since,char* date_str);
00127 void myerror(char *s);
00128 int getptype(long mpitype);
00129 int erroron;
00130 
00131 static PyObject *mpiError;
00132 
00133 void eh( MPI_Comm *comm, int *err, ... )
00134 {
00135 char string[256];
00136 int len;
00137 
00138 /*
00139  if (*err != MPI_ERR_OTHER) {
00140  errs++;
00141  printf( "Unexpected error code\n" );fflush(stdout);
00142  }
00143  if (*comm != mycomm) {
00144  errs++;
00145  printf( "Unexpected communicator\n" );fflush(stdout);
00146  }
00147  calls++;
00148  */
00149  ierr=*err;
00150  /*
00151  MPI_Error_string(ierr, string,  &len);
00152  printf( "mpi generated the error %d %s\n",*err,string );fflush(stdout);
00153  */
00154  printf( "mpi generated the error %d\n",*err );fflush(stdout);
00155  return;
00156 }
00157 
00158 
00159 static PyObject *mpi_get_processor_name(PyObject *self, PyObject *args)
00160 {
00161 /* int MPI_Get_processor_name( char *name, int *resultlen) */
00162 char c_name[MPI_MAX_PROCESSOR_NAME];
00163 int c_len;
00164         ierr=MPI_Get_processor_name((char *)c_name,&c_len);
00165       return PyString_FromStringAndSize(c_name,c_len);
00166 }
00167 
00168 int getptype(long mpitype) {
00169         if(mpitype == (long)MPI_INT)    return(PyArray_INT);
00170         if(mpitype == (long)MPI_FLOAT)  return(PyArray_FLOAT);
00171         if(mpitype == (long)MPI_DOUBLE) return(PyArray_DOUBLE);
00172         printf("could not find type input: %ld  available: MPI_FLOAT %ld MPI_INT %ld MPI_DOUBLE %ld\n",mpitype,(long)MPI_FLOAT,(long)MPI_INT,(long)MPI_DOUBLE);
00173         return(PyArray_INT);
00174 }
00175 
00176 static PyObject *mpi_test(PyObject *self, PyObject *args)
00177 {
00178 /* int MPI_Test (MPI_Request  *request,int *flag, MPI_Status *status) */
00179         printf("this routine does not work yet\n");
00180     return NULL;
00181 }
00182 
00183 static PyObject *mpi_wait(PyObject *self, PyObject *args)
00184 {
00185 /* int MPI_Wait (MPI_Request  *request, MPI_Status *status) */
00186         printf("this routine does not work yet\n");
00187     return NULL;
00188 }
00189 static PyObject *mpi_isend(PyObject *self, PyObject *args)
00190 {
00191 /* int MPI_Isend( void *buf, int count, MPI_Datatype datatype, int dest, int tag,MPI_Comm comm, MPI_Request *request ) */
00192         printf("this routine does not work yet\n");
00193     return NULL;
00194 }
00195 static PyObject *mpi_irecv(PyObject *self, PyObject *args)
00196 {
00197 /* int MPI_Irecv( void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request ) */
00198         printf("this routine does not work yet\n");
00199     return NULL;
00200 }
00201 
00202 static PyObject *mpi_group_rank(PyObject *self, PyObject *args)
00203 {
00204 /* int MPI_Group_rank ( MPI_Group group, int *rank ) */
00205 long in_group;
00206 int rank;
00207 MPI_Group group;
00208 
00209         if (!PyArg_ParseTuple(args, "l", &in_group))
00210                 return NULL;
00211         group=(MPI_Group)in_group;
00212         ierr=MPI_Group_rank (group, &rank );
00213         return PyInt_FromLong((long)rank);
00214 }
00215 
00216 static PyObject *mpi_group_incl(PyObject *self, PyObject *args)
00217 {
00218 /* int MPI_Group_incl ( MPI_Group group, int n, int *ranks, MPI_Group *group_out ) */
00219 #ifdef DO_UNSIGED
00220 #define CAST unsigned long
00221 #define VERT_FUNC PyLong_FromUnsignedLong
00222 #else
00223 #define CAST long
00224 #define VERT_FUNC PyInt_FromLong
00225 #endif
00226 long in_group;
00227 int *ranks,n;
00228 MPI_Group group,out_group;
00229 PyObject *ranks_obj;
00230 PyArrayObject *array;
00231 
00232         if (!PyArg_ParseTuple(args, "liO", &in_group,&n,&ranks_obj))
00233         return NULL;
00234     group=(MPI_Group)in_group;
00235         array = (PyArrayObject *) PyArray_ContiguousFromObject(ranks_obj, PyArray_INT, 1, 1);
00236         if (array == NULL)
00237                 return NULL;
00238         if(array->dimensions[0] < n)
00239                 return NULL;
00240         ranks=(int*)malloc((size_t) (n*sizeof(int)));
00241         memcpy((void*)ranks,(void *)(array->data),  (size_t) (n*sizeof(int)));
00242         ierr=MPI_Group_incl ( (MPI_Group )group, n, ranks, &out_group);
00243         free(ranks);
00244         Py_DECREF(array);
00245         return VERT_FUNC((CAST)out_group);
00246 }
00247 
00248 static PyObject *mpi_comm_group(PyObject *self, PyObject *args)
00249 {
00250 /* int MPI_Comm_group ( MPI_Comm comm, MPI_Group *group ) */
00251 #ifdef DO_UNSIGED
00252 #define CAST unsigned long
00253 #define VERT_FUNC PyLong_FromUnsignedLong
00254 #else
00255 #define CAST long
00256 #define VERT_FUNC PyInt_FromLong
00257 #endif
00258 MPI_Group group;
00259 COM_TYPE comm;
00260 int ierr;
00261 
00262         if (!PyArg_ParseTuple(args, "l", &comm))
00263         return NULL;
00264     if((sizeof(MPI_Group) != sizeof(long))  &&  (sizeof(MPI_Group) != sizeof(int)))
00265         printf("can not return MPI_Group as long or int sizes %ld %ld %ld",
00266                             sizeof(MPI_Group),sizeof(long),sizeof(int));
00267     ierr=MPI_Comm_group ( (MPI_Comm) comm, &group );
00268         return VERT_FUNC((CAST)group);
00269 }
00270 
00271 static PyObject *mpi_comm_dup(PyObject *self, PyObject *args)
00272 {
00273 /* int MPI_Comm_dup ( MPI_Comm comm, MPI_Comm *comm_out ) */
00274 #ifdef DO_UNSIGED
00275 #define CAST unsigned long
00276 #define VERT_FUNC PyLong_FromUnsignedLong
00277 #else
00278 #define CAST long
00279 #define VERT_FUNC PyInt_FromLong
00280 #endif
00281 long tmpcomm;
00282 COM_TYPE  incomm,outcomm;
00283 
00284         if (!PyArg_ParseTuple(args, "l", &tmpcomm))
00285         return NULL;
00286     incomm=(COM_TYPE)tmpcomm;
00287         ierr=MPI_Comm_dup ((MPI_Comm)incomm,(MPI_Comm*)&outcomm );
00288         return VERT_FUNC((CAST)outcomm);
00289 }
00290 
00291 
00292 static PyObject *mpi_comm_set_errhandler(PyObject *self, PyObject *args)
00293 {
00294 /* int MPI_Comm_dup ( MPI_Comm comm, MPI_Comm *comm_out ) */
00295 #ifdef DO_UNSIGED
00296 #define CAST unsigned long
00297 #define VERT_FUNC PyLong_FromUnsignedLong
00298 #else
00299 #define CAST long
00300 #define VERT_FUNC PyInt_FromLong
00301 #endif
00302 long tmpcomm;
00303 COM_TYPE  incomm;
00304 int choice;
00305 
00306         if (!PyArg_ParseTuple(args, "li", &tmpcomm,&choice))
00307         return NULL;
00308     incomm=(COM_TYPE)tmpcomm;
00309     if(choice == 0)
00310                 ierr= MPI_Comm_set_errhandler( (MPI_Comm)incomm, MPI_ERRORS_ARE_FATAL );
00311     if(choice == 1)
00312                 ierr= MPI_Comm_set_errhandler( (MPI_Comm)incomm, MPI_ERRORS_RETURN );
00313     if(choice == 2)
00314                 ierr= MPI_Comm_set_errhandler( (MPI_Comm)incomm, newerr );
00315 
00316         return PyInt_FromLong((long)ierr);
00317 }
00318 
00319 
00320 
00321 
00322 static PyObject *mpi_comm_create(PyObject *self, PyObject *args)
00323 {
00324 /* int MPI_Comm_create ( MPI_Comm comm, MPI_Group group, MPI_Comm *comm_out ) */
00325 #ifdef DO_UNSIGED
00326 #define CAST unsigned long
00327 #define VERT_FUNC PyLong_FromUnsignedLong
00328 #else
00329 #define CAST long
00330 #define VERT_FUNC PyInt_FromLong
00331 #endif
00332 COM_TYPE  incomm,outcomm;
00333 long group;
00334 
00335         if (!PyArg_ParseTuple(args, "ll", &incomm,&group))
00336         return NULL;
00337         ierr=MPI_Comm_create ((MPI_Comm)incomm,(MPI_Group)group,(MPI_Comm*)&outcomm );
00338         return VERT_FUNC((CAST)outcomm);
00339 }
00340 
00341 
00342 static PyObject *mpi_barrier(PyObject *self, PyObject *args)
00343 {
00344 /* int MPI_Barrier ( MPI_Comm comm ) */
00345 COM_TYPE comm;
00346 int ierr;
00347 
00348         if (!PyArg_ParseTuple(args, "l", &comm))
00349         return NULL;
00350     ierr=MPI_Barrier((MPI_Comm)comm );
00351         return PyInt_FromLong((long)ierr);
00352 }
00353 static PyObject *mpi_send(PyObject *self, PyObject *args)
00354 {
00355 /* int MPI_Send( void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm ) */
00356 int count,dest,tag;
00357 DATA_TYPE datatype;
00358 COM_TYPE comm;
00359 int i,n;
00360 PyObject *input;
00361 PyArrayObject *array;
00362 char *aptr;
00363 
00364         if (!PyArg_ParseTuple(args, "Oiliil", &input, &count,&datatype,&dest,&tag,&comm))
00365         return NULL;
00366         array = (PyArrayObject *) PyArray_ContiguousFromObject(input, getptype(datatype), 0, 3);
00367         if (array == NULL)
00368                 return NULL;
00369 /*
00370         n=1;
00371         for(i=0;i<array->nd;i++)
00372                 n = n* array->dimensions[i];
00373         if(array->nd == 0)n=1;
00374         if (n < count)
00375                 return NULL;
00376 */
00377         aptr=(char*)(array->data);
00378     ierr=MPI_Send(aptr,  count,  (MPI_Datatype)datatype,  dest,  tag,  (MPI_Comm)comm );
00379     Py_DECREF(array);
00380         return PyInt_FromLong((long)ierr);
00381 }
00382 
00383 
00384 static PyObject *mpi_recv(PyObject *self, PyObject *args)
00385 {
00386 /* int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status ) */
00387 int count,source,tag;
00388 DATA_TYPE datatype;
00389 COM_TYPE comm;
00390 PyArrayObject *result;
00391 int dimensions[1];
00392 char *aptr;
00393 
00394         if (!PyArg_ParseTuple(args, "iliil", &count,&datatype,&source,&tag,&comm))
00395         return NULL;
00396     dimensions[0]=count;
00397     result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(datatype));
00398         aptr=(char*)(result->data);
00399         ierr=MPI_Recv( aptr,  count, (MPI_Datatype)datatype,source,tag, (MPI_Comm)comm, &status );
00400         return PyArray_Return(result);
00401 }
00402 
00403 static PyObject *mpi_status(PyObject *self, PyObject *args)
00404 {
00405 /* int MPI_Recv( void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status ) */
00406 PyArrayObject *result;
00407 int dimensions[1],statray[3];
00408 
00409     dimensions[0]=3;
00410     result = (PyArrayObject *)PyArray_FromDims(1, dimensions, PyArray_INT);
00411         statray[0]=status.MPI_SOURCE;
00412         statray[1]=status.MPI_TAG;
00413         statray[2]=status.MPI_ERROR;
00414         memcpy((void *)(result->data), (void*)statray, (size_t) (12));
00415         return PyArray_Return(result);
00416 }
00417 
00418 static PyObject *mpi_error(PyObject *self, PyObject *args)
00419 {
00420         return PyInt_FromLong((long)ierr);
00421 }
00422 
00423 
00424 static PyObject * mpi_wtime(PyObject *self, PyObject *args) {
00425 
00426         return( PyFloat_FromDouble(MPI_Wtime()));
00427 }
00428 
00429 static PyObject * mpi_wtick(PyObject *self, PyObject *args) {
00430 
00431         return( PyFloat_FromDouble(MPI_Wtick()));
00432 }
00433 
00434 static PyObject * mpi_attr_get(PyObject *self, PyObject *args) {
00435 /*
00436   int MPI_Attr_get ( MPI_Comm comm,int keyval,void *attr_value,int *flag)
00437 Input Parameters
00438         comm    communicator to which attribute is attached (handle)
00439         keyval  key value (integer)
00440 
00441 Output Parameters
00442         attr_value      attribute value, unless flag = false
00443         flag    true if an attribute value was extracted; false if no attribute is associated with the key
00444 */
00445 
00446         int keyval, *attr_value;
00447         int flag;
00448         COM_TYPE comm;
00449         if (!PyArg_ParseTuple(args, "li", &comm, &keyval))
00450         return NULL;
00451 
00452 /*        printf("mpi_attr_get:  keyval:%d\n",keyval); */
00453 
00454         /* get the keyval for the specified attribute */
00455         ierr = MPI_Attr_get((MPI_Comm)comm, keyval, &attr_value,&flag);
00456         if ( !flag ) {
00457                 return NULL;
00458         }
00459 
00460 /*        printf("mpi_attr_get:  attr_val: %d  %d\n",*attr_value,flag); */
00461         return( PyInt_FromLong((long)*attr_value));
00462 }
00463 
00464 #ifdef MPI2
00465 static PyObject *mpi_array_of_errcodes(PyObject *self, PyObject *args)
00466 {
00467         int dimensions[1];
00468         if(array_of_errcodes){
00469         dimensions[0]=array_of_errcodes_size;
00470         return(PyArray_FromDimsAndData(1,
00471                         dimensions,
00472                         PyArray_INT,
00473                         (char *)array_of_errcodes));
00474         }
00475         else {
00476         dimensions[0]=0;
00477         return(PyArray_FromDimsAndData(1,
00478                         dimensions,
00479                         PyArray_INT,
00480                         (char *)dimensions));
00481     }
00482 
00483 }
00484 
00485 static PyObject *mpi_intercomm_merge(PyObject *self, PyObject *args)
00486 {
00487 /* int MPI_Intercomm_merge ( MPI_Comm comm, int high, MPI_Comm *comm_out ) */
00488 #ifdef DO_UNSIGED
00489 #define CAST unsigned long
00490 #define VERT_FUNC PyLong_FromUnsignedLong
00491 #else
00492 #define CAST long
00493 #define VERT_FUNC PyInt_FromLong
00494 #endif
00495 COM_TYPE  incomm,outcomm;
00496 int high;
00497 
00498         if (!PyArg_ParseTuple(args, "li", &incomm,&high))
00499         return NULL;
00500         ierr=MPI_Intercomm_merge ((MPI_Comm)incomm,high,(MPI_Comm*)&outcomm );
00501         return VERT_FUNC((CAST)outcomm);
00502 }
00503 static PyObject *mpi_comm_free(PyObject *self, PyObject *args)
00504 {
00505 /* int MPI_Comm_free ( MPI_Comm *comm) */
00506 #ifdef DO_UNSIGED
00507 #define CAST unsigned long
00508 #define VERT_FUNC PyLong_FromUnsignedLong
00509 #else
00510 #define CAST long
00511 #define VERT_FUNC PyInt_FromLong
00512 #endif
00513 COM_TYPE  incomm;
00514 
00515 
00516         if (!PyArg_ParseTuple(args, "l", &incomm))
00517         return NULL;
00518         ierr=MPI_Comm_free ((MPI_Comm*)&incomm);
00519         return VERT_FUNC((CAST)ierr);
00520 }
00521 
00522 static PyObject *mpi_comm_spawn(PyObject *self, PyObject *args)
00523 {
00524 /* int MPI_Comm_spawn(char *command, char *argv[], int maxprocs, MPI_Info info,
00525                   int root, MPI_Comm comm, MPI_Comm *intercomm,
00526                   int array_of_errcodes[])                    */
00527 #ifdef DO_UNSIGED
00528 #define CAST unsigned long
00529 #define VERT_FUNC PyLong_FromUnsignedLong
00530 #else
00531 #define CAST long
00532 #define VERT_FUNC PyInt_FromLong
00533 #endif
00534 int maxprocs,info,root,comm;
00535 MPI_Comm  outcomm;
00536 char *command;
00537 PyObject *input;
00538 int n,len,i;
00539 char **argv;
00540 
00541 
00542 if (!PyArg_ParseTuple(args, "sOiiii", &command,&input,&maxprocs,&info,&root,&comm))
00543         return NULL;
00544         argv=MPI_ARGV_NULL;
00545         if((input == NULL )|| (input == Py_None )){
00546                 /* printf("is none\n"); */
00547         }
00548         if(strncmp("int",input->ob_type->tp_name,3)==0){
00549                 /* printf("is int\n"); */
00550         }
00551         if(strncmp("str",input->ob_type->tp_name,3)==0){
00552                 /* printf("is str\n"); */
00553                 argv=(char**)malloc((maxprocs+2)*sizeof(char*));
00554                 for(i=0;i<maxprocs+2;i++) {
00555                         argv[i]=(char*)0;
00556                 }
00557                 n=maxprocs;
00558                 if(n > 0){
00559                         for(i=0;i<n;i++) {
00560                                 len=strlen(PyString_AsString(input));
00561                                 argv[i]=(char*)malloc(len+1);
00562                                 argv[i][len]=(char)0;
00563                                 strncpy(argv[i],PyString_AsString(input),(size_t)len);
00564                                 /* printf("%s\n",argv[i]); */
00565                         }
00566                 }
00567         }
00568 
00569         if(strncmp("list",input->ob_type->tp_name,4)==0){
00570                 printf("is list\n");
00571                 argv=(char**)malloc((maxprocs+2)*sizeof(char*));
00572                 for(i=0;i<maxprocs+2;i++) {
00573                         argv[i]=(char*)0;
00574                 }
00575                 n=PyList_Size(input);
00576                 if(n > 0){
00577                         for(i=0;i<n;i++) {
00578                                 len=strlen(PyString_AsString(PyList_GetItem(input,i)));
00579                                 argv[i]=(char*)malloc(len+1);
00580                                 argv[i][len]=(char)0;
00581                                 strncpy(argv[i],PyString_AsString(PyList_GetItem(input,i)),(size_t)len);
00582                                 printf("%s\n",argv[i]);
00583                         }
00584                 }
00585         }
00586 
00587         if(array_of_errcodes)free(array_of_errcodes);
00588         array_of_errcodes=(int*)malloc(maxprocs*sizeof(int));
00589         array_of_errcodes_size=maxprocs;
00590 
00591 /* int MPI_Comm_spawn(char *command, char *argv[], int maxprocs, MPI_Info info,
00592                   int root, MPI_Comm comm, MPI_Comm *intercomm,
00593                   int array_of_errcodes[])                    */
00594 /*      printf("launching %s from %d\n",command,root); */
00595         ierr=MPI_Comm_spawn(command,
00596                             argv,
00597                             maxprocs,
00598                             (MPI_Info)info,
00599                             root,
00600                             (MPI_Comm)comm,
00601                             &outcomm,
00602                             array_of_errcodes);
00603 
00604 
00605 if(argv != MPI_ARGV_NULL){
00606                 n=maxprocs+2;
00607                 for(i=0;i<n;i++) {
00608                         if(argv[i])free(argv[i]);
00609                 }
00610                 free(argv);
00611                 }
00612 
00613 return VERT_FUNC((CAST)outcomm);
00614 }
00615 
00616 static PyObject *mpi_comm_get_parent(PyObject *self, PyObject *args)
00617 {
00618 /* int MPI_Comm_get_parent(MPI_Comm *parent)*/
00619 #ifdef DO_UNSIGED
00620 #define CAST unsigned long
00621 #define VERT_FUNC PyLong_FromUnsignedLong
00622 #else
00623 #define CAST long
00624 #define VERT_FUNC PyInt_FromLong
00625 #endif
00626 COM_TYPE  outcomm;
00627 ierr=MPI_Comm_get_parent((MPI_Comm*)&outcomm);
00628 return VERT_FUNC((CAST)outcomm);
00629 }
00630 
00631 static PyObject *mpi_open_port(PyObject *self, PyObject *args)
00632 {
00633 /* int MPI_Open_port ( MPI_Info info, char *port_name) */
00634 #ifdef DO_UNSIGED
00635 #define CAST unsigned long
00636 #define VERT_FUNC PyLong_FromUnsignedLong
00637 #else
00638 #define CAST long
00639 #define VERT_FUNC PyInt_FromLong
00640 #endif
00641 char  port_name[MPI_MAX_PORT_NAME];
00642 int info;
00643         if (!PyArg_ParseTuple(args, "i", &info))
00644         return NULL;
00645         ierr=MPI_Open_port(info,port_name);
00646         return PyString_FromString(port_name);
00647 }
00648 
00649 static PyObject *mpi_close_port(PyObject *self, PyObject *args)
00650 {
00651 /* int MPI_Close_port ( char *port_name) */
00652 #ifdef DO_UNSIGED
00653 #define CAST unsigned long
00654 #define VERT_FUNC PyLong_FromUnsignedLong
00655 #else
00656 #define CAST long
00657 #define VERT_FUNC PyInt_FromLong
00658 #endif
00659 char  *port_name;
00660         if (!PyArg_ParseTuple(args, "s", &port_name))
00661         return NULL;
00662         ierr=MPI_Close_port(port_name);
00663         return VERT_FUNC((CAST)ierr);
00664 }
00665 
00666 static PyObject *mpi_comm_accept(PyObject *self, PyObject *args)
00667 {
00668 /* int MPI_Comm_accept(char* port_name, MPI_info info,int root, MPI_Comm comm, MPI_Comm *newcomm)*/
00669 #ifdef DO_UNSIGED
00670 #define CAST unsigned long
00671 #define VERT_FUNC PyLong_FromUnsignedLong
00672 #else
00673 #define CAST long
00674 #define VERT_FUNC PyInt_FromLong
00675 #endif
00676 COM_TYPE  comm,newcomm;
00677 char* port_name;
00678 int info,root;
00679         if (!PyArg_ParseTuple(args, "siii", &port_name,&info,&root,&comm))
00680         return NULL;
00681         ierr=MPI_Comm_accept(port_name,  info, root,  comm,  (MPI_Comm*)&newcomm);
00682         return VERT_FUNC((CAST)newcomm);
00683 }
00684 static PyObject *mpi_comm_connect(PyObject *self, PyObject *args)
00685 {
00686 /* int MPI_Comm_connect(char* port_name, MPI_info info,int root, MPI_Comm comm, MPI_Comm *newcomm)*/
00687 #ifdef DO_UNSIGED
00688 #define CAST unsigned long
00689 #define VERT_FUNC PyLong_FromUnsignedLong
00690 #else
00691 #define CAST long
00692 #define VERT_FUNC PyInt_FromLong
00693 #endif
00694 COM_TYPE  comm,newcomm;
00695 char* port_name;
00696 int info,root;
00697         if (!PyArg_ParseTuple(args, "siii", &port_name,&info,&root,&comm))
00698         return NULL;
00699         ierr=MPI_Comm_connect(port_name,  info, root,  comm,  (MPI_Comm*)&newcomm);
00700         return VERT_FUNC((CAST)newcomm);
00701 }
00702 static PyObject *mpi_comm_disconnect(PyObject *self, PyObject *args)
00703 {
00704 /* int MPI_Comm_disconnect(MPI_Comm *comm)*/
00705 #ifdef DO_UNSIGED
00706 #define CAST unsigned long
00707 #define VERT_FUNC PyLong_FromUnsignedLong
00708 #else
00709 #define CAST long
00710 #define VERT_FUNC PyInt_FromLong
00711 #endif
00712 COM_TYPE  comm;
00713         if (!PyArg_ParseTuple(args, "i", &comm))
00714         return NULL;
00715         ierr=MPI_Comm_disconnect((MPI_Comm*)&comm);
00716         return VERT_FUNC((CAST)ierr);
00717 }
00718 
00719 #endif
00720 
00721 static PyObject *mpi_comm_split(PyObject *self, PyObject *args)
00722 {
00723 /* int MPI_Comm_split ( MPI_Comm comm, int color, int key, MPI_Comm *comm_out ) */
00724 #ifdef DO_UNSIGED
00725 #define CAST unsigned long
00726 #define VERT_FUNC PyLong_FromUnsignedLong
00727 #else
00728 #define CAST long
00729 #define VERT_FUNC PyInt_FromLong
00730 #endif
00731 int color,key;
00732 COM_TYPE  incomm,outcomm;
00733 
00734         if (!PyArg_ParseTuple(args, "lii", &incomm,&color,&key))
00735         return NULL;
00736         ierr=MPI_Comm_split ((MPI_Comm)incomm,color,key,(MPI_Comm*)&outcomm );
00737         return VERT_FUNC((CAST)outcomm);
00738 }
00739 
00740 static PyObject *mpi_probe(PyObject *self, PyObject *args)
00741 {
00742 /* int MPI_Probe( int source, int tag, MPI_Comm comm, MPI_Status *status ) */
00743 int source,tag;
00744 COM_TYPE comm;
00745 
00746         if (!PyArg_ParseTuple(args, "iil", &source,&tag,&comm))
00747         return NULL;
00748     ierr=MPI_Probe(source,tag, (MPI_Comm )comm, &status );
00749         return PyInt_FromLong((long)0);
00750 }
00751 
00752 static PyObject *mpi_get_count(PyObject *self, PyObject *args)
00753 {
00754 /* int MPI_Get_count( MPI_Status *status, MPI_Datatype datatype, int *count ) */
00755 DATA_TYPE datatype;
00756 int count;
00757 
00758         if (!PyArg_ParseTuple(args, "l",&datatype))
00759         return NULL;
00760     ierr=MPI_Get_count(&status,(MPI_Datatype)datatype,&count);
00761         return PyInt_FromLong((long)count);
00762 }
00763 
00764 
00765 static PyObject *mpi_comm_size(PyObject *self, PyObject *args)
00766 {
00767 /* int MPI_Probe( int source, int tag, MPI_Comm comm, MPI_Status *status ) */
00768 COM_TYPE comm;
00769 int numprocs;
00770 
00771         if (!PyArg_ParseTuple(args, "l",&comm))
00772         return NULL;
00773         ierr=MPI_Comm_size((MPI_Comm)comm,&numprocs);
00774         return PyInt_FromLong((long)numprocs);
00775 }
00776 
00777 static PyObject *mpi_comm_rank(PyObject *self, PyObject *args)
00778 {
00779 /* int MPI_Probe( int source, int tag, MPI_Comm comm, MPI_Status *status ) */
00780 COM_TYPE comm;
00781 int rank;
00782 
00783         if (!PyArg_ParseTuple(args, "l",&comm))
00784         return NULL;
00785         ierr=MPI_Comm_rank((MPI_Comm)comm,&rank);
00786         return PyInt_FromLong((long)rank);
00787 }
00788 
00789 
00790 static PyObject *mpi_iprobe(PyObject *self, PyObject *args)
00791 {
00792 /* int MPI_Iprobe( int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status ) */
00793 int source,tag,flag;
00794 COM_TYPE comm;
00795 
00796         if (!PyArg_ParseTuple(args, "iil", &source,&tag,&comm))
00797         return NULL;
00798     ierr=MPI_Iprobe(source,tag, (MPI_Comm )comm, &flag,&status );
00799         return PyInt_FromLong((long)flag);
00800 }
00801 
00802 static PyObject * mpi_init(PyObject *self, PyObject *args) {
00803         PyObject *input;
00804         int argc,i,n;
00805         int did_it;
00806         char **argv;
00807 #ifdef ARG_STR
00808         char *argstr;
00809         int *strides;
00810         int arglen;
00811 #endif
00812 #ifdef SIZE_RANK
00813         PyArrayObject *result;
00814         int dimensions[1],data[2];
00815         char *aptr;
00816 #endif
00817 #ifdef ARG_ARRAY
00818         PyObject *result;
00819 #endif
00820     int myid;
00821         int len;
00822         argv=NULL;
00823         erroron=0;
00824         ierr=MPI_Initialized(&did_it);
00825         if(!did_it){
00826                 if (!PyArg_ParseTuple(args, "iO", &argc, &input))
00827                         return NULL;
00828                 argv=(char**)malloc((argc+2)*sizeof(char*));
00829                 n=PyList_Size(input);
00830                 for(i=0;i<n;i++) {
00831                         len=strlen(PyString_AsString(PyList_GetItem(input,i)));
00832                         argv[i]=(char*)malloc(len+1);
00833                         argv[i][len]=(char)0;
00834                         strncpy(argv[i],PyString_AsString(PyList_GetItem(input,i)),(size_t)len);
00835                         /* printf("%s ",argv[i]); */
00836                 }
00837 
00838                 /* printf("\n"); */
00839                 Py_DECREF(input);
00840 #ifdef LAM_MPI
00841                 ierr=MPI_Init(NULL,NULL);
00842 #else
00843                 ierr=MPI_Init(&argc,&argv);
00844                 ierr=MPI_Comm_rank(MPI_COMM_WORLD,&myid);
00845 
00846 /*
00847 for(i=0;i<argc;i++) {
00848                    printf("from %d init %d %s\n",myid,i,argv[i]);
00849 
00850                 }
00851 */
00852 #endif
00853 
00854 #ifdef MPI2
00855                 MPI_Comm_create_errhandler( eh, &newerr );
00856 #endif
00857 
00858 /*              free(argv); */
00859         }
00860 
00861 /*  this returns the command line as a string */
00862 #ifdef ARG_STR
00863                 arglen=0;
00864                 strides=(int*)malloc(argc*sizeof(int));
00865                 strides[0]=0;
00866                 for(i=0;i<argc;i++) {
00867                         arglen=arglen+strlen(argv[i])+1;
00868                         strides[i+1]=strides[i]+strlen(argv[i])+1;
00869                 }
00870                 argstr=(char*)malloc(arglen*sizeof(char));
00871                 for(i=0;i<argc;i++) {
00872                     for(n=0;n<strlen(argv[i]);n++) {
00873                         argstr[strides[i]+n]=argv[i][n];
00874                     }
00875                     argstr[strides[i]+strlen(argv[i])]=(char)32;
00876 /*
00877                         free(argv[i]);
00878 */
00879                 }
00880                 return PyString_FromString(argstr);
00881 #endif
00882 #ifdef ARG_ARRAY
00883                 result = PyTuple_New(argc);
00884                 for(i=0;i<argc;i++) {
00885                         PyTuple_SetItem(result,i,PyString_FromString(argv[i]));
00886                 }
00887 /*
00888 for(i=0;i<argc;i++) {
00889                         free(argv[i]);
00890                 }
00891 */
00892                 return result;
00893 #endif
00894 /*  this returns size and rank */
00895 #ifdef SIZE_RANK
00896     ierr=MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
00897     ierr=MPI_Comm_rank(MPI_COMM_WORLD,&myid);
00898         dimensions[0]=2;
00899         result = (PyArrayObject *)PyArray_FromDims(1, dimensions, PyArray_INT);
00900         if (result == NULL)
00901                 return NULL;
00902         data[0]=myid;
00903         data[1]=numprocs;
00904         aptr=(char*)&(data);
00905         for(i=0;i<8;i++)
00906                 result->data[i]=aptr[i];
00907         if(erroron){ erroron=0; return NULL;}
00908         return PyArray_Return(result);
00909 #endif
00910 }
00911 
00912 static PyObject * mpi_start(PyObject *self, PyObject *args) {
00913         PyArrayObject *result;
00914         int argc,did_it,i;
00915         int dimensions[1],data[2];
00916         int numprocs,myid;
00917         char *command,*aptr;
00918         char **argv;
00919         erroron=0;
00920         if (!PyArg_ParseTuple(args, "is", &argc, &command))
00921         return NULL;
00922         ierr=MPI_Initialized(&did_it);
00923     if(!did_it){
00924                 /* MPI_Init(0,0); */ /* lam mpi will start with this line
00925                                         mpich requires us to build a real
00926                                         command line */
00927                 /* MPI_Init(0,0); */
00928                 argv=(char**)malloc((argc+2)*sizeof(char*));
00929                 argv[0]=(char*)malloc(128);
00930                 sprintf(argv[0],"dummy");
00931                 strtok(command, " ");
00932                 for(i=0;i<argc-1;i++) {
00933                                 argv[i+1]=strtok(NULL, " ");
00934                 }
00935                 printf("calling mpi init from mpi_start\n");
00936                 for (i=0;i<argc;i++)
00937                         printf("%d %d %s\n",i,(int)strlen(argv[i]),argv[i]);
00938 #ifdef LAM_MPI
00939                 ierr=MPI_Init(NULL,NULL);
00940 #else
00941                 ierr=MPI_Init(&argc,&argv);
00942 #endif
00943         }
00944         ierr=MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
00945     ierr=MPI_Comm_rank(MPI_COMM_WORLD,&myid);
00946 #ifdef MPI2
00947                 MPI_Comm_create_errhandler( eh, &newerr );
00948 #endif
00949 
00950 
00951         dimensions[0]=2;
00952         result = (PyArrayObject *)PyArray_FromDims(1, dimensions, PyArray_INT);
00953         if (result == NULL)
00954                 return NULL;
00955         data[0]=myid;
00956         data[1]=numprocs;
00957         aptr=(char*)&(data);
00958         for(i=0;i<8;i++)
00959                 result->data[i]=aptr[i];
00960         if(erroron){ erroron=0; return NULL;}
00961         return PyArray_Return(result);
00962 }
00963 
00964 static PyObject * mpi_bcast(PyObject *self, PyObject *args) {
00965 /* int MPI_Bcast ( void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm ) */
00966 int count,root;
00967 DATA_TYPE datatype;
00968 COM_TYPE comm;
00969 int myid;
00970 int mysize;
00971 PyArrayObject *result;
00972 PyArrayObject *array;
00973 PyObject *input;
00974 int dimensions[1];
00975 char *aptr;
00976 
00977         if (!PyArg_ParseTuple(args, "Oilil", &input, &count,&datatype,&root,&comm))
00978         return NULL;
00979     dimensions[0]=count;
00980     result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(datatype));
00981         aptr=(char*)(result->data);
00982     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
00983 #ifdef MPI2
00984     if(myid == root || root == MPI_ROOT) {
00985 #else
00986     if(myid == root) {
00987 #endif
00988                 array = (PyArrayObject *) PyArray_ContiguousFromObject(input, getptype(datatype), 0, 3);
00989                 if (array == NULL)
00990                         return NULL;
00991                 ierr=MPI_Type_size((MPI_Datatype)datatype,&mysize);
00992                 memcpy((void *)(result->data), (void*)array->data, (size_t) (mysize*count));
00993                 Py_DECREF(array);
00994         }
00995         ierr=MPI_Bcast(aptr,count,(MPI_Datatype)datatype,root,(MPI_Comm)comm);
00996         return PyArray_Return(result);
00997 }
00998 
00999 
01000 static PyObject * mpi_scatterv(PyObject *self, PyObject *args) {
01001 /* int MPI_Scatterv(void *sendbuf, int *sendcnts, int *displs, MPI_Datatype sendtype,
01002                     void *recvbuf, int recvcnt,                MPI_Datatype recvtype,
01003                     int root, MPI_Comm comm ) */
01004 int root;
01005 COM_TYPE comm;
01006 DATA_TYPE sendtype,recvtype;
01007 PyObject *sendbuf_obj, *sendcnts_obj,*displs_obj;
01008 PyArrayObject *array,*result;
01009 int *sendcnts,*displs,recvcnt;
01010 char *sptr,*rptr;
01011 int *sray;
01012 int numprocs,myid;
01013 int dimensions[1];
01014 
01015         sendcnts=0;
01016         displs=0;
01017 
01018         array=NULL;
01019         sptr=NULL;
01020 
01021         if (!PyArg_ParseTuple(args, "OOOlilil", &sendbuf_obj, &sendcnts_obj,&displs_obj,&sendtype,&recvcnt,&recvtype,&root,&comm))
01022         return NULL;
01023     /* ! get the number of processors in this comm */
01024     ierr=MPI_Comm_size((MPI_Comm)comm,&numprocs);
01025     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01026 
01027 
01028 #ifdef MPI2
01029     if(myid == root || root == MPI_ROOT) {
01030 #else
01031     if(myid == root) {
01032 #endif
01033                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sendcnts_obj, PyArray_INT, 1, 1);
01034                 if (array == NULL)
01035                         return NULL;
01036                 sendcnts=(int*)malloc((size_t) (sizeof(int)*numprocs));
01037                 memcpy((void *)sendcnts, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01038                 Py_DECREF(array);
01039                 array = (PyArrayObject *) PyArray_ContiguousFromObject(displs_obj, PyArray_INT, 1, 1);
01040                 if (array == NULL)
01041                         return NULL;
01042                 displs=(int*)malloc((size_t) (sizeof(int)*numprocs));
01043                 memcpy((void *)displs, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01044                 Py_DECREF(array);
01045                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sendbuf_obj, getptype(sendtype), 1, 3);
01046                 if (array == NULL)
01047                         return NULL;
01048                 sptr=(char*)(array->data);
01049         }
01050 
01051     dimensions[0]=recvcnt;
01052     result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(recvtype));
01053     rptr=(char*)(result->data);
01054 
01055         ierr=MPI_Scatterv(sptr, sendcnts, displs, (MPI_Datatype)sendtype,rptr,recvcnt,(MPI_Datatype)recvtype, root, (MPI_Comm )comm );
01056     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01057 #ifdef MPI2
01058     if(myid == root || root == MPI_ROOT) {
01059 #else
01060     if(myid == root) {
01061 #endif
01062                 Py_DECREF(array);
01063                 free(sendcnts);
01064                 free(displs);
01065         }
01066         return PyArray_Return(result);
01067 }
01068 
01069 static PyObject * mpi_gatherv(PyObject *self, PyObject *args) {
01070 /*
01071 int MPI_Gatherv ( void *sendbuf, int sendcnt,                MPI_Datatype sendtype,
01072                   void *recvbuf, int *recvcnts, int *displs, MPI_Datatype recvtype,
01073                   int root, MPI_Comm comm )
01074  */
01075 int root;
01076 COM_TYPE comm;
01077 DATA_TYPE sendtype,recvtype;
01078 PyObject *sendbuf_obj, *recvcnts_obj,*displs_obj;
01079 PyArrayObject *array,*result;
01080 int sendcnt,*displs,*recvcnts,rtot,i;
01081 char *sptr,*rptr;
01082 int numprocs,myid;
01083 int dimensions[1];
01084 
01085         displs=0;
01086 
01087         array=NULL;
01088         sptr=NULL;
01089 
01090         if (!PyArg_ParseTuple(args, "OilOOlil", &sendbuf_obj, &sendcnt,&sendtype,&recvcnts_obj,&displs_obj,&recvtype,&root,&comm))
01091         return NULL;
01092     /* ! get the number of processors in this comm */
01093     ierr=MPI_Comm_size((MPI_Comm)comm,&numprocs);
01094     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01095     rtot=0;
01096     recvcnts=0;
01097     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01098 #ifdef MPI2
01099     if(myid == root || root == MPI_ROOT) {
01100 #else
01101     if(myid == root) {
01102 #endif
01103     /* printf("  get the recv_counts array \n"); */
01104                 array = (PyArrayObject *) PyArray_ContiguousFromObject(recvcnts_obj, PyArray_INT, 1, 1);
01105                 if (array == NULL)
01106                         return NULL;
01107                 recvcnts=(int*)malloc((size_t) (sizeof(int)*numprocs));
01108                 memcpy((void *)recvcnts, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01109                 rtot=0;
01110                 for(i=0;i<numprocs;i++)
01111                         rtot=rtot+recvcnts[i];
01112                 Py_DECREF(array);
01113     /* printf("  get the offset array \n"); */
01114                 array = (PyArrayObject *) PyArray_ContiguousFromObject(displs_obj, PyArray_INT, 1, 1);
01115                 if (array == NULL)
01116                         return NULL;
01117                 displs=(int*)malloc((size_t) (sizeof(int)*numprocs));
01118                 memcpy((void *)displs, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01119                 Py_DECREF(array);
01120         }
01121         /* printf("  allocate the recvbuf \n"); */
01122                 dimensions[0]=rtot;
01123                 result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(recvtype));
01124                 rptr=(char*)(result->data);
01125    /* printf("  get sendbuf\n"); */
01126                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sendbuf_obj, getptype(sendtype), 1, 3);
01127                 if (array == NULL)
01128                         return NULL;
01129                 sptr=array->data;
01130 
01131 
01132    /* printf("   do the call %d \n",recvcnt); */
01133         ierr=MPI_Gatherv(sptr, sendcnt, (MPI_Datatype)sendtype,rptr,recvcnts,displs,(MPI_Datatype)recvtype, root, (MPI_Comm )comm );
01134     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01135 #ifdef MPI2
01136     if(myid == root || root == MPI_ROOT) {
01137 #else
01138     if(myid == root) {
01139 #endif
01140                 Py_DECREF(array);
01141                 free(recvcnts);
01142                 free(displs);
01143         }
01144    /* printf("   did the call  %d \n",myid); */
01145         return PyArray_Return(result);
01146 }
01147 
01148 static PyObject * mpi_gather(PyObject *self, PyObject *args) {
01149 /*
01150 int MPI_Gather ( void *sendbuf, int sendcnt, MPI_Datatype sendtype,
01151                   void *recvbuf, int recvcnts,
01152                   MPI_Datatype recvtype,
01153                   int root, MPI_Comm comm )
01154  */
01155 int root;
01156 COM_TYPE comm;
01157 DATA_TYPE sendtype,recvtype;
01158 PyObject *sendbuf_obj;
01159 PyArrayObject *array,*result;
01160 int sendcnt,recvcnt,rtot;
01161 char *sptr,*rptr;
01162 int numprocs,myid;
01163 int dimensions[1];
01164 
01165         array=NULL;
01166         sptr=NULL;
01167 
01168         if (!PyArg_ParseTuple(args, "Oililil", &sendbuf_obj, &sendcnt,&sendtype,&recvcnt,&recvtype,&root,&comm))
01169         return NULL;
01170     /* ! get the number of processors in this comm */
01171     ierr=MPI_Comm_size((MPI_Comm)comm,&numprocs);
01172     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01173     rtot=0;
01174    /* printf("  get sendbuf\n"); */
01175         array = (PyArrayObject *) PyArray_ContiguousFromObject(sendbuf_obj, getptype(sendtype), 0, 3);
01176         if (array == NULL)
01177                 return NULL;
01178         sptr=array->data;
01179     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01180 #ifdef MPI2
01181     if(myid == root || root == MPI_ROOT) {
01182 #else
01183     if(myid == root) {
01184 #endif
01185                 rtot=recvcnt*numprocs;
01186     }
01187         /* printf("  allocate the recvbuf \n"); */
01188         dimensions[0]=rtot;
01189         result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(recvtype));
01190         rptr=(char*)(result->data);
01191 
01192 
01193    /* printf("   do the call %d \n",recvcnt); */
01194         ierr=MPI_Gather(sptr, sendcnt, (MPI_Datatype)sendtype,rptr,recvcnt,(MPI_Datatype)recvtype, root, (MPI_Comm )comm );
01195         Py_DECREF(array);
01196    /* printf("   did the call  %d \n",myid); */
01197         return PyArray_Return(result);
01198 }
01199 
01200 static PyObject * mpi_scatter(PyObject *self, PyObject *args) {
01201 /*
01202   int MPI_Scatter ( void *sendbuf, int sendcnt, MPI_Datatype sendtype,
01203                     void *recvbuf, int recvcnt, MPI_Datatype recvtype,
01204                     int root, MPI_Comm comm )
01205 */
01206 int root;
01207 COM_TYPE comm;
01208 DATA_TYPE sendtype,recvtype;
01209 PyObject *sendbuf_obj;
01210 PyArrayObject *array,*result;
01211 int sendcnts,recvcnt;
01212 int numprocs,myid;
01213 int dimensions[1];
01214 char *sptr,*rptr;
01215 
01216         sendcnts=0;
01217 
01218         array=NULL;
01219         sptr=NULL;
01220 
01221         if (!PyArg_ParseTuple(args, "Oililil", &sendbuf_obj, &sendcnts,&sendtype,&recvcnt,&recvtype,&root,&comm))
01222         return NULL;
01223     /* ! get the number of processors in this comm */
01224     ierr=MPI_Comm_size((MPI_Comm)comm,&numprocs);
01225     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01226 
01227 #ifdef MPI2
01228     if(myid == root || root == MPI_ROOT) {
01229 #else
01230     if(myid == root) {
01231 #endif
01232     /* get sendbuf */
01233                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sendbuf_obj, getptype(sendtype), 1, 3);
01234                 if (array == NULL)
01235                         return NULL;
01236                     sptr=(char*)(array->data);
01237 
01238     }
01239 
01240     /* allocate the recvbuf */
01241     dimensions[0]=recvcnt;
01242     result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(recvtype));
01243     rptr=(char*)(result->data);
01244 
01245    /*  do the call */
01246         ierr=MPI_Scatter(sptr, sendcnts, (MPI_Datatype)sendtype,rptr,recvcnt,(MPI_Datatype)recvtype, root, (MPI_Comm )comm );
01247     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01248 #ifdef MPI2
01249     if(myid == root || root == MPI_ROOT) {
01250 #else
01251     if(myid == root) {
01252 #endif
01253                 Py_DECREF(array);
01254         }
01255         return PyArray_Return(result);
01256 }
01257 
01258 static PyObject * mpi_reduce(PyObject *self, PyObject *args) {
01259 /* int MPI_Reduce ( void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm ) */
01260 int count,root;
01261 DATA_TYPE datatype;
01262 COM_TYPE comm;
01263 long op;
01264 int myid;
01265 PyArrayObject *result;
01266 PyArrayObject *array;
01267 PyObject *input;
01268 int dimensions[1];
01269 char *sptr,*rptr;
01270 
01271         if (!PyArg_ParseTuple(args, "Oillil", &input, &count,&datatype,&op,&root,&comm))
01272         return NULL;
01273     MPI_Comm_rank((MPI_Comm)comm,&myid);
01274     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01275 #ifdef MPI2
01276     if(myid == root || root == MPI_ROOT) {
01277 #else
01278     if(myid == root) {
01279 #endif
01280         dimensions[0]=count;
01281         }
01282         else {
01283                 dimensions[0]=0;
01284         }
01285     result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(datatype));
01286         rptr=(char*)(result->data);
01287 
01288         array = (PyArrayObject *) PyArray_ContiguousFromObject(input, getptype(datatype), 0, 3);
01289         if (array == NULL)
01290                 return NULL;
01291         sptr=(char*)(array->data);
01292         ierr=MPI_Reduce(sptr,rptr,count,(MPI_Datatype)datatype,(MPI_Op)op,root,(MPI_Comm)comm);
01293         Py_DECREF(array);
01294         return PyArray_Return(result);
01295 }
01296 
01297 
01298 static PyObject * mpi_finalize(PyObject *self, PyObject *args) {
01299 /* int MPI_Finalize() */
01300         if(erroron){ erroron=0; return NULL;}
01301     return PyInt_FromLong((long)MPI_Finalize());
01302 }
01303 static PyObject * mpi_alltoall(PyObject *self, PyObject *args) {
01304 /*
01305    int MPI_Alltoall( void *sendbuf, int sendcount, MPI_Datatype sendtype,
01306                      void *recvbuf, int recvcnt,   MPI_Datatype recvtype,
01307                      MPI_Comm comm )
01308  */
01309 COM_TYPE comm;
01310 DATA_TYPE sendtype,recvtype;
01311 PyObject *sendbuf_obj;
01312 PyArrayObject *array,*result;
01313 int sendcnts,recvcnt;
01314 int numprocs,myid;
01315 int dimensions[1];
01316 char *sptr,*rptr;
01317 sendcnts=0;
01318 
01319         array=NULL;
01320         sptr=NULL;
01321 
01322         if (!PyArg_ParseTuple(args, "Oilill", &sendbuf_obj, &sendcnts,&sendtype,&recvcnt,&recvtype,&comm))
01323         return NULL;
01324     /* ! get the number of processors in this comm */
01325     ierr=MPI_Comm_size((MPI_Comm)comm,&numprocs);
01326     ierr=MPI_Comm_rank((MPI_Comm)comm,&myid);
01327 
01328     /* get sendbuf */
01329                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sendbuf_obj, getptype(sendtype), 1, 3);
01330                 if (array == NULL)
01331                         return NULL;
01332                     sptr=(char*)(array->data);
01333 
01334 
01335     /* allocate the recvbuf */
01336     dimensions[0]=recvcnt*numprocs;
01337     result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(recvtype));
01338     rptr=(char*)(result->data);
01339 
01340    /*  do the call */
01341         ierr=MPI_Alltoall(sptr, sendcnts, (MPI_Datatype)sendtype,rptr,recvcnt,(MPI_Datatype)recvtype, (MPI_Comm )comm );
01342         Py_DECREF(array);
01343         return PyArray_Return(result);
01344 }
01345 static PyObject * mpi_alltoallv(PyObject *self, PyObject *args) {
01346 /*
01347   int MPI_Alltoallv ( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype sendtype,
01348                       void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype recvtype,
01349                       MPI_Comm comm )
01350 */
01351 COM_TYPE comm;
01352 DATA_TYPE sendtype,recvtype;
01353 PyObject *sendbuf_obj, *recvcnts_obj,*rdispls_obj,*sdispls_obj,*sendcnts_obj;
01354 PyArrayObject *array,*result;
01355 int *sendcnts,*sdispls,*rdispls,*recvcnts,rtot,i;
01356 char *sptr,*rptr;
01357 int numprocs;
01358 int dimensions[1];
01359 
01360         rdispls=0;
01361 
01362         array=NULL;
01363         sptr=NULL;
01364 
01365         if (!PyArg_ParseTuple(args, "OOOlOOll", &sendbuf_obj, &sendcnts_obj,&sdispls_obj,&sendtype,&recvcnts_obj,&rdispls_obj,&recvtype,&comm))
01366         return NULL;
01367     /* ! get the number of processors in this comm */
01368     ierr=MPI_Comm_size((MPI_Comm)comm,&numprocs);
01369     rtot=0;
01370     recvcnts=0;
01371 
01372     /* printf("  get the recvcnts array \n"); */
01373                 array = (PyArrayObject *) PyArray_ContiguousFromObject(recvcnts_obj, PyArray_INT, 1, 1);
01374                 if (array == NULL)
01375                         return NULL;
01376                 recvcnts=(int*)malloc((size_t) (sizeof(int)*numprocs));
01377                 memcpy((void *)recvcnts, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01378                 rtot=0;
01379                 for(i=0;i<numprocs;i++)
01380                         rtot=rtot+recvcnts[i];
01381                 Py_DECREF(array);
01382 
01383     /* printf("  get the recv offset array \n"); */
01384                 array = (PyArrayObject *) PyArray_ContiguousFromObject(rdispls_obj, PyArray_INT, 1, 1);
01385                 if (array == NULL)
01386                         return NULL;
01387                 rdispls=(int*)malloc((size_t) (sizeof(int)*numprocs));
01388                 memcpy((void *)rdispls, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01389                 Py_DECREF(array);
01390 
01391         /* printf("  allocate the recvbuf \n"); */
01392                 dimensions[0]=rtot;
01393                 result = (PyArrayObject *)PyArray_FromDims(1, dimensions, getptype(recvtype));
01394                 rptr=(char*)(result->data);
01395 
01396 
01397 
01398     /* printf("  get the sendcnts array \n"); */
01399                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sendcnts_obj, PyArray_INT, 1, 1);
01400                 if (array == NULL)
01401                         return NULL;
01402                 sendcnts=(int*)malloc((size_t) (sizeof(int)*numprocs));
01403                 memcpy((void *)sendcnts, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01404                 Py_DECREF(array);
01405 
01406     /* printf("  get the send offset array \n"); */
01407                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sdispls_obj, PyArray_INT, 1, 1);
01408                 if (array == NULL)
01409                         return NULL;
01410                 sdispls=(int*)malloc((size_t) (sizeof(int)*numprocs));
01411                 memcpy((void *)sdispls, (void*)array->data, (size_t) (sizeof(int)*numprocs));
01412                 Py_DECREF(array);
01413 
01414    /* printf("  get sendbuf\n"); */
01415                 array = (PyArrayObject *) PyArray_ContiguousFromObject(sendbuf_obj, getptype(sendtype), 1, 3);
01416                 if (array == NULL)
01417                         return NULL;
01418                 sptr=(char*)array->data;
01419 
01420    /* printf("   do the call %d \n"); */
01421    /*
01422         MPI_Comm_rank((MPI_Comm)comm,&myid);
01423                 printf("myid =%d ",myid);
01424                 for(i=0;i<numprocs;i++)
01425                         printf("%d ",sendcnts[i]);
01426                 printf(" | ");
01427                 for(i=0;i<numprocs;i++)
01428                         printf("%d ",sdispls[i]);
01429                 printf(" | ");
01430                 for(i=0;i<numprocs;i++)
01431                         printf("%d ",recvcnts[i]);
01432                 printf(" | ");
01433                 for(i=0;i<numprocs;i++)
01434                         printf("%d ",rdispls[i]);
01435                 printf("\n");
01436    */
01437        ierr=MPI_Alltoallv(sptr, sendcnts, sdispls, (MPI_Datatype)sendtype,
01438                           rptr, recvcnts, rdispls, (MPI_Datatype)recvtype,
01439                           (MPI_Comm)comm);
01440 
01441                 Py_DECREF(array);
01442                 free(recvcnts);
01443                 free(rdispls);
01444                 free(sendcnts);
01445                 free(sdispls);
01446 
01447         return PyArray_Return(result);
01448 }
01449 #include <string.h>
01450 static PyObject * copywrite(PyObject *self, PyObject *args) {
01451 int i;
01452 for(i=0;i<2160;i++) {
01453         cw[i]=(char)0;
01454 }
01455 strncat(cw,"Copyright (c) 2005 The Regents of the University of California\n",80);
01456 strncat(cw,"All Rights Reserved\n",80);
01457 strncat(cw,"Permission to use, copy, modify and distribute any part of this\n",80);
01458 strncat(cw,"    software for educational, research and non-profit purposes,\n",80);
01459 strncat(cw,"    without fee, and without a written agreement is hereby granted,\n",80);
01460 strncat(cw,"    provided that the above copyright notice, this paragraph and the\n",80);
01461 strncat(cw,"    following three paragraphs appear in all copies.\n",80);
01462 strncat(cw,"Those desiring to incorporate this software into commercial products or\n",80);
01463 strncat(cw,"    use for commercial purposes should contact the Technology\n",80);
01464 strncat(cw,"    Transfer & Intellectual Property Services, University of\n",80);
01465 strncat(cw,"    California, San Diego, 9500 Gilman Drive, Mail Code 0910, La\n",80);
01466 strncat(cw,"    Jolla, CA 92093-0910, Ph: (858) 534-5815, FAX: (858) 534-7345,\n",80);
01467 strncat(cw,"    E-MAIL:invent@ucsd.edu.\n",80);
01468 strncat(cw,"IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY\n",80);
01469 strncat(cw,"    PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR\n",80);
01470 strncat(cw,"    CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF\n",80);
01471 strncat(cw,"    THE USE OF THIS SOFTWARE  EVEN IF THE UNIVERSITY OF\n",80);
01472 strncat(cw,"    CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n",80);
01473 strncat(cw,"THE SOFTWARE PROVIDED HEREIN IS ON AN AS IS BASIS, AND THE\n",80);
01474 strncat(cw,"    UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE\n",80);
01475 strncat(cw,"    MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.\n",80);
01476 strncat(cw,"    THE UNIVERSITY OF CALIFORNIA MAKES NO REPRESENTATIONS AND\n",80);
01477 strncat(cw,"    EXTENDS NO WARRANTIES OF ANY KIND, EITHER IMPLIED OR EXPRESS,\n",80);
01478 strncat(cw,"    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n",80);
01479 strncat(cw,"    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT THE\n",80);
01480 strncat(cw,"    USE OF THIS SOFTWARE WILL NOT INFRINGE ANY PATENT, TRADEMARK OR\n",80);
01481 strncat(cw,"    OTHER RIGHTS.\n",80);
01482 return PyString_FromString(cw);
01483 }
01484 /*
01485 **** to add ****
01486 mpi_isend
01487 mpi_irecv
01488 mpi_test
01489 mpi_wait
01490 */
01491 
01492 
01493 static PyMethodDef mpiMethods[] = {
01494     {"mpi_alltoall",    mpi_alltoall,           METH_VARARGS,            mpi_alltoall__},
01495     {"mpi_alltoallv",   mpi_alltoallv,      METH_VARARGS,        mpi_alltoallv__},
01496     {"mpi_barrier",             mpi_barrier,            METH_VARARGS,            mpi_barrier__},
01497     {"mpi_bcast",               mpi_bcast,                      METH_VARARGS,            mpi_bcast__},
01498     {"mpi_comm_create", mpi_comm_create,        METH_VARARGS,            mpi_comm_create__},
01499     {"mpi_comm_dup",    mpi_comm_dup,           METH_VARARGS,            mpi_comm_dup__},
01500     {"mpi_comm_group",  mpi_comm_group,         METH_VARARGS,            mpi_comm_group__},
01501     {"mpi_comm_rank",   mpi_comm_rank,          METH_VARARGS,            mpi_comm_rank__},
01502     {"mpi_comm_size",   mpi_comm_size,          METH_VARARGS,            mpi_comm_size__},
01503     {"mpi_comm_split",  mpi_comm_split,         METH_VARARGS,            mpi_comm_split__},
01504     {"mpi_error",               mpi_error,                      METH_VARARGS,            mpi_error__},
01505     {"mpi_finalize",    mpi_finalize,           METH_VARARGS,            mpi_finalize__},
01506     {"mpi_gather",              mpi_gather,                     METH_VARARGS,            mpi_gather__},
01507     {"mpi_gatherv",             mpi_gatherv,            METH_VARARGS,            mpi_gatherv__},
01508     {"mpi_get_count",   mpi_get_count,          METH_VARARGS,            mpi_get_count__},
01509     {"mpi_group_incl",  mpi_group_incl,         METH_VARARGS,            mpi_group_incl__},
01510     {"mpi_group_rank",  mpi_group_rank,         METH_VARARGS,            mpi_group_rank__},
01511     {"mpi_init",                mpi_init,                       METH_VARARGS,            mpi_init__},
01512     {"mpi_iprobe",              mpi_iprobe,                     METH_VARARGS,            mpi_iprobe__},
01513     {"mpi_irecv",               mpi_irecv,                      METH_VARARGS,            mpi_irecv__},
01514     {"mpi_isend",               mpi_isend,                      METH_VARARGS,            mpi_isend__},
01515     {"mpi_probe",               mpi_probe,                      METH_VARARGS,            mpi_probe__},
01516     {"mpi_recv",                mpi_recv,                       METH_VARARGS,            mpi_recv__},
01517     {"mpi_reduce",              mpi_reduce,                     METH_VARARGS,            mpi_reduce__},
01518     {"mpi_scatter",             mpi_scatter,            METH_VARARGS,            mpi_scatter__},
01519     {"mpi_scatterv",    mpi_scatterv,           METH_VARARGS,            mpi_scatterv__},
01520     {"mpi_send",                mpi_send,                       METH_VARARGS,            mpi_send__},
01521     {"mpi_start",               mpi_start,                      METH_VARARGS,            mpi_start__},
01522     {"mpi_status",              mpi_status,                     METH_VARARGS,            mpi_status__},
01523     {"mpi_get_processor_name",          mpi_get_processor_name,                 METH_VARARGS,            mpi_get_processor_name__},
01524     {"mpi_test",                mpi_test,                       METH_VARARGS,            mpi_test__},
01525     {"mpi_wait",                mpi_wait,                       METH_VARARGS,            mpi_wait__},
01526     {"mpi_wtime",               mpi_wtime,                      METH_VARARGS,            mpi_wtime__},
01527     {"mpi_wtick",               mpi_wtick,                      METH_VARARGS,            mpi_wtick__},
01528     {"mpi_attr_get",    mpi_attr_get,           METH_VARARGS,            mpi_attr_get__},
01529 
01530 
01531 #ifdef MPI2
01532     {"mpi_comm_spawn",              mpi_comm_spawn,                     METH_VARARGS,            mpi_comm_spawn__},
01533     {"mpi_array_of_errcodes",   mpi_array_of_errcodes,  METH_VARARGS,            mpi_array_of_errcodes__},
01534     {"mpi_comm_get_parent",             mpi_comm_get_parent,    METH_VARARGS,            mpi_comm_get_parent__},
01535     {"mpi_comm_free",                   mpi_comm_free,                  METH_VARARGS,            mpi_comm_free__},
01536     {"mpi_intercomm_merge",             mpi_intercomm_merge,    METH_VARARGS,            mpi_intercomm_merge__},
01537     {"mpi_open_port",                   mpi_open_port,                  METH_VARARGS,            mpi_open_port__},
01538     {"mpi_close_port",                  mpi_close_port,                 METH_VARARGS,            mpi_close_port__},
01539     {"mpi_comm_accept",                 mpi_comm_accept,                METH_VARARGS,            mpi_comm_accept__},
01540     {"mpi_comm_connect",                mpi_comm_connect,               METH_VARARGS,            mpi_comm_connect__},
01541     {"mpi_comm_disconnect",             mpi_comm_disconnect,    METH_VARARGS,            mpi_comm_disconnect__},
01542     {"mpi_comm_set_errhandler", mpi_comm_set_errhandler,METH_VARARGS,            mpi_comm_set_errhandler__},
01543 
01544 #endif
01545     {"copywrite",               copywrite,                      METH_VARARGS,           COPYWRITE_STR__},
01546     {NULL, NULL, 0, NULL}        /* Sentinel */
01547 };
01548 
01549 /*
01550 */
01551 
01552 PyMODINIT_FUNC initmpi(void)
01553 {
01554 #ifdef DO_UNSIGED
01555 #define CAST unsigned long
01556 #define VERT_FUNC PyLong_FromUnsignedLong
01557 #else
01558 #define CAST long
01559 #define VERT_FUNC PyInt_FromLong
01560 #endif
01561         PyObject *m, *d;
01562     PyObject *tmp;
01563         import_array();
01564         m=Py_InitModule("mpi", mpiMethods);
01565         mpiError = PyErr_NewException("mpi.error", NULL, NULL);
01566     Py_INCREF(mpiError);
01567     PyModule_AddObject(m, "error", mpiError);
01568     d = PyModule_GetDict(m);
01569     tmp = PyString_FromString(VERSION);
01570     PyDict_SetItemString(d,   "VERSION", tmp);  Py_DECREF(tmp);
01571     tmp = PyInt_FromLong((long)MPI_VERSION);
01572     PyDict_SetItemString(d,   "MPI_VERSION", tmp);  Py_DECREF(tmp);
01573     tmp = PyInt_FromLong((long)MPI_SUBVERSION);
01574     PyDict_SetItemString(d,   "MPI_SUBVERSION", tmp);  Py_DECREF(tmp);
01575     tmp = PyString_FromString(COPYWRITE);
01576     PyDict_SetItemString(d,   "COPYWRITE", tmp);  Py_DECREF(tmp);
01577     tmp = VERT_FUNC((CAST)MPI_CHAR);
01578     PyDict_SetItemString(d,   "MPI_CHAR", tmp);  Py_DECREF(tmp);
01579     tmp = VERT_FUNC((CAST)MPI_BYTE);
01580     PyDict_SetItemString(d,   "MPI_BYTE", tmp);  Py_DECREF(tmp);
01581     tmp = VERT_FUNC((CAST)MPI_SHORT);
01582     PyDict_SetItemString(d,   "MPI_SHORT", tmp);  Py_DECREF(tmp);
01583     tmp = VERT_FUNC((CAST)MPI_INT);
01584     PyDict_SetItemString(d,   "MPI_INT", tmp);  Py_DECREF(tmp);
01585     tmp = VERT_FUNC((CAST)MPI_LONG);
01586     PyDict_SetItemString(d,   "MPI_LONG", tmp);  Py_DECREF(tmp);
01587     tmp = VERT_FUNC((CAST)MPI_FLOAT);
01588     PyDict_SetItemString(d,   "MPI_FLOAT", tmp);  Py_DECREF(tmp);
01589     tmp = VERT_FUNC((CAST)MPI_DOUBLE);
01590     PyDict_SetItemString(d,   "MPI_DOUBLE", tmp);  Py_DECREF(tmp);
01591     tmp = VERT_FUNC((CAST)MPI_UNSIGNED_CHAR);
01592     PyDict_SetItemString(d,   "MPI_UNSIGNED_CHAR", tmp);  Py_DECREF(tmp);
01593     tmp = VERT_FUNC((CAST)MPI_UNSIGNED_SHORT);
01594     PyDict_SetItemString(d,   "MPI_UNSIGNED_SHORT", tmp);  Py_DECREF(tmp);
01595     tmp = VERT_FUNC((CAST)MPI_UNSIGNED);
01596     PyDict_SetItemString(d,   "MPI_UNSIGNED", tmp);  Py_DECREF(tmp);
01597     tmp = VERT_FUNC((CAST)MPI_UNSIGNED_LONG);
01598     PyDict_SetItemString(d,   "MPI_UNSIGNED_LONG", tmp);  Py_DECREF(tmp);
01599     tmp = VERT_FUNC((CAST)MPI_LONG_DOUBLE);
01600     PyDict_SetItemString(d,   "MPI_LONG_DOUBLE", tmp);  Py_DECREF(tmp);
01601     tmp = VERT_FUNC((CAST)MPI_FLOAT_INT);
01602     PyDict_SetItemString(d,   "MPI_FLOAT_INT", tmp);  Py_DECREF(tmp);
01603     tmp = VERT_FUNC((CAST)MPI_LONG_INT);
01604     PyDict_SetItemString(d,   "MPI_LONG_INT", tmp);  Py_DECREF(tmp);
01605     tmp = VERT_FUNC((CAST)MPI_DOUBLE_INT);
01606     PyDict_SetItemString(d,   "MPI_DOUBLE_INT", tmp);  Py_DECREF(tmp);
01607     tmp = VERT_FUNC((CAST)MPI_SHORT_INT);
01608     PyDict_SetItemString(d,   "MPI_SHORT_INT", tmp);  Py_DECREF(tmp);
01609     tmp = VERT_FUNC((CAST)MPI_2INT);
01610     PyDict_SetItemString(d,   "MPI_2INT", tmp);  Py_DECREF(tmp);
01611     tmp = VERT_FUNC((CAST)MPI_LONG_DOUBLE_INT);
01612     PyDict_SetItemString(d,   "MPI_LONG_DOUBLE_INT", tmp);  Py_DECREF(tmp);
01613     tmp = VERT_FUNC((CAST)MPI_LONG_LONG_INT);
01614     PyDict_SetItemString(d,   "MPI_LONG_LONG_INT", tmp);  Py_DECREF(tmp);
01615     tmp = VERT_FUNC((CAST)MPI_PACKED);
01616     PyDict_SetItemString(d,   "MPI_PACKED", tmp);  Py_DECREF(tmp);
01617     tmp = VERT_FUNC((CAST)MPI_Pack);
01618     PyDict_SetItemString(d,   "MPI_Pack", tmp);  Py_DECREF(tmp);
01619     tmp = VERT_FUNC((CAST)MPI_Unpack);
01620     PyDict_SetItemString(d,   "MPI_Unpack", tmp);  Py_DECREF(tmp);
01621     tmp = VERT_FUNC((CAST)MPI_UB);
01622     PyDict_SetItemString(d,   "MPI_UB", tmp);  Py_DECREF(tmp);
01623     tmp = VERT_FUNC((CAST)MPI_LB);
01624     PyDict_SetItemString(d,   "MPI_LB", tmp);  Py_DECREF(tmp);
01625     tmp = VERT_FUNC((CAST)MPI_MAX);
01626     PyDict_SetItemString(d,   "MPI_MAX", tmp);  Py_DECREF(tmp);
01627     tmp = VERT_FUNC((CAST)MPI_MIN);
01628     PyDict_SetItemString(d,   "MPI_MIN", tmp);  Py_DECREF(tmp);
01629     tmp = VERT_FUNC((CAST)MPI_SUM);
01630     PyDict_SetItemString(d,   "MPI_SUM", tmp);  Py_DECREF(tmp);
01631     tmp = VERT_FUNC((CAST)MPI_PROD);
01632     PyDict_SetItemString(d,   "MPI_PROD", tmp);  Py_DECREF(tmp);
01633     tmp = VERT_FUNC((CAST)MPI_LAND);
01634     PyDict_SetItemString(d,   "MPI_LAND", tmp);  Py_DECREF(tmp);
01635     tmp = VERT_FUNC((CAST)MPI_BAND);
01636     PyDict_SetItemString(d,   "MPI_BAND", tmp);  Py_DECREF(tmp);
01637     tmp = VERT_FUNC((CAST)MPI_LOR);
01638     PyDict_SetItemString(d,   "MPI_LOR", tmp);  Py_DECREF(tmp);
01639     tmp = VERT_FUNC((CAST)MPI_BOR);
01640     PyDict_SetItemString(d,   "MPI_BOR", tmp);  Py_DECREF(tmp);
01641     tmp = VERT_FUNC((CAST)MPI_LXOR);
01642     PyDict_SetItemString(d,   "MPI_LXOR", tmp);  Py_DECREF(tmp);
01643     tmp = VERT_FUNC((CAST)MPI_BXOR);
01644     PyDict_SetItemString(d,   "MPI_BXOR", tmp);  Py_DECREF(tmp);
01645     tmp = VERT_FUNC((CAST)MPI_MINLOC);
01646     PyDict_SetItemString(d,   "MPI_MINLOC", tmp);  Py_DECREF(tmp);
01647     tmp = VERT_FUNC((CAST)MPI_MAXLOC);
01648     PyDict_SetItemString(d,   "MPI_MAXLOC", tmp);  Py_DECREF(tmp);
01649     tmp = VERT_FUNC((CAST)MPI_MAXLOC);
01650     PyDict_SetItemString(d,   "MPI_MAXLOC", tmp);  Py_DECREF(tmp);
01651     tmp = VERT_FUNC((CAST)MPI_COMM_NULL);
01652     PyDict_SetItemString(d,   "MPI_COMM_NULL", tmp);  Py_DECREF(tmp);
01653     tmp = VERT_FUNC((CAST)MPI_OP_NULL);
01654     PyDict_SetItemString(d,   "MPI_OP_NULL", tmp);  Py_DECREF(tmp);
01655     tmp = VERT_FUNC((CAST)MPI_GROUP_NULL);
01656     PyDict_SetItemString(d,   "MPI_GROUP_NULL", tmp);  Py_DECREF(tmp);
01657     tmp = VERT_FUNC((CAST)MPI_DATATYPE_NULL);
01658     PyDict_SetItemString(d,   "MPI_DATATYPE_NULL", tmp);  Py_DECREF(tmp);
01659     tmp = VERT_FUNC((CAST)MPI_REQUEST_NULL);
01660     PyDict_SetItemString(d,   "MPI_REQUEST_NULL", tmp);  Py_DECREF(tmp);
01661     tmp = VERT_FUNC((CAST)MPI_ERRHANDLER_NULL);
01662     PyDict_SetItemString(d,   "MPI_ERRHANDLER_NULL", tmp);  Py_DECREF(tmp);
01663     tmp = VERT_FUNC((CAST)MPI_MAX_PROCESSOR_NAME);
01664     PyDict_SetItemString(d,   "MPI_MAX_PROCESSOR_NAME", tmp);  Py_DECREF(tmp);
01665     tmp = VERT_FUNC((CAST)MPI_MAX_ERROR_STRING);
01666     PyDict_SetItemString(d,   "MPI_MAX_ERROR_STRING", tmp);  Py_DECREF(tmp);
01667         tmp = PyInt_FromLong((long)MPI_UNDEFINED);
01668     PyDict_SetItemString(d,   "MPI_UNDEFINED", tmp);  Py_DECREF(tmp);
01669     tmp = VERT_FUNC((CAST)MPI_KEYVAL_INVALID);
01670     PyDict_SetItemString(d,   "MPI_KEYVAL_INVALID", tmp);  Py_DECREF(tmp);
01671     tmp = VERT_FUNC((CAST)MPI_BSEND_OVERHEAD);
01672     PyDict_SetItemString(d,   "MPI_BSEND_OVERHEAD", tmp);  Py_DECREF(tmp);
01673     tmp = VERT_FUNC((CAST)MPI_PROC_NULL);
01674     PyDict_SetItemString(d,   "MPI_PROC_NULL", tmp);  Py_DECREF(tmp);
01675     tmp = VERT_FUNC((CAST)MPI_ANY_SOURCE);
01676     PyDict_SetItemString(d,   "MPI_ANY_SOURCE", tmp);  Py_DECREF(tmp);
01677     tmp = VERT_FUNC((CAST)MPI_ANY_TAG);
01678     PyDict_SetItemString(d,   "MPI_ANY_TAG", tmp);  Py_DECREF(tmp);
01679     tmp = VERT_FUNC((CAST)MPI_BOTTOM);
01680     PyDict_SetItemString(d,   "MPI_BOTTOM", tmp);  Py_DECREF(tmp);
01681     tmp = VERT_FUNC((CAST)MPI_COMM_WORLD);
01682     PyDict_SetItemString(d,   "MPI_COMM_WORLD", tmp);  Py_DECREF(tmp);
01683     tmp = VERT_FUNC((CAST)MPI_TAG_UB);
01684     PyDict_SetItemString(d,   "MPI_TAG_UB", tmp);  Py_DECREF(tmp);
01685     tmp = VERT_FUNC((CAST)MPI_HOST);
01686     PyDict_SetItemString(d,   "MPI_HOST", tmp);  Py_DECREF(tmp);
01687     tmp = VERT_FUNC((CAST)MPI_IO);
01688     PyDict_SetItemString(d,   "MPI_IO", tmp);  Py_DECREF(tmp);
01689     tmp = VERT_FUNC((CAST)MPI_WTIME_IS_GLOBAL);
01690     PyDict_SetItemString(d,   "MPI_WTIME_IS_GLOBAL", tmp);  Py_DECREF(tmp);
01691 
01692     tmp = PyString_FromString(LIBRARY);
01693     PyDict_SetItemString(d,   "ARRAY_LIBRARY", tmp);  Py_DECREF(tmp);
01694 
01695     tmp = PyString_FromString(DATE_DOC);
01696     PyDict_SetItemString(d,   "DATE_DOC", tmp);  Py_DECREF(tmp);
01697     tmp = PyString_FromString(DATE_SRC);
01698     PyDict_SetItemString(d,   "DATE_SRC", tmp);  Py_DECREF(tmp);
01699 
01700 #ifdef MPI2
01701     tmp = VERT_FUNC((CAST)MPI_UNIVERSE_SIZE);
01702     PyDict_SetItemString(d,   "MPI_UNIVERSE_SIZE", tmp);  Py_DECREF(tmp);
01703     tmp = VERT_FUNC((CAST)MPI_ROOT);
01704     PyDict_SetItemString(d,   "MPI_ROOT", tmp);  Py_DECREF(tmp);
01705     tmp = VERT_FUNC((CAST)MPI_ARGV_NULL);
01706     PyDict_SetItemString(d,   "MPI_ARGV_NULL", tmp);  Py_DECREF(tmp);
01707     tmp = VERT_FUNC((CAST)MPI_INFO_NULL);
01708     PyDict_SetItemString(d,   "MPI_INFO_NULL", tmp);  Py_DECREF(tmp);
01709 #endif
01710 }
01711 void myerror(char *s) {
01712         erroron=1;
01713         PyErr_SetString(mpiError,s);
01714 }
01715 
01716 /*int MPIR_Err_return_comm( MPI_Comm  *comm_ptr, const char fcname[], int errcode ) {} */