2 * Copyright 2009-2013 Distene SAS
9 #include "meshgems_mpi.h"
13 static MPI_Datatype *meshgems_mpi_datatype_map = NULL;
14 static MPI_Op *meshgems_mpi_op_map = NULL;
15 static int meshgems_mpi_datatype_count = 0;
16 static int meshgems_mpi_op_count = 0;
18 struct meshgems_mpi_handler_
23 /* note : MPI standard states that a MPI_Datatype is a simple type (pointer or int) */
25 static inline int meshgems_mpi_find_type(meshgems_mpi_datatype datatype, MPI_Datatype *odt)
27 if(meshgems_mpi_datatype_map && datatype > 0 && datatype <= meshgems_mpi_datatype_count) {
28 *odt = meshgems_mpi_datatype_map[datatype];
29 return MESHGEMS_MPI_SUCCESS;
32 return MESHGEMS_MPI_ERR;
35 int meshgems_mpi_type_new(int count, int *array_of_blocklengths, long *array_of_displacements,
36 meshgems_mpi_datatype *array_of_types, meshgems_mpi_datatype *newtype)
38 MPI_Datatype nt, *aot;
43 ret = MESHGEMS_MPI_SUCCESS;
45 aot = (MPI_Datatype *) calloc(count, sizeof(MPI_Datatype));
46 aod = (MPI_Aint *) calloc(count, sizeof(MPI_Aint));
48 ret = MESHGEMS_MPI_ERR;
52 for(i = 0;i < count;i++) {
54 r = meshgems_mpi_find_type(array_of_types[i], aot+i);
55 if(r != MESHGEMS_MPI_SUCCESS){
60 aot[i] = meshgems_mpi_datatype_map[array_of_types[i]];
61 aod[i] = (MPI_Aint) array_of_displacements[i];
64 r = MPI_Type_create_struct(count, array_of_blocklengths, aod, aot, &nt);
65 /* With MPI1 you can use :
66 r = MPI_Type_struct(count, array_of_blocklengths,
70 if(r != MPI_SUCCESS) {
71 ret = MESHGEMS_MPI_ERR;
74 r = MPI_Type_commit(&nt);
75 if(r != MPI_SUCCESS) {
76 ret = MESHGEMS_MPI_ERR;
80 meshgems_mpi_datatype_count++;
81 t = realloc(meshgems_mpi_datatype_map, (meshgems_mpi_datatype_count + 1) * sizeof(MPI_Datatype));
83 ret = MESHGEMS_MPI_ERR;
86 meshgems_mpi_datatype_map = (MPI_Datatype *) t;
87 meshgems_mpi_datatype_map[meshgems_mpi_datatype_count] = nt;
88 *newtype = meshgems_mpi_datatype_count;
98 int meshgems_mpi_type_delete(meshgems_mpi_datatype datatype)
101 return MESHGEMS_MPI_SUCCESS;
104 int meshgems_mpi_init(int *argc, char ***argv)
108 ret = MESHGEMS_MPI_SUCCESS;
110 meshgems_mpi_datatype_map = calloc(meshgems_mpi_datatype_enum_count, sizeof(MPI_Datatype));
111 meshgems_mpi_op_map = calloc(meshgems_mpi_op_enum_count, sizeof(MPI_Op));
112 if(!meshgems_mpi_datatype_map || !meshgems_mpi_op_map) {
113 ret = MESHGEMS_MPI_ERR;
116 meshgems_mpi_datatype_count = meshgems_mpi_datatype_enum_count - 1;
117 meshgems_mpi_op_count = meshgems_mpi_op_enum_count - 1;
119 if(sizeof(int) == 4) {
120 meshgems_mpi_datatype_map[meshgems_mpi_datatype_i4] = MPI_INT;
121 } else if(sizeof(int) == 4) {
122 meshgems_mpi_datatype_map[meshgems_mpi_datatype_i4] = MPI_SHORT;
124 fprintf(stderr, "Unable to find mpi type for 4 bytes integer\n");
125 ret = MESHGEMS_MPI_ERR;
129 if(sizeof(int) == 8) {
130 meshgems_mpi_datatype_map[meshgems_mpi_datatype_i8] = MPI_INT;
131 } else if(sizeof(long) == 8) {
132 meshgems_mpi_datatype_map[meshgems_mpi_datatype_i8] = MPI_LONG;
133 } else if(sizeof(long long) == 8) {
134 meshgems_mpi_datatype_map[meshgems_mpi_datatype_i8] = MPI_LONG_LONG;
136 fprintf(stderr, "Unable to find mpi type for 8 bytes integer\n");
137 ret = MESHGEMS_MPI_ERR;
141 if(sizeof(float) == 4) {
142 meshgems_mpi_datatype_map[meshgems_mpi_datatype_r4] = MPI_FLOAT;
144 fprintf(stderr, "Unable to find mpi type for 4 bytes real\n");
145 ret = MESHGEMS_MPI_ERR;
149 if(sizeof(double) == 8) {
150 meshgems_mpi_datatype_map[meshgems_mpi_datatype_r8] = MPI_DOUBLE;
152 fprintf(stderr, "Unable to find mpi type for 8 bytes real\n");
153 ret = MESHGEMS_MPI_ERR;
157 meshgems_mpi_op_map[meshgems_mpi_op_max] = MPI_MAX;
158 meshgems_mpi_op_map[meshgems_mpi_op_sum] = MPI_SUM;
160 MPI_Init(argc, argv);
164 if(ret != MESHGEMS_MPI_SUCCESS) {
165 if(meshgems_mpi_datatype_map)
166 free(meshgems_mpi_datatype_map);
167 if(meshgems_mpi_op_map)
168 free(meshgems_mpi_op_map);
174 int meshgems_mpi_rank(int *r)
176 MPI_Comm_rank(MPI_COMM_WORLD, r);
178 return MESHGEMS_MPI_SUCCESS;
181 int meshgems_mpi_size(int *n)
183 MPI_Comm_size(MPI_COMM_WORLD, n);
185 return MESHGEMS_MPI_SUCCESS;
188 int meshgems_mpi_finalize(void)
192 return MESHGEMS_MPI_SUCCESS;
195 meshgems_mpi_handler *meshgems_mpi_handler_new(void)
197 meshgems_mpi_handler *handler;
199 handler = calloc(1, sizeof(meshgems_mpi_handler));
204 void meshgems_mpi_handler_delete(meshgems_mpi_handler *handler)
210 int meshgems_mpi_send(void* buffer, int count, meshgems_mpi_datatype datatype, int dest, int tag)
216 dtt = meshgems_mpi_datatype_map[datatype];
218 r = MPI_Send(buffer, count, dtt, dest, tag, MPI_COMM_WORLD);
220 if(r != MPI_SUCCESS) {
221 ret = MESHGEMS_MPI_ERR;
223 ret = MESHGEMS_MPI_SUCCESS;
229 int meshgems_mpi_isend(void* buffer, int count, meshgems_mpi_datatype datatype, int dest, int tag,
230 meshgems_mpi_handler *handler)
236 dtt = meshgems_mpi_datatype_map[datatype];
238 r = MPI_Isend(buffer, count, dtt, dest, tag, MPI_COMM_WORLD, &(handler->rq));
240 if(r != MPI_SUCCESS) {
241 ret = MESHGEMS_MPI_ERR;
243 ret = MESHGEMS_MPI_SUCCESS;
249 int meshgems_mpi_wait(meshgems_mpi_handler *handler)
254 r = MPI_Wait(&(handler->rq), MPI_STATUS_IGNORE );
256 if(r != MPI_SUCCESS) {
257 ret = MESHGEMS_MPI_ERR;
259 ret = MESHGEMS_MPI_SUCCESS;
265 int meshgems_mpi_recv(void* buffer, int count, meshgems_mpi_datatype datatype, int src, int tag)
271 dtt = meshgems_mpi_datatype_map[datatype];
273 if(src == MESHGEMS_MPI_ANY_SOURCE) {
274 src = MPI_ANY_SOURCE;
277 r = MPI_Recv(buffer, count, dtt, src, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
279 if(r != MPI_SUCCESS) {
280 ret = MESHGEMS_MPI_ERR;
282 ret = MESHGEMS_MPI_SUCCESS;
288 int meshgems_mpi_reduce(void *sendbuf, void *recvbuf, int count, meshgems_mpi_datatype datatype,
289 meshgems_mpi_op op, int root)
296 dtt = meshgems_mpi_datatype_map[datatype];
297 mop = meshgems_mpi_op_map[op];
299 r = MPI_Reduce(sendbuf, recvbuf, count, dtt, mop, root, MPI_COMM_WORLD);
301 if(r != MPI_SUCCESS) {
302 ret = MESHGEMS_MPI_ERR;
304 ret = MESHGEMS_MPI_SUCCESS;
310 int meshgems_mpi_allreduce(void *sendbuf, void *recvbuf, int count, meshgems_mpi_datatype datatype,
318 dtt = meshgems_mpi_datatype_map[datatype];
319 mop = meshgems_mpi_op_map[op];
321 r = MPI_Allreduce(sendbuf, recvbuf, count, dtt, mop, MPI_COMM_WORLD);
323 if(r != MPI_SUCCESS) {
324 ret = MESHGEMS_MPI_ERR;
326 ret = MESHGEMS_MPI_SUCCESS;
332 int meshgems_mpi_gather(void *sendbuf, int sendcount, meshgems_mpi_datatype sendtype, void *recvbuf,
333 int recvcount, meshgems_mpi_datatype recvtype, int root)
337 MPI_Datatype sdtt, rdtt;
339 sdtt = meshgems_mpi_datatype_map[sendtype];
340 rdtt = meshgems_mpi_datatype_map[recvtype];
342 r = MPI_Gather(sendbuf, sendcount, sdtt, recvbuf, recvcount, rdtt, root, MPI_COMM_WORLD);
344 if(r != MPI_SUCCESS) {
345 ret = MESHGEMS_MPI_ERR;
347 ret = MESHGEMS_MPI_SUCCESS;
353 int meshgems_mpi_allgather(void *sendbuf, int sendcount, meshgems_mpi_datatype sendtype,
354 void *recvbuf, int recvcount, meshgems_mpi_datatype recvtype)
358 MPI_Datatype sdtt, rdtt;
360 ret = MESHGEMS_MPI_SUCCESS;
362 sdtt = meshgems_mpi_datatype_map[sendtype];
363 rdtt = meshgems_mpi_datatype_map[recvtype];
365 r = MPI_Allgather(sendbuf, sendcount, sdtt, recvbuf, recvcount, rdtt, MPI_COMM_WORLD);
366 if(r != MPI_SUCCESS) {
367 ret = MESHGEMS_MPI_ERR;
376 int meshgems_mpi_allgatherv(void *sendbuf, int sendcount, meshgems_mpi_datatype sendtype,
377 void *recvbuf, int *recvcount, int *displs, meshgems_mpi_datatype recvtype)
381 MPI_Datatype sdtt, rdtt;
383 sdtt = meshgems_mpi_datatype_map[sendtype];
384 rdtt = meshgems_mpi_datatype_map[recvtype];
386 r = MPI_Allgatherv(sendbuf, sendcount, sdtt, recvbuf, recvcount, displs, rdtt, MPI_COMM_WORLD);
388 if(r != MPI_SUCCESS) {
389 ret = MESHGEMS_MPI_ERR;
391 ret = MESHGEMS_MPI_SUCCESS;
397 int meshgems_mpi_barrier(void)
402 r = MPI_Barrier(MPI_COMM_WORLD);
404 if(r != MPI_SUCCESS) {
405 ret = MESHGEMS_MPI_ERR;
407 ret = MESHGEMS_MPI_SUCCESS;
413 int meshgems_mpi_abort(int errorcode)
418 r = MPI_Abort(MPI_COMM_WORLD, errorcode);
420 if(r != MPI_SUCCESS) {
421 ret = MESHGEMS_MPI_ERR;
423 ret = MESHGEMS_MPI_SUCCESS;