Salome HOME
Increment version: 9.8.0
[plugins/ghs3dprlplugin.git] / bin / meshgems_mpi.c
1 /*
2  * Copyright 2009-2013 Distene SAS
3  *
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 #include "meshgems_mpi.h"
10
11 #include <mpi.h>
12
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;
17
18 struct meshgems_mpi_handler_
19 {
20   MPI_Request rq;
21 };
22
23 /* note : MPI standard states that a MPI_Datatype is a simple type (pointer or int) */
24
25 static inline int meshgems_mpi_find_type(meshgems_mpi_datatype datatype, MPI_Datatype *odt)
26 {
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;
30   }
31
32   return MESHGEMS_MPI_ERR;
33 }
34
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)
37 {
38   MPI_Datatype nt, *aot;
39   MPI_Aint *aod;
40   int ret, r, i;
41   void *t;
42
43   ret = MESHGEMS_MPI_SUCCESS;
44
45   aot = (MPI_Datatype *) calloc(count, sizeof(MPI_Datatype));
46   aod = (MPI_Aint *) calloc(count, sizeof(MPI_Aint));
47   if(!aot || !aod) {
48     ret = MESHGEMS_MPI_ERR;
49     goto out;
50   }
51
52   for(i = 0;i < count;i++) {
53     /*
54      r = meshgems_mpi_find_type(array_of_types[i], aot+i);
55      if(r != MESHGEMS_MPI_SUCCESS){
56      ret  = r;
57      goto out;
58      }
59      */
60     aot[i] = meshgems_mpi_datatype_map[array_of_types[i]];
61     aod[i] = (MPI_Aint) array_of_displacements[i];
62   }
63
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,
67    aod, aot, &nt);
68    */
69
70   if(r != MPI_SUCCESS) {
71     ret = MESHGEMS_MPI_ERR;
72     goto out;
73   }
74   r = MPI_Type_commit(&nt);
75   if(r != MPI_SUCCESS) {
76     ret = MESHGEMS_MPI_ERR;
77     goto out;
78   }
79
80   meshgems_mpi_datatype_count++;
81   t = realloc(meshgems_mpi_datatype_map, (meshgems_mpi_datatype_count + 1) * sizeof(MPI_Datatype));
82   if(!t) {
83     ret = MESHGEMS_MPI_ERR;
84     goto out;
85   }
86   meshgems_mpi_datatype_map = (MPI_Datatype *) t;
87   meshgems_mpi_datatype_map[meshgems_mpi_datatype_count] = nt;
88   *newtype = meshgems_mpi_datatype_count;
89
90   out: if(aod)
91     free(aod);
92   if(aot)
93     free(aot);
94
95   return ret;
96 }
97
98 int meshgems_mpi_type_delete(meshgems_mpi_datatype datatype)
99 {
100   /* no op for now */
101   return MESHGEMS_MPI_SUCCESS;
102 }
103
104 int meshgems_mpi_init(int *argc, char ***argv)
105 {
106   int ret;
107
108   ret = MESHGEMS_MPI_SUCCESS;
109
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;
114     goto out;
115   }
116   meshgems_mpi_datatype_count = meshgems_mpi_datatype_enum_count - 1;
117   meshgems_mpi_op_count = meshgems_mpi_op_enum_count - 1;
118
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;
123   } else {
124     fprintf(stderr, "Unable to find mpi type for 4 bytes integer\n");
125     ret = MESHGEMS_MPI_ERR;
126     goto out;
127   }
128
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;
135   } else {
136     fprintf(stderr, "Unable to find mpi type for 8 bytes integer\n");
137     ret = MESHGEMS_MPI_ERR;
138     goto out;
139   }
140
141   if(sizeof(float) == 4) {
142     meshgems_mpi_datatype_map[meshgems_mpi_datatype_r4] = MPI_FLOAT;
143   } else {
144     fprintf(stderr, "Unable to find mpi type for 4 bytes real\n");
145     ret = MESHGEMS_MPI_ERR;
146     goto out;
147   }
148
149   if(sizeof(double) == 8) {
150     meshgems_mpi_datatype_map[meshgems_mpi_datatype_r8] = MPI_DOUBLE;
151   } else {
152     fprintf(stderr, "Unable to find mpi type for 8 bytes real\n");
153     ret = MESHGEMS_MPI_ERR;
154     goto out;
155   }
156
157   meshgems_mpi_op_map[meshgems_mpi_op_max] = MPI_MAX;
158   meshgems_mpi_op_map[meshgems_mpi_op_sum] = MPI_SUM;
159
160   MPI_Init(argc, argv);
161
162   out:
163
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);
169   }
170
171   return ret;
172 }
173
174 int meshgems_mpi_rank(int *r)
175 {
176   MPI_Comm_rank(MPI_COMM_WORLD, r);
177
178   return MESHGEMS_MPI_SUCCESS;
179 }
180
181 int meshgems_mpi_size(int *n)
182 {
183   MPI_Comm_size(MPI_COMM_WORLD, n);
184
185   return MESHGEMS_MPI_SUCCESS;
186 }
187
188 int meshgems_mpi_finalize(void)
189 {
190   MPI_Finalize();
191
192   return MESHGEMS_MPI_SUCCESS;
193 }
194
195 meshgems_mpi_handler *meshgems_mpi_handler_new(void)
196 {
197   meshgems_mpi_handler *handler;
198
199   handler = calloc(1, sizeof(meshgems_mpi_handler));
200
201   return handler;
202 }
203
204 void meshgems_mpi_handler_delete(meshgems_mpi_handler *handler)
205 {
206   if(handler)
207     free(handler);
208 }
209
210 int meshgems_mpi_send(void* buffer, int count, meshgems_mpi_datatype datatype, int dest, int tag)
211 {
212   int ret;
213   int r;
214   MPI_Datatype dtt;
215
216   dtt = meshgems_mpi_datatype_map[datatype];
217
218   r = MPI_Send(buffer, count, dtt, dest, tag, MPI_COMM_WORLD);
219
220   if(r != MPI_SUCCESS) {
221     ret = MESHGEMS_MPI_ERR;
222   } else {
223     ret = MESHGEMS_MPI_SUCCESS;
224   }
225
226   return ret;
227 }
228
229 int meshgems_mpi_isend(void* buffer, int count, meshgems_mpi_datatype datatype, int dest, int tag,
230     meshgems_mpi_handler *handler)
231 {
232   int ret;
233   int r;
234   MPI_Datatype dtt;
235
236   dtt = meshgems_mpi_datatype_map[datatype];
237
238   r = MPI_Isend(buffer, count, dtt, dest, tag, MPI_COMM_WORLD, &(handler->rq));
239
240   if(r != MPI_SUCCESS) {
241     ret = MESHGEMS_MPI_ERR;
242   } else {
243     ret = MESHGEMS_MPI_SUCCESS;
244   }
245
246   return ret;
247 }
248
249 int meshgems_mpi_wait(meshgems_mpi_handler *handler)
250 {
251   int ret;
252   int r;
253
254   r = MPI_Wait(&(handler->rq), MPI_STATUS_IGNORE );
255
256   if(r != MPI_SUCCESS) {
257     ret = MESHGEMS_MPI_ERR;
258   } else {
259     ret = MESHGEMS_MPI_SUCCESS;
260   }
261
262   return ret;
263 }
264
265 int meshgems_mpi_recv(void* buffer, int count, meshgems_mpi_datatype datatype, int src, int tag)
266 {
267   int ret;
268   int r;
269   MPI_Datatype dtt;
270
271   dtt = meshgems_mpi_datatype_map[datatype];
272
273   if(src == MESHGEMS_MPI_ANY_SOURCE) {
274     src = MPI_ANY_SOURCE;
275   }
276
277   r = MPI_Recv(buffer, count, dtt, src, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
278
279   if(r != MPI_SUCCESS) {
280     ret = MESHGEMS_MPI_ERR;
281   } else {
282     ret = MESHGEMS_MPI_SUCCESS;
283   }
284
285   return ret;
286 }
287
288 int meshgems_mpi_reduce(void *sendbuf, void *recvbuf, int count, meshgems_mpi_datatype datatype,
289     meshgems_mpi_op op, int root)
290 {
291   int ret;
292   int r;
293   MPI_Datatype dtt;
294   MPI_Op mop;
295
296   dtt = meshgems_mpi_datatype_map[datatype];
297   mop = meshgems_mpi_op_map[op];
298
299   r = MPI_Reduce(sendbuf, recvbuf, count, dtt, mop, root, MPI_COMM_WORLD);
300
301   if(r != MPI_SUCCESS) {
302     ret = MESHGEMS_MPI_ERR;
303   } else {
304     ret = MESHGEMS_MPI_SUCCESS;
305   }
306
307   return ret;
308 }
309
310 int meshgems_mpi_allreduce(void *sendbuf, void *recvbuf, int count, meshgems_mpi_datatype datatype,
311     meshgems_mpi_op op)
312 {
313   int ret;
314   int r;
315   MPI_Datatype dtt;
316   MPI_Op mop;
317
318   dtt = meshgems_mpi_datatype_map[datatype];
319   mop = meshgems_mpi_op_map[op];
320
321   r = MPI_Allreduce(sendbuf, recvbuf, count, dtt, mop, MPI_COMM_WORLD);
322
323   if(r != MPI_SUCCESS) {
324     ret = MESHGEMS_MPI_ERR;
325   } else {
326     ret = MESHGEMS_MPI_SUCCESS;
327   }
328
329   return ret;
330 }
331
332 int meshgems_mpi_gather(void *sendbuf, int sendcount, meshgems_mpi_datatype sendtype, void *recvbuf,
333     int recvcount, meshgems_mpi_datatype recvtype, int root)
334 {
335   int ret;
336   int r;
337   MPI_Datatype sdtt, rdtt;
338
339   sdtt = meshgems_mpi_datatype_map[sendtype];
340   rdtt = meshgems_mpi_datatype_map[recvtype];
341
342   r = MPI_Gather(sendbuf, sendcount, sdtt, recvbuf, recvcount, rdtt, root, MPI_COMM_WORLD);
343
344   if(r != MPI_SUCCESS) {
345     ret = MESHGEMS_MPI_ERR;
346   } else {
347     ret = MESHGEMS_MPI_SUCCESS;
348   }
349
350   return ret;
351 }
352
353 int meshgems_mpi_allgather(void *sendbuf, int sendcount, meshgems_mpi_datatype sendtype,
354     void *recvbuf, int recvcount, meshgems_mpi_datatype recvtype)
355 {
356   int ret;
357   int r;
358   MPI_Datatype sdtt, rdtt;
359
360   ret = MESHGEMS_MPI_SUCCESS;
361
362   sdtt = meshgems_mpi_datatype_map[sendtype];
363   rdtt = meshgems_mpi_datatype_map[recvtype];
364
365   r = MPI_Allgather(sendbuf, sendcount, sdtt, recvbuf, recvcount, rdtt, MPI_COMM_WORLD);
366   if(r != MPI_SUCCESS) {
367     ret = MESHGEMS_MPI_ERR;
368     goto out;
369   }
370
371   out:
372
373   return ret;
374 }
375
376 int meshgems_mpi_allgatherv(void *sendbuf, int sendcount, meshgems_mpi_datatype sendtype,
377     void *recvbuf, int *recvcount, int *displs, meshgems_mpi_datatype recvtype)
378 {
379   int ret;
380   int r;
381   MPI_Datatype sdtt, rdtt;
382
383   sdtt = meshgems_mpi_datatype_map[sendtype];
384   rdtt = meshgems_mpi_datatype_map[recvtype];
385
386   r = MPI_Allgatherv(sendbuf, sendcount, sdtt, recvbuf, recvcount, displs, rdtt, MPI_COMM_WORLD);
387
388   if(r != MPI_SUCCESS) {
389     ret = MESHGEMS_MPI_ERR;
390   } else {
391     ret = MESHGEMS_MPI_SUCCESS;
392   }
393
394   return ret;
395 }
396
397 int meshgems_mpi_barrier(void)
398 {
399   int ret;
400   int r;
401
402   r = MPI_Barrier(MPI_COMM_WORLD);
403
404   if(r != MPI_SUCCESS) {
405     ret = MESHGEMS_MPI_ERR;
406   } else {
407     ret = MESHGEMS_MPI_SUCCESS;
408   }
409
410   return ret;
411 }
412
413 int meshgems_mpi_abort(int errorcode)
414 {
415   int ret;
416   int r;
417
418   r = MPI_Abort(MPI_COMM_WORLD, errorcode);
419
420   if(r != MPI_SUCCESS) {
421     ret = MESHGEMS_MPI_ERR;
422   } else {
423     ret = MESHGEMS_MPI_SUCCESS;
424   }
425
426   return ret;
427 }