1 #ifndef MADNESS_STUBMPI_H
2 #define MADNESS_STUBMPI_H
3 
4 #include <madness/madness_config.h>
5 #include <cstddef>
6 #include <cstdlib>
7 #include <cstring>
8 #include <madness/world/timers.h>
9 
10 typedef int MPI_Group;
11 typedef int MPI_Request;
12 typedef struct MPI_Status {
13     int count;
14     int cancelled;
15     int MPI_SOURCE;
16     int MPI_TAG;
17     int MPI_ERROR;
18 
19 } MPI_Status;
20 #define MPI_STATUS_IGNORE ((MPI_Status *)1)
21 #define MPI_STATUSES_IGNORE ((MPI_Status *)1)
22 
23 typedef int MPI_Comm;
24 #define MPI_COMM_WORLD (0x44000000)
25 #define MPI_UNDEFINED      (-32766)
26 
27 typedef int MPI_Errhandler; // ehem?
28 
29 /* MPI's error classes */
30 /* these constants are consistent with MPICH2 mpi.h */
31 #define MPI_SUCCESS          0      /* Successful return code */
32 #define MPI_ERR_COMM         5      /* Invalid communicator */
33 #define MPI_ERR_ARG         12      /* Invalid argument */
34 #define MPI_ERR_IN_STATUS 999999
35 #define MPI_ERRORS_RETURN 888888
36 #define MPI_MAX_ERROR_STRING 1024
37 
38 /* Results of the compare operations. */
39 #define MPI_IDENT     0
40 #define MPI_CONGRUENT 1
41 #define MPI_SIMILAR   2
42 #define MPI_UNEQUAL   3
43 
44 /* MPI null objects */
45 #define MPI_COMM_NULL       ((MPI_Comm)0x04000000)
46 #define MPI_OP_NULL         ((MPI_Op)0x18000000)
47 #define MPI_GROUP_NULL      ((MPI_Group)0x08000000)
48 #define MPI_DATATYPE_NULL   ((MPI_Datatype)0x0c000000)
49 #define MPI_REQUEST_NULL    ((MPI_Request)0x2c000000)
50 #define MPI_ERRHANDLER_NULL ((MPI_Errhandler)0x14000000)
51 
52 /* MPI thread support levels */
53 /* these constants are consistent with MPICH2 mpi.h */
54 #define MPI_THREAD_SINGLE     0
55 #define MPI_THREAD_FUNNELED   1
56 #define MPI_THREAD_SERIALIZED 2
57 #define MPI_THREAD_MULTIPLE   3
58 
59 /* these constants are consistent with MPICH2 mpi.h */
60 #define MPI_IN_PLACE   ((void *) -1)
61 #define MPI_PROC_NULL  -1
62 #define MPI_ANY_SOURCE -2
63 #define MPI_ANY_TAG    -1
64 
65 /* MPI data types */
66 /* these constants are consistent with MPICH2 mpi.h */
67 typedef int MPI_Datatype;
68 #define MPI_CHAR               ((MPI_Datatype)0x4c000101)
69 #define MPI_SIGNED_CHAR        ((MPI_Datatype)0x4c000118)
70 #define MPI_UNSIGNED_CHAR      ((MPI_Datatype)0x4c000102)
71 #define MPI_BYTE               ((MPI_Datatype)0x4c00010d)
72 #define MPI_WCHAR              ((MPI_Datatype)0x4c00040e)
73 #define MPI_SHORT              ((MPI_Datatype)0x4c000203)
74 #define MPI_UNSIGNED_SHORT     ((MPI_Datatype)0x4c000204)
75 #define MPI_INT                ((MPI_Datatype)0x4c000405)
76 #define MPI_UNSIGNED           ((MPI_Datatype)0x4c000406)
77 #define MPI_LONG               ((MPI_Datatype)0x4c000807)
78 #define MPI_UNSIGNED_LONG      ((MPI_Datatype)0x4c000808)
79 #define MPI_FLOAT              ((MPI_Datatype)0x4c00040a)
80 #define MPI_DOUBLE             ((MPI_Datatype)0x4c00080b)
81 #define MPI_LONG_DOUBLE        ((MPI_Datatype)0x4c00100c)
82 #define MPI_LONG_LONG_INT      ((MPI_Datatype)0x4c000809)
83 #define MPI_UNSIGNED_LONG_LONG ((MPI_Datatype)0x4c000819)
84 #define MPI_LONG_LONG          ((MPI_Datatype)0x4c000809)
85 
86 /* MPI Reduction operation */
87 /* these constants are consistent with MPICH2 mpi.h */
88 typedef int MPI_Op;
89 #define MPI_MAX     ((MPI_Op)0x58000001)
90 #define MPI_MIN     ((MPI_Op)0x58000002)
91 #define MPI_SUM     ((MPI_Op)0x58000003)
92 #define MPI_PROD    ((MPI_Op)0x58000004)
93 #define MPI_LAND    ((MPI_Op)0x58000005)
94 #define MPI_BAND    ((MPI_Op)0x58000006)
95 #define MPI_LOR     ((MPI_Op)0x58000007)
96 #define MPI_BOR     ((MPI_Op)0x58000008)
97 #define MPI_LXOR    ((MPI_Op)0x58000009)
98 #define MPI_BXOR    ((MPI_Op)0x5800000a)
99 #define MPI_MINLOC  ((MPI_Op)0x5800000b)
100 #define MPI_MAXLOC  ((MPI_Op)0x5800000c)
101 #define MPI_REPLACE ((MPI_Op)0x5800000d)
102 
103 /* function type given to MPI_Op_create */
104 typedef void (MPI_User_function) ( void * a,
105                void * b, int * len, MPI_Datatype * );
106 
MPI_Group_translate_ranks(MPI_Group,int,const int[],MPI_Group,int ranks2[])107 inline int MPI_Group_translate_ranks(MPI_Group, int, const int [],
108                             MPI_Group, int ranks2[]) {
109     ranks2[0] = 0;
110     return MPI_SUCCESS;
111 }
112 
113 /* TODO The NO-OP implementation of may not be adequate. */
MPI_Group_incl(MPI_Group group,int n,const int ranks[],MPI_Group * newgroup)114 inline int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group *newgroup) {
115     return MPI_SUCCESS;
116 }
117 
118 /* TODO The NO-OP implementation may not be adequate. */
MPI_Group_free(MPI_Group * group)119 inline int MPI_Group_free(MPI_Group *group) {
120     return MPI_SUCCESS;
121 }
122 
123 // Initialization and finalize functions
MPI_Init(int *,char ***)124 inline int MPI_Init(int *, char ***) { return MPI_SUCCESS; }
MPI_Init_thread(int *,char ***,int,int * provided)125 inline int MPI_Init_thread(int *, char ***, int, int *provided) { *provided = MADNESS_MPI_THREAD_LEVEL; return MPI_SUCCESS; }
MPI_Initialized(int * flag)126 inline int MPI_Initialized(int* flag) { *flag = 1; return MPI_SUCCESS; }
MPI_Finalize()127 inline int MPI_Finalize() { return MPI_SUCCESS; }
MPI_Finalized(int * flag)128 inline int MPI_Finalized(int* flag) { *flag = 0; return MPI_SUCCESS; }
MPI_Query_thread(int * provided)129 inline int MPI_Query_thread(int *provided) { *provided = MADNESS_MPI_THREAD_LEVEL; return MPI_SUCCESS; }
130 
131 // Buffer functions (do nothing since no messages may be sent)
MPI_Buffer_attach(void *,int)132 inline int MPI_Buffer_attach(void*, int) { return MPI_SUCCESS; }
MPI_Buffer_detach(void * buffer,int * size)133 inline int MPI_Buffer_detach(void* buffer, int* size) { return MPI_SUCCESS; }
134 
MPI_Test(MPI_Request *,int * flag,MPI_Status *)135 inline int MPI_Test(MPI_Request *, int *flag, MPI_Status *) {
136     *flag = 1;
137     return MPI_SUCCESS;
138 }
139 
MPI_Testany(int,MPI_Request[],int * index,int * flag,MPI_Status *)140 inline int MPI_Testany(int, MPI_Request[], int* index, int *flag, MPI_Status*) {
141     *index = MPI_UNDEFINED;
142     *flag = 1;
143     return MPI_SUCCESS;
144 }
145 
MPI_Testsome(int,MPI_Request *,int * outcount,int *,MPI_Status *)146 inline int MPI_Testsome(int, MPI_Request*, int *outcount, int*, MPI_Status*) {
147     *outcount = MPI_UNDEFINED;
148     return MPI_SUCCESS;
149 }
150 
MPI_Get_count(MPI_Status *,MPI_Datatype,int * count)151 inline int MPI_Get_count(MPI_Status *, MPI_Datatype, int *count) {
152     *count = 0;
153     return MPI_SUCCESS;
154 }
155 
156 // Communicator rank and size
MPI_Comm_rank(MPI_Comm,int * rank)157 inline int MPI_Comm_rank(MPI_Comm, int* rank) { *rank = 0; return MPI_SUCCESS; }
MPI_Comm_size(MPI_Comm,int * size)158 inline unsigned int MPI_Comm_size(MPI_Comm, int* size) { *size = 1; return MPI_SUCCESS; }
159 
160 // There is only one node so sending messages is not allowed. Always return MPI_ERR_COMM
MPI_Isend(void *,int,MPI_Datatype,int,int,MPI_Comm,MPI_Request *)161 inline int MPI_Isend(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request *) { return MPI_ERR_COMM; }
MPI_Issend(void *,int,MPI_Datatype,int,int,MPI_Comm,MPI_Request *)162 inline int MPI_Issend(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request *) { return MPI_ERR_COMM; }
MPI_Send(void *,int,MPI_Datatype,int,int,MPI_Comm)163 inline int MPI_Send(void*, int, MPI_Datatype, int, int, MPI_Comm) { return MPI_ERR_COMM; }
MPI_Ssend(void *,int,MPI_Datatype,int,int,MPI_Comm)164 inline int MPI_Ssend(void*, int, MPI_Datatype, int, int, MPI_Comm) { return MPI_ERR_COMM; }
MPI_Bsend(void *,int,MPI_Datatype,int,int,MPI_Comm)165 inline int MPI_Bsend(void*, int, MPI_Datatype, int, int, MPI_Comm) { return MPI_ERR_COMM; }
MPI_Irecv(void *,int,MPI_Datatype,int,int,MPI_Comm,MPI_Request *)166 inline int MPI_Irecv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request*) { return MPI_ERR_COMM; }
MPI_Recv(void *,int,MPI_Datatype,int,int,MPI_Comm,MPI_Status *)167 inline int MPI_Recv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status*) { return MPI_ERR_COMM; }
168 
169 // Bcast does nothing but return MPI_SUCCESS
MPI_Bcast(void *,int,MPI_Datatype,int,MPI_Comm)170 inline int MPI_Bcast(void*, int, MPI_Datatype, int, MPI_Comm) { return MPI_SUCCESS; }
171 
172 // Reduce does memcpy and returns MPI_SUCCESS
MPI_Reduce(void * sendbuf,void * recvbuf,int count,MPI_Datatype,MPI_Op,int,MPI_Comm)173 inline int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype, MPI_Op, int, MPI_Comm) {
174     if(sendbuf != MPI_IN_PLACE) std::memcpy(recvbuf, sendbuf, count);
175     return MPI_SUCCESS;
176 }
MPI_Allreduce(void * sendbuf,void * recvbuf,int count,MPI_Datatype,MPI_Op,MPI_Comm)177 inline int MPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype, MPI_Op, MPI_Comm) {
178     if(sendbuf != MPI_IN_PLACE) std::memcpy(recvbuf, sendbuf, count);
179     return MPI_SUCCESS;
180 }
181 
MPI_Comm_get_attr(MPI_Comm,int,void *,int *)182 inline int MPI_Comm_get_attr(MPI_Comm, int, void*, int*) { return MPI_ERR_COMM; }
183 
MPI_Comm_split(MPI_Comm comm,int color,int key,MPI_Comm * newcomm)184 inline int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm) { return MPI_ERR_COMM; }
185 
MPI_Abort(MPI_Comm,int code)186 inline int MPI_Abort(MPI_Comm, int code) { exit(code); return MPI_SUCCESS; }
187 
MPI_Barrier(MPI_Comm)188 inline int MPI_Barrier(MPI_Comm) { return MPI_SUCCESS; }
189 
MPI_Comm_create(MPI_Comm,MPI_Group,MPI_Comm * newcomm)190 inline int MPI_Comm_create(MPI_Comm,  MPI_Group, MPI_Comm *newcomm) {
191     *newcomm = MPI_COMM_NULL;
192     return MPI_SUCCESS;
193 }
194 
MPI_Comm_group(MPI_Comm,MPI_Group * group)195 inline int MPI_Comm_group(MPI_Comm, MPI_Group* group) {
196     *group = MPI_GROUP_NULL;
197     return MPI_SUCCESS;
198 }
199 
MPI_Comm_free(MPI_Comm * comm)200 inline int MPI_Comm_free(MPI_Comm * comm) {
201     *comm = MPI_COMM_NULL;
202     return MPI_SUCCESS;
203 }
204 
MPI_Comm_compare(MPI_Comm comm1,MPI_Comm comm2,int * result)205 inline int MPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result) {
206     if (comm1 == comm2) {
207         *result = MPI_IDENT;
208     } else {
209         *result = MPI_UNEQUAL;
210     }
211     return MPI_SUCCESS;
212 }
213 
214 
MPI_Error_string(int errorcode,char * string,int * resultlen)215 inline int MPI_Error_string(int errorcode, char *string, int *resultlen) {
216     switch(errorcode) {
217         case MPI_SUCCESS:
218             *resultlen = 8;
219             std::strncpy(string, "Success", *resultlen);
220             break;
221         case MPI_ERR_COMM:
222             *resultlen = 21;
223             std::strncpy(string, "Invalid communicator", *resultlen);
224             break;
225         case MPI_ERR_ARG:
226             *resultlen = 17;
227             std::strncpy(string, "Invalid argument", *resultlen);
228             break;
229         default:
230             return MPI_ERR_ARG;
231             break;
232     }
233 
234     return MPI_SUCCESS;
235 }
236 
MPI_Comm_set_errhandler(MPI_Comm comm,MPI_Errhandler errhandler)237 inline int MPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler) {return MPI_SUCCESS;}
238 
MPI_Wtime()239 inline double MPI_Wtime() { return madness::wall_time(); }
240 
MPI_Op_create(MPI_User_function * user_fn,int commute,MPI_Op * op)241 inline int MPI_Op_create(MPI_User_function *user_fn, int commute, MPI_Op *op) {
242   return MPI_SUCCESS;
243 }
244 
MPI_Op_free(MPI_Op * op)245 inline int MPI_Op_free(MPI_Op *op) {
246   return MPI_SUCCESS;
247 }
248 
249 #endif
250