ESPResSo 3.2.0-11-g9950804-git
Extensible Simulation Package for Soft Matter Research
mpi.h
Go to the documentation of this file.
00001 /*
00002   Copyright (C) 2010,2011,2012,2013 The ESPResSo project
00003   Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 
00004     Max-Planck-Institute for Polymer Research, Theory Group
00005   
00006   This file is part of ESPResSo.
00007   
00008   ESPResSo is free software: you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation, either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   ESPResSo is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
00020 */
00021 /** \file mpi.h
00022     This is the MPIfake implementation. This is NOT a real MPI implementation, but rather implements
00023     a subset of the MPI commands such that Espresso is able to run with a single processor. For this to work,
00024     you do not have to have any MPI implementation like LAM or MPICH installed.
00025 */
00026 
00027 #ifndef MPI_H
00028 #define MPI_H
00029 
00030 #include <string.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 
00034 //#include "utils.h"
00035 
00036 void errexit();
00037 
00038 #ifndef MDINLINE
00039  #define MDINLINE static inline
00040 #endif
00041 
00042 
00043 /********************************** REMARK **********************/
00044 /* This is the fake MPI header of Espresso, and has nothing to  */
00045 /* with Espresso's MPI handling using other mpi variants        */
00046 /********************************** REMARK **********************/
00047 
00048 typedef struct mpifake_dtype *MPI_Datatype;
00049 
00050 struct mpifake_dtype {
00051   int           format;
00052 #define LAM_DTBASIC             0               /* basic datatype */
00053 #define LAM_DTCONTIG            1               /* contiguous */
00054 #define LAM_DTVECTOR            2               /* vector */
00055 #define LAM_DTHVECTOR           3               /* hvector */
00056 #define LAM_DTINDEXED           4               /* indexed */
00057 #define LAM_DTHINDEXED          5               /* hindexed */
00058 #define LAM_DTSTRUCT            6               /* struct */
00059 #define LAM_DTHVECTORCREAT      7               /* extended vector */
00060 #define LAM_DTHINDEXEDCREAT     8               /* extended indexed */
00061 #define LAM_DTSTRUCTCREAT       9               /* extended struct */
00062 #define LAM_DTINDEXEDBLK        10              /* indexed block */
00063 #define LAM_DTSUBARRAY          11              /* local array */
00064 #define LAM_DTDARRAY            12              /* distributed array */
00065   int           lower;          /* lower extent */
00066   int           upper;          /* upper extent */
00067   int           size;           /* basic size */
00068   int           count;          /* count */
00069   int           length;         /* vector length */
00070   int           stride;         /* vector stride */
00071   MPI_Datatype  dtype;          /* c/v/i datatype */
00072   int           *lengths;       /* i/s lengths */
00073   int           *disps;         /* i/s displacements */
00074   MPI_Datatype  *dtypes;        /* struct datatypes */
00075 };
00076 
00077 typedef void *MPI_Status;
00078 typedef void *MPI_Comm;
00079 typedef void *MPI_Errhandler;
00080 typedef void *MPI_Request;
00081 typedef long MPI_Aint;
00082 
00083 typedef void (MPI_User_function)(void *, void *, int *, MPI_Datatype *);
00084 typedef void (MPI_Handler_function)(MPI_Comm *, int *, ...);
00085 
00086 typedef MPI_User_function *MPI_Op;
00087 
00088 void mpifake_copy(void *from, void *to, int *count, MPI_Datatype *dtype);
00089 int mpifake_sendrecv(void *s, int scount, MPI_Datatype sdtype,
00090                          void *r, int rcount, MPI_Datatype rdtype);
00091 
00092 #define MPI_LOR mpifake_copy
00093 #define MPI_SUM mpifake_copy
00094 #define MPI_MAX mpifake_copy
00095 #define MPI_COPY mpifake_copy
00096 
00097 #define MPI_STATUS_IGNORE NULL
00098 #define MPI_SUCCESS 1
00099 
00100 #define MPI_COMM_WORLD NULL
00101 
00102 #define MPI_REQUEST_NULL NULL
00103 
00104 #define MPI_ANY_SOURCE 0
00105 
00106 #define MPI_IN_PLACE (void*)0x1
00107 
00108 extern struct mpifake_dtype mpifake_dtype_int;
00109 extern struct mpifake_dtype mpifake_dtype_double;
00110 extern struct mpifake_dtype mpifake_dtype_byte;
00111 extern struct mpifake_dtype mpifake_dtype_long;
00112 extern struct mpifake_dtype mpifake_dtype_char;
00113 extern struct mpifake_dtype mpifake_dtype_ub;
00114 extern struct mpifake_dtype mpifake_dtype_lb;
00115 
00116 #define MPI_INT    (&mpifake_dtype_int)
00117 #define MPI_DOUBLE (&mpifake_dtype_double)
00118 #define MPI_BYTE   (&mpifake_dtype_byte)
00119 #define MPI_LONG   (&mpifake_dtype_long)
00120 #define MPI_CHAR   (&mpifake_dtype_char)
00121 #define MPI_LB     (&mpifake_dtype_lb)
00122 #define MPI_UB     (&mpifake_dtype_ub)
00123 #define MPI_DATATYPE_NULL NULL
00124 
00125 int MPI_Type_struct(int count, int *lengths, MPI_Aint *disps, MPI_Datatype *oldtypes, MPI_Datatype *newtype);
00126 int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype);
00127 int MPI_Type_vector(int count, int length, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype);
00128 int MPI_Type_hvector(int count, int length, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype);
00129 
00130 MDINLINE int MPI_Init(int *a, char ***b) { return MPI_SUCCESS; }
00131 MDINLINE int MPI_Finalize(void) { return MPI_SUCCESS; }
00132 MDINLINE int MPI_Comm_size(MPI_Comm comm, int *psize) { *psize = 1; return MPI_SUCCESS; }
00133 MDINLINE int MPI_Comm_rank(MPI_Comm comm, int *rank) { *rank = 0; return MPI_SUCCESS; }
00134 MDINLINE int MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank) { *rank = 0; return MPI_SUCCESS; }
00135 MDINLINE int MPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int *coords) { coords[0] = coords[1] = coords[2] = 0; return MPI_SUCCESS; }
00136 MDINLINE int MPI_Cart_shift(MPI_Comm comm, int direction, int disp, \
00137                             int *rank_source, int *rank_dest){ *rank_source = *rank_dest = 0; return MPI_SUCCESS; }
00138 MDINLINE int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods, int reorder, MPI_Comm *comm_cart)
00139 { *comm_cart = NULL; return MPI_SUCCESS; }
00140 MDINLINE int MPI_Dims_create(int nnodes, int ndims, int *dims){ dims[0] = dims[1] = dims[2] = 1; return MPI_SUCCESS; }
00141 MDINLINE int MPI_Comm_split(MPI_Comm comm, int colour, int key, MPI_Comm *newcomm) { return MPI_SUCCESS; }
00142 MDINLINE int MPI_Comm_free(MPI_Comm *comm) { return MPI_SUCCESS; }
00143 MDINLINE int MPI_Type_commit(MPI_Datatype *dtype) { return MPI_SUCCESS; }
00144 MDINLINE int MPI_Type_free(MPI_Datatype *dtype) { free(*dtype); *dtype = NULL; return MPI_SUCCESS; }
00145 MDINLINE int MPI_Type_extent(MPI_Datatype dtype, MPI_Aint *pextent) { *pextent = dtype->upper - dtype->lower; return MPI_SUCCESS; }
00146 MDINLINE int MPI_Barrier(MPI_Comm comm) { return MPI_SUCCESS; }
00147 MDINLINE int MPI_Waitall(int count, MPI_Request *reqs, MPI_Status *stats) { return MPI_SUCCESS; }
00148 MDINLINE int MPI_Wait(MPI_Request *reqs, MPI_Status *stats) { return MPI_SUCCESS; }
00149 MDINLINE int MPI_Errhandler_create(MPI_Handler_function *errfunc, MPI_Errhandler *errhdl) { return MPI_SUCCESS; }
00150 MDINLINE int MPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhdl) { return MPI_SUCCESS; }
00151 MDINLINE int MPI_Bcast(void *buff, int count, MPI_Datatype datatype, int root, MPI_Comm comm) { return MPI_SUCCESS; }
00152 
00153 #ifndef GNU_MPIFAKE_DEBUG
00154 
00155 MDINLINE int MPI_Recv(void *buf, int count, MPI_Datatype dtype, int src, int tag, MPI_Comm comm, MPI_Status *stat) {
00156   fprintf(stderr, "MPI_Recv on a single node\n"); errexit(); return MPI_SUCCESS; }
00157 MDINLINE int MPI_Irecv(void *buf, int count, MPI_Datatype dtype, int src, int tag, MPI_Comm comm, MPI_Request *req) {
00158   fprintf(stderr, "MPI_Recv on a single node\n"); errexit(); return MPI_SUCCESS; }
00159 MDINLINE int MPI_Send(void *buf, int count, MPI_Datatype dtype, int dst, int tag, MPI_Comm comm) {
00160   fprintf(stderr, "MPI_Recv on a single node\n"); errexit(); return MPI_SUCCESS; }
00161 MDINLINE int MPI_Sendrecv(void *sbuf, int scount, MPI_Datatype stype, int dst, int stag, void *rbuf, int rcount, MPI_Datatype rtype, int src, int rtag, MPI_Comm comm, MPI_Status *stat) {
00162   fprintf(stderr, "MPI_Sendrecv on a single node\n"); errexit(); return MPI_SUCCESS;
00163 }
00164 MDINLINE int MPI_Isend(void *buf, int count, MPI_Datatype dtype, int dst, int tag, MPI_Comm comm, MPI_Request *req) {
00165   fprintf(stderr, "MPI_Recv on a single node\n"); errexit(); return MPI_SUCCESS; }
00166 
00167 #else
00168 
00169 MDINLINE int __MPI_ERR(char *func, char *file, int line) {
00170   fprintf(stderr, "%s on a single node at %s:%d\n", func, file, line);
00171   errexit(); return MPI_ERR_RANK;
00172 }
00173 
00174 #define MPI_Recv(buf, count, dtype, src, tag, comm, stat)  __MPI_ERR("MPI_Recv", __FILE__, __LINE__)
00175 #define MPI_Irecv(buf, count, dtype, src, tag, comm, req) __MPI_ERR("MPI_IRecv", __FILE__, __LINE__)
00176 #define MPI_Send(buf, count, dtype, dst, tag, comm) __MPI_ERR("MPI_Send", __FILE__, __LINE__)
00177 #define MPI_Isend(buf, count, dtype, dst, tag, comm, req) __MPI_ERR("MPI_Isend", __FILE__, __LINE__)
00178 #define MPI_Sendrecv(sbuf, scount, stype, dst, stag, rbuf, rcount, rtype, src, rtag, comm, stat) \
00179   __MPI_ERR("MPI_Sendrecv", __FILE__, __LINE__)
00180 
00181 #endif
00182 
00183 MDINLINE int MPI_Gather(void *sbuf, int scount, MPI_Datatype sdtype,
00184                         void *rbuf, int rcount, MPI_Datatype rdtype,
00185                         int root, MPI_Comm comm)
00186 { return mpifake_sendrecv(sbuf, scount, sdtype, rbuf, rcount, rdtype); }
00187 MDINLINE int MPI_Allgather(void *sbuf, int scount, MPI_Datatype sdtype,
00188                            void *rbuf, int rcount, MPI_Datatype rdtype,
00189                            MPI_Comm comm)
00190 { return mpifake_sendrecv(sbuf, scount, sdtype, rbuf, rcount, rdtype); }
00191 MDINLINE int MPI_Scatter(void *sbuf, int scount, MPI_Datatype sdtype,
00192                          void *rbuf, int rcount, MPI_Datatype rdtype,
00193                          int root, MPI_Comm comm)
00194 { return mpifake_sendrecv(sbuf, scount, sdtype, rbuf, rcount, rdtype); }
00195 MDINLINE int MPI_Op_create(MPI_User_function func, int commute, MPI_Op *pop) { *pop = func; return MPI_SUCCESS; }
00196 MDINLINE int MPI_Reduce(void *sbuf, void* rbuf, int count, MPI_Datatype dtype, MPI_Op op, int root, MPI_Comm comm)
00197 { op(sbuf, rbuf, &count, &dtype); return MPI_SUCCESS; }
00198 MDINLINE int MPI_Allreduce(void *sbuf, void *rbuf, int count, MPI_Datatype dtype, MPI_Op op, MPI_Comm comm)
00199 { if(sbuf == MPI_IN_PLACE)
00200     return MPI_SUCCESS; 
00201   op(sbuf, rbuf, &count, &dtype); return MPI_SUCCESS; }
00202 MDINLINE int MPI_Error_string(int errcode, char *string, int *len) { *string = 0; *len = 0; return MPI_SUCCESS; }
00203 
00204 #endif