#include "mpiP.h" /****************************************************************************/ static int initialized=0; /****************************************************************************/ /* * INIT/FINALIZE * */ FC_FUNC( mpi_init_fort , MPI_INIT_FORT) (int *f_MPI_COMM_WORLD, int *f_MPI_ANY_SOURCE, int *f_MPI_ANY_TAG, int *f_MPI_PROC_NULL, int *f_MPI_ROOT, int *f_MPI_COMM_NULL, int *f_MPI_REQUEST_NULL, int *f_MPI_GROUP_NULL, int *f_MPI_GROUP_EMPTY, int *f_MPI_UNDEFINED, int *f_MPI_MAX_ERROR_STRING, int *f_MPI_MAX_PROCESSOR_NAME, int *f_MPI_STATUS_SIZE, int *f_MPI_SOURCE, int *f_MPI_TAG, int *f_MPI_ERROR, int *f_status, int *fsource, int *ftag, int *ferror, int *f_MPI_INTEGER, void *fint1, void *fint2, int *f_MPI_LOGICAL, void *flog1, void *flog2, int *f_MPI_REAL, void *freal1, void *freal2, int *f_MPI_DOUBLE_PRECISION, void *fdub1, void *fdub2, int *f_MPI_COMPLEX, void *fcomp1, void *fcomp2, int *ierror) { int err; int size; int offset; *ierror=MPI_Init(NULL,NULL); err=0; /* * These 3 macros compare things from mpif.h (as passed in by the f_ * arguments) to the values in C (from #including mpi.h). * * Unfortunately, this kind of thing is done most easily in a nasty * looking macto. * */ /* * verify_eq * compare value of constants in C and fortran * i.e. compare *f_ to */ #define verify_eq(name) \ if (*f_##name != name) \ { fprintf(stderr,"mpi-serial: mpi_init_fort: %s not consistant " \ "between mpif.h (%d) and mpi.h (%d)\n",\ #name,*f_##name,name); \ err=1; } #define verify_eq_warn(name) \ if (*f_##name != name) \ { fprintf(stderr,"mpi-serial: mpi_init_fort: warning: %s not consistant " \ "between mpif.h (%d) and mpi.h (%d)\n",\ #name,*f_##name,name); \ } /* * verify_size * verify that the type name in fortran has the correct * value (i.e. the size of that data type). * Determine size by subtracting the pointer values of two * consecutive array locations. */ #define verify_size(name,p1,p2) \ if ( (size=((char *)(p2) - (char *)(p1))) != *f_##name ) \ { fprintf(stderr,"mpi-serial: mpi_init_fort: mpif.h %s (%d) " \ "does not match actual fortran size (%d)\n", \ #name,*f_##name,size); \ err=1; } /* * verify_field * check the struct member offsets for MPI_Status vs. the * fortan integer array offsets. E.g. the location of * status->MPI_SOURCE should be the same as STATUS(MPI_SOURCE) */ #define verify_field(name) \ { offset= (char *)&((MPI_Status *)f_status)->name - (char *)f_status; \ if ( offset != (*f_##name-1)*sizeof(int) ) \ { fprintf(stderr,"mpi-serial: mpi_init_fort: mpif.h %s (%d) (%d bytes) " \ "is inconsistant w/offset in MPI_Status (%d bytes)\n", \ #name,*f_##name,(*f_##name-1)*sizeof(int),offset); \ err=1; }} verify_eq(MPI_COMM_WORLD); verify_eq(MPI_ANY_SOURCE); verify_eq(MPI_ANY_TAG); verify_eq(MPI_PROC_NULL); verify_eq(MPI_ROOT); verify_eq(MPI_COMM_NULL); verify_eq(MPI_REQUEST_NULL); verify_eq(MPI_GROUP_NULL); verify_eq(MPI_GROUP_EMPTY); verify_eq(MPI_UNDEFINED); verify_eq(MPI_MAX_ERROR_STRING); verify_eq(MPI_MAX_PROCESSOR_NAME); verify_eq(MPI_STATUS_SIZE); verify_field(MPI_SOURCE); verify_field(MPI_TAG); verify_field(MPI_ERROR); verify_eq(MPI_INTEGER); verify_size(MPI_INTEGER,fint1,fint2); verify_size(MPI_LOGICAL,flog1,flog2); verify_eq_warn(MPI_REAL); verify_size(MPI_REAL,freal1,freal2); verify_eq(MPI_DOUBLE_PRECISION); verify_size(MPI_DOUBLE_PRECISION,fdub1,fdub2); verify_size(MPI_COMPLEX,fcomp1,fcomp2); if (err) abort(); } int MPI_Init(int *argc, char **argv[]) { MPI_Comm my_comm_world; if (sizeof(MPI_Aint) < sizeof(void *)) { fprintf(stderr, "mpi-serial: MPI_Init: " "MPI_Aint is not large enough for void *\n"); abort(); } my_comm_world=mpi_comm_new(); if (my_comm_world != MPI_COMM_WORLD) { fprintf(stderr,"MPI_Init: conflicting MPI_COMM_WORLD\n"); abort(); } initialized=1; return(MPI_SUCCESS); } /*********/ FC_FUNC( mpi_finalize, MPI_FINALIZE )(int *ierror) { *ierror=MPI_Finalize(); } /* * MPI_Finalize() * * this library doesn't support re-initializing MPI, so * the finalize will just leave everythign as it is... * */ int MPI_Finalize(void) { initialized=0; mpi_destroy_handles(); return(MPI_SUCCESS); } /*********/ FC_FUNC( mpi_abort , MPI_ABORT )(int *comm, int *errorcode, int *ierror) { *ierror=MPI_Abort( *comm, *errorcode); } int MPI_Abort(MPI_Comm comm, int errorcode) { fprintf(stderr,"MPI_Abort: error code = %d\n",errorcode); exit(errorcode); } /*********/ FC_FUNC( mpi_error_string , MPI_ERROR_STRING) (int *errorcode, char *string, int *resultlen, int *ierror) { *ierror=MPI_Error_string(*errorcode, string, resultlen); } int MPI_Error_string(int errorcode, char *string, int *resultlen) { sprintf(string,"MPI Error: code %d\n",errorcode); *resultlen=strlen(string); return(MPI_SUCCESS); } /*********/ FC_FUNC( mpi_get_processor_name , MPI_GET_PROCESSOR_NAME ) (char *name, int *resultlen, int *ierror) { *ierror=MPI_Get_processor_name(name,resultlen); } int MPI_Get_processor_name(char *name, int *resultlen) { int ret; ret=gethostname(name,MPI_MAX_PROCESSOR_NAME); if (ret!=0) strncpy(name,"unknown host name",MPI_MAX_PROCESSOR_NAME); name[MPI_MAX_PROCESSOR_NAME-1]='\0'; /* make sure NULL terminated */ *resultlen=strlen(name); return(MPI_SUCCESS); } /*********/ FC_FUNC( mpi_initialized , MPI_INITIALIZED )(int *flag, int *ierror) { *ierror=MPI_Initialized(flag); } int MPI_Initialized(int *flag) { *flag= initialized; return(MPI_SUCCESS); }