-/* $Id$tag */
-
/* smpi_mpi_dt.c -- MPI primitives to handle datatypes */
-
-/* Note: a very incomplete implementation */
+/* FIXME: a very incomplete implementation */
-/* Copyright (c) 2009 Stephane Genaud. */
-/* All rights reserved. */
+/* Copyright (c) 2009, 2010. The SimGrid Team.
+ * All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
- * * under the terms of the license (GNU LGPL) which comes with this package. */
-
+ * under the terms of the license (GNU LGPL) which comes with this package. */
#include <stdio.h>
#include <stdlib.h>
}; \
MPI_Datatype name = &mpi_##name;
+
+//The following are datatypes for the MPI functions MPI_MAXLOC and MPI_MINLOC.
+typedef struct { float value; int index;} float_int;
+typedef struct { long value; int index;} long_int ;
+typedef struct { double value; int index;} double_int;
+typedef struct { short value; int index;} short_int;
+typedef struct { int value; int index;} int_int;
+typedef struct { long double value; int index;} long_double_int;
+
// Predefined data types
CREATE_MPI_DATATYPE(MPI_CHAR, char);
CREATE_MPI_DATATYPE(MPI_SHORT, short);
CREATE_MPI_DATATYPE(MPI_AINT, MPI_Aint);
CREATE_MPI_DATATYPE(MPI_OFFSET, MPI_Offset);
+CREATE_MPI_DATATYPE(MPI_FLOAT_INT, float_int);
+CREATE_MPI_DATATYPE(MPI_LONG_INT, long_int);
+CREATE_MPI_DATATYPE(MPI_DOUBLE_INT, double_int);
+CREATE_MPI_DATATYPE(MPI_SHORT_INT, short_int);
+CREATE_MPI_DATATYPE(MPI_2INT, int_int);
+CREATE_MPI_DATATYPE(MPI_LONG_DOUBLE_INT, long_double_int);
+
+
size_t smpi_datatype_size(MPI_Datatype datatype) {
return datatype->size;
}
/* First check if we really have something to do */
if(recvcount == 0) {
retval = sendcount == 0 ? MPI_SUCCESS : MPI_ERR_TRUNCATE;
- } else if(sendtype == recvtype) {
- /* If same datatypes used, just copy. */
- count = sendcount < recvcount ? sendcount : recvcount;
- memcpy(recvbuf, sendbuf, smpi_datatype_size(sendtype) * count);
- retval = sendcount > recvcount ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
- } else {
- /* FIXME: cases
- * - If receive packed.
- * - If send packed
- * to be treated once we have the MPI_Pack things ...
- **/
- retval = MPI_SUCCESS;
- }
- return retval;
+ } else {
+ /* FIXME: treat packed cases */
+ sendcount *= smpi_datatype_size(sendtype);
+ recvcount *= smpi_datatype_size(recvtype);
+ count = sendcount < recvcount ? sendcount : recvcount;
+ memcpy(recvbuf, sendbuf, count);
+ retval = sendcount > recvcount ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
+ }
+ return retval;
}
typedef struct s_smpi_mpi_op {
#define BAND_OP(a, b) (b) &= (a)
#define BOR_OP(a, b) (b) |= (a)
#define BXOR_OP(a, b) (b) ^= (a)
+#define MAXLOC_OP(a, b) (b) = (a.value) < (b.value) ? (b) : (a)
+#define MINLOC_OP(a, b) (b) = (a.value) < (b.value) ? (a) : (b)
//TODO : MINLOC & MAXLOC
#define APPLY_FUNC(a, b, length, type, func) \
}
static void max_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, MAX_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, MAX_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, MAX_OP);
APPLY_FUNC(a, b, length, long double, MAX_OP);
}
}
-
+
static void min_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, MIN_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, MIN_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, MIN_OP);
APPLY_FUNC(a, b, length, long double, MIN_OP);
}
}
-
+
static void sum_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, SUM_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, SUM_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, SUM_OP);
APPLY_FUNC(a, b, length, long double _Complex, SUM_OP);
}
}
-
+
static void prod_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, PROD_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, PROD_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, PROD_OP);
APPLY_FUNC(a, b, length, long double _Complex, PROD_OP);
}
}
-
+
static void land_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, LAND_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, LAND_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, LAND_OP);
APPLY_FUNC(a, b, length, _Bool, LAND_OP);
}
}
-
+
static void lor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, LOR_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, LOR_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, LOR_OP);
APPLY_FUNC(a, b, length, _Bool, LOR_OP);
}
}
-
+
static void lxor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, LXOR_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, LXOR_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, LXOR_OP);
APPLY_FUNC(a, b, length, _Bool, LXOR_OP);
}
}
-
+
static void band_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, BAND_OP);
+ } if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, BAND_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, BAND_OP);
APPLY_FUNC(a, b, length, uint8_t, BAND_OP);
}
}
-
+
static void bor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, BOR_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, BOR_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, BOR_OP);
APPLY_FUNC(a, b, length, uint8_t, BOR_OP);
}
}
-
+
static void bxor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
- if(*datatype == MPI_SHORT) {
+ if(*datatype == MPI_CHAR) {
+ APPLY_FUNC(a, b, length, char, BXOR_OP);
+ } else if(*datatype == MPI_SHORT) {
APPLY_FUNC(a, b, length, short, BXOR_OP);
} else if(*datatype == MPI_INT) {
APPLY_FUNC(a, b, length, int, BXOR_OP);
}
}
+static void minloc_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
+ if(*datatype == MPI_FLOAT_INT) {
+ APPLY_FUNC(a, b, length, float_int, MINLOC_OP);
+ } else if(*datatype == MPI_LONG_INT) {
+ APPLY_FUNC(a, b, length, long_int, MINLOC_OP);
+ } else if(*datatype == MPI_DOUBLE_INT) {
+ APPLY_FUNC(a, b, length, double_int, MINLOC_OP);
+ } else if(*datatype == MPI_SHORT_INT) {
+ APPLY_FUNC(a, b, length, short_int, MINLOC_OP);
+ } else if(*datatype == MPI_2INT) {
+ APPLY_FUNC(a, b, length, int_int, MINLOC_OP);
+ } else if(*datatype == MPI_LONG_DOUBLE_INT) {
+ APPLY_FUNC(a, b, length, long_double_int, MINLOC_OP);
+ }
+}
+
+static void maxloc_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
+ if(*datatype == MPI_FLOAT_INT) {
+ APPLY_FUNC(a, b, length, float_int, MAXLOC_OP);
+ } else if(*datatype == MPI_LONG_INT) {
+ APPLY_FUNC(a, b, length, long_int, MAXLOC_OP);
+ } else if(*datatype == MPI_DOUBLE_INT) {
+ APPLY_FUNC(a, b, length, double_int, MAXLOC_OP);
+ } else if(*datatype == MPI_SHORT_INT) {
+ APPLY_FUNC(a, b, length, short_int, MAXLOC_OP);
+ } else if(*datatype == MPI_2INT) {
+ APPLY_FUNC(a, b, length, int_int, MAXLOC_OP);
+ } else if(*datatype == MPI_LONG_DOUBLE_INT) {
+ APPLY_FUNC(a, b, length, long_double_int, MAXLOC_OP);
+ }
+}
+
+
#define CREATE_MPI_OP(name, func) \
static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \
MPI_Op name = &mpi_##name;
-CREATE_MPI_OP(MPI_MAX, max_func);
-CREATE_MPI_OP(MPI_MIN, min_func);
-CREATE_MPI_OP(MPI_SUM, sum_func);
-CREATE_MPI_OP(MPI_PROD, prod_func);
-CREATE_MPI_OP(MPI_LAND, land_func);
-CREATE_MPI_OP(MPI_LOR, lor_func);
-CREATE_MPI_OP(MPI_LXOR, lxor_func);
-CREATE_MPI_OP(MPI_BAND, band_func);
-CREATE_MPI_OP(MPI_BOR, bor_func);
-CREATE_MPI_OP(MPI_BXOR, bxor_func);
+CREATE_MPI_OP(MPI_MAX, max_func);
+CREATE_MPI_OP(MPI_MIN, min_func);
+CREATE_MPI_OP(MPI_SUM, sum_func);
+CREATE_MPI_OP(MPI_PROD, prod_func);
+CREATE_MPI_OP(MPI_LAND, land_func);
+CREATE_MPI_OP(MPI_LOR, lor_func);
+CREATE_MPI_OP(MPI_LXOR, lxor_func);
+CREATE_MPI_OP(MPI_BAND, band_func);
+CREATE_MPI_OP(MPI_BOR, bor_func);
+CREATE_MPI_OP(MPI_BXOR, bxor_func);
+CREATE_MPI_OP(MPI_MAXLOC, maxloc_func);
+CREATE_MPI_OP(MPI_MINLOC, minloc_func);
MPI_Op smpi_op_new(MPI_User_function* function, int commute) {
MPI_Op op;