Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
9adfdb39e492c15dd819669fb0a640599b11d06d
[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
102 size_t smpi_datatype_size(MPI_Datatype datatype)
103 {
104   return datatype->size;
105 }
106
107 MPI_Aint smpi_datatype_lb(MPI_Datatype datatype)
108 {
109   return datatype->lb;
110 }
111
112 MPI_Aint smpi_datatype_ub(MPI_Datatype datatype)
113 {
114   return datatype->ub;
115 }
116
117 int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb,
118                          MPI_Aint * extent)
119 {
120   int retval;
121
122   if ((datatype->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
123     retval = MPI_ERR_TYPE;
124   } else {
125     *lb = datatype->lb;
126     *extent = datatype->ub - datatype->lb;
127     retval = MPI_SUCCESS;
128   }
129   return MPI_SUCCESS;
130 }
131
132 int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
133                        void *recvbuf, int recvcount, MPI_Datatype recvtype)
134 {
135   int retval, count;
136
137   /* First check if we really have something to do */
138   if (recvcount == 0) {
139     retval = sendcount == 0 ? MPI_SUCCESS : MPI_ERR_TRUNCATE;
140   } else {
141     /* FIXME: treat packed cases */
142     sendcount *= smpi_datatype_size(sendtype);
143     recvcount *= smpi_datatype_size(recvtype);
144     count = sendcount < recvcount ? sendcount : recvcount;
145     memcpy(recvbuf, sendbuf, count);
146     retval = sendcount > recvcount ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
147   }
148   return retval;
149 }
150
151 typedef struct s_smpi_mpi_op {
152   MPI_User_function *func;
153 } s_smpi_mpi_op_t;
154
155 #define MAX_OP(a, b)  (b) = (a) < (b) ? (b) : (a)
156 #define MIN_OP(a, b)  (b) = (a) < (b) ? (a) : (b)
157 #define SUM_OP(a, b)  (b) += (a)
158 #define PROD_OP(a, b) (b) *= (a)
159 #define LAND_OP(a, b) (b) = (a) && (b)
160 #define LOR_OP(a, b)  (b) = (a) || (b)
161 #define LXOR_OP(a, b) (b) = (!(a) && (b)) || ((a) && !(b))
162 #define BAND_OP(a, b) (b) &= (a)
163 #define BOR_OP(a, b)  (b) |= (a)
164 #define BXOR_OP(a, b) (b) ^= (a)
165 #define MAXLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (b) : (a)
166 #define MINLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (a) : (b)
167 //TODO : MINLOC & MAXLOC
168
169 #define APPLY_FUNC(a, b, length, type, func) \
170   {                                          \
171     int i;                                   \
172     type* x = (type*)(a);                    \
173     type* y = (type*)(b);                    \
174     for(i = 0; i < *(length); i++) {         \
175       func(x[i], y[i]);                      \
176     }                                        \
177   }
178
179 static void max_func(void *a, void *b, int *length,
180                      MPI_Datatype * datatype)
181 {
182   if (*datatype == MPI_CHAR) {
183     APPLY_FUNC(a, b, length, char, MAX_OP);
184   } else if (*datatype == MPI_SHORT) {
185     APPLY_FUNC(a, b, length, short, MAX_OP);
186   } else if (*datatype == MPI_INT) {
187     APPLY_FUNC(a, b, length, int, MAX_OP);
188   } else if (*datatype == MPI_LONG) {
189     APPLY_FUNC(a, b, length, long, MAX_OP);
190   } else if (*datatype == MPI_UNSIGNED_SHORT) {
191     APPLY_FUNC(a, b, length, unsigned short, MAX_OP);
192   } else if (*datatype == MPI_UNSIGNED) {
193     APPLY_FUNC(a, b, length, unsigned int, MAX_OP);
194   } else if (*datatype == MPI_UNSIGNED_LONG) {
195     APPLY_FUNC(a, b, length, unsigned long, MAX_OP);
196   } else if (*datatype == MPI_FLOAT) {
197     APPLY_FUNC(a, b, length, float, MAX_OP);
198   } else if (*datatype == MPI_DOUBLE) {
199     APPLY_FUNC(a, b, length, double, MAX_OP);
200   } else if (*datatype == MPI_LONG_DOUBLE) {
201     APPLY_FUNC(a, b, length, long double, MAX_OP);
202   }
203 }
204
205 static void min_func(void *a, void *b, int *length,
206                      MPI_Datatype * datatype)
207 {
208   if (*datatype == MPI_CHAR) {
209     APPLY_FUNC(a, b, length, char, MIN_OP);
210   } else if (*datatype == MPI_SHORT) {
211     APPLY_FUNC(a, b, length, short, MIN_OP);
212   } else if (*datatype == MPI_INT) {
213     APPLY_FUNC(a, b, length, int, MIN_OP);
214   } else if (*datatype == MPI_LONG) {
215     APPLY_FUNC(a, b, length, long, MIN_OP);
216   } else if (*datatype == MPI_UNSIGNED_SHORT) {
217     APPLY_FUNC(a, b, length, unsigned short, MIN_OP);
218   } else if (*datatype == MPI_UNSIGNED) {
219     APPLY_FUNC(a, b, length, unsigned int, MIN_OP);
220   } else if (*datatype == MPI_UNSIGNED_LONG) {
221     APPLY_FUNC(a, b, length, unsigned long, MIN_OP);
222   } else if (*datatype == MPI_FLOAT) {
223     APPLY_FUNC(a, b, length, float, MIN_OP);
224   } else if (*datatype == MPI_DOUBLE) {
225     APPLY_FUNC(a, b, length, double, MIN_OP);
226   } else if (*datatype == MPI_LONG_DOUBLE) {
227     APPLY_FUNC(a, b, length, long double, MIN_OP);
228   }
229 }
230
231 static void sum_func(void *a, void *b, int *length,
232                      MPI_Datatype * datatype)
233 {
234   if (*datatype == MPI_CHAR) {
235     APPLY_FUNC(a, b, length, char, SUM_OP);
236   } else if (*datatype == MPI_SHORT) {
237     APPLY_FUNC(a, b, length, short, SUM_OP);
238   } else if (*datatype == MPI_INT) {
239     APPLY_FUNC(a, b, length, int, SUM_OP);
240   } else if (*datatype == MPI_LONG) {
241     APPLY_FUNC(a, b, length, long, SUM_OP);
242   } else if (*datatype == MPI_UNSIGNED_SHORT) {
243     APPLY_FUNC(a, b, length, unsigned short, SUM_OP);
244   } else if (*datatype == MPI_UNSIGNED) {
245     APPLY_FUNC(a, b, length, unsigned int, SUM_OP);
246   } else if (*datatype == MPI_UNSIGNED_LONG) {
247     APPLY_FUNC(a, b, length, unsigned long, SUM_OP);
248   } else if (*datatype == MPI_FLOAT) {
249     APPLY_FUNC(a, b, length, float, SUM_OP);
250   } else if (*datatype == MPI_DOUBLE) {
251     APPLY_FUNC(a, b, length, double, SUM_OP);
252   } else if (*datatype == MPI_LONG_DOUBLE) {
253     APPLY_FUNC(a, b, length, long double, SUM_OP);
254   } else if (*datatype == MPI_C_FLOAT_COMPLEX) {
255     APPLY_FUNC(a, b, length, float _Complex, SUM_OP);
256   } else if (*datatype == MPI_C_DOUBLE_COMPLEX) {
257     APPLY_FUNC(a, b, length, double _Complex, SUM_OP);
258   } else if (*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
259     APPLY_FUNC(a, b, length, long double _Complex, SUM_OP);
260   }
261 }
262
263 static void prod_func(void *a, void *b, int *length,
264                       MPI_Datatype * datatype)
265 {
266   if (*datatype == MPI_CHAR) {
267     APPLY_FUNC(a, b, length, char, PROD_OP);
268   } else if (*datatype == MPI_SHORT) {
269     APPLY_FUNC(a, b, length, short, PROD_OP);
270   } else if (*datatype == MPI_INT) {
271     APPLY_FUNC(a, b, length, int, PROD_OP);
272   } else if (*datatype == MPI_LONG) {
273     APPLY_FUNC(a, b, length, long, PROD_OP);
274   } else if (*datatype == MPI_UNSIGNED_SHORT) {
275     APPLY_FUNC(a, b, length, unsigned short, PROD_OP);
276   } else if (*datatype == MPI_UNSIGNED) {
277     APPLY_FUNC(a, b, length, unsigned int, PROD_OP);
278   } else if (*datatype == MPI_UNSIGNED_LONG) {
279     APPLY_FUNC(a, b, length, unsigned long, PROD_OP);
280   } else if (*datatype == MPI_FLOAT) {
281     APPLY_FUNC(a, b, length, float, PROD_OP);
282   } else if (*datatype == MPI_DOUBLE) {
283     APPLY_FUNC(a, b, length, double, PROD_OP);
284   } else if (*datatype == MPI_LONG_DOUBLE) {
285     APPLY_FUNC(a, b, length, long double, PROD_OP);
286   } else if (*datatype == MPI_C_FLOAT_COMPLEX) {
287     APPLY_FUNC(a, b, length, float _Complex, PROD_OP);
288   } else if (*datatype == MPI_C_DOUBLE_COMPLEX) {
289     APPLY_FUNC(a, b, length, double _Complex, PROD_OP);
290   } else if (*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
291     APPLY_FUNC(a, b, length, long double _Complex, PROD_OP);
292   }
293 }
294
295 static void land_func(void *a, void *b, int *length,
296                       MPI_Datatype * datatype)
297 {
298   if (*datatype == MPI_CHAR) {
299     APPLY_FUNC(a, b, length, char, LAND_OP);
300   } else if (*datatype == MPI_SHORT) {
301     APPLY_FUNC(a, b, length, short, LAND_OP);
302   } else if (*datatype == MPI_INT) {
303     APPLY_FUNC(a, b, length, int, LAND_OP);
304   } else if (*datatype == MPI_LONG) {
305     APPLY_FUNC(a, b, length, long, LAND_OP);
306   } else if (*datatype == MPI_UNSIGNED_SHORT) {
307     APPLY_FUNC(a, b, length, unsigned short, LAND_OP);
308   } else if (*datatype == MPI_UNSIGNED) {
309     APPLY_FUNC(a, b, length, unsigned int, LAND_OP);
310   } else if (*datatype == MPI_UNSIGNED_LONG) {
311     APPLY_FUNC(a, b, length, unsigned long, LAND_OP);
312   } else if (*datatype == MPI_C_BOOL) {
313     APPLY_FUNC(a, b, length, _Bool, LAND_OP);
314   }
315 }
316
317 static void lor_func(void *a, void *b, int *length,
318                      MPI_Datatype * datatype)
319 {
320   if (*datatype == MPI_CHAR) {
321     APPLY_FUNC(a, b, length, char, LOR_OP);
322   } else if (*datatype == MPI_SHORT) {
323     APPLY_FUNC(a, b, length, short, LOR_OP);
324   } else if (*datatype == MPI_INT) {
325     APPLY_FUNC(a, b, length, int, LOR_OP);
326   } else if (*datatype == MPI_LONG) {
327     APPLY_FUNC(a, b, length, long, LOR_OP);
328   } else if (*datatype == MPI_UNSIGNED_SHORT) {
329     APPLY_FUNC(a, b, length, unsigned short, LOR_OP);
330   } else if (*datatype == MPI_UNSIGNED) {
331     APPLY_FUNC(a, b, length, unsigned int, LOR_OP);
332   } else if (*datatype == MPI_UNSIGNED_LONG) {
333     APPLY_FUNC(a, b, length, unsigned long, LOR_OP);
334   } else if (*datatype == MPI_C_BOOL) {
335     APPLY_FUNC(a, b, length, _Bool, LOR_OP);
336   }
337 }
338
339 static void lxor_func(void *a, void *b, int *length,
340                       MPI_Datatype * datatype)
341 {
342   if (*datatype == MPI_CHAR) {
343     APPLY_FUNC(a, b, length, char, LXOR_OP);
344   } else if (*datatype == MPI_SHORT) {
345     APPLY_FUNC(a, b, length, short, LXOR_OP);
346   } else if (*datatype == MPI_INT) {
347     APPLY_FUNC(a, b, length, int, LXOR_OP);
348   } else if (*datatype == MPI_LONG) {
349     APPLY_FUNC(a, b, length, long, LXOR_OP);
350   } else if (*datatype == MPI_UNSIGNED_SHORT) {
351     APPLY_FUNC(a, b, length, unsigned short, LXOR_OP);
352   } else if (*datatype == MPI_UNSIGNED) {
353     APPLY_FUNC(a, b, length, unsigned int, LXOR_OP);
354   } else if (*datatype == MPI_UNSIGNED_LONG) {
355     APPLY_FUNC(a, b, length, unsigned long, LXOR_OP);
356   } else if (*datatype == MPI_C_BOOL) {
357     APPLY_FUNC(a, b, length, _Bool, LXOR_OP);
358   }
359 }
360
361 static void band_func(void *a, void *b, int *length,
362                       MPI_Datatype * datatype)
363 {
364   if (*datatype == MPI_CHAR) {
365     APPLY_FUNC(a, b, length, char, BAND_OP);
366   }
367   if (*datatype == MPI_SHORT) {
368     APPLY_FUNC(a, b, length, short, BAND_OP);
369   } else if (*datatype == MPI_INT) {
370     APPLY_FUNC(a, b, length, int, BAND_OP);
371   } else if (*datatype == MPI_LONG) {
372     APPLY_FUNC(a, b, length, long, BAND_OP);
373   } else if (*datatype == MPI_UNSIGNED_SHORT) {
374     APPLY_FUNC(a, b, length, unsigned short, BAND_OP);
375   } else if (*datatype == MPI_UNSIGNED) {
376     APPLY_FUNC(a, b, length, unsigned int, BAND_OP);
377   } else if (*datatype == MPI_UNSIGNED_LONG) {
378     APPLY_FUNC(a, b, length, unsigned long, BAND_OP);
379   } else if (*datatype == MPI_BYTE) {
380     APPLY_FUNC(a, b, length, uint8_t, BAND_OP);
381   }
382 }
383
384 static void bor_func(void *a, void *b, int *length,
385                      MPI_Datatype * datatype)
386 {
387   if (*datatype == MPI_CHAR) {
388     APPLY_FUNC(a, b, length, char, BOR_OP);
389   } else if (*datatype == MPI_SHORT) {
390     APPLY_FUNC(a, b, length, short, BOR_OP);
391   } else if (*datatype == MPI_INT) {
392     APPLY_FUNC(a, b, length, int, BOR_OP);
393   } else if (*datatype == MPI_LONG) {
394     APPLY_FUNC(a, b, length, long, BOR_OP);
395   } else if (*datatype == MPI_UNSIGNED_SHORT) {
396     APPLY_FUNC(a, b, length, unsigned short, BOR_OP);
397   } else if (*datatype == MPI_UNSIGNED) {
398     APPLY_FUNC(a, b, length, unsigned int, BOR_OP);
399   } else if (*datatype == MPI_UNSIGNED_LONG) {
400     APPLY_FUNC(a, b, length, unsigned long, BOR_OP);
401   } else if (*datatype == MPI_BYTE) {
402     APPLY_FUNC(a, b, length, uint8_t, BOR_OP);
403   }
404 }
405
406 static void bxor_func(void *a, void *b, int *length,
407                       MPI_Datatype * datatype)
408 {
409   if (*datatype == MPI_CHAR) {
410     APPLY_FUNC(a, b, length, char, BXOR_OP);
411   } else if (*datatype == MPI_SHORT) {
412     APPLY_FUNC(a, b, length, short, BXOR_OP);
413   } else if (*datatype == MPI_INT) {
414     APPLY_FUNC(a, b, length, int, BXOR_OP);
415   } else if (*datatype == MPI_LONG) {
416     APPLY_FUNC(a, b, length, long, BXOR_OP);
417   } else if (*datatype == MPI_UNSIGNED_SHORT) {
418     APPLY_FUNC(a, b, length, unsigned short, BXOR_OP);
419   } else if (*datatype == MPI_UNSIGNED) {
420     APPLY_FUNC(a, b, length, unsigned int, BXOR_OP);
421   } else if (*datatype == MPI_UNSIGNED_LONG) {
422     APPLY_FUNC(a, b, length, unsigned long, BXOR_OP);
423   } else if (*datatype == MPI_BYTE) {
424     APPLY_FUNC(a, b, length, uint8_t, BXOR_OP);
425   }
426 }
427
428 static void minloc_func(void *a, void *b, int *length,
429                         MPI_Datatype * datatype)
430 {
431   if (*datatype == MPI_FLOAT_INT) {
432     APPLY_FUNC(a, b, length, float_int, MINLOC_OP);
433   } else if (*datatype == MPI_LONG_INT) {
434     APPLY_FUNC(a, b, length, long_int, MINLOC_OP);
435   } else if (*datatype == MPI_DOUBLE_INT) {
436     APPLY_FUNC(a, b, length, double_int, MINLOC_OP);
437   } else if (*datatype == MPI_SHORT_INT) {
438     APPLY_FUNC(a, b, length, short_int, MINLOC_OP);
439   } else if (*datatype == MPI_2INT) {
440     APPLY_FUNC(a, b, length, int_int, MINLOC_OP);
441   } else if (*datatype == MPI_LONG_DOUBLE_INT) {
442     APPLY_FUNC(a, b, length, long_double_int, MINLOC_OP);
443   }
444 }
445
446 static void maxloc_func(void *a, void *b, int *length,
447                         MPI_Datatype * datatype)
448 {
449   if (*datatype == MPI_FLOAT_INT) {
450     APPLY_FUNC(a, b, length, float_int, MAXLOC_OP);
451   } else if (*datatype == MPI_LONG_INT) {
452     APPLY_FUNC(a, b, length, long_int, MAXLOC_OP);
453   } else if (*datatype == MPI_DOUBLE_INT) {
454     APPLY_FUNC(a, b, length, double_int, MAXLOC_OP);
455   } else if (*datatype == MPI_SHORT_INT) {
456     APPLY_FUNC(a, b, length, short_int, MAXLOC_OP);
457   } else if (*datatype == MPI_2INT) {
458     APPLY_FUNC(a, b, length, int_int, MAXLOC_OP);
459   } else if (*datatype == MPI_LONG_DOUBLE_INT) {
460     APPLY_FUNC(a, b, length, long_double_int, MAXLOC_OP);
461   }
462 }
463
464
465 #define CREATE_MPI_OP(name, func)                             \
466   static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \
467   MPI_Op name = &mpi_##name;
468
469 CREATE_MPI_OP(MPI_MAX, max_func);
470 CREATE_MPI_OP(MPI_MIN, min_func);
471 CREATE_MPI_OP(MPI_SUM, sum_func);
472 CREATE_MPI_OP(MPI_PROD, prod_func);
473 CREATE_MPI_OP(MPI_LAND, land_func);
474 CREATE_MPI_OP(MPI_LOR, lor_func);
475 CREATE_MPI_OP(MPI_LXOR, lxor_func);
476 CREATE_MPI_OP(MPI_BAND, band_func);
477 CREATE_MPI_OP(MPI_BOR, bor_func);
478 CREATE_MPI_OP(MPI_BXOR, bxor_func);
479 CREATE_MPI_OP(MPI_MAXLOC, maxloc_func);
480 CREATE_MPI_OP(MPI_MINLOC, minloc_func);
481
482 MPI_Op smpi_op_new(MPI_User_function * function, int commute)
483 {
484   MPI_Op op;
485
486   //FIXME: add commute param
487   op = xbt_new(s_smpi_mpi_op_t, 1);
488   op->func = function;
489   return op;
490 }
491
492 void smpi_op_destroy(MPI_Op op)
493 {
494   xbt_free(op);
495 }
496
497 void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len,
498                    MPI_Datatype * datatype)
499 {
500   op->func(invec, inoutvec, len, datatype);
501 }