Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Expand space-separated values of --log and --cfg arguments.
[simgrid.git] / src / smpi / smpi_mpi_dt.c
1 /* $Id$tag */
2
3 /* smpi_mpi_dt.c -- MPI primitives to handle datatypes                        */
4  
5 /* Note: a very incomplete implementation                                     */
6
7 /* Copyright (c) 2009 Stephane Genaud.                                        */
8 /* All rights reserved.                                                       */
9
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. */
12
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "private.h"
19 #include "smpi_mpi_dt_private.h"
20
21 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi,
22                                 "Logging specific to SMPI (datatype)");
23
24 typedef struct s_smpi_mpi_datatype {
25   size_t size;
26   MPI_Aint lb;
27   MPI_Aint ub;
28   int flags;
29 } s_smpi_mpi_datatype_t;
30
31 #define CREATE_MPI_DATATYPE(name, type)       \
32   static s_smpi_mpi_datatype_t mpi_##name = { \
33     sizeof(type),  /* size */                 \
34     0,             /* lb */                   \
35     sizeof(type),  /* ub = lb + size */       \
36     DT_FLAG_BASIC  /* flags */                \
37   };                                          \
38   MPI_Datatype name = &mpi_##name;
39
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);
70
71 size_t smpi_datatype_size(MPI_Datatype datatype) {
72   return datatype->size;
73 }
74
75 MPI_Aint smpi_datatype_lb(MPI_Datatype datatype) {
76   return datatype->lb;
77 }
78
79 MPI_Aint smpi_datatype_ub(MPI_Datatype datatype) {
80   return datatype->ub;
81 }
82
83 int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint* lb, MPI_Aint * extent) {
84   int retval;
85
86   if((datatype->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
87     retval = MPI_ERR_TYPE;
88   } else {
89     *lb =  datatype->lb;
90     *extent =  datatype->ub - datatype->lb;
91     retval = MPI_SUCCESS;
92   }
93   return MPI_SUCCESS;
94 }
95
96 int smpi_datatype_copy(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype) {
97   int retval, count;
98
99   /* First check if we really have something to do */
100   if(recvcount == 0) {
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;
107  } else {
108    /* FIXME:  cases 
109     * - If receive packed. 
110     * - If send packed
111     * to be treated once we have the MPI_Pack things ...
112     **/
113    retval = MPI_SUCCESS;
114  }
115  return retval;
116 }
117
118 typedef struct s_smpi_mpi_op {
119   MPI_User_function* func;
120 } s_smpi_mpi_op_t;
121
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
133
134 #define APPLY_FUNC(a, b, length, type, func) \
135   {                                          \
136     int i;                                   \
137     type* x = (type*)(a);                    \
138     type* y = (type*)(b);                    \
139     for(i = 0; i < *(length); i++) {         \
140       func(x[i], y[i]);                      \
141     }                                        \
142   }
143
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);
163   }
164 }
165  
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);
185   }
186 }
187  
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);
213   }
214 }
215  
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);
241   }
242 }
243  
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);
259   }
260 }
261  
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);
277   }
278 }
279  
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);
295   }
296 }
297  
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);
313   }
314 }
315  
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);
331   }
332 }
333  
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);
349   }
350 }
351
352 #define CREATE_MPI_OP(name, func)                             \
353   static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \
354   MPI_Op name = &mpi_##name;
355
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);
366
367 MPI_Op smpi_op_new(MPI_User_function* function, int commute) {
368   MPI_Op op;
369
370   //FIXME: add commute param
371   op = xbt_new(s_smpi_mpi_op_t, 1);
372   op->func = function;
373   return op;
374 }
375
376 void smpi_op_destroy(MPI_Op op) {
377   xbt_free(op);
378 }
379
380 void smpi_op_apply(MPI_Op op, void* invec, void* inoutvec, int* len, MPI_Datatype* datatype) {
381   op->func(invec, inoutvec, len, datatype);
382 }