Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
700870df075322c47c130b0b7afc2abf2dbde002
[simgrid.git] / src / smpi / smpi_mpi_dt.c
1 /* smpi_mpi_dt.c -- MPI primitives to handle datatypes                        */
2 /* FIXME: a very incomplete implementation                                    */
3
4 /* Copyright (c) 2009, 2010. The SimGrid Team.
5  * All rights reserved.                                                     */
6
7 /* This program is free software; you can redistribute it and/or modify it
8   * under the terms of the license (GNU LGPL) which comes with this package. */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "private.h"
15 #include "smpi_mpi_dt_private.h"
16
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi,
18                                 "Logging specific to SMPI (datatype)");
19
20 typedef struct s_smpi_mpi_datatype {
21   size_t size;
22   MPI_Aint lb;
23   MPI_Aint ub;
24   int flags;
25 } s_smpi_mpi_datatype_t;
26
27 #define CREATE_MPI_DATATYPE(name, type)       \
28   static s_smpi_mpi_datatype_t mpi_##name = { \
29     sizeof(type),  /* size */                 \
30     0,             /* lb */                   \
31     sizeof(type),  /* ub = lb + size */       \
32     DT_FLAG_BASIC  /* flags */                \
33   };                                          \
34   MPI_Datatype name = &mpi_##name;
35
36
37 //The following are datatypes for the MPI functions MPI_MAXLOC and MPI_MINLOC.
38 typedef struct {
39   float value;
40   int index;
41 } float_int;
42 typedef struct {
43   long value;
44   int index;
45 } long_int;
46 typedef struct {
47   double value;
48   int index;
49 } double_int;
50 typedef struct {
51   short value;
52   int index;
53 } short_int;
54 typedef struct {
55   int value;
56   int index;
57 } int_int;
58 typedef struct {
59   long double value;
60   int index;
61 } long_double_int;
62
63 // Predefined data types
64 CREATE_MPI_DATATYPE(MPI_CHAR, char);
65 CREATE_MPI_DATATYPE(MPI_SHORT, short);
66 CREATE_MPI_DATATYPE(MPI_INT, int);
67 CREATE_MPI_DATATYPE(MPI_LONG, long);
68 CREATE_MPI_DATATYPE(MPI_LONG_LONG, long long);
69 CREATE_MPI_DATATYPE(MPI_SIGNED_CHAR, signed char);
70 CREATE_MPI_DATATYPE(MPI_UNSIGNED_CHAR, unsigned char);
71 CREATE_MPI_DATATYPE(MPI_UNSIGNED_SHORT, unsigned short);
72 CREATE_MPI_DATATYPE(MPI_UNSIGNED, unsigned int);
73 CREATE_MPI_DATATYPE(MPI_UNSIGNED_LONG, unsigned long);
74 CREATE_MPI_DATATYPE(MPI_UNSIGNED_LONG_LONG, unsigned long long);
75 CREATE_MPI_DATATYPE(MPI_FLOAT, float);
76 CREATE_MPI_DATATYPE(MPI_DOUBLE, double);
77 CREATE_MPI_DATATYPE(MPI_LONG_DOUBLE, long double);
78 CREATE_MPI_DATATYPE(MPI_WCHAR, wchar_t);
79 CREATE_MPI_DATATYPE(MPI_C_BOOL, _Bool);
80 CREATE_MPI_DATATYPE(MPI_INT8_T, int8_t);
81 CREATE_MPI_DATATYPE(MPI_INT16_T, int16_t);
82 CREATE_MPI_DATATYPE(MPI_INT32_T, int32_t);
83 CREATE_MPI_DATATYPE(MPI_INT64_T, int64_t);
84 CREATE_MPI_DATATYPE(MPI_UINT8_T, uint8_t);
85 CREATE_MPI_DATATYPE(MPI_UINT16_T, uint16_t);
86 CREATE_MPI_DATATYPE(MPI_UINT32_T, uint32_t);
87 CREATE_MPI_DATATYPE(MPI_UINT64_T, uint64_t);
88 CREATE_MPI_DATATYPE(MPI_C_FLOAT_COMPLEX, float _Complex);
89 CREATE_MPI_DATATYPE(MPI_C_DOUBLE_COMPLEX, double _Complex);
90 CREATE_MPI_DATATYPE(MPI_C_LONG_DOUBLE_COMPLEX, long double _Complex);
91 CREATE_MPI_DATATYPE(MPI_AINT, MPI_Aint);
92 CREATE_MPI_DATATYPE(MPI_OFFSET, MPI_Offset);
93
94 CREATE_MPI_DATATYPE(MPI_FLOAT_INT, float_int);
95 CREATE_MPI_DATATYPE(MPI_LONG_INT, long_int);
96 CREATE_MPI_DATATYPE(MPI_DOUBLE_INT, double_int);
97 CREATE_MPI_DATATYPE(MPI_SHORT_INT, short_int);
98 CREATE_MPI_DATATYPE(MPI_2INT, int_int);
99 CREATE_MPI_DATATYPE(MPI_LONG_DOUBLE_INT, long_double_int);
100
101 // Internal use only
102 CREATE_MPI_DATATYPE(MPI_PTR, void*);
103
104
105 size_t smpi_datatype_size(MPI_Datatype datatype)
106 {
107   return datatype->size;
108 }
109
110 MPI_Aint smpi_datatype_lb(MPI_Datatype datatype)
111 {
112   return datatype->lb;
113 }
114
115 MPI_Aint smpi_datatype_ub(MPI_Datatype datatype)
116 {
117   return datatype->ub;
118 }
119
120 int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb,
121                          MPI_Aint * extent)
122 {
123   int retval;
124
125   if ((datatype->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
126     retval = MPI_ERR_TYPE;
127   } else {
128     *lb = datatype->lb;
129     *extent = datatype->ub - datatype->lb;
130     retval = MPI_SUCCESS;
131   }
132   return retval;
133 }
134
135 int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
136                        void *recvbuf, int recvcount, MPI_Datatype recvtype)
137 {
138   int retval, count;
139
140   /* First check if we really have something to do */
141   if (recvcount == 0) {
142     retval = sendcount == 0 ? MPI_SUCCESS : MPI_ERR_TRUNCATE;
143   } else {
144     /* FIXME: treat packed cases */
145     sendcount *= smpi_datatype_size(sendtype);
146     recvcount *= smpi_datatype_size(recvtype);
147     count = sendcount < recvcount ? sendcount : recvcount;
148     memcpy(recvbuf, sendbuf, count);
149     retval = sendcount > recvcount ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
150   }
151   return retval;
152 }
153
154 typedef struct s_smpi_mpi_op {
155   MPI_User_function *func;
156 } s_smpi_mpi_op_t;
157
158 #define MAX_OP(a, b)  (b) = (a) < (b) ? (b) : (a)
159 #define MIN_OP(a, b)  (b) = (a) < (b) ? (a) : (b)
160 #define SUM_OP(a, b)  (b) += (a)
161 #define PROD_OP(a, b) (b) *= (a)
162 #define LAND_OP(a, b) (b) = (a) && (b)
163 #define LOR_OP(a, b)  (b) = (a) || (b)
164 #define LXOR_OP(a, b) (b) = (!(a) && (b)) || ((a) && !(b))
165 #define BAND_OP(a, b) (b) &= (a)
166 #define BOR_OP(a, b)  (b) |= (a)
167 #define BXOR_OP(a, b) (b) ^= (a)
168 #define MAXLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (b) : (a)
169 #define MINLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (a) : (b)
170 //TODO : MINLOC & MAXLOC
171
172 #define APPLY_FUNC(a, b, length, type, func) \
173   {                                          \
174     int i;                                   \
175     type* x = (type*)(a);                    \
176     type* y = (type*)(b);                    \
177     for(i = 0; i < *(length); i++) {         \
178       func(x[i], y[i]);                      \
179     }                                        \
180   }
181
182 static void max_func(void *a, void *b, int *length,
183                      MPI_Datatype * datatype)
184 {
185   if (*datatype == MPI_CHAR) {
186     APPLY_FUNC(a, b, length, char, MAX_OP);
187   } else if (*datatype == MPI_SHORT) {
188     APPLY_FUNC(a, b, length, short, MAX_OP);
189   } else if (*datatype == MPI_INT) {
190     APPLY_FUNC(a, b, length, int, MAX_OP);
191   } else if (*datatype == MPI_LONG) {
192     APPLY_FUNC(a, b, length, long, MAX_OP);
193   } else if (*datatype == MPI_UNSIGNED_SHORT) {
194     APPLY_FUNC(a, b, length, unsigned short, MAX_OP);
195   } else if (*datatype == MPI_UNSIGNED) {
196     APPLY_FUNC(a, b, length, unsigned int, MAX_OP);
197   } else if (*datatype == MPI_UNSIGNED_LONG) {
198     APPLY_FUNC(a, b, length, unsigned long, MAX_OP);
199   } else if (*datatype == MPI_FLOAT) {
200     APPLY_FUNC(a, b, length, float, MAX_OP);
201   } else if (*datatype == MPI_DOUBLE) {
202     APPLY_FUNC(a, b, length, double, MAX_OP);
203   } else if (*datatype == MPI_LONG_DOUBLE) {
204     APPLY_FUNC(a, b, length, long double, MAX_OP);
205   }
206 }
207
208 static void min_func(void *a, void *b, int *length,
209                      MPI_Datatype * datatype)
210 {
211   if (*datatype == MPI_CHAR) {
212     APPLY_FUNC(a, b, length, char, MIN_OP);
213   } else if (*datatype == MPI_SHORT) {
214     APPLY_FUNC(a, b, length, short, MIN_OP);
215   } else if (*datatype == MPI_INT) {
216     APPLY_FUNC(a, b, length, int, MIN_OP);
217   } else if (*datatype == MPI_LONG) {
218     APPLY_FUNC(a, b, length, long, MIN_OP);
219   } else if (*datatype == MPI_UNSIGNED_SHORT) {
220     APPLY_FUNC(a, b, length, unsigned short, MIN_OP);
221   } else if (*datatype == MPI_UNSIGNED) {
222     APPLY_FUNC(a, b, length, unsigned int, MIN_OP);
223   } else if (*datatype == MPI_UNSIGNED_LONG) {
224     APPLY_FUNC(a, b, length, unsigned long, MIN_OP);
225   } else if (*datatype == MPI_FLOAT) {
226     APPLY_FUNC(a, b, length, float, MIN_OP);
227   } else if (*datatype == MPI_DOUBLE) {
228     APPLY_FUNC(a, b, length, double, MIN_OP);
229   } else if (*datatype == MPI_LONG_DOUBLE) {
230     APPLY_FUNC(a, b, length, long double, MIN_OP);
231   }
232 }
233
234 static void sum_func(void *a, void *b, int *length,
235                      MPI_Datatype * datatype)
236 {
237   if (*datatype == MPI_CHAR) {
238     APPLY_FUNC(a, b, length, char, SUM_OP);
239   } else if (*datatype == MPI_SHORT) {
240     APPLY_FUNC(a, b, length, short, SUM_OP);
241   } else if (*datatype == MPI_INT) {
242     APPLY_FUNC(a, b, length, int, SUM_OP);
243   } else if (*datatype == MPI_LONG) {
244     APPLY_FUNC(a, b, length, long, SUM_OP);
245   } else if (*datatype == MPI_UNSIGNED_SHORT) {
246     APPLY_FUNC(a, b, length, unsigned short, SUM_OP);
247   } else if (*datatype == MPI_UNSIGNED) {
248     APPLY_FUNC(a, b, length, unsigned int, SUM_OP);
249   } else if (*datatype == MPI_UNSIGNED_LONG) {
250     APPLY_FUNC(a, b, length, unsigned long, SUM_OP);
251   } else if (*datatype == MPI_FLOAT) {
252     APPLY_FUNC(a, b, length, float, SUM_OP);
253   } else if (*datatype == MPI_DOUBLE) {
254     APPLY_FUNC(a, b, length, double, SUM_OP);
255   } else if (*datatype == MPI_LONG_DOUBLE) {
256     APPLY_FUNC(a, b, length, long double, SUM_OP);
257   } else if (*datatype == MPI_C_FLOAT_COMPLEX) {
258     APPLY_FUNC(a, b, length, float _Complex, SUM_OP);
259   } else if (*datatype == MPI_C_DOUBLE_COMPLEX) {
260     APPLY_FUNC(a, b, length, double _Complex, SUM_OP);
261   } else if (*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
262     APPLY_FUNC(a, b, length, long double _Complex, SUM_OP);
263   }
264 }
265
266 static void prod_func(void *a, void *b, int *length,
267                       MPI_Datatype * datatype)
268 {
269   if (*datatype == MPI_CHAR) {
270     APPLY_FUNC(a, b, length, char, PROD_OP);
271   } else if (*datatype == MPI_SHORT) {
272     APPLY_FUNC(a, b, length, short, PROD_OP);
273   } else if (*datatype == MPI_INT) {
274     APPLY_FUNC(a, b, length, int, PROD_OP);
275   } else if (*datatype == MPI_LONG) {
276     APPLY_FUNC(a, b, length, long, PROD_OP);
277   } else if (*datatype == MPI_UNSIGNED_SHORT) {
278     APPLY_FUNC(a, b, length, unsigned short, PROD_OP);
279   } else if (*datatype == MPI_UNSIGNED) {
280     APPLY_FUNC(a, b, length, unsigned int, PROD_OP);
281   } else if (*datatype == MPI_UNSIGNED_LONG) {
282     APPLY_FUNC(a, b, length, unsigned long, PROD_OP);
283   } else if (*datatype == MPI_FLOAT) {
284     APPLY_FUNC(a, b, length, float, PROD_OP);
285   } else if (*datatype == MPI_DOUBLE) {
286     APPLY_FUNC(a, b, length, double, PROD_OP);
287   } else if (*datatype == MPI_LONG_DOUBLE) {
288     APPLY_FUNC(a, b, length, long double, PROD_OP);
289   } else if (*datatype == MPI_C_FLOAT_COMPLEX) {
290     APPLY_FUNC(a, b, length, float _Complex, PROD_OP);
291   } else if (*datatype == MPI_C_DOUBLE_COMPLEX) {
292     APPLY_FUNC(a, b, length, double _Complex, PROD_OP);
293   } else if (*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
294     APPLY_FUNC(a, b, length, long double _Complex, PROD_OP);
295   }
296 }
297
298 static void land_func(void *a, void *b, int *length,
299                       MPI_Datatype * datatype)
300 {
301   if (*datatype == MPI_CHAR) {
302     APPLY_FUNC(a, b, length, char, LAND_OP);
303   } else if (*datatype == MPI_SHORT) {
304     APPLY_FUNC(a, b, length, short, LAND_OP);
305   } else if (*datatype == MPI_INT) {
306     APPLY_FUNC(a, b, length, int, LAND_OP);
307   } else if (*datatype == MPI_LONG) {
308     APPLY_FUNC(a, b, length, long, LAND_OP);
309   } else if (*datatype == MPI_UNSIGNED_SHORT) {
310     APPLY_FUNC(a, b, length, unsigned short, LAND_OP);
311   } else if (*datatype == MPI_UNSIGNED) {
312     APPLY_FUNC(a, b, length, unsigned int, LAND_OP);
313   } else if (*datatype == MPI_UNSIGNED_LONG) {
314     APPLY_FUNC(a, b, length, unsigned long, LAND_OP);
315   } else if (*datatype == MPI_C_BOOL) {
316     APPLY_FUNC(a, b, length, _Bool, LAND_OP);
317   }
318 }
319
320 static void lor_func(void *a, void *b, int *length,
321                      MPI_Datatype * datatype)
322 {
323   if (*datatype == MPI_CHAR) {
324     APPLY_FUNC(a, b, length, char, LOR_OP);
325   } else if (*datatype == MPI_SHORT) {
326     APPLY_FUNC(a, b, length, short, LOR_OP);
327   } else if (*datatype == MPI_INT) {
328     APPLY_FUNC(a, b, length, int, LOR_OP);
329   } else if (*datatype == MPI_LONG) {
330     APPLY_FUNC(a, b, length, long, LOR_OP);
331   } else if (*datatype == MPI_UNSIGNED_SHORT) {
332     APPLY_FUNC(a, b, length, unsigned short, LOR_OP);
333   } else if (*datatype == MPI_UNSIGNED) {
334     APPLY_FUNC(a, b, length, unsigned int, LOR_OP);
335   } else if (*datatype == MPI_UNSIGNED_LONG) {
336     APPLY_FUNC(a, b, length, unsigned long, LOR_OP);
337   } else if (*datatype == MPI_C_BOOL) {
338     APPLY_FUNC(a, b, length, _Bool, LOR_OP);
339   }
340 }
341
342 static void lxor_func(void *a, void *b, int *length,
343                       MPI_Datatype * datatype)
344 {
345   if (*datatype == MPI_CHAR) {
346     APPLY_FUNC(a, b, length, char, LXOR_OP);
347   } else if (*datatype == MPI_SHORT) {
348     APPLY_FUNC(a, b, length, short, LXOR_OP);
349   } else if (*datatype == MPI_INT) {
350     APPLY_FUNC(a, b, length, int, LXOR_OP);
351   } else if (*datatype == MPI_LONG) {
352     APPLY_FUNC(a, b, length, long, LXOR_OP);
353   } else if (*datatype == MPI_UNSIGNED_SHORT) {
354     APPLY_FUNC(a, b, length, unsigned short, LXOR_OP);
355   } else if (*datatype == MPI_UNSIGNED) {
356     APPLY_FUNC(a, b, length, unsigned int, LXOR_OP);
357   } else if (*datatype == MPI_UNSIGNED_LONG) {
358     APPLY_FUNC(a, b, length, unsigned long, LXOR_OP);
359   } else if (*datatype == MPI_C_BOOL) {
360     APPLY_FUNC(a, b, length, _Bool, LXOR_OP);
361   }
362 }
363
364 static void band_func(void *a, void *b, int *length,
365                       MPI_Datatype * datatype)
366 {
367   if (*datatype == MPI_CHAR) {
368     APPLY_FUNC(a, b, length, char, BAND_OP);
369   }
370   if (*datatype == MPI_SHORT) {
371     APPLY_FUNC(a, b, length, short, BAND_OP);
372   } else if (*datatype == MPI_INT) {
373     APPLY_FUNC(a, b, length, int, BAND_OP);
374   } else if (*datatype == MPI_LONG) {
375     APPLY_FUNC(a, b, length, long, BAND_OP);
376   } else if (*datatype == MPI_UNSIGNED_SHORT) {
377     APPLY_FUNC(a, b, length, unsigned short, BAND_OP);
378   } else if (*datatype == MPI_UNSIGNED) {
379     APPLY_FUNC(a, b, length, unsigned int, BAND_OP);
380   } else if (*datatype == MPI_UNSIGNED_LONG) {
381     APPLY_FUNC(a, b, length, unsigned long, BAND_OP);
382   } else if (*datatype == MPI_BYTE) {
383     APPLY_FUNC(a, b, length, uint8_t, BAND_OP);
384   }
385 }
386
387 static void bor_func(void *a, void *b, int *length,
388                      MPI_Datatype * datatype)
389 {
390   if (*datatype == MPI_CHAR) {
391     APPLY_FUNC(a, b, length, char, BOR_OP);
392   } else if (*datatype == MPI_SHORT) {
393     APPLY_FUNC(a, b, length, short, BOR_OP);
394   } else if (*datatype == MPI_INT) {
395     APPLY_FUNC(a, b, length, int, BOR_OP);
396   } else if (*datatype == MPI_LONG) {
397     APPLY_FUNC(a, b, length, long, BOR_OP);
398   } else if (*datatype == MPI_UNSIGNED_SHORT) {
399     APPLY_FUNC(a, b, length, unsigned short, BOR_OP);
400   } else if (*datatype == MPI_UNSIGNED) {
401     APPLY_FUNC(a, b, length, unsigned int, BOR_OP);
402   } else if (*datatype == MPI_UNSIGNED_LONG) {
403     APPLY_FUNC(a, b, length, unsigned long, BOR_OP);
404   } else if (*datatype == MPI_BYTE) {
405     APPLY_FUNC(a, b, length, uint8_t, BOR_OP);
406   }
407 }
408
409 static void bxor_func(void *a, void *b, int *length,
410                       MPI_Datatype * datatype)
411 {
412   if (*datatype == MPI_CHAR) {
413     APPLY_FUNC(a, b, length, char, BXOR_OP);
414   } else if (*datatype == MPI_SHORT) {
415     APPLY_FUNC(a, b, length, short, BXOR_OP);
416   } else if (*datatype == MPI_INT) {
417     APPLY_FUNC(a, b, length, int, BXOR_OP);
418   } else if (*datatype == MPI_LONG) {
419     APPLY_FUNC(a, b, length, long, BXOR_OP);
420   } else if (*datatype == MPI_UNSIGNED_SHORT) {
421     APPLY_FUNC(a, b, length, unsigned short, BXOR_OP);
422   } else if (*datatype == MPI_UNSIGNED) {
423     APPLY_FUNC(a, b, length, unsigned int, BXOR_OP);
424   } else if (*datatype == MPI_UNSIGNED_LONG) {
425     APPLY_FUNC(a, b, length, unsigned long, BXOR_OP);
426   } else if (*datatype == MPI_BYTE) {
427     APPLY_FUNC(a, b, length, uint8_t, BXOR_OP);
428   }
429 }
430
431 static void minloc_func(void *a, void *b, int *length,
432                         MPI_Datatype * datatype)
433 {
434   if (*datatype == MPI_FLOAT_INT) {
435     APPLY_FUNC(a, b, length, float_int, MINLOC_OP);
436   } else if (*datatype == MPI_LONG_INT) {
437     APPLY_FUNC(a, b, length, long_int, MINLOC_OP);
438   } else if (*datatype == MPI_DOUBLE_INT) {
439     APPLY_FUNC(a, b, length, double_int, MINLOC_OP);
440   } else if (*datatype == MPI_SHORT_INT) {
441     APPLY_FUNC(a, b, length, short_int, MINLOC_OP);
442   } else if (*datatype == MPI_2INT) {
443     APPLY_FUNC(a, b, length, int_int, MINLOC_OP);
444   } else if (*datatype == MPI_LONG_DOUBLE_INT) {
445     APPLY_FUNC(a, b, length, long_double_int, MINLOC_OP);
446   }
447 }
448
449 static void maxloc_func(void *a, void *b, int *length,
450                         MPI_Datatype * datatype)
451 {
452   if (*datatype == MPI_FLOAT_INT) {
453     APPLY_FUNC(a, b, length, float_int, MAXLOC_OP);
454   } else if (*datatype == MPI_LONG_INT) {
455     APPLY_FUNC(a, b, length, long_int, MAXLOC_OP);
456   } else if (*datatype == MPI_DOUBLE_INT) {
457     APPLY_FUNC(a, b, length, double_int, MAXLOC_OP);
458   } else if (*datatype == MPI_SHORT_INT) {
459     APPLY_FUNC(a, b, length, short_int, MAXLOC_OP);
460   } else if (*datatype == MPI_2INT) {
461     APPLY_FUNC(a, b, length, int_int, MAXLOC_OP);
462   } else if (*datatype == MPI_LONG_DOUBLE_INT) {
463     APPLY_FUNC(a, b, length, long_double_int, MAXLOC_OP);
464   }
465 }
466
467
468 #define CREATE_MPI_OP(name, func)                             \
469   static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \
470   MPI_Op name = &mpi_##name;
471
472 CREATE_MPI_OP(MPI_MAX, max_func);
473 CREATE_MPI_OP(MPI_MIN, min_func);
474 CREATE_MPI_OP(MPI_SUM, sum_func);
475 CREATE_MPI_OP(MPI_PROD, prod_func);
476 CREATE_MPI_OP(MPI_LAND, land_func);
477 CREATE_MPI_OP(MPI_LOR, lor_func);
478 CREATE_MPI_OP(MPI_LXOR, lxor_func);
479 CREATE_MPI_OP(MPI_BAND, band_func);
480 CREATE_MPI_OP(MPI_BOR, bor_func);
481 CREATE_MPI_OP(MPI_BXOR, bxor_func);
482 CREATE_MPI_OP(MPI_MAXLOC, maxloc_func);
483 CREATE_MPI_OP(MPI_MINLOC, minloc_func);
484
485 MPI_Op smpi_op_new(MPI_User_function * function, int commute)
486 {
487   MPI_Op op;
488
489   //FIXME: add commute param
490   op = xbt_new(s_smpi_mpi_op_t, 1);
491   op->func = function;
492   return op;
493 }
494
495 void smpi_op_destroy(MPI_Op op)
496 {
497   xbt_free(op);
498 }
499
500 void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len,
501                    MPI_Datatype * datatype)
502 {
503   op->func(invec, inoutvec, len, datatype);
504 }