Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
First works on the datatypes. Still missing a lot.
[simgrid.git] / src / smpi / smpi_mpi_dt.cpp
1 /* smpi_mpi_dt.c -- MPI primitives to handle datatypes                      */
2 /* Copyright (c) 2009-2017. The SimGrid Team. All rights reserved.          */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "mc/mc.h"
8 #include "private.h"
9 #include "simgrid/modelchecker.h"
10 #include "smpi_mpi_dt_private.h"
11 #include "xbt/replay.h"
12 #include <limits.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <string>
17 #include <xbt/ex.hpp>
18
19 //XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi, "Logging specific to SMPI (datatype)");
20
21 //xbt_dict_t smpi_type_keyvals = nullptr;
22 //int type_keyval_id=0;//avoid collisions
23
24
25 /** Check if the datatype is usable for communications */
26 bool is_datatype_valid(MPI_Datatype datatype) {
27     return datatype != MPI_DATATYPE_NULL && ((datatype->flags_ & DT_FLAG_COMMITED) != 0);
28 }
29
30 size_t smpi_datatype_size(MPI_Datatype datatype)
31 {
32   return datatype->size_;
33 }
34
35 MPI_Aint smpi_datatype_lb(MPI_Datatype datatype)
36 {
37   return datatype->lb_;
38 }
39
40 MPI_Aint smpi_datatype_ub(MPI_Datatype datatype)
41 {
42   return datatype->ub_;
43 }
44
45 int smpi_datatype_dup(MPI_Datatype datatype, MPI_Datatype* new_t)
46 {
47   int ret=MPI_SUCCESS;
48   return ret;
49 }
50
51 int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
52 {
53   return MPI_SUCCESS;
54 }
55
56 MPI_Aint smpi_datatype_get_extent(MPI_Datatype datatype){
57   if(datatype == MPI_DATATYPE_NULL){
58     return 0;
59   }
60   return datatype->ub_ - datatype->lb_;
61 }
62
63 void smpi_datatype_get_name(MPI_Datatype datatype, char* name, int* length){
64   *length = strlen(datatype->name_);
65   strncpy(name, datatype->name_, *length+1);
66 }
67
68 void smpi_datatype_set_name(MPI_Datatype datatype, char* name){
69   if(datatype->name_!=nullptr &&  (datatype->flags_ & DT_FLAG_PREDEFINED) == 0)
70     xbt_free(datatype->name_);
71   datatype->name_ = xbt_strdup(name);
72 }
73
74 int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
75                        void *recvbuf, int recvcount, MPI_Datatype recvtype)
76 {
77  
78   return sendcount > recvcount ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
79 }
80
81 /*
82  *  Copies noncontiguous data into contiguous memory.
83  *  @param contiguous_vector - output vector
84  *  @param noncontiguous_vector - input vector
85  *  @param type - pointer containing :
86  *      - stride - stride of between noncontiguous data
87  *      - block_length - the width or height of blocked matrix
88  *      - count - the number of rows of matrix
89  */
90 void serialize_vector( void* noncontiguous_vector, void *contiguous_vector, int count, void *type)
91 {
92 //  s_smpi_mpi_vector_t* type_c = reinterpret_cast<s_smpi_mpi_vector_t*>(type);
93 //  int i;
94 //  char* contiguous_vector_char = static_cast<char*>(contiguous_vector);
95 //  char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_vector);
96
97 //  for (i = 0; i < type_c->block_count * count; i++) {
98 //      if (type_c->old_type->sizeof_substruct == 0)
99 //        memcpy(contiguous_vector_char, noncontiguous_vector_char, type_c->block_length * type_c->size_oldtype);
100 //      else
101 //        static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->serialize( noncontiguous_vector_char,
102 //                                                                     contiguous_vector_char,
103 //                                                                     type_c->block_length, type_c->old_type->substruct);
104
105 //    contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
106 //    if((i+1)%type_c->block_count ==0)
107 //      noncontiguous_vector_char += type_c->block_length*smpi_datatype_get_extent(type_c->old_type);
108 //    else
109 //      noncontiguous_vector_char += type_c->block_stride*smpi_datatype_get_extent(type_c->old_type);
110 //  }
111 }
112
113 /*
114  *  Copies contiguous data into noncontiguous memory.
115  *  @param noncontiguous_vector - output vector
116  *  @param contiguous_vector - input vector
117  *  @param type - pointer contening :
118  *      - stride - stride of between noncontiguous data
119  *      - block_length - the width or height of blocked matrix
120  *      - count - the number of rows of matrix
121  */
122 void unserialize_vector( void* contiguous_vector, void *noncontiguous_vector, int count, void *type, MPI_Op op)
123 {
124 //  s_smpi_mpi_vector_t* type_c = reinterpret_cast<s_smpi_mpi_vector_t*>(type);
125 //  int i;
126
127 //  char* contiguous_vector_char = static_cast<char*>(contiguous_vector);
128 //  char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_vector);
129
130 //  for (i = 0; i < type_c->block_count * count; i++) {
131 //    if (type_c->old_type->sizeof_substruct == 0){
132 //      if(op!=MPI_OP_NULL)
133 //        op->apply( contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length,
134 //          &type_c->old_type);
135 //    }else
136 //      static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize(contiguous_vector_char, noncontiguous_vector_char,
137 //                                                                    type_c->block_length,type_c->old_type->substruct,
138 //                                                                    op);
139 //    contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
140 //    if((i+1)%type_c->block_count ==0)
141 //      noncontiguous_vector_char += type_c->block_length*smpi_datatype_get_extent(type_c->old_type);
142 //    else
143 //      noncontiguous_vector_char += type_c->block_stride*smpi_datatype_get_extent(type_c->old_type);
144 //  }
145 }
146
147 /* Create a Sub type vector to be able to serialize and unserialize it the structure s_smpi_mpi_vector_t is derived
148  * from s_smpi_subtype which required the functions unserialize and serialize */
149 s_smpi_mpi_vector_t* smpi_datatype_vector_create( int block_stride, int block_length, int block_count,
150                                                   MPI_Datatype old_type, int size_oldtype){
151   s_smpi_mpi_vector_t *new_t= xbt_new(s_smpi_mpi_vector_t,1);
152   new_t->base.serialize = &serialize_vector;
153   new_t->base.unserialize = &unserialize_vector;
154   new_t->base.subtype_free = &free_vector;
155   new_t->base.subtype_use = &use_vector;
156   new_t->block_stride = block_stride;
157   new_t->block_length = block_length;
158   new_t->block_count = block_count;
159   smpi_datatype_use(old_type);
160   new_t->old_type = old_type;
161   new_t->size_oldtype = size_oldtype;
162   return new_t;
163 }
164
165 void smpi_datatype_create(MPI_Datatype* new_type, int size,int lb, int ub, int sizeof_substruct, void *struct_type,
166                           int flags){
167 //  MPI_Datatype new_t= xbt_new(s_smpi_mpi_datatype_t,1);
168 //  new_t->name = nullptr;
169 //  new_t->size = size;
170 //  new_t->sizeof_substruct = size>0? sizeof_substruct:0;
171 //  new_t->lb = lb;
172 //  new_t->ub = ub;
173 //  new_t->flags = flags;
174 //  new_t->substruct = struct_type;
175 //  new_t->in_use=1;
176 //  new_t->attributes=nullptr;
177 //  *new_type = new_t;
178
179 //#if HAVE_MC
180 //  if(MC_is_active())
181 //    MC_ignore(&(new_t->in_use), sizeof(new_t->in_use));
182 //#endif
183 }
184
185 void smpi_datatype_free(MPI_Datatype* type){
186 //  xbt_assert((*type)->in_use_ >= 0);
187
188 //  if((*type)->flags & DT_FLAG_PREDEFINED)
189 //    return;
190
191 //  //if still used, mark for deletion
192 //  if((*type)->in_use_!=0){
193 //      (*type)->flags_ |=DT_FLAG_DESTROYED;
194 //      return;
195 //  }
196
197 //  if((*type)->attributes_ !=nullptr){
198 //    xbt_dict_cursor_t cursor = nullptr;
199 //    char* key;
200 //    void * value;
201 //    int flag;
202 //    xbt_dict_foreach((*type)->attributes, cursor, key, value){
203 //      smpi_type_key_elem elem =
204 //          static_cast<smpi_type_key_elem>(xbt_dict_get_or_null_ext(smpi_type_keyvals, key, sizeof(int)));
205 //      if(elem!=nullptr && elem->delete_fn!=nullptr)
206 //        elem->delete_fn(*type,*key, value, &flag);
207 //    }
208 //    xbt_dict_free(&(*type)->attributes);
209 //  }
210
211 //  if ((*type)->sizeof_substruct != 0){
212 //    //((s_smpi_subtype_t *)(*type)->substruct)->subtype_free(type);  
213 //    xbt_free((*type)->substruct);
214 //  }
215 //  xbt_free((*type)->name);
216 //  xbt_free(*type);
217 //  *type = MPI_DATATYPE_NULL;
218 }
219
220 void smpi_datatype_use(MPI_Datatype type){
221
222 //  if(type == MPI_DATATYPE_NULL)
223 //    return;
224 //  type->in_use++;
225
226 //  if(type->sizeof_substruct!=0){
227 //    static_cast<s_smpi_subtype_t *>((type)->substruct)->subtype_use(&type);  
228 //  }
229 //#if HAVE_MC
230 //  if(MC_is_active())
231 //    MC_ignore(&(type->in_use), sizeof(type->in_use));
232 //#endif
233 }
234
235 void smpi_datatype_unuse(MPI_Datatype type)
236 {
237 //  if (type == MPI_DATATYPE_NULL)
238 //    return;
239
240 //  if (type->in_use > 0)
241 //    type->in_use--;
242
243 //  if(type->sizeof_substruct!=0){
244 //    static_cast<s_smpi_subtype_t *>((type)->substruct)->subtype_free(&type);  
245 //  }
246
247 //  if (type->in_use == 0)
248 //    smpi_datatype_free(&type);
249
250 //#if HAVE_MC
251 //  if(MC_is_active())
252 //    MC_ignore(&(type->in_use), sizeof(type->in_use));
253 //#endif
254 }
255
256 /*Contiguous Implementation*/
257
258 /* Copies noncontiguous data into contiguous memory.
259  *  @param contiguous_hvector - output hvector
260  *  @param noncontiguous_hvector - input hvector
261  *  @param type - pointer contening :
262  *      - stride - stride of between noncontiguous data, in bytes
263  *      - block_length - the width or height of blocked matrix
264  *      - count - the number of rows of matrix
265  */
266 void serialize_contiguous( void* noncontiguous_hvector, void *contiguous_hvector, int count, void *type)
267 {
268   s_smpi_mpi_contiguous_t* type_c = reinterpret_cast<s_smpi_mpi_contiguous_t*>(type);
269   char* contiguous_vector_char = static_cast<char*>(contiguous_hvector);
270   char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_hvector)+type_c->lb;
271   memcpy(contiguous_vector_char, noncontiguous_vector_char, count* type_c->block_count * type_c->size_oldtype);
272 }
273 /* Copies contiguous data into noncontiguous memory.
274  *  @param noncontiguous_vector - output hvector
275  *  @param contiguous_vector - input hvector
276  *  @param type - pointer contening :
277  *      - stride - stride of between noncontiguous data, in bytes
278  *      - block_length - the width or height of blocked matrix
279  *      - count - the number of rows of matrix
280  */
281 void unserialize_contiguous(void* contiguous_vector, void *noncontiguous_vector, int count, void *type, MPI_Op op)
282 {
283 //  s_smpi_mpi_contiguous_t* type_c = reinterpret_cast<s_smpi_mpi_contiguous_t*>(type);
284 //  char* contiguous_vector_char = static_cast<char*>(contiguous_vector);
285 //  char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_vector)+type_c->lb;
286 //  int n= count* type_c->block_count;
287 //  if(op!=MPI_OP_NULL)
288 //    op->apply( contiguous_vector_char, noncontiguous_vector_char, &n, &type_c->old_type);
289 }
290
291 void free_contiguous(MPI_Datatype* d){
292 //  smpi_datatype_unuse(reinterpret_cast<s_smpi_mpi_contiguous_t*>((*d)->substruct)->old_type);
293 }
294
295 void use_contiguous(MPI_Datatype* d){
296 //  smpi_datatype_use(reinterpret_cast<s_smpi_mpi_contiguous_t*>((*d)->substruct)->old_type);
297 }
298
299 /* Create a Sub type contiguous to be able to serialize and unserialize it the structure s_smpi_mpi_contiguous_t is
300  * derived from s_smpi_subtype which required the functions unserialize and serialize */
301 s_smpi_mpi_contiguous_t* smpi_datatype_contiguous_create( MPI_Aint lb, int block_count, MPI_Datatype old_type,
302                                                   int size_oldtype){
303   if(block_count==0)
304     return nullptr;
305   s_smpi_mpi_contiguous_t *new_t= xbt_new(s_smpi_mpi_contiguous_t,1);
306   new_t->base.serialize = &serialize_contiguous;
307   new_t->base.unserialize = &unserialize_contiguous;
308   new_t->base.subtype_free = &free_contiguous;
309   new_t->base.subtype_use = &use_contiguous;
310   new_t->lb = lb;
311   new_t->block_count = block_count;
312   new_t->old_type = old_type;
313   smpi_datatype_use(old_type);
314   new_t->size_oldtype = size_oldtype;
315   smpi_datatype_use(old_type);
316   return new_t;
317 }
318
319 int smpi_datatype_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type, MPI_Aint lb)
320 {
321   int retval;
322 //  if(old_type->sizeof_substruct){
323 //    //handle this case as a hvector with stride equals to the extent of the datatype
324 //    return smpi_datatype_hvector(count, 1, smpi_datatype_get_extent(old_type), old_type, new_type);
325 //  }
326 //  
327 //  s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create( lb, count, old_type,smpi_datatype_size(old_type));
328
329 //  smpi_datatype_create(new_type, count * smpi_datatype_size(old_type),lb,lb + count * smpi_datatype_size(old_type),
330 //            sizeof(s_smpi_mpi_contiguous_t),subtype, DT_FLAG_CONTIGUOUS);
331   retval=MPI_SUCCESS;
332   return retval;
333 }
334
335 int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type)
336 {
337   int retval;
338 //  if (blocklen<0) 
339 //    return MPI_ERR_ARG;
340 //  MPI_Aint lb = 0;
341 //  MPI_Aint ub = 0;
342 //  if(count>0){
343 //    lb=smpi_datatype_lb(old_type);
344 //    ub=((count-1)*stride+blocklen-1)*smpi_datatype_get_extent(old_type)+smpi_datatype_ub(old_type);
345 //  }
346 //  if(old_type->sizeof_substruct != 0 || stride != blocklen){
347
348 //    s_smpi_mpi_vector_t* subtype = smpi_datatype_vector_create(stride, blocklen, count, old_type,
349 //                                                                smpi_datatype_size(old_type));
350 //    smpi_datatype_create(new_type, count * (blocklen) * smpi_datatype_size(old_type), lb, ub, sizeof(s_smpi_mpi_vector_t), subtype,
351 //                         DT_FLAG_VECTOR);
352 //    retval=MPI_SUCCESS;
353 //  }else{
354 //    /* in this situation the data are contiguous thus it's not required to serialize and unserialize it*/
355 //    smpi_datatype_create(new_type, count * blocklen * smpi_datatype_size(old_type), 0, ((count -1) * stride + blocklen)*
356 //                         smpi_datatype_size(old_type), 0, nullptr, DT_FLAG_VECTOR|DT_FLAG_CONTIGUOUS);
357     retval=MPI_SUCCESS;
358 //  }
359   return retval;
360 }
361
362 void free_vector(MPI_Datatype* d){
363 //  smpi_datatype_unuse(reinterpret_cast<s_smpi_mpi_indexed_t*>((*d)->substruct)->old_type);
364 }
365
366 void use_vector(MPI_Datatype* d){
367 //  smpi_datatype_use(reinterpret_cast<s_smpi_mpi_indexed_t*>((*d)->substruct)->old_type);
368 }
369
370 /* Hvector Implementation - Vector with stride in bytes */
371
372 /* Copies noncontiguous data into contiguous memory.
373  *  @param contiguous_hvector - output hvector
374  *  @param noncontiguous_hvector - input hvector
375  *  @param type - pointer contening :
376  *      - stride - stride of between noncontiguous data, in bytes
377  *      - block_length - the width or height of blocked matrix
378  *      - count - the number of rows of matrix
379  */
380 void serialize_hvector( void* noncontiguous_hvector, void *contiguous_hvector, int count, void *type)
381 {
382 //  s_smpi_mpi_hvector_t* type_c = reinterpret_cast<s_smpi_mpi_hvector_t*>(type);
383 //  int i;
384 //  char* contiguous_vector_char = static_cast<char*>(contiguous_hvector);
385 //  char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_hvector);
386
387 //  for (i = 0; i < type_c->block_count * count; i++) {
388 //    if (type_c->old_type->sizeof_substruct == 0)
389 //      memcpy(contiguous_vector_char, noncontiguous_vector_char, type_c->block_length * type_c->size_oldtype);
390 //    else
391 //      static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->serialize( noncontiguous_vector_char,
392 //                                                                   contiguous_vector_char,
393 //                                                                   type_c->block_length, type_c->old_type->substruct);
394
395 //    contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
396 //    if((i+1)%type_c->block_count ==0)
397 //      noncontiguous_vector_char += type_c->block_length*type_c->size_oldtype;
398 //    else
399 //      noncontiguous_vector_char += type_c->block_stride;
400 //  }
401 }
402 /* Copies contiguous data into noncontiguous memory.
403  *  @param noncontiguous_vector - output hvector
404  *  @param contiguous_vector - input hvector
405  *  @param type - pointer contening :
406  *      - stride - stride of between noncontiguous data, in bytes
407  *      - block_length - the width or height of blocked matrix
408  *      - count - the number of rows of matrix
409  */
410 void unserialize_hvector( void* contiguous_vector, void *noncontiguous_vector, int count, void *type, MPI_Op op)
411 {
412 //  s_smpi_mpi_hvector_t* type_c = reinterpret_cast<s_smpi_mpi_hvector_t*>(type);
413 //  int i;
414
415 //  char* contiguous_vector_char = static_cast<char*>(contiguous_vector);
416 //  char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_vector);
417
418 //  for (i = 0; i < type_c->block_count * count; i++) {
419 //    if (type_c->old_type->sizeof_substruct == 0){
420 //      if(op!=MPI_OP_NULL) 
421 //        op->apply( contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length, &type_c->old_type);
422 //    }else
423 //      static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize( contiguous_vector_char, noncontiguous_vector_char,
424 //                                                                     type_c->block_length, type_c->old_type->substruct,
425 //                                                                     op);
426 //    contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
427 //    if((i+1)%type_c->block_count ==0)
428 //      noncontiguous_vector_char += type_c->block_length*type_c->size_oldtype;
429 //    else
430 //      noncontiguous_vector_char += type_c->block_stride;
431 //  }
432 }
433
434 /* Create a Sub type vector to be able to serialize and unserialize it the structure s_smpi_mpi_vector_t is derived
435  * from s_smpi_subtype which required the functions unserialize and serialize
436  *
437  */
438 s_smpi_mpi_hvector_t* smpi_datatype_hvector_create( MPI_Aint block_stride, int block_length, int block_count,
439                                                   MPI_Datatype old_type, int size_oldtype){
440   s_smpi_mpi_hvector_t *new_t= xbt_new(s_smpi_mpi_hvector_t,1);
441   new_t->base.serialize = &serialize_hvector;
442   new_t->base.unserialize = &unserialize_hvector;
443   new_t->base.subtype_free = &free_hvector;
444   new_t->base.subtype_use = &use_hvector;
445   new_t->block_stride = block_stride;
446   new_t->block_length = block_length;
447   new_t->block_count = block_count;
448   new_t->old_type = old_type;
449   new_t->size_oldtype = size_oldtype;
450   smpi_datatype_use(old_type);
451   return new_t;
452 }
453
454 //do nothing for vector types
455 void free_hvector(MPI_Datatype* d){
456 //  smpi_datatype_unuse(reinterpret_cast<s_smpi_mpi_hvector_t*>((*d)->substruct)->old_type);
457 }
458
459 void use_hvector(MPI_Datatype* d){
460 //  smpi_datatype_use(reinterpret_cast<s_smpi_mpi_hvector_t*>((*d)->substruct)->old_type);
461 }
462
463 int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type)
464 {
465   int retval;
466 //  if (blocklen<0) 
467 //    return MPI_ERR_ARG;
468 //  MPI_Aint lb = 0;
469 //  MPI_Aint ub = 0;
470 //  if(count>0){
471 //    lb=smpi_datatype_lb(old_type);
472 //    ub=((count-1)*stride)+(blocklen-1)*smpi_datatype_get_extent(old_type)+smpi_datatype_ub(old_type);
473 //  }
474 //  if(old_type->sizeof_substruct != 0 || stride != blocklen*smpi_datatype_get_extent(old_type)){
475 //    s_smpi_mpi_hvector_t* subtype = smpi_datatype_hvector_create( stride, blocklen, count, old_type,
476 //                                                                  smpi_datatype_size(old_type));
477
478 //    smpi_datatype_create(new_type, count * blocklen * smpi_datatype_size(old_type), lb,ub, sizeof(s_smpi_mpi_hvector_t), subtype, DT_FLAG_VECTOR);
479 //    retval=MPI_SUCCESS;
480 //  }else{
481 //    smpi_datatype_create(new_type, count * blocklen * smpi_datatype_size(old_type),0,count * blocklen *
482 //                                             smpi_datatype_size(old_type), 0, nullptr, DT_FLAG_VECTOR|DT_FLAG_CONTIGUOUS);
483   retval=MPI_SUCCESS;
484 //  }
485   return retval;
486 }
487
488 /* Indexed Implementation */
489
490 /* Copies noncontiguous data into contiguous memory.
491  *  @param contiguous_indexed - output indexed
492  *  @param noncontiguous_indexed - input indexed
493  *  @param type - pointer contening :
494  *      - block_lengths - the width or height of blocked matrix
495  *      - block_indices - indices of each data, in element
496  *      - count - the number of rows of matrix
497  */
498 void serialize_indexed( void* noncontiguous_indexed, void *contiguous_indexed, int count, void *type)
499 {
500 //  s_smpi_mpi_indexed_t* type_c = reinterpret_cast<s_smpi_mpi_indexed_t*>(type);
501 //  char* contiguous_indexed_char = static_cast<char*>(contiguous_indexed);
502 //  char* noncontiguous_indexed_char = static_cast<char*>(noncontiguous_indexed)+type_c->block_indices[0] * type_c->size_oldtype;
503 //  for (int j = 0; j < count; j++) {
504 //    for (int i = 0; i < type_c->block_count; i++) {
505 //      if (type_c->old_type->sizeof_substruct == 0)
506 //        memcpy(contiguous_indexed_char, noncontiguous_indexed_char, type_c->block_lengths[i] * type_c->size_oldtype);
507 //      else
508 //        static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->serialize( noncontiguous_indexed_char,
509 //                                                                     contiguous_indexed_char,
510 //                                                                     type_c->block_lengths[i],
511 //                                                                     type_c->old_type->substruct);
512
513 //      contiguous_indexed_char += type_c->block_lengths[i]*type_c->size_oldtype;
514 //      if (i<type_c->block_count-1)
515 //        noncontiguous_indexed_char =
516 //          static_cast<char*>(noncontiguous_indexed) + type_c->block_indices[i+1]*smpi_datatype_get_extent(type_c->old_type);
517 //      else
518 //        noncontiguous_indexed_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_type);
519 //    }
520 //    noncontiguous_indexed=static_cast< void*>(noncontiguous_indexed_char);
521 //  }
522 }
523 /* Copies contiguous data into noncontiguous memory.
524  *  @param noncontiguous_indexed - output indexed
525  *  @param contiguous_indexed - input indexed
526  *  @param type - pointer contening :
527  *      - block_lengths - the width or height of blocked matrix
528  *      - block_indices - indices of each data, in element
529  *      - count - the number of rows of matrix
530  */
531 void unserialize_indexed( void* contiguous_indexed, void *noncontiguous_indexed, int count, void *type, MPI_Op op)
532 {
533 //  s_smpi_mpi_indexed_t* type_c = reinterpret_cast<s_smpi_mpi_indexed_t*>(type);
534 //  char* contiguous_indexed_char = static_cast<char*>(contiguous_indexed);
535 //  char* noncontiguous_indexed_char =
536 //    static_cast<char*>(noncontiguous_indexed)+type_c->block_indices[0]*smpi_datatype_get_extent(type_c->old_type);
537 //  for (int j = 0; j < count; j++) {
538 //    for (int i = 0; i < type_c->block_count; i++) {
539 //      if (type_c->old_type->sizeof_substruct == 0){
540 //        if(op!=MPI_OP_NULL) 
541 //          op->apply( contiguous_indexed_char, noncontiguous_indexed_char, &type_c->block_lengths[i],
542 //                    &type_c->old_type);
543 //      }else
544 //        static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize( contiguous_indexed_char,
545 //                                                                       noncontiguous_indexed_char,
546 //                                                                       type_c->block_lengths[i],
547 //                                                                       type_c->old_type->substruct, op);
548
549 //      contiguous_indexed_char += type_c->block_lengths[i]*type_c->size_oldtype;
550 //      if (i<type_c->block_count-1)
551 //        noncontiguous_indexed_char =
552 //          static_cast<char*>(noncontiguous_indexed) + type_c->block_indices[i+1]*smpi_datatype_get_extent(type_c->old_type);
553 //      else
554 //        noncontiguous_indexed_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_type);
555 //    }
556 //    noncontiguous_indexed=static_cast<void*>(noncontiguous_indexed_char);
557 //  }
558 }
559
560 void free_indexed(MPI_Datatype* type){
561 //  if((*type)->in_use==0){
562 //    xbt_free(reinterpret_cast<s_smpi_mpi_indexed_t*>((*type)->substruct)->block_lengths);
563 //    xbt_free(reinterpret_cast<s_smpi_mpi_indexed_t*>((*type)->substruct)->block_indices);
564 //  }
565 //  smpi_datatype_unuse(reinterpret_cast<s_smpi_mpi_indexed_t*>((*type)->substruct)->old_type);
566 }
567
568 void use_indexed(MPI_Datatype* type){
569 //  smpi_datatype_use(reinterpret_cast<s_smpi_mpi_indexed_t*>((*type)->substruct)->old_type);
570 }
571
572
573 /* Create a Sub type indexed to be able to serialize and unserialize it the structure s_smpi_mpi_indexed_t is derived
574  * from s_smpi_subtype which required the functions unserialize and serialize */
575 s_smpi_mpi_indexed_t* smpi_datatype_indexed_create( int* block_lengths, int* block_indices, int block_count,
576                                                   MPI_Datatype old_type, int size_oldtype){
577   s_smpi_mpi_indexed_t *new_t= xbt_new(s_smpi_mpi_indexed_t,1);
578   new_t->base.serialize = &serialize_indexed;
579   new_t->base.unserialize = &unserialize_indexed;
580   new_t->base.subtype_free = &free_indexed;
581   new_t->base.subtype_use = &use_indexed;
582   new_t->block_lengths= xbt_new(int, block_count);
583   new_t->block_indices= xbt_new(int, block_count);
584   for (int i = 0; i < block_count; i++) {
585     new_t->block_lengths[i]=block_lengths[i];
586     new_t->block_indices[i]=block_indices[i];
587   }
588   new_t->block_count = block_count;
589   smpi_datatype_use(old_type);
590   new_t->old_type = old_type;
591   new_t->size_oldtype = size_oldtype;
592   return new_t;
593 }
594
595 int smpi_datatype_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
596 {
597 //  int size = 0;
598 //  bool contiguous=true;
599 //  MPI_Aint lb = 0;
600 //  MPI_Aint ub = 0;
601 //  if(count>0){
602 //    lb=indices[0]*smpi_datatype_get_extent(old_type);
603 //    ub=indices[0]*smpi_datatype_get_extent(old_type) + blocklens[0]*smpi_datatype_ub(old_type);
604 //  }
605
606 //  for (int i = 0; i < count; i++) {
607 //    if (blocklens[i] < 0)
608 //      return MPI_ERR_ARG;
609 //    size += blocklens[i];
610
611 //    if(indices[i]*smpi_datatype_get_extent(old_type)+smpi_datatype_lb(old_type)<lb)
612 //      lb = indices[i]*smpi_datatype_get_extent(old_type)+smpi_datatype_lb(old_type);
613 //    if(indices[i]*smpi_datatype_get_extent(old_type)+blocklens[i]*smpi_datatype_ub(old_type)>ub)
614 //      ub = indices[i]*smpi_datatype_get_extent(old_type)+blocklens[i]*smpi_datatype_ub(old_type);
615
616 //    if ( (i< count -1) && (indices[i]+blocklens[i] != indices[i+1]) )
617 //      contiguous=false;
618 //  }
619 //  if (old_type->sizeof_substruct != 0)
620 //    contiguous=false;
621
622 //  if(!contiguous){
623 //    s_smpi_mpi_indexed_t* subtype = smpi_datatype_indexed_create( blocklens, indices, count, old_type,
624 //                                                                  smpi_datatype_size(old_type));
625 //     smpi_datatype_create(new_type,  size * smpi_datatype_size(old_type),lb,ub,sizeof(s_smpi_mpi_indexed_t), subtype, DT_FLAG_DATA);
626 //  }else{
627 //    s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create( lb, size, old_type,
628 //                                                                  smpi_datatype_size(old_type));
629 //    smpi_datatype_create(new_type, size * smpi_datatype_size(old_type), lb, ub, sizeof(s_smpi_mpi_contiguous_t), subtype,
630 //                         DT_FLAG_DATA|DT_FLAG_CONTIGUOUS);
631 //  }
632   return MPI_SUCCESS;
633 }
634 /* Hindexed Implementation - Indexed with indices in bytes */
635
636 /* Copies noncontiguous data into contiguous memory.
637  *  @param contiguous_hindexed - output hindexed
638  *  @param noncontiguous_hindexed - input hindexed
639  *  @param type - pointer contening :
640  *      - block_lengths - the width or height of blocked matrix
641  *      - block_indices - indices of each data, in bytes
642  *      - count - the number of rows of matrix
643  */
644 void serialize_hindexed( void* noncontiguous_hindexed, void *contiguous_hindexed, int count, void *type)
645 {
646 //  s_smpi_mpi_hindexed_t* type_c = reinterpret_cast<s_smpi_mpi_hindexed_t*>(type);
647 //  char* contiguous_hindexed_char = static_cast<char*>(contiguous_hindexed);
648 //  char* noncontiguous_hindexed_char = static_cast<char*>(noncontiguous_hindexed)+ type_c->block_indices[0];
649 //  for (int j = 0; j < count; j++) {
650 //    for (int i = 0; i < type_c->block_count; i++) {
651 //      if (type_c->old_type->sizeof_substruct == 0)
652 //        memcpy(contiguous_hindexed_char, noncontiguous_hindexed_char, type_c->block_lengths[i] * type_c->size_oldtype);
653 //      else
654 //        static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->serialize( noncontiguous_hindexed_char,
655 //                                                                     contiguous_hindexed_char,
656 //                                                                     type_c->block_lengths[i],
657 //                                                                     type_c->old_type->substruct);
658
659 //      contiguous_hindexed_char += type_c->block_lengths[i]*type_c->size_oldtype;
660 //      if (i<type_c->block_count-1)
661 //        noncontiguous_hindexed_char = static_cast<char*>(noncontiguous_hindexed) + type_c->block_indices[i+1];
662 //      else
663 //        noncontiguous_hindexed_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_type);
664 //    }
665 //    noncontiguous_hindexed=static_cast<void*>(noncontiguous_hindexed_char);
666 //  }
667 }
668 /* Copies contiguous data into noncontiguous memory.
669  *  @param noncontiguous_hindexed - output hindexed
670  *  @param contiguous_hindexed - input hindexed
671  *  @param type - pointer contening :
672  *      - block_lengths - the width or height of blocked matrix
673  *      - block_indices - indices of each data, in bytes
674  *      - count - the number of rows of matrix
675  */
676 void unserialize_hindexed( void* contiguous_hindexed, void *noncontiguous_hindexed, int count, void *type,
677                          MPI_Op op)
678 {
679 //  s_smpi_mpi_hindexed_t* type_c = reinterpret_cast<s_smpi_mpi_hindexed_t*>(type);
680
681 //  char* contiguous_hindexed_char = static_cast<char*>(contiguous_hindexed);
682 //  char* noncontiguous_hindexed_char = static_cast<char*>(noncontiguous_hindexed)+ type_c->block_indices[0];
683 //  for (int j = 0; j < count; j++) {
684 //    for (int i = 0; i < type_c->block_count; i++) {
685 //      if (type_c->old_type->sizeof_substruct == 0){
686 //        if(op!=MPI_OP_NULL) 
687 //          op->apply( contiguous_hindexed_char, noncontiguous_hindexed_char, &type_c->block_lengths[i],
688 //                            &type_c->old_type);
689 //      }else
690 //        static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize( contiguous_hindexed_char,
691 //                                                                       noncontiguous_hindexed_char,
692 //                                                                       type_c->block_lengths[i],
693 //                                                                       type_c->old_type->substruct, op);
694
695 //      contiguous_hindexed_char += type_c->block_lengths[i]*type_c->size_oldtype;
696 //      if (i<type_c->block_count-1)
697 //        noncontiguous_hindexed_char = static_cast<char*>(noncontiguous_hindexed) + type_c->block_indices[i+1];
698 //      else
699 //        noncontiguous_hindexed_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_type);
700 //    }
701 //    noncontiguous_hindexed=static_cast<void*>(noncontiguous_hindexed_char);
702 //  }
703 }
704
705 void free_hindexed(MPI_Datatype* type){
706 //  if((*type)->in_use==0){
707 //    xbt_free(reinterpret_cast<s_smpi_mpi_hindexed_t*>((*type)->substruct)->block_lengths);
708 //    xbt_free(reinterpret_cast<s_smpi_mpi_hindexed_t*>((*type)->substruct)->block_indices);
709 //  }
710 //  smpi_datatype_unuse(reinterpret_cast<s_smpi_mpi_hindexed_t*>((*type)->substruct)->old_type);
711 }
712
713 void use_hindexed(MPI_Datatype* type){
714 //  smpi_datatype_use(reinterpret_cast<s_smpi_mpi_hindexed_t*>((*type)->substruct)->old_type);
715 }
716
717 /* Create a Sub type hindexed to be able to serialize and unserialize it the structure s_smpi_mpi_hindexed_t is derived
718  * from s_smpi_subtype which required the functions unserialize and serialize
719  */
720 s_smpi_mpi_hindexed_t* smpi_datatype_hindexed_create( int* block_lengths, MPI_Aint* block_indices, int block_count,
721                                                   MPI_Datatype old_type, int size_oldtype){
722   s_smpi_mpi_hindexed_t *new_t= xbt_new(s_smpi_mpi_hindexed_t,1);
723   new_t->base.serialize = &serialize_hindexed;
724   new_t->base.unserialize = &unserialize_hindexed;
725   new_t->base.subtype_free = &free_hindexed;
726   new_t->base.subtype_use = &use_hindexed;
727   new_t->block_lengths= xbt_new(int, block_count);
728   new_t->block_indices= xbt_new(MPI_Aint, block_count);
729   for(int i=0;i<block_count;i++){
730     new_t->block_lengths[i]=block_lengths[i];
731     new_t->block_indices[i]=block_indices[i];
732   }
733   new_t->block_count = block_count;
734   new_t->old_type = old_type;
735   smpi_datatype_use(old_type);
736   new_t->size_oldtype = size_oldtype;
737   return new_t;
738 }
739
740 int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
741 {
742 //  int size = 0;
743 //  bool contiguous=true;
744 //  MPI_Aint lb = 0;
745 //  MPI_Aint ub = 0;
746 //  if(count>0){
747 //    lb=indices[0] + smpi_datatype_lb(old_type);
748 //    ub=indices[0] + blocklens[0]*smpi_datatype_ub(old_type);
749 //  }
750 //  for (int i = 0; i < count; i++) {
751 //    if (blocklens[i] < 0)
752 //      return MPI_ERR_ARG;
753 //    size += blocklens[i];
754
755 //    if(indices[i]+smpi_datatype_lb(old_type)<lb) 
756 //      lb = indices[i]+smpi_datatype_lb(old_type);
757 //    if(indices[i]+blocklens[i]*smpi_datatype_ub(old_type)>ub) 
758 //      ub = indices[i]+blocklens[i]*smpi_datatype_ub(old_type);
759
760 //    if ( (i< count -1) && (indices[i]+blocklens[i]*(static_cast<int>(smpi_datatype_size(old_type))) != indices[i+1]) )
761 //      contiguous=false;
762 //  }
763 //  if (old_type->sizeof_substruct != 0 || lb!=0)
764 //    contiguous=false;
765
766 //  if(!contiguous){
767 //    s_smpi_mpi_hindexed_t* subtype = smpi_datatype_hindexed_create( blocklens, indices, count, old_type,
768 //                                                                  smpi_datatype_size(old_type));
769 //    smpi_datatype_create(new_type,  size * smpi_datatype_size(old_type), lb, ub ,sizeof(s_smpi_mpi_hindexed_t), subtype, DT_FLAG_DATA);
770 //  }else{
771 //    s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create(lb,size, old_type, smpi_datatype_size(old_type));
772 //    smpi_datatype_create(new_type,  size * smpi_datatype_size(old_type), 0,size * smpi_datatype_size(old_type),
773 //               1, subtype, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS);
774 //  }
775   return MPI_SUCCESS;
776 }
777
778 /* struct Implementation - Indexed with indices in bytes */
779
780 /* Copies noncontiguous data into contiguous memory.
781  *  @param contiguous_struct - output struct
782  *  @param noncontiguous_struct - input struct
783  *  @param type - pointer contening :
784  *      - stride - stride of between noncontiguous data
785  *      - block_length - the width or height of blocked matrix
786  *      - count - the number of rows of matrix
787  */
788 void serialize_struct( void* noncontiguous_struct, void *contiguous_struct, int count, void *type)
789 {
790 //  s_smpi_mpi_struct_t* type_c = reinterpret_cast<s_smpi_mpi_struct_t*>(type);
791 //  char* contiguous_struct_char = static_cast<char*>(contiguous_struct);
792 //  char* noncontiguous_struct_char = static_cast<char*>(noncontiguous_struct)+ type_c->block_indices[0];
793 //  for (int j = 0; j < count; j++) {
794 //    for (int i = 0; i < type_c->block_count; i++) {
795 //      if (type_c->old_types[i]->sizeof_substruct == 0)
796 //        memcpy(contiguous_struct_char, noncontiguous_struct_char,
797 //               type_c->block_lengths[i] * smpi_datatype_size(type_c->old_types[i]));
798 //      else
799 //        static_cast<s_smpi_subtype_t*>(type_c->old_types[i]->substruct)->serialize( noncontiguous_struct_char,
800 //                                                                         contiguous_struct_char,
801 //                                                                         type_c->block_lengths[i],
802 //                                                                         type_c->old_types[i]->substruct);
803
804
805 //      contiguous_struct_char += type_c->block_lengths[i]*smpi_datatype_size(type_c->old_types[i]);
806 //      if (i<type_c->block_count-1)
807 //        noncontiguous_struct_char = static_cast<char*>(noncontiguous_struct) + type_c->block_indices[i+1];
808 //      else //let's hope this is MPI_UB ?
809 //        noncontiguous_struct_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_types[i]);
810 //    }
811 //    noncontiguous_struct=static_cast<void*>(noncontiguous_struct_char);
812 //  }
813 }
814
815 /* Copies contiguous data into noncontiguous memory.
816  *  @param noncontiguous_struct - output struct
817  *  @param contiguous_struct - input struct
818  *  @param type - pointer contening :
819  *      - stride - stride of between noncontiguous data
820  *      - block_length - the width or height of blocked matrix
821  *      - count - the number of rows of matrix
822  */
823 void unserialize_struct( void* contiguous_struct, void *noncontiguous_struct, int count, void *type, MPI_Op op)
824 {
825 //  s_smpi_mpi_struct_t* type_c = reinterpret_cast<s_smpi_mpi_struct_t*>(type);
826
827 //  char* contiguous_struct_char = static_cast<char*>(contiguous_struct);
828 //  char* noncontiguous_struct_char = static_cast<char*>(noncontiguous_struct)+ type_c->block_indices[0];
829 //  for (int j = 0; j < count; j++) {
830 //    for (int i = 0; i < type_c->block_count; i++) {
831 //      if (type_c->old_types[i]->sizeof_substruct == 0){
832 //        if(op!=MPI_OP_NULL) 
833 //          op->apply( contiguous_struct_char, noncontiguous_struct_char, &type_c->block_lengths[i],
834 //           & type_c->old_types[i]);
835 //      }else
836 //        static_cast<s_smpi_subtype_t*>(type_c->old_types[i]->substruct)->unserialize( contiguous_struct_char,
837 //                                                                           noncontiguous_struct_char,
838 //                                                                           type_c->block_lengths[i],
839 //                                                                           type_c->old_types[i]->substruct, op);
840
841 //      contiguous_struct_char += type_c->block_lengths[i]*smpi_datatype_size(type_c->old_types[i]);
842 //      if (i<type_c->block_count-1)
843 //        noncontiguous_struct_char =  static_cast<char*>(noncontiguous_struct) + type_c->block_indices[i+1];
844 //      else
845 //        noncontiguous_struct_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_types[i]);
846 //    }
847 //    noncontiguous_struct=reinterpret_cast<void*>(noncontiguous_struct_char);
848 //  }
849 }
850
851 void free_struct(MPI_Datatype* type){
852 //  for (int i = 0; i < reinterpret_cast<s_smpi_mpi_struct_t*>((*type)->substruct)->block_count; i++)
853 //    smpi_datatype_unuse(reinterpret_cast<s_smpi_mpi_struct_t*>((*type)->substruct)->old_types[i]);
854 //  if((*type)->in_use==0){
855 //    xbt_free(reinterpret_cast<s_smpi_mpi_struct_t*>((*type)->substruct)->block_lengths);
856 //    xbt_free(reinterpret_cast<s_smpi_mpi_struct_t*>((*type)->substruct)->block_indices);
857 //    xbt_free(reinterpret_cast<s_smpi_mpi_struct_t*>((*type)->substruct)->old_types);
858 //  }
859 }
860
861 void use_struct(MPI_Datatype* type){
862 //  for (int i = 0; i < reinterpret_cast<s_smpi_mpi_struct_t*>((*type)->substruct)->block_count; i++)
863 //    smpi_datatype_use(reinterpret_cast<s_smpi_mpi_struct_t*>((*type)->substruct)->old_types[i]);
864 }
865
866 /* Create a Sub type struct to be able to serialize and unserialize it the structure s_smpi_mpi_struct_t is derived
867  * from s_smpi_subtype which required the functions unserialize and serialize
868  */
869 s_smpi_mpi_struct_t* smpi_datatype_struct_create( int* block_lengths, MPI_Aint* block_indices, int block_count,
870                                                   MPI_Datatype* old_types){
871   s_smpi_mpi_struct_t *new_t= xbt_new(s_smpi_mpi_struct_t,1);
872   new_t->base.serialize = &serialize_struct;
873   new_t->base.unserialize = &unserialize_struct;
874   new_t->base.subtype_free = &free_struct;
875   new_t->base.subtype_use = &use_struct;
876   new_t->block_lengths= xbt_new(int, block_count);
877   new_t->block_indices= xbt_new(MPI_Aint, block_count);
878   new_t->old_types=  xbt_new(MPI_Datatype, block_count);
879   for (int i = 0; i < block_count; i++) {
880     new_t->block_lengths[i]=block_lengths[i];
881     new_t->block_indices[i]=block_indices[i];
882     new_t->old_types[i]=old_types[i];
883     smpi_datatype_use(new_t->old_types[i]);
884   }
885   new_t->block_count = block_count;
886   return new_t;
887 }
888
889 int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type)
890 {
891 //  size_t size = 0;
892 //  bool contiguous=true;
893 //  size = 0;
894 //  MPI_Aint lb = 0;
895 //  MPI_Aint ub = 0;
896 //  if(count>0){
897 //    lb=indices[0] + smpi_datatype_lb(old_types[0]);
898 //    ub=indices[0] + blocklens[0]*smpi_datatype_ub(old_types[0]);
899 //  }
900 //  bool forced_lb=false;
901 //  bool forced_ub=false;
902 //  for (int i = 0; i < count; i++) {
903 //    if (blocklens[i]<0)
904 //      return MPI_ERR_ARG;
905 //    if (old_types[i]->sizeof_substruct != 0)
906 //      contiguous=false;
907
908 //    size += blocklens[i]*smpi_datatype_size(old_types[i]);
909 //    if (old_types[i]==MPI_LB){
910 //      lb=indices[i];
911 //      forced_lb=true;
912 //    }
913 //    if (old_types[i]==MPI_UB){
914 //      ub=indices[i];
915 //      forced_ub=true;
916 //    }
917
918 //    if(!forced_lb && indices[i]+smpi_datatype_lb(old_types[i])<lb) 
919 //      lb = indices[i];
920 //    if(!forced_ub &&  indices[i]+blocklens[i]*smpi_datatype_ub(old_types[i])>ub)
921 //      ub = indices[i]+blocklens[i]*smpi_datatype_ub(old_types[i]);
922
923 //    if ( (i< count -1) && (indices[i]+blocklens[i]*static_cast<int>(smpi_datatype_size(old_types[i])) != indices[i+1]) )
924 //      contiguous=false;
925 //  }
926
927 //  if(!contiguous){
928 //    s_smpi_mpi_struct_t* subtype = smpi_datatype_struct_create( blocklens, indices, count, old_types);
929
930 //    smpi_datatype_create(new_type,  size, lb, ub,sizeof(s_smpi_mpi_struct_t), subtype, DT_FLAG_DATA);
931 //  }else{
932 //    s_smpi_mpi_contiguous_t* subtype = smpi_datatype_contiguous_create( lb, size, MPI_CHAR, 1);
933 //    smpi_datatype_create(new_type,  size, lb, ub,1, subtype, DT_FLAG_DATA|DT_FLAG_CONTIGUOUS);
934 //  }
935   return MPI_SUCCESS;
936 }
937
938 void smpi_datatype_commit(MPI_Datatype *datatype)
939 {
940 //  (*datatype)->flags=  ((*datatype)->flags | DT_FLAG_COMMITED);
941 }
942
943
944 int smpi_type_attr_delete(MPI_Datatype type, int keyval){
945 //  smpi_type_key_elem elem =
946 //    static_cast<smpi_type_key_elem>(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast<const char*>(&keyval), sizeof(int)));
947 //  if(elem==nullptr)
948 //    return MPI_ERR_ARG;
949 //  if(elem->delete_fn!=MPI_NULL_DELETE_FN){
950 //    void * value = nullptr;
951 //    int flag;
952 //    if(smpi_type_attr_get(type, keyval, &value, &flag)==MPI_SUCCESS){
953 //      int ret = elem->delete_fn(type, keyval, value, &flag);
954 //      if(ret!=MPI_SUCCESS) 
955 //        return ret;
956 //    }
957 //  }  
958 //  if(type->attributes==nullptr)
959 //    return MPI_ERR_ARG;
960
961 //  xbt_dict_remove_ext(type->attributes, reinterpret_cast<const char*>(&keyval), sizeof(int));
962   return MPI_SUCCESS;
963 }
964
965 int smpi_type_attr_get(MPI_Datatype type, int keyval, void* attr_value, int* flag){
966 //  smpi_type_key_elem elem =
967 //    static_cast<smpi_type_key_elem>(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast<const char*>(&keyval), sizeof(int)));
968 //  if(elem==nullptr)
969 //    return MPI_ERR_ARG;
970 //  if(type->attributes==nullptr){
971 //    *flag=0;
972 //    return MPI_SUCCESS;
973 //  }
974 //  try {
975 //    *static_cast<void**>(attr_value) = xbt_dict_get_ext(type->attributes, reinterpret_cast<const char*>(&keyval), sizeof(int));
976 //    *flag=1;
977 //  }
978 //  catch (xbt_ex& ex) {
979 //    *flag=0;
980 //  }
981   return MPI_SUCCESS;
982 }
983
984 int smpi_type_attr_put(MPI_Datatype type, int keyval, void* attr_value){
985 //  if(smpi_type_keyvals==nullptr)
986 //    smpi_type_keyvals = xbt_dict_new_homogeneous(nullptr);
987 //  smpi_type_key_elem elem =
988 //     static_cast<smpi_type_key_elem>(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast<const char*>(&keyval), sizeof(int)));
989 //  if(elem==nullptr)
990 //    return MPI_ERR_ARG;
991 //  int flag;
992 //  void* value = nullptr;
993 //  smpi_type_attr_get(type, keyval, &value, &flag);
994 //  if(flag!=0 && elem->delete_fn!=MPI_NULL_DELETE_FN){
995 //    int ret = elem->delete_fn(type, keyval, value, &flag);
996 //    if(ret!=MPI_SUCCESS) 
997 //      return ret;
998 //  }
999 //  if(type->attributes==nullptr)
1000 //    type->attributes = xbt_dict_new_homogeneous(nullptr);
1001
1002 //  xbt_dict_set_ext(type->attributes, reinterpret_cast<const char*>(&keyval), sizeof(int), attr_value, nullptr);
1003   return MPI_SUCCESS;
1004 }
1005
1006 int smpi_type_keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
1007                             void* extra_state){
1008 //  if(smpi_type_keyvals==nullptr)
1009 //    smpi_type_keyvals = xbt_dict_new_homogeneous(nullptr);
1010
1011 //  smpi_type_key_elem value = (smpi_type_key_elem) xbt_new0(s_smpi_mpi_type_key_elem_t,1);
1012
1013 //  value->copy_fn=copy_fn;
1014 //  value->delete_fn=delete_fn;
1015
1016 //  *keyval = type_keyval_id;
1017 //  xbt_dict_set_ext(smpi_type_keyvals,reinterpret_cast<const char*>(keyval), sizeof(int),reinterpret_cast<void*>(value), nullptr);
1018 //  type_keyval_id++;
1019   return MPI_SUCCESS;
1020 }
1021
1022 int smpi_type_keyval_free(int* keyval){
1023 //  smpi_type_key_elem elem =
1024 //    static_cast<smpi_type_key_elem>(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast<const char*>(keyval), sizeof(int)));
1025 //  if(elem==0){
1026 //    return MPI_ERR_ARG;
1027 //  }
1028 //  xbt_dict_remove_ext(smpi_type_keyvals, reinterpret_cast<const char*>(keyval), sizeof(int));
1029 //  xbt_free(elem);
1030   return MPI_SUCCESS;
1031 }
1032
1033 int smpi_mpi_pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position,MPI_Comm comm){
1034   size_t size = smpi_datatype_size(type);
1035   if (outcount - *position < incount*static_cast<int>(size))
1036     return MPI_ERR_BUFFER;
1037   smpi_datatype_copy(inbuf, incount, type, static_cast<char*>(outbuf) + *position, outcount, MPI_CHAR);
1038   *position += incount * size;
1039   return MPI_SUCCESS;
1040 }
1041
1042 int smpi_mpi_unpack(void* inbuf, int insize, int* position, void* outbuf, int outcount, MPI_Datatype type,MPI_Comm comm){
1043   int size = static_cast<int>(smpi_datatype_size(type));
1044   if (outcount*size> insize)
1045     return MPI_ERR_BUFFER;
1046   smpi_datatype_copy(static_cast<char*>(inbuf) + *position, insize, MPI_CHAR, outbuf, outcount, type);
1047   *position += outcount * size;
1048   return MPI_SUCCESS;
1049 }