Actual source code: mpi.h

      1: /*
      2:    This is a special set of bindings for uni-processor use of MPI by the PETSc library.
      3:
      4:    NOT ALL THE MPI CALLS ARE IMPLEMENTED CORRECTLY! Only those needed in PETSc.

      6:    For example,
      7:    * Does not implement send to self.
      8:    * Does not implement attributes correctly.
      9: */

     11: /*
     12:   The following info is a response to one of the petsc-maint questions
     13:   regarding MPIUNI.

     15:   MPIUNI was developed with the aim of getting PETSc compiled, and
     16:   usable in the absence of MPI. This is the reason each function is
     17:   not documented.  The development strategy was - to make enough
     18:   changes to it so that PETSc source compiles without errors, and runs
     19:   in the uni-processor mode.

     21:   Most PETSc objects have both sequential and parallel
     22:   implementations, which are separate. For eg: We have two types of
     23:   sparse matrix storage formats - SeqAIJ, and MPIAIJ. Some MPI
     24:   routines are used in the Seq part, but most of them are used in the
     25:   MPI part. The send/receive calls can be found mostly in the MPI
     26:   part.

     28:   When MPIUNI is used, only the Seq version of the PETSc objects are
     29:   used, even though the MPI variant of the objects are compiled. Since
     30:   there are no send/receive calls in the Seq variant, PETSc works fine
     31:   with MPIUNI in seq mode.

     33:   The reason some send/receive functions are defined to abort(), is to
     34:   detect sections of code that use send/receive functions, and gets
     35:   executed in the sequential mode. (which shouldn't happen in case of
     36:   PETSc).

     38:   One of the goals with MPIUNI, is to avoid the function call overhead
     39:   of a regular MPI implementation. If this was not the case, we could
     40:   as well have used a regular implementation of MPI as they are
     41:   available on almost all machines. Hence most of the functions are
     42:   implemented as macros. One of the additional benefits we got from
     43:   MPIUNI is, we were able to use PETSc on machines where using a
     44:   proper implementation of MPI was painful (for eg NT).

     46:   Proper implementation of send/receive would involve writing a
     47:   function for each of them. Inside each of these functions, we have
     48:   to check if the send is to self or receive is from self, and then
     49:   doing the buffering accordingly (until the receive is called) - or
     50:   what if a nonblocking receive is called, do a copy etc.. Handling
     51:   the buffering aspects might be complicated enough, that in this
     52:   case, a proper implementation of MPI might as well be used. This is
     53:   the reason the send to self is not implemented in MPIUNI, and never
     54:   will be.
     55: */

     60: /* Requred by abort() in mpi.c & for win64 */
     61: #include "petscconf.h"

     63: #if defined(__cplusplus)
     65: #endif

     67: /* require an int variable large enough to hold a pointer */
     68: #if !defined(MPIUNI_INTPTR)
     69: #define MPIUNI_INTPTR long
     70: #endif

     72: #define _petsc_mpi_uni

     74: /*

     76:     MPIUNI_TMP is used in the macros below only to stop various C/C++ compilers
     77: from generating warning messages about unused variables while compiling PETSc.
     78: */

     81: #define MPI_COMM_WORLD       1
     82: #define MPI_COMM_SELF        MPI_COMM_WORLD
     83: #define MPI_COMM_NULL        0
     84: #define MPI_SUCCESS          0
     85: #define MPI_IDENT            0
     86: #define MPI_CONGRUENT        0
     87: #define MPI_SIMILAR          0
     88: #define MPI_UNEQUAL          3
     89: #define MPI_ANY_SOURCE     (-2)
     90: #define MPI_KEYVAL_INVALID   0
     91: #define MPI_ERR_UNKNOWN     18
     92: #define MPI_ERR_INTERN      21
     93: #define MPI_ERR_OTHER        1
     94: #define MPI_TAG_UB           0
     95: #define MPI_ERRORS_RETURN    0

     97: /* External types */
     98: typedef int    MPI_Comm;
     99: typedef void   *MPI_Request;
    100: typedef void   *MPI_Group;
    101: typedef struct {int MPI_TAG,MPI_SOURCE,MPI_ERROR;} MPI_Status;
    102: typedef char   *MPI_Errhandler;
    103: typedef int    MPI_Fint;

    107: /* In order to handle datatypes, we make them into "sizeof(raw-type)";
    108:     this allows us to do the MPIUNI_Memcpy's easily */
    109: #define MPI_Datatype        int
    110: #define MPI_FLOAT           sizeof(float)
    111: #define MPI_DOUBLE          sizeof(double)
    112: #define MPI_LONG_DOUBLE     sizeof(long double)
    113: #define MPI_CHAR            sizeof(char)
    114: #define MPI_BYTE            sizeof(char)
    115: #define MPI_INT             sizeof(int)
    116: #define MPI_LONG            sizeof(long)
    117: #define MPI_LONG_LONG_INT   sizeof(long long)
    118: #define MPI_SHORT           sizeof(short)
    119: #define MPI_UNSIGNED_SHORT  sizeof(unsigned short)
    120: #define MPI_UNSIGNED        sizeof(unsigned)
    121: #define MPI_UNSIGNED_CHAR   sizeof(unsigned char)
    122: #define MPI_UNSIGNED_LONG   sizeof(unsigned long)
    123: #define MPI_COMPLEX         2*sizeof(float)
    124: #define MPI_DOUBLE_COMPLEX  2*sizeof(double)
    125: #define MPI_FLOAT_INT       (sizeof(float) + sizeof(int))
    126: #define MPI_DOUBLE_INT      (sizeof(double) + sizeof(int))
    127: #define MPI_LONG_INT        (sizeof(long) + sizeof(int))
    128: #define MPI_SHORT_INT       (sizeof(short) + sizeof(int))
    129: #define MPI_2INT            (2* sizeof(int))

    131: #define MPI_REQUEST_NULL    ((MPI_Request)0)
    132: #define MPI_GROUP_NULL      ((MPI_Group)0)
    133: typedef int MPI_Op;

    135: #define MPI_SUM           0
    136: #define MPI_MAX           0
    137: #define MPI_MIN           0
    138: #define MPI_ANY_TAG     (-1)
    139: #define MPI_DATATYPE_NULL 0

    141: #define MPI_MAX_ERROR_STRING 2056
    142: /*
    143:   Prototypes of some functions which are implemented in mpi.c
    144: */
    145: typedef int   (MPI_Copy_function)(MPI_Comm,int,void *,void *,void *,int *);
    146: typedef int   (MPI_Delete_function)(MPI_Comm,int,void *,void *);
    147: typedef void  (MPI_User_function)(void*, void *, int *, MPI_Datatype *);

    149: /*
    150:   In order that the PETSc MPIUNI can be used with another package that has its
    151:   own MPIUni we map the following function names to a unique PETSc name. Those functions
    152:   are defined in mpi.c
    153: */

    168: #define MPI_Abort         Petsc_MPI_Abort
    169: #define MPI_Attr_get      Petsc_MPI_Attr_get
    170: #define MPI_Keyval_free   Petsc_MPI_Keyval_free
    171: #define MPI_Attr_put      Petsc_MPI_Attr_put
    172: #define MPI_Attr_delete   Petsc_MPI_Attr_delete
    173: #define MPI_Keyval_create Petsc_MPI_Keyval_create
    174: #define MPI_Comm_free     Petsc_MPI_Comm_free
    175: #define MPI_Comm_dup      Petsc_MPI_Comm_dup

    177: #define MPI_Init          Petsc_MPI_Init
    178: #define MPI_Finalize      Petsc_MPI_Finalize
    179: #define MPI_Initialized   Petsc_MPI_Initialized
    180: #define MPI_Finalized     Petsc_MPI_Finalized

    182: #define MPI_Aint int
    183: /*
    184:     Routines we have replace with macros that do nothing
    185:     Some return error codes others return success
    186: */

    188: #define MPI_Comm_f2c(comm) (MPI_Comm)(comm)
    189: #define MPI_Comm_c2f(comm) (MPI_Fint)(comm)

    191: #define MPI_Send(buf,count,datatype,dest,tag,comm)  \
    192:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    193:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    194:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    195:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    196:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    197:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    198:       MPI_SUCCESS)
    199: #define MPI_Recv(buf,count,datatype,source,tag,comm,status) \
    200:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    201:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    202:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    203:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (source),\
    204:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    205:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    206:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (status),\
    207:       MPI_Abort(MPI_COMM_WORLD,0))
    208: #define MPI_Get_count(status, datatype,count) \
    209:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (status),\
    210:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    211:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    212:       MPI_Abort(MPI_COMM_WORLD,0))
    213: #define MPI_Bsend(buf,count,datatype,dest,tag,comm)  \
    214:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    215:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    216:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    217:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    218:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    219:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    220:       MPI_SUCCESS)
    221: #define MPI_Ssend(buf,count, datatype,dest,tag,comm) \
    222:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    223:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    224:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    225:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    226:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    227:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    228:       MPI_SUCCESS)
    229: #define MPI_Rsend(buf,count, datatype,dest,tag,comm) \
    230:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    231:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    232:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    233:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    234:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    235:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    236:       MPI_SUCCESS)
    237: #define MPI_Buffer_attach(buffer,size) \
    238:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buffer),\
    239:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (size),\
    240:       MPI_SUCCESS)
    241: #define MPI_Buffer_detach(buffer,size)\
    242:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buffer),\
    243:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (size),\
    244:       MPI_SUCCESS)
    245: #define MPI_Ibsend(buf,count, datatype,dest,tag,comm,request) \
    246:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    247:        MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    248:        MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    249:        MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    250:        MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    251:        MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    252:        MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    253:        MPI_SUCCESS)
    254: #define MPI_Issend(buf,count, datatype,dest,tag,comm,request) \
    255:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    256:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    257:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    258:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    259:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    260:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    261:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    262:       MPI_SUCCESS)
    263: #define MPI_Irsend(buf,count, datatype,dest,tag,comm,request) \
    264:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    265:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    266:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    267:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    268:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    269:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    270:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    271:       MPI_SUCCESS)
    272: #define MPI_Irecv(buf,count, datatype,source,tag,comm,request) \
    273:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    274:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    275:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    276:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (source),\
    277:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    278:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    279:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    280:       MPI_Abort(MPI_COMM_WORLD,0))
    281: #define MPI_Isend(buf,count, datatype,dest,tag,comm,request) \
    282:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    283:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    284:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    285:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    286:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    287:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    288:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    289:       MPI_Abort(MPI_COMM_WORLD,0))
    290: #define MPI_Wait(request,status) \
    291:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    292:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (status),\
    293:       MPI_SUCCESS)
    294: #define MPI_Test(request,flag,status) \
    295:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    296:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (status),\
    297:       *(flag) = 0, \
    298:       MPI_SUCCESS)
    299: #define MPI_Request_free(request) \
    300:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    301:       MPI_SUCCESS)
    302: #define MPI_Waitany(a,b,c,d) \
    303:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (a),\
    304:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (b),\
    305:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (c),\
    306:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (d),\
    307:       MPI_SUCCESS)
    308: #define MPI_Testany(a,b,c,d,e) \
    309:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (a),\
    310:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (b),\
    311:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (c),\
    312:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (d),\
    313:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (e),\
    314:       MPI_SUCCESS)
    315: #define MPI_Waitall(count,array_of_requests,array_of_statuses) \
    316:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    317:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_requests),\
    318:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_statuses),\
    319:       MPI_SUCCESS)
    320: #define MPI_Testall(count,array_of_requests,flag,array_of_statuses) \
    321:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    322:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_requests),\
    323:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (flag),\
    324:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_statuses),\
    325:       MPI_SUCCESS)
    326: #define MPI_Waitsome(incount,array_of_requests,outcount,\
    327:                      array_of_indices,array_of_statuses) \
    328:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (incount),\
    329:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_requests),\
    330:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (outcount),\
    331:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_indices),\
    332:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_statuses),\
    333:       MPI_SUCCESS)
    334: #define MPI_Comm_group(comm,group) \
    335:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    336:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (group),\
    337:       MPI_SUCCESS)
    338: #define MPI_Group_incl(group,n,ranks,newgroup) \
    339:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (group),\
    340:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (n),\
    341:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (ranks),\
    342:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (newgroup),\
    343:       MPI_SUCCESS)
    344: #define MPI_Testsome(incount,array_of_requests,outcount,\
    345:                      array_of_indices,array_of_statuses) MPI_SUCCESS
    346: #define MPI_Iprobe(source,tag,comm,flag,status) (*(flag)=0, MPI_SUCCESS)
    347: #define MPI_Probe(source,tag,comm,status) MPI_SUCCESS
    348: #define MPI_Cancel(request) (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),MPI_SUCCESS)
    349: #define MPI_Test_cancelled(status,flag) (*(flag)=0,MPI_SUCCESS)
    350: #define MPI_Send_init(buf,count, datatype,dest,tag,comm,request) \
    351:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    352:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    353:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    354:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    355:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    356:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    357:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    358:      MPI_SUCCESS)
    359: #define MPI_Bsend_init(buf,count, datatype,dest,tag,comm,request) \
    360:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    361:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    362:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    363:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    364:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    365:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    366:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    367:      MPI_SUCCESS)
    368: #define MPI_Ssend_init(buf,count, datatype,dest,tag,comm,request) \
    369:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    370:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    371:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    372:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    373:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    374:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    375:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    376:      MPI_SUCCESS)
    377: #define MPI_Bsend_init(buf,count, datatype,dest,tag,comm,request) \
    378:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    379:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    380:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    381:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    382:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    383:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    384:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    385:      MPI_SUCCESS)
    386: #define MPI_Rsend_init(buf,count, datatype,dest,tag,comm,request) \
    387:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    388:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    389:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    390:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (dest),\
    391:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    392:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    393:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    394:      MPI_SUCCESS)
    395: #define MPI_Recv_init(buf,count, datatype,source,tag,comm,request) \
    396:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buf),\
    397:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    398:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    399:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (source),\
    400:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (tag),\
    401:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    402:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),\
    403:      MPI_SUCCESS)
    404: #define MPI_Start(request) (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (request),MPI_SUCCESS)
    405: #define MPI_Startall(count,array_of_requests) \
    406:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    407:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (array_of_requests),\
    408:      MPI_SUCCESS)
    409: #define MPI_Op_create(function,commute,op) \
    410:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (function),\
    411:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (commute),\
    412:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (op),\
    413:      MPI_SUCCESS)
    414: #define MPI_Op_free(op) \
    415:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (op),\
    416:      MPI_SUCCESS)
    417:      /* Need to determine sizeof "sendtype" */
    418: #define MPI_Sendrecv(sendbuf,sendcount, sendtype,\
    419:      dest,sendtag,recvbuf,recvcount,\
    420:      recvtype,source,recvtag,\
    421:      comm,status) \
    422:      MPIUNI_Memcpy(recvbuf,sendbuf,(sendcount) * (sendtype))
    423: #define MPI_Sendrecv_replace(buf,count, datatype,dest,sendtag,\
    424:      source,recvtag,comm,status) MPI_SUCCESS
    425: #define MPI_Type_contiguous(count, oldtype,newtype) \
    426:      (*(newtype) = (count)*(oldtype),MPI_SUCCESS)
    427: #define MPI_Type_vector(count,blocklength,stride,oldtype, newtype) MPI_SUCCESS
    428: #define MPI_Type_hvector(count,blocklength,stride,oldtype, newtype) MPI_SUCCESS
    429: #define MPI_Type_indexed(count,array_of_blocklengths,\
    430:      array_of_displacements, oldtype,\
    431:      newtype) MPI_SUCCESS
    432: #define MPI_Type_hindexed(count,array_of_blocklengths,\
    433:      array_of_displacements, oldtype,\
    434:      newtype) MPI_SUCCESS
    435: #define MPI_Type_struct(count,array_of_blocklengths,\
    436:      array_of_displacements,\
    437:      array_of_types, newtype) MPI_SUCCESS
    438: #define MPI_Address(location,address) \
    439:      (*(address) = (MPIUNI_INTPTR)(char *)(location),MPI_SUCCESS)
    440: #define MPI_Type_extent(datatype,extent) \
    441:      MPI_Abort(MPI_COMM_WORLD,0)
    442: #define MPI_Type_size(datatype,size) \
    443:      MPI_Abort(MPI_COMM_WORLD,0)
    444: #define MPI_Type_lb(datatype,displacement) \
    445:      MPI_Abort(MPI_COMM_WORLD,0)
    446: #define MPI_Type_ub(datatype,displacement) \
    447:      MPI_Abort(MPI_COMM_WORLD,0)
    448: #define MPI_Type_commit(datatype) (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    449:      MPI_SUCCESS)
    450: #define MPI_Type_free(datatype) MPI_SUCCESS
    451: #define MPI_Get_elements(status, datatype,count) \
    452:      MPI_Abort(MPI_COMM_WORLD,0)
    453: #define MPI_Pack(inbuf,incount, datatype,outbuf,\
    454:      outsize,position, comm) \
    455:      MPI_Abort(MPI_COMM_WORLD,0)
    456: #define MPI_Unpack(inbuf,insize,position,outbuf,\
    457:      outcount, datatype,comm) \
    458:      MPI_Abort(MPI_COMM_WORLD,0)
    459: #define MPI_Pack_size(incount, datatype,comm,size) \
    460:      MPI_Abort(MPI_COMM_WORLD,0)
    461: #define MPI_Barrier(comm) \
    462:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    463:      MPI_SUCCESS)
    464: #define MPI_Bcast(buffer,count,datatype,root,comm) \
    465:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (buffer),\
    466:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (count),\
    467:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (datatype),\
    468:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    469:      MPI_SUCCESS)
    470: #define MPI_Gather(sendbuf,sendcount, sendtype,\
    471:      recvbuf,recvcount, recvtype,\
    472:      root,comm) \
    473:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvcount),\
    474:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (root),\
    475:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvtype),\
    476:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    477:      MPIUNI_Memcpy(recvbuf,sendbuf,(sendcount)* (sendtype)),\
    478:      MPI_SUCCESS)
    479: #define MPI_Gatherv(sendbuf,sendcount, sendtype,\
    480:      recvbuf,recvcounts,displs,\
    481:      recvtype,root,comm) \
    482:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvcounts),\
    483:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (displs),\
    484:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvtype),\
    485:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (root),\
    486:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    487:      MPIUNI_Memcpy(recvbuf,sendbuf,(sendcount)* (sendtype)),\
    488:      MPI_SUCCESS)
    489: #define MPI_Scatter(sendbuf,sendcount, sendtype,\
    490:      recvbuf,recvcount, recvtype,\
    491:      root,comm) \
    492:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (sendbuf),\
    493:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (sendcount),\
    494:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (sendtype),\
    495:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvbuf),\
    496:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvcount),\
    497:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvtype),\
    498:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (root),\
    499:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),MPI_Abort(MPI_COMM_WORLD,0))
    500: #define MPI_Scatterv(sendbuf,sendcounts,displs,\
    501:      sendtype, recvbuf,recvcount,\
    502:      recvtype,root,comm) \
    503:      (MPIUNI_Memcpy(recvbuf,sendbuf,(recvcount)*(recvtype)),\
    504:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (displs),\
    505:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (sendtype),\
    506:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (sendcounts),\
    507:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (root),\
    508:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    509:      MPI_SUCCESS)
    510: #define MPI_Allgather(sendbuf,sendcount, sendtype,\
    511:      recvbuf,recvcount, recvtype,comm) \
    512:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvcount),\
    513:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvtype),\
    514:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    515:      MPIUNI_Memcpy(recvbuf,sendbuf,(sendcount)* (sendtype)),\
    516:      MPI_SUCCESS)
    517: #define MPI_Allgatherv(sendbuf,sendcount, sendtype,\
    518:      recvbuf,recvcounts,displs,recvtype,comm) \
    519:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvcounts),\
    520:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (displs),\
    521:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvtype),\
    522:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    523:      MPIUNI_Memcpy(recvbuf,sendbuf,(sendcount)* (sendtype)),\
    524:      MPI_SUCCESS)
    525: #define MPI_Alltoall(sendbuf,sendcount, sendtype,\
    526:      recvbuf,recvcount, recvtype,comm) \
    527:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvcount),\
    528:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (recvtype),\
    529:       MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    530:       MPIUNI_Memcpy(recvbuf,sendbuf,(sendcount)* (sendtype)),\
    531:       MPI_SUCCESS)
    532: #define MPI_Alltoallv(sendbuf,sendcounts,sdispls,\
    533:      sendtype, recvbuf,recvcounts,\
    534:      rdispls, recvtype,comm) MPI_Abort(MPI_COMM_WORLD,0)
    535: #define MPI_Alltoallw(sendbuf,sendcounts,sdispls,\
    536:      sendtypes, recvbuf,recvcounts,\
    537:      rdispls, recvtypes,comm) MPI_Abort(MPI_COMM_WORLD,0)
    538: #define MPI_Reduce(sendbuf, recvbuf,count,\
    539:      datatype,op,root,comm) \
    540:      (MPIUNI_Memcpy(recvbuf,sendbuf,(count)*(datatype)),\
    541:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),MPI_SUCCESS)
    542: #define MPI_Allreduce(sendbuf, recvbuf,count,datatype,op,comm) \
    543:      (MPIUNI_Memcpy(recvbuf,sendbuf,(count)*(datatype)),\
    544:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),MPI_SUCCESS)
    545: #define MPI_Scan(sendbuf, recvbuf,count,datatype,op,comm) \
    546:      (MPIUNI_Memcpy(recvbuf,sendbuf,(count)*(datatype)),\
    547:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),MPI_SUCCESS)
    548: #define MPI_Reduce_scatter(sendbuf, recvbuf,recvcounts,\
    549:      datatype,op,comm) \
    550:      MPI_Abort(MPI_COMM_WORLD,0)
    551: #define MPI_Group_size(group,size) (*(size)=1,MPI_SUCCESS)
    552: #define MPI_Group_rank(group,rank) (*(rank)=0,MPI_SUCCESS)
    553: #define MPI_Group_translate_ranks (group1,n,ranks1,\
    554:      group2,ranks2) MPI_Abort(MPI_COMM_WORLD,0)
    555: #define MPI_Group_compare(group1,group2,result) \
    556:      (*(result)=1,MPI_SUCCESS)
    557: #define MPI_Group_union(group1,group2,newgroup) MPI_SUCCESS
    558: #define MPI_Group_intersection(group1,group2,newgroup) MPI_SUCCESS
    559: #define MPI_Group_difference(group1,group2,newgroup) MPI_SUCCESS
    560: #define MPI_Group_excl(group,n,ranks,newgroup) MPI_SUCCESS
    561: #define MPI_Group_range_incl(group,n,ranges,newgroup) MPI_SUCCESS
    562: #define MPI_Group_range_excl(group,n,ranges,newgroup) MPI_SUCCESS
    563: #define MPI_Group_free(group) \
    564:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (group),\
    565:      MPI_SUCCESS)
    566: #define MPI_Comm_size(comm,size) \
    567:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    568:      *(size)=1,\
    569:      MPI_SUCCESS)
    570: #define MPI_Comm_rank(comm,rank) \
    571:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    572:      *(rank)=0,\
    573:      MPI_SUCCESS)
    574: #define MPI_Comm_compare(comm1,comm2,result) \
    575:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm1),\
    576:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm2),\
    577:      *(result)=MPI_IDENT,\
    578:      MPI_SUCCESS)
    579: #define MPI_Comm_create(comm,group,newcomm)  \
    580:      (*(newcomm) =  (comm),\
    581:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (group),\
    582:      MPI_SUCCESS)
    583: #define MPI_Comm_split(comm,color,key,newcomm) MPI_SUCCESS
    584: #define MPI_Comm_test_inter(comm,flag) (*(flag)=1,MPI_SUCCESS)
    585: #define MPI_Comm_remote_size(comm,size) (*(size)=1,MPI_SUCCESS)
    586: #define MPI_Comm_remote_group(comm,group) MPI_SUCCESS
    587: #define MPI_Intercomm_create(local_comm,local_leader,peer_comm,\
    588:      remote_leader,tag,newintercomm) MPI_SUCCESS
    589: #define MPI_Intercomm_merge(intercomm,high,newintracomm) MPI_SUCCESS

    591: #define MPI_Topo_test(comm,status) MPI_SUCCESS
    592: #define MPI_Cart_create(comm_old,ndims,dims,periods,\
    593:      reorder,comm_cart) MPI_SUCCESS
    594: #define MPI_Dims_create(nnodes,ndims,dims) MPI_Abort(MPI_COMM_WORLD,0)
    595: #define MPI_Graph_create(comm,a,b,c,d,e) MPI_SUCCESS
    596: #define MPI_Graphdims_Get(comm,nnodes,nedges) MPI_Abort(MPI_COMM_WORLD,0)
    597: #define MPI_Graph_get(comm,a,b,c,d) MPI_Abort(MPI_COMM_WORLD,0)
    598: #define MPI_Cartdim_get(comm,ndims) MPI_Abort(MPI_COMM_WORLD,0)
    599: #define MPI_Cart_get(comm,maxdims,dims,periods,coords) \
    600:      MPI_Abort(MPI_COMM_WORLD,0)
    601: #define MPI_Cart_rank(comm,coords,rank) MPI_Abort(MPI_COMM_WORLD,0)
    602: #define MPI_Cart_coords(comm,rank,maxdims,coords) \
    603:      MPI_Abort(MPI_COMM_WORLD,0)
    604: #define MPI_Graph_neighbors_count(comm,rank,nneighbors) \
    605:      MPI_Abort(MPI_COMM_WORLD,0)
    606: #define MPI_Graph_neighbors(comm,rank,maxneighbors,neighbors) \
    607:      MPI_Abort(MPI_COMM_WORLD,0)
    608: #define MPI_Cart_shift(comm,direction,disp,rank_source,rank_dest) \
    609:      MPI_Abort(MPI_COMM_WORLD,0)
    610: #define MPI_Cart_sub(comm,remain_dims,newcomm) MPI_Abort(MPI_COMM_WORLD,0)
    611: #define MPI_Cart_map(comm,ndims,dims,periods,newrank) MPI_Abort(MPI_COMM_WORLD,0)
    612: #define MPI_Graph_map(comm,a,b,c,d) MPI_Abort(MPI_COMM_WORLD,0)
    613: #define MPI_Get_processor_name(name,result_len) \
    614:      (MPIUNI_Memcpy(name,"localhost",9*sizeof(char)),name[10] = 0,*(result_len) = 10)
    615: #define MPI_Errhandler_create(function,errhandler) \
    616:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (errhandler),\
    617:      MPI_SUCCESS)
    618: #define MPI_Errhandler_set(comm,errhandler) \
    619:      (MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (comm),\
    620:      MPIUNI_TMP = (void*)(MPIUNI_INTPTR) (errhandler),\
    621:      MPI_SUCCESS)
    622: #define MPI_Errhandler_get(comm,errhandler) MPI_SUCCESS
    623: #define MPI_Errhandler_free(errhandler) MPI_SUCCESS
    624: #define MPI_Error_string(errorcode,string,result_len) MPI_SUCCESS
    625: #define MPI_Error_class(errorcode,errorclass) MPI_SUCCESS
    626: #define MPI_Wtick() 1.0
    627: #define MPI_Wtime() 0.0
    628: #define MPI_Pcontrol(level) MPI_SUCCESS

    630: #define MPI_NULL_COPY_FN   0
    631: #define MPI_NULL_DELETE_FN 0

    633: #if defined(__cplusplus)
    634: }
    635: #endif
    636: #endif