3 /* smpi_mpi_dt.c -- MPI primitives to handle datatypes */
5 /* Note: a very incomplete implementation */
7 /* Copyright (c) 2009 Stephane Genaud. */
8 /* All rights reserved. */
10 /* This program is free software; you can redistribute it and/or modify it
11 * * under the terms of the license (GNU LGPL) which comes with this package. */
19 #include "smpi_mpi_dt_private.h"
21 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi,
22 "Logging specific to SMPI (datatype)");
24 typedef struct s_smpi_mpi_datatype {
29 } s_smpi_mpi_datatype_t;
31 #define CREATE_MPI_DATATYPE(name, type) \
32 static s_smpi_mpi_datatype_t mpi_##name = { \
33 sizeof(type), /* size */ \
35 sizeof(type), /* ub = lb + size */ \
36 DT_FLAG_BASIC /* flags */ \
38 MPI_Datatype name = &mpi_##name;
40 // Predefined data types
41 CREATE_MPI_DATATYPE(MPI_CHAR, char);
42 CREATE_MPI_DATATYPE(MPI_SHORT, short);
43 CREATE_MPI_DATATYPE(MPI_INT, int);
44 CREATE_MPI_DATATYPE(MPI_LONG, long);
45 CREATE_MPI_DATATYPE(MPI_LONG_LONG, long long);
46 CREATE_MPI_DATATYPE(MPI_SIGNED_CHAR, signed char);
47 CREATE_MPI_DATATYPE(MPI_UNSIGNED_CHAR, unsigned char);
48 CREATE_MPI_DATATYPE(MPI_UNSIGNED_SHORT, unsigned short);
49 CREATE_MPI_DATATYPE(MPI_UNSIGNED, unsigned int);
50 CREATE_MPI_DATATYPE(MPI_UNSIGNED_LONG, unsigned long);
51 CREATE_MPI_DATATYPE(MPI_UNSIGNED_LONG_LONG, unsigned long long);
52 CREATE_MPI_DATATYPE(MPI_FLOAT, float);
53 CREATE_MPI_DATATYPE(MPI_DOUBLE, double);
54 CREATE_MPI_DATATYPE(MPI_LONG_DOUBLE, long double);
55 CREATE_MPI_DATATYPE(MPI_WCHAR, wchar_t);
56 CREATE_MPI_DATATYPE(MPI_C_BOOL, _Bool);
57 CREATE_MPI_DATATYPE(MPI_INT8_T, int8_t);
58 CREATE_MPI_DATATYPE(MPI_INT16_T, int16_t);
59 CREATE_MPI_DATATYPE(MPI_INT32_T, int32_t);
60 CREATE_MPI_DATATYPE(MPI_INT64_T, int64_t);
61 CREATE_MPI_DATATYPE(MPI_UINT8_T, uint8_t);
62 CREATE_MPI_DATATYPE(MPI_UINT16_T, uint16_t);
63 CREATE_MPI_DATATYPE(MPI_UINT32_T, uint32_t);
64 CREATE_MPI_DATATYPE(MPI_UINT64_T, uint64_t);
65 CREATE_MPI_DATATYPE(MPI_C_FLOAT_COMPLEX, float _Complex);
66 CREATE_MPI_DATATYPE(MPI_C_DOUBLE_COMPLEX, double _Complex);
67 CREATE_MPI_DATATYPE(MPI_C_LONG_DOUBLE_COMPLEX, long double _Complex);
68 CREATE_MPI_DATATYPE(MPI_AINT, MPI_Aint);
69 CREATE_MPI_DATATYPE(MPI_OFFSET, MPI_Offset);
71 size_t smpi_datatype_size(MPI_Datatype datatype) {
72 return datatype->size;
75 MPI_Aint smpi_datatype_lb(MPI_Datatype datatype) {
79 MPI_Aint smpi_datatype_ub(MPI_Datatype datatype) {
83 int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint* lb, MPI_Aint * extent) {
86 if((datatype->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
87 retval = MPI_ERR_TYPE;
90 *extent = datatype->ub - datatype->lb;
96 int smpi_datatype_copy(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype) {
99 /* First check if we really have something to do */
101 retval = sendcount == 0 ? MPI_SUCCESS : MPI_ERR_TRUNCATE;
102 } else if(sendtype == recvtype) {
103 /* If same datatypes used, just copy. */
104 count = sendcount < recvcount ? sendcount : recvcount;
105 memcpy(recvbuf, sendbuf, smpi_datatype_size(sendtype) * count);
106 retval = sendcount > recvcount ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
109 * - If receive packed.
111 * to be treated once we have the MPI_Pack things ...
113 retval = MPI_SUCCESS;
118 typedef struct s_smpi_mpi_op {
119 MPI_User_function* func;
122 #define MAX_OP(a, b) (b) = (a) < (b) ? (b) : (a)
123 #define MIN_OP(a, b) (b) = (a) < (b) ? (a) : (b)
124 #define SUM_OP(a, b) (b) += (a)
125 #define PROD_OP(a, b) (b) *= (a)
126 #define LAND_OP(a, b) (b) = (a) && (b)
127 #define LOR_OP(a, b) (b) = (a) || (b)
128 #define LXOR_OP(a, b) (b) = (!(a) && (b)) || ((a) && !(b))
129 #define BAND_OP(a, b) (b) &= (a)
130 #define BOR_OP(a, b) (b) |= (a)
131 #define BXOR_OP(a, b) (b) ^= (a)
132 //TODO : MINLOC & MAXLOC
134 #define APPLY_FUNC(a, b, length, type, func) \
137 type* x = (type*)(a); \
138 type* y = (type*)(b); \
139 for(i = 0; i < *(length); i++) { \
144 static void max_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
145 if(*datatype == MPI_SHORT) {
146 APPLY_FUNC(a, b, length, short, MAX_OP);
147 } else if(*datatype == MPI_INT) {
148 APPLY_FUNC(a, b, length, int, MAX_OP);
149 } else if(*datatype == MPI_LONG) {
150 APPLY_FUNC(a, b, length, long, MAX_OP);
151 } else if(*datatype == MPI_UNSIGNED_SHORT) {
152 APPLY_FUNC(a, b, length, unsigned short, MAX_OP);
153 } else if(*datatype == MPI_UNSIGNED) {
154 APPLY_FUNC(a, b, length, unsigned int, MAX_OP);
155 } else if(*datatype == MPI_UNSIGNED_LONG) {
156 APPLY_FUNC(a, b, length, unsigned long, MAX_OP);
157 } else if(*datatype == MPI_FLOAT) {
158 APPLY_FUNC(a, b, length, float, MAX_OP);
159 } else if(*datatype == MPI_DOUBLE) {
160 APPLY_FUNC(a, b, length, double, MAX_OP);
161 } else if(*datatype == MPI_LONG_DOUBLE) {
162 APPLY_FUNC(a, b, length, long double, MAX_OP);
166 static void min_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
167 if(*datatype == MPI_SHORT) {
168 APPLY_FUNC(a, b, length, short, MIN_OP);
169 } else if(*datatype == MPI_INT) {
170 APPLY_FUNC(a, b, length, int, MIN_OP);
171 } else if(*datatype == MPI_LONG) {
172 APPLY_FUNC(a, b, length, long, MIN_OP);
173 } else if(*datatype == MPI_UNSIGNED_SHORT) {
174 APPLY_FUNC(a, b, length, unsigned short, MIN_OP);
175 } else if(*datatype == MPI_UNSIGNED) {
176 APPLY_FUNC(a, b, length, unsigned int, MIN_OP);
177 } else if(*datatype == MPI_UNSIGNED_LONG) {
178 APPLY_FUNC(a, b, length, unsigned long, MIN_OP);
179 } else if(*datatype == MPI_FLOAT) {
180 APPLY_FUNC(a, b, length, float, MIN_OP);
181 } else if(*datatype == MPI_DOUBLE) {
182 APPLY_FUNC(a, b, length, double, MIN_OP);
183 } else if(*datatype == MPI_LONG_DOUBLE) {
184 APPLY_FUNC(a, b, length, long double, MIN_OP);
188 static void sum_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
189 if(*datatype == MPI_SHORT) {
190 APPLY_FUNC(a, b, length, short, SUM_OP);
191 } else if(*datatype == MPI_INT) {
192 APPLY_FUNC(a, b, length, int, SUM_OP);
193 } else if(*datatype == MPI_LONG) {
194 APPLY_FUNC(a, b, length, long, SUM_OP);
195 } else if(*datatype == MPI_UNSIGNED_SHORT) {
196 APPLY_FUNC(a, b, length, unsigned short, SUM_OP);
197 } else if(*datatype == MPI_UNSIGNED) {
198 APPLY_FUNC(a, b, length, unsigned int, SUM_OP);
199 } else if(*datatype == MPI_UNSIGNED_LONG) {
200 APPLY_FUNC(a, b, length, unsigned long, SUM_OP);
201 } else if(*datatype == MPI_FLOAT) {
202 APPLY_FUNC(a, b, length, float, SUM_OP);
203 } else if(*datatype == MPI_DOUBLE) {
204 APPLY_FUNC(a, b, length, double, SUM_OP);
205 } else if(*datatype == MPI_LONG_DOUBLE) {
206 APPLY_FUNC(a, b, length, long double, SUM_OP);
207 } else if(*datatype == MPI_C_FLOAT_COMPLEX) {
208 APPLY_FUNC(a, b, length, float _Complex, SUM_OP);
209 } else if(*datatype == MPI_C_DOUBLE_COMPLEX) {
210 APPLY_FUNC(a, b, length, double _Complex, SUM_OP);
211 } else if(*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
212 APPLY_FUNC(a, b, length, long double _Complex, SUM_OP);
216 static void prod_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
217 if(*datatype == MPI_SHORT) {
218 APPLY_FUNC(a, b, length, short, PROD_OP);
219 } else if(*datatype == MPI_INT) {
220 APPLY_FUNC(a, b, length, int, PROD_OP);
221 } else if(*datatype == MPI_LONG) {
222 APPLY_FUNC(a, b, length, long, PROD_OP);
223 } else if(*datatype == MPI_UNSIGNED_SHORT) {
224 APPLY_FUNC(a, b, length, unsigned short, PROD_OP);
225 } else if(*datatype == MPI_UNSIGNED) {
226 APPLY_FUNC(a, b, length, unsigned int, PROD_OP);
227 } else if(*datatype == MPI_UNSIGNED_LONG) {
228 APPLY_FUNC(a, b, length, unsigned long, PROD_OP);
229 } else if(*datatype == MPI_FLOAT) {
230 APPLY_FUNC(a, b, length, float, PROD_OP);
231 } else if(*datatype == MPI_DOUBLE) {
232 APPLY_FUNC(a, b, length, double, PROD_OP);
233 } else if(*datatype == MPI_LONG_DOUBLE) {
234 APPLY_FUNC(a, b, length, long double, PROD_OP);
235 } else if(*datatype == MPI_C_FLOAT_COMPLEX) {
236 APPLY_FUNC(a, b, length, float _Complex, PROD_OP);
237 } else if(*datatype == MPI_C_DOUBLE_COMPLEX) {
238 APPLY_FUNC(a, b, length, double _Complex, PROD_OP);
239 } else if(*datatype == MPI_C_LONG_DOUBLE_COMPLEX) {
240 APPLY_FUNC(a, b, length, long double _Complex, PROD_OP);
244 static void land_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
245 if(*datatype == MPI_SHORT) {
246 APPLY_FUNC(a, b, length, short, LAND_OP);
247 } else if(*datatype == MPI_INT) {
248 APPLY_FUNC(a, b, length, int, LAND_OP);
249 } else if(*datatype == MPI_LONG) {
250 APPLY_FUNC(a, b, length, long, LAND_OP);
251 } else if(*datatype == MPI_UNSIGNED_SHORT) {
252 APPLY_FUNC(a, b, length, unsigned short, LAND_OP);
253 } else if(*datatype == MPI_UNSIGNED) {
254 APPLY_FUNC(a, b, length, unsigned int, LAND_OP);
255 } else if(*datatype == MPI_UNSIGNED_LONG) {
256 APPLY_FUNC(a, b, length, unsigned long, LAND_OP);
257 } else if(*datatype == MPI_C_BOOL) {
258 APPLY_FUNC(a, b, length, _Bool, LAND_OP);
262 static void lor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
263 if(*datatype == MPI_SHORT) {
264 APPLY_FUNC(a, b, length, short, LOR_OP);
265 } else if(*datatype == MPI_INT) {
266 APPLY_FUNC(a, b, length, int, LOR_OP);
267 } else if(*datatype == MPI_LONG) {
268 APPLY_FUNC(a, b, length, long, LOR_OP);
269 } else if(*datatype == MPI_UNSIGNED_SHORT) {
270 APPLY_FUNC(a, b, length, unsigned short, LOR_OP);
271 } else if(*datatype == MPI_UNSIGNED) {
272 APPLY_FUNC(a, b, length, unsigned int, LOR_OP);
273 } else if(*datatype == MPI_UNSIGNED_LONG) {
274 APPLY_FUNC(a, b, length, unsigned long, LOR_OP);
275 } else if(*datatype == MPI_C_BOOL) {
276 APPLY_FUNC(a, b, length, _Bool, LOR_OP);
280 static void lxor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
281 if(*datatype == MPI_SHORT) {
282 APPLY_FUNC(a, b, length, short, LXOR_OP);
283 } else if(*datatype == MPI_INT) {
284 APPLY_FUNC(a, b, length, int, LXOR_OP);
285 } else if(*datatype == MPI_LONG) {
286 APPLY_FUNC(a, b, length, long, LXOR_OP);
287 } else if(*datatype == MPI_UNSIGNED_SHORT) {
288 APPLY_FUNC(a, b, length, unsigned short, LXOR_OP);
289 } else if(*datatype == MPI_UNSIGNED) {
290 APPLY_FUNC(a, b, length, unsigned int, LXOR_OP);
291 } else if(*datatype == MPI_UNSIGNED_LONG) {
292 APPLY_FUNC(a, b, length, unsigned long, LXOR_OP);
293 } else if(*datatype == MPI_C_BOOL) {
294 APPLY_FUNC(a, b, length, _Bool, LXOR_OP);
298 static void band_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
299 if(*datatype == MPI_SHORT) {
300 APPLY_FUNC(a, b, length, short, BAND_OP);
301 } else if(*datatype == MPI_INT) {
302 APPLY_FUNC(a, b, length, int, BAND_OP);
303 } else if(*datatype == MPI_LONG) {
304 APPLY_FUNC(a, b, length, long, BAND_OP);
305 } else if(*datatype == MPI_UNSIGNED_SHORT) {
306 APPLY_FUNC(a, b, length, unsigned short, BAND_OP);
307 } else if(*datatype == MPI_UNSIGNED) {
308 APPLY_FUNC(a, b, length, unsigned int, BAND_OP);
309 } else if(*datatype == MPI_UNSIGNED_LONG) {
310 APPLY_FUNC(a, b, length, unsigned long, BAND_OP);
311 } else if(*datatype == MPI_BYTE) {
312 APPLY_FUNC(a, b, length, uint8_t, BAND_OP);
316 static void bor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
317 if(*datatype == MPI_SHORT) {
318 APPLY_FUNC(a, b, length, short, BOR_OP);
319 } else if(*datatype == MPI_INT) {
320 APPLY_FUNC(a, b, length, int, BOR_OP);
321 } else if(*datatype == MPI_LONG) {
322 APPLY_FUNC(a, b, length, long, BOR_OP);
323 } else if(*datatype == MPI_UNSIGNED_SHORT) {
324 APPLY_FUNC(a, b, length, unsigned short, BOR_OP);
325 } else if(*datatype == MPI_UNSIGNED) {
326 APPLY_FUNC(a, b, length, unsigned int, BOR_OP);
327 } else if(*datatype == MPI_UNSIGNED_LONG) {
328 APPLY_FUNC(a, b, length, unsigned long, BOR_OP);
329 } else if(*datatype == MPI_BYTE) {
330 APPLY_FUNC(a, b, length, uint8_t, BOR_OP);
334 static void bxor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
335 if(*datatype == MPI_SHORT) {
336 APPLY_FUNC(a, b, length, short, BXOR_OP);
337 } else if(*datatype == MPI_INT) {
338 APPLY_FUNC(a, b, length, int, BXOR_OP);
339 } else if(*datatype == MPI_LONG) {
340 APPLY_FUNC(a, b, length, long, BXOR_OP);
341 } else if(*datatype == MPI_UNSIGNED_SHORT) {
342 APPLY_FUNC(a, b, length, unsigned short, BXOR_OP);
343 } else if(*datatype == MPI_UNSIGNED) {
344 APPLY_FUNC(a, b, length, unsigned int, BXOR_OP);
345 } else if(*datatype == MPI_UNSIGNED_LONG) {
346 APPLY_FUNC(a, b, length, unsigned long, BXOR_OP);
347 } else if(*datatype == MPI_BYTE) {
348 APPLY_FUNC(a, b, length, uint8_t, BXOR_OP);
352 #define CREATE_MPI_OP(name, func) \
353 static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \
354 MPI_Op name = &mpi_##name;
356 CREATE_MPI_OP(MPI_MAX, max_func);
357 CREATE_MPI_OP(MPI_MIN, min_func);
358 CREATE_MPI_OP(MPI_SUM, sum_func);
359 CREATE_MPI_OP(MPI_PROD, prod_func);
360 CREATE_MPI_OP(MPI_LAND, land_func);
361 CREATE_MPI_OP(MPI_LOR, lor_func);
362 CREATE_MPI_OP(MPI_LXOR, lxor_func);
363 CREATE_MPI_OP(MPI_BAND, band_func);
364 CREATE_MPI_OP(MPI_BOR, bor_func);
365 CREATE_MPI_OP(MPI_BXOR, bxor_func);
367 MPI_Op smpi_op_new(MPI_User_function* function, int commute) {
370 //FIXME: add commute param
371 op = xbt_new(s_smpi_mpi_op_t, 1);
376 void smpi_op_destroy(MPI_Op op) {
380 void smpi_op_apply(MPI_Op op, void* invec, void* inoutvec, int* len, MPI_Datatype* datatype) {
381 op->func(invec, inoutvec, len, datatype);