1 /* smpi_mpi_dt.c -- MPI primitives to handle datatypes */
2 /* FIXME: a very incomplete implementation */
4 /* Copyright (c) 2009, 2010. The SimGrid Team.
5 * All rights reserved. */
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. */
15 #include "smpi_mpi_dt_private.h"
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi,
18 "Logging specific to SMPI (datatype)");
20 typedef struct s_smpi_mpi_datatype {
25 } s_smpi_mpi_datatype_t;
27 #define CREATE_MPI_DATATYPE(name, type) \
28 static s_smpi_mpi_datatype_t mpi_##name = { \
29 sizeof(type), /* size */ \
31 sizeof(type), /* ub = lb + size */ \
32 DT_FLAG_BASIC /* flags */ \
34 MPI_Datatype name = &mpi_##name;
37 //The following are datatypes for the MPI functions MPI_MAXLOC and MPI_MINLOC.
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);
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);
102 CREATE_MPI_DATATYPE(MPI_PTR, void*);
105 size_t smpi_datatype_size(MPI_Datatype datatype)
107 return datatype->size;
110 MPI_Aint smpi_datatype_lb(MPI_Datatype datatype)
115 MPI_Aint smpi_datatype_ub(MPI_Datatype datatype)
120 int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb,
125 if ((datatype->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
126 retval = MPI_ERR_TYPE;
129 *extent = datatype->ub - datatype->lb;
130 retval = MPI_SUCCESS;
135 int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
136 void *recvbuf, int recvcount, MPI_Datatype recvtype)
140 /* First check if we really have something to do */
141 if (recvcount == 0) {
142 retval = sendcount == 0 ? MPI_SUCCESS : MPI_ERR_TRUNCATE;
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;
154 void smpi_datatype_create(MPI_Datatype* new_type, int size, int flags){
155 MPI_Datatype new_t= xbt_new(s_smpi_mpi_datatype_t,1);
163 void smpi_datatype_free(MPI_Datatype* type){
167 int smpi_datatype_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type)
170 if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
171 retval = MPI_ERR_TYPE;
173 smpi_datatype_create(new_type, count * smpi_datatype_size(old_type), DT_FLAG_CONTIGUOUS);
179 int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type)
182 if (blocklen<=0)return MPI_ERR_ARG;
183 if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
184 retval = MPI_ERR_TYPE;
186 smpi_datatype_create(new_type, count * (blocklen+stride) * smpi_datatype_size(old_type), DT_FLAG_VECTOR);
192 int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type)
195 if (blocklen<=0)return MPI_ERR_ARG;
196 if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
197 retval = MPI_ERR_TYPE;
199 smpi_datatype_create(new_type, count * ((blocklen * smpi_datatype_size(old_type))+stride), DT_FLAG_VECTOR);
206 int smpi_datatype_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
210 for(i=0; i< count; i++){
214 if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
215 retval = MPI_ERR_TYPE;
217 smpi_datatype_create(new_type, (blocklens[count-1] + indices[count-1]) * smpi_datatype_size(old_type), DT_FLAG_DATA);
223 int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
227 for(i=0; i< count; i++){
231 if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
232 retval = MPI_ERR_TYPE;
234 smpi_datatype_create(new_type,indices[count-1] + (blocklens[count-1] * smpi_datatype_size(old_type)), DT_FLAG_DATA);
240 int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type)
243 for(i=0; i< count; i++){
246 if ((old_types[i]->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED)
249 smpi_datatype_create(new_type,indices[count-1] + (blocklens[count-1] * smpi_datatype_size(old_types[count-1])), DT_FLAG_DATA);
253 void smpi_datatype_commit(MPI_Datatype* datatype)
255 (*datatype)->flags= ( (*datatype)->flags | DT_FLAG_COMMITED);
258 typedef struct s_smpi_mpi_op {
259 MPI_User_function *func;
262 #define MAX_OP(a, b) (b) = (a) < (b) ? (b) : (a)
263 #define MIN_OP(a, b) (b) = (a) < (b) ? (a) : (b)
264 #define SUM_OP(a, b) (b) += (a)
265 #define PROD_OP(a, b) (b) *= (a)
266 #define LAND_OP(a, b) (b) = (a) && (b)
267 #define LOR_OP(a, b) (b) = (a) || (b)
268 #define LXOR_OP(a, b) (b) = (!(a) && (b)) || ((a) && !(b))
269 #define BAND_OP(a, b) (b) &= (a)
270 #define BOR_OP(a, b) (b) |= (a)
271 #define BXOR_OP(a, b) (b) ^= (a)
272 #define MAXLOC_OP(a, b) (b) = (a.value) < (b.value) ? (b) : (a)
273 #define MINLOC_OP(a, b) (b) = (a.value) < (b.value) ? (a) : (b)
274 //TODO : MINLOC & MAXLOC
276 #define APPLY_FUNC(a, b, length, type, func) \
279 type* x = (type*)(a); \
280 type* y = (type*)(b); \
281 for(i = 0; i < *(length); i++) { \
286 static void max_func(void *a, void *b, int *length,
287 MPI_Datatype * datatype)
289 if (*datatype == MPI_CHAR) {
290 APPLY_FUNC(a, b, length, char, MAX_OP);
291 } else if (*datatype == MPI_SHORT) {
292 APPLY_FUNC(a, b, length, short, MAX_OP);
293 } else if (*datatype == MPI_INT) {
294 APPLY_FUNC(a, b, length, int, MAX_OP);
295 } else if (*datatype == MPI_LONG) {
296 APPLY_FUNC(a, b, length, long, MAX_OP);
297 } else if (*datatype == MPI_UNSIGNED_SHORT) {
298 APPLY_FUNC(a, b, length, unsigned short, MAX_OP);
299 } else if (*datatype == MPI_UNSIGNED) {
300 APPLY_FUNC(a, b, length, unsigned int, MAX_OP);
301 } else if (*datatype == MPI_UNSIGNED_LONG) {
302 APPLY_FUNC(a, b, length, unsigned long, MAX_OP);
303 } else if (*datatype == MPI_FLOAT) {
304 APPLY_FUNC(a, b, length, float, MAX_OP);
305 } else if (*datatype == MPI_DOUBLE) {
306 APPLY_FUNC(a, b, length, double, MAX_OP);
307 } else if (*datatype == MPI_LONG_DOUBLE) {
308 APPLY_FUNC(a, b, length, long double, MAX_OP);
312 static void min_func(void *a, void *b, int *length,
313 MPI_Datatype * datatype)
315 if (*datatype == MPI_CHAR) {
316 APPLY_FUNC(a, b, length, char, MIN_OP);
317 } else if (*datatype == MPI_SHORT) {
318 APPLY_FUNC(a, b, length, short, MIN_OP);
319 } else if (*datatype == MPI_INT) {
320 APPLY_FUNC(a, b, length, int, MIN_OP);
321 } else if (*datatype == MPI_LONG) {
322 APPLY_FUNC(a, b, length, long, MIN_OP);
323 } else if (*datatype == MPI_UNSIGNED_SHORT) {
324 APPLY_FUNC(a, b, length, unsigned short, MIN_OP);
325 } else if (*datatype == MPI_UNSIGNED) {
326 APPLY_FUNC(a, b, length, unsigned int, MIN_OP);
327 } else if (*datatype == MPI_UNSIGNED_LONG) {
328 APPLY_FUNC(a, b, length, unsigned long, MIN_OP);
329 } else if (*datatype == MPI_FLOAT) {
330 APPLY_FUNC(a, b, length, float, MIN_OP);
331 } else if (*datatype == MPI_DOUBLE) {
332 APPLY_FUNC(a, b, length, double, MIN_OP);
333 } else if (*datatype == MPI_LONG_DOUBLE) {
334 APPLY_FUNC(a, b, length, long double, MIN_OP);
338 static void sum_func(void *a, void *b, int *length,
339 MPI_Datatype * datatype)
341 if (*datatype == MPI_CHAR) {
342 APPLY_FUNC(a, b, length, char, SUM_OP);
343 } else if (*datatype == MPI_SHORT) {
344 APPLY_FUNC(a, b, length, short, SUM_OP);
345 } else if (*datatype == MPI_INT) {
346 APPLY_FUNC(a, b, length, int, SUM_OP);
347 } else if (*datatype == MPI_LONG) {
348 APPLY_FUNC(a, b, length, long, SUM_OP);
349 } else if (*datatype == MPI_UNSIGNED_SHORT) {
350 APPLY_FUNC(a, b, length, unsigned short, SUM_OP);
351 } else if (*datatype == MPI_UNSIGNED) {
352 APPLY_FUNC(a, b, length, unsigned int, SUM_OP);
353 } else if (*datatype == MPI_UNSIGNED_LONG) {
354 APPLY_FUNC(a, b, length, unsigned long, SUM_OP);
355 } else if (*datatype == MPI_FLOAT) {
356 APPLY_FUNC(a, b, length, float, SUM_OP);
357 } else if (*datatype == MPI_DOUBLE) {
358 APPLY_FUNC(a, b, length, double, SUM_OP);
359 } else if (*datatype == MPI_LONG_DOUBLE) {
360 APPLY_FUNC(a, b, length, long double, SUM_OP);
361 } else if (*datatype == MPI_C_FLOAT_COMPLEX) {
362 APPLY_FUNC(a, b, length, float _Complex, SUM_OP);
363 } else if (*datatype == MPI_C_DOUBLE_COMPLEX) {
364 APPLY_FUNC(a, b, length, double _Complex, SUM_OP);
365 } else if (*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
366 APPLY_FUNC(a, b, length, long double _Complex, SUM_OP);
370 static void prod_func(void *a, void *b, int *length,
371 MPI_Datatype * datatype)
373 if (*datatype == MPI_CHAR) {
374 APPLY_FUNC(a, b, length, char, PROD_OP);
375 } else if (*datatype == MPI_SHORT) {
376 APPLY_FUNC(a, b, length, short, PROD_OP);
377 } else if (*datatype == MPI_INT) {
378 APPLY_FUNC(a, b, length, int, PROD_OP);
379 } else if (*datatype == MPI_LONG) {
380 APPLY_FUNC(a, b, length, long, PROD_OP);
381 } else if (*datatype == MPI_UNSIGNED_SHORT) {
382 APPLY_FUNC(a, b, length, unsigned short, PROD_OP);
383 } else if (*datatype == MPI_UNSIGNED) {
384 APPLY_FUNC(a, b, length, unsigned int, PROD_OP);
385 } else if (*datatype == MPI_UNSIGNED_LONG) {
386 APPLY_FUNC(a, b, length, unsigned long, PROD_OP);
387 } else if (*datatype == MPI_FLOAT) {
388 APPLY_FUNC(a, b, length, float, PROD_OP);
389 } else if (*datatype == MPI_DOUBLE) {
390 APPLY_FUNC(a, b, length, double, PROD_OP);
391 } else if (*datatype == MPI_LONG_DOUBLE) {
392 APPLY_FUNC(a, b, length, long double, PROD_OP);
393 } else if (*datatype == MPI_C_FLOAT_COMPLEX) {
394 APPLY_FUNC(a, b, length, float _Complex, PROD_OP);
395 } else if (*datatype == MPI_C_DOUBLE_COMPLEX) {
396 APPLY_FUNC(a, b, length, double _Complex, PROD_OP);
397 } else if (*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
398 APPLY_FUNC(a, b, length, long double _Complex, PROD_OP);
402 static void land_func(void *a, void *b, int *length,
403 MPI_Datatype * datatype)
405 if (*datatype == MPI_CHAR) {
406 APPLY_FUNC(a, b, length, char, LAND_OP);
407 } else if (*datatype == MPI_SHORT) {
408 APPLY_FUNC(a, b, length, short, LAND_OP);
409 } else if (*datatype == MPI_INT) {
410 APPLY_FUNC(a, b, length, int, LAND_OP);
411 } else if (*datatype == MPI_LONG) {
412 APPLY_FUNC(a, b, length, long, LAND_OP);
413 } else if (*datatype == MPI_UNSIGNED_SHORT) {
414 APPLY_FUNC(a, b, length, unsigned short, LAND_OP);
415 } else if (*datatype == MPI_UNSIGNED) {
416 APPLY_FUNC(a, b, length, unsigned int, LAND_OP);
417 } else if (*datatype == MPI_UNSIGNED_LONG) {
418 APPLY_FUNC(a, b, length, unsigned long, LAND_OP);
419 } else if (*datatype == MPI_C_BOOL) {
420 APPLY_FUNC(a, b, length, _Bool, LAND_OP);
424 static void lor_func(void *a, void *b, int *length,
425 MPI_Datatype * datatype)
427 if (*datatype == MPI_CHAR) {
428 APPLY_FUNC(a, b, length, char, LOR_OP);
429 } else if (*datatype == MPI_SHORT) {
430 APPLY_FUNC(a, b, length, short, LOR_OP);
431 } else if (*datatype == MPI_INT) {
432 APPLY_FUNC(a, b, length, int, LOR_OP);
433 } else if (*datatype == MPI_LONG) {
434 APPLY_FUNC(a, b, length, long, LOR_OP);
435 } else if (*datatype == MPI_UNSIGNED_SHORT) {
436 APPLY_FUNC(a, b, length, unsigned short, LOR_OP);
437 } else if (*datatype == MPI_UNSIGNED) {
438 APPLY_FUNC(a, b, length, unsigned int, LOR_OP);
439 } else if (*datatype == MPI_UNSIGNED_LONG) {
440 APPLY_FUNC(a, b, length, unsigned long, LOR_OP);
441 } else if (*datatype == MPI_C_BOOL) {
442 APPLY_FUNC(a, b, length, _Bool, LOR_OP);
446 static void lxor_func(void *a, void *b, int *length,
447 MPI_Datatype * datatype)
449 if (*datatype == MPI_CHAR) {
450 APPLY_FUNC(a, b, length, char, LXOR_OP);
451 } else if (*datatype == MPI_SHORT) {
452 APPLY_FUNC(a, b, length, short, LXOR_OP);
453 } else if (*datatype == MPI_INT) {
454 APPLY_FUNC(a, b, length, int, LXOR_OP);
455 } else if (*datatype == MPI_LONG) {
456 APPLY_FUNC(a, b, length, long, LXOR_OP);
457 } else if (*datatype == MPI_UNSIGNED_SHORT) {
458 APPLY_FUNC(a, b, length, unsigned short, LXOR_OP);
459 } else if (*datatype == MPI_UNSIGNED) {
460 APPLY_FUNC(a, b, length, unsigned int, LXOR_OP);
461 } else if (*datatype == MPI_UNSIGNED_LONG) {
462 APPLY_FUNC(a, b, length, unsigned long, LXOR_OP);
463 } else if (*datatype == MPI_C_BOOL) {
464 APPLY_FUNC(a, b, length, _Bool, LXOR_OP);
468 static void band_func(void *a, void *b, int *length,
469 MPI_Datatype * datatype)
471 if (*datatype == MPI_CHAR) {
472 APPLY_FUNC(a, b, length, char, BAND_OP);
474 if (*datatype == MPI_SHORT) {
475 APPLY_FUNC(a, b, length, short, BAND_OP);
476 } else if (*datatype == MPI_INT) {
477 APPLY_FUNC(a, b, length, int, BAND_OP);
478 } else if (*datatype == MPI_LONG) {
479 APPLY_FUNC(a, b, length, long, BAND_OP);
480 } else if (*datatype == MPI_UNSIGNED_SHORT) {
481 APPLY_FUNC(a, b, length, unsigned short, BAND_OP);
482 } else if (*datatype == MPI_UNSIGNED) {
483 APPLY_FUNC(a, b, length, unsigned int, BAND_OP);
484 } else if (*datatype == MPI_UNSIGNED_LONG) {
485 APPLY_FUNC(a, b, length, unsigned long, BAND_OP);
486 } else if (*datatype == MPI_BYTE) {
487 APPLY_FUNC(a, b, length, uint8_t, BAND_OP);
491 static void bor_func(void *a, void *b, int *length,
492 MPI_Datatype * datatype)
494 if (*datatype == MPI_CHAR) {
495 APPLY_FUNC(a, b, length, char, BOR_OP);
496 } else if (*datatype == MPI_SHORT) {
497 APPLY_FUNC(a, b, length, short, BOR_OP);
498 } else if (*datatype == MPI_INT) {
499 APPLY_FUNC(a, b, length, int, BOR_OP);
500 } else if (*datatype == MPI_LONG) {
501 APPLY_FUNC(a, b, length, long, BOR_OP);
502 } else if (*datatype == MPI_UNSIGNED_SHORT) {
503 APPLY_FUNC(a, b, length, unsigned short, BOR_OP);
504 } else if (*datatype == MPI_UNSIGNED) {
505 APPLY_FUNC(a, b, length, unsigned int, BOR_OP);
506 } else if (*datatype == MPI_UNSIGNED_LONG) {
507 APPLY_FUNC(a, b, length, unsigned long, BOR_OP);
508 } else if (*datatype == MPI_BYTE) {
509 APPLY_FUNC(a, b, length, uint8_t, BOR_OP);
513 static void bxor_func(void *a, void *b, int *length,
514 MPI_Datatype * datatype)
516 if (*datatype == MPI_CHAR) {
517 APPLY_FUNC(a, b, length, char, BXOR_OP);
518 } else if (*datatype == MPI_SHORT) {
519 APPLY_FUNC(a, b, length, short, BXOR_OP);
520 } else if (*datatype == MPI_INT) {
521 APPLY_FUNC(a, b, length, int, BXOR_OP);
522 } else if (*datatype == MPI_LONG) {
523 APPLY_FUNC(a, b, length, long, BXOR_OP);
524 } else if (*datatype == MPI_UNSIGNED_SHORT) {
525 APPLY_FUNC(a, b, length, unsigned short, BXOR_OP);
526 } else if (*datatype == MPI_UNSIGNED) {
527 APPLY_FUNC(a, b, length, unsigned int, BXOR_OP);
528 } else if (*datatype == MPI_UNSIGNED_LONG) {
529 APPLY_FUNC(a, b, length, unsigned long, BXOR_OP);
530 } else if (*datatype == MPI_BYTE) {
531 APPLY_FUNC(a, b, length, uint8_t, BXOR_OP);
535 static void minloc_func(void *a, void *b, int *length,
536 MPI_Datatype * datatype)
538 if (*datatype == MPI_FLOAT_INT) {
539 APPLY_FUNC(a, b, length, float_int, MINLOC_OP);
540 } else if (*datatype == MPI_LONG_INT) {
541 APPLY_FUNC(a, b, length, long_int, MINLOC_OP);
542 } else if (*datatype == MPI_DOUBLE_INT) {
543 APPLY_FUNC(a, b, length, double_int, MINLOC_OP);
544 } else if (*datatype == MPI_SHORT_INT) {
545 APPLY_FUNC(a, b, length, short_int, MINLOC_OP);
546 } else if (*datatype == MPI_2INT) {
547 APPLY_FUNC(a, b, length, int_int, MINLOC_OP);
548 } else if (*datatype == MPI_LONG_DOUBLE_INT) {
549 APPLY_FUNC(a, b, length, long_double_int, MINLOC_OP);
553 static void maxloc_func(void *a, void *b, int *length,
554 MPI_Datatype * datatype)
556 if (*datatype == MPI_FLOAT_INT) {
557 APPLY_FUNC(a, b, length, float_int, MAXLOC_OP);
558 } else if (*datatype == MPI_LONG_INT) {
559 APPLY_FUNC(a, b, length, long_int, MAXLOC_OP);
560 } else if (*datatype == MPI_DOUBLE_INT) {
561 APPLY_FUNC(a, b, length, double_int, MAXLOC_OP);
562 } else if (*datatype == MPI_SHORT_INT) {
563 APPLY_FUNC(a, b, length, short_int, MAXLOC_OP);
564 } else if (*datatype == MPI_2INT) {
565 APPLY_FUNC(a, b, length, int_int, MAXLOC_OP);
566 } else if (*datatype == MPI_LONG_DOUBLE_INT) {
567 APPLY_FUNC(a, b, length, long_double_int, MAXLOC_OP);
572 #define CREATE_MPI_OP(name, func) \
573 static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \
574 MPI_Op name = &mpi_##name;
576 CREATE_MPI_OP(MPI_MAX, max_func);
577 CREATE_MPI_OP(MPI_MIN, min_func);
578 CREATE_MPI_OP(MPI_SUM, sum_func);
579 CREATE_MPI_OP(MPI_PROD, prod_func);
580 CREATE_MPI_OP(MPI_LAND, land_func);
581 CREATE_MPI_OP(MPI_LOR, lor_func);
582 CREATE_MPI_OP(MPI_LXOR, lxor_func);
583 CREATE_MPI_OP(MPI_BAND, band_func);
584 CREATE_MPI_OP(MPI_BOR, bor_func);
585 CREATE_MPI_OP(MPI_BXOR, bxor_func);
586 CREATE_MPI_OP(MPI_MAXLOC, maxloc_func);
587 CREATE_MPI_OP(MPI_MINLOC, minloc_func);
589 MPI_Op smpi_op_new(MPI_User_function * function, int commute)
593 //FIXME: add commute param
594 op = xbt_new(s_smpi_mpi_op_t, 1);
599 void smpi_op_destroy(MPI_Op op)
604 void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len,
605 MPI_Datatype * datatype)
607 op->func(invec, inoutvec, len, datatype);