Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
[simgrid.git] / src / smpi / smpi_pmpi.cpp
1
2 /* Copyright (c) 2007-2015. The SimGrid Team.
3  * All rights reserved.                                                     */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "private.h"
9 #include "smpi_mpi_dt_private.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi, "Logging specific to SMPI (pmpi)");
12
13 //this function need to be here because of the calls to smpi_bench
14 void TRACE_smpi_set_category(const char *category)
15 {
16   //need to end bench otherwise categories for execution tasks are wrong
17   smpi_bench_end();
18   TRACE_internal_smpi_set_category (category);
19   //begin bench after changing process's category
20   smpi_bench_begin();
21 }
22
23 /* PMPI User level calls */
24
25 int PMPI_Init(int *argc, char ***argv)
26 {
27   // PMPI_Init is call only one time by only by SMPI process
28   int already_init;
29   MPI_Initialized(&already_init);
30   if(!(already_init)){
31     smpi_process_init(argc, argv);
32     smpi_process_mark_as_initialized();
33     int rank = smpi_process_index();
34     TRACE_smpi_init(rank);
35     TRACE_smpi_computing_init(rank);
36     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
37     extra->type = TRACING_INIT;
38     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
39     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
40     smpi_bench_begin();
41   }
42   return MPI_SUCCESS;
43 }
44
45 int PMPI_Finalize(void)
46 {
47   smpi_bench_end();
48   int rank = smpi_process_index();
49   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
50   extra->type = TRACING_FINALIZE;
51   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
52
53   smpi_process_finalize();
54
55   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
56   TRACE_smpi_finalize(smpi_process_index());
57   smpi_process_destroy();
58   return MPI_SUCCESS;
59 }
60
61 int PMPI_Finalized(int* flag)
62 {
63   *flag=smpi_process_finalized();
64   return MPI_SUCCESS;
65 }
66
67 int PMPI_Get_version (int *version,int *subversion){
68   *version = MPI_VERSION;
69   *subversion= MPI_SUBVERSION;
70   return MPI_SUCCESS;
71 }
72
73 int PMPI_Get_library_version (char *version,int *len){
74   int retval = MPI_SUCCESS;
75   smpi_bench_end();
76   snprintf(version,MPI_MAX_LIBRARY_VERSION_STRING,"SMPI Version %d.%d. Copyright The Simgrid Team 2007-2015",
77            SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR);
78   *len = strlen(version) > MPI_MAX_LIBRARY_VERSION_STRING ? MPI_MAX_LIBRARY_VERSION_STRING : strlen(version);
79   smpi_bench_begin();
80   return retval;
81 }
82
83 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
84 {
85   if (provided != NULL) {
86     *provided = MPI_THREAD_SINGLE;
87   }
88   return MPI_Init(argc, argv);
89 }
90
91 int PMPI_Query_thread(int *provided)
92 {
93   int retval = 0;
94
95   if (provided == NULL) {
96     retval = MPI_ERR_ARG;
97   } else {
98     *provided = MPI_THREAD_SINGLE;
99     retval = MPI_SUCCESS;
100   }
101   return retval;
102 }
103
104 int PMPI_Is_thread_main(int *flag)
105 {
106   int retval = 0;
107
108   if (flag == NULL) {
109     retval = MPI_ERR_ARG;
110   } else {
111     *flag = smpi_process_index() == 0;
112     retval = MPI_SUCCESS;
113   }
114   return retval;
115 }
116
117 int PMPI_Abort(MPI_Comm comm, int errorcode)
118 {
119   smpi_bench_end();
120   smpi_process_destroy();
121   // FIXME: should kill all processes in comm instead
122   simcall_process_kill(SIMIX_process_self());
123   return MPI_SUCCESS;
124 }
125
126 double PMPI_Wtime(void)
127 {
128   return smpi_mpi_wtime();
129 }
130
131 extern double sg_maxmin_precision;
132 double PMPI_Wtick(void)
133 {
134   return sg_maxmin_precision;
135 }
136
137 int PMPI_Address(void *location, MPI_Aint * address)
138 {
139   int retval = 0;
140
141   if (!address) {
142     retval = MPI_ERR_ARG;
143   } else {
144     *address = (MPI_Aint) location;
145     retval = MPI_SUCCESS;
146   }
147   return retval;
148 }
149
150 int PMPI_Get_address(void *location, MPI_Aint * address)
151 {
152   return PMPI_Address(location, address);
153 }
154
155 int PMPI_Type_free(MPI_Datatype * datatype)
156 {
157   int retval = 0;
158   /* Free a predefined datatype is an error according to the standard, and should be checked for */
159   if (*datatype == MPI_DATATYPE_NULL) {
160     retval = MPI_ERR_ARG;
161   } else {
162     smpi_datatype_unuse(*datatype);
163     retval = MPI_SUCCESS;
164   }
165   return retval;
166 }
167
168 int PMPI_Type_size(MPI_Datatype datatype, int *size)
169 {
170   int retval = 0;
171
172   if (datatype == MPI_DATATYPE_NULL) {
173     retval = MPI_ERR_TYPE;
174   } else if (size == NULL) {
175     retval = MPI_ERR_ARG;
176   } else {
177     *size = (int) smpi_datatype_size(datatype);
178     retval = MPI_SUCCESS;
179   }
180   return retval;
181 }
182
183 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
184 {
185   int retval = 0;
186
187   if (datatype == MPI_DATATYPE_NULL) {
188     retval = MPI_ERR_TYPE;
189   } else if (lb == NULL || extent == NULL) {
190     retval = MPI_ERR_ARG;
191   } else {
192     retval = smpi_datatype_extent(datatype, lb, extent);
193   }
194   return retval;
195 }
196
197 int PMPI_Type_get_true_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
198 {
199   return PMPI_Type_get_extent(datatype, lb, extent);
200 }
201
202 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
203 {
204   int retval = 0;
205
206   if (datatype == MPI_DATATYPE_NULL) {
207     retval = MPI_ERR_TYPE;
208   } else if (extent == NULL) {
209     retval = MPI_ERR_ARG;
210   } else {
211     *extent = smpi_datatype_get_extent(datatype);
212     retval = MPI_SUCCESS;
213   }
214   return retval;
215 }
216
217 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
218 {
219   int retval = 0;
220
221   if (datatype == MPI_DATATYPE_NULL) {
222     retval = MPI_ERR_TYPE;
223   } else if (disp == NULL) {
224     retval = MPI_ERR_ARG;
225   } else {
226     *disp = smpi_datatype_lb(datatype);
227     retval = MPI_SUCCESS;
228   }
229   return retval;
230 }
231
232 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
233 {
234   int retval = 0;
235
236   if (datatype == MPI_DATATYPE_NULL) {
237     retval = MPI_ERR_TYPE;
238   } else if (disp == NULL) {
239     retval = MPI_ERR_ARG;
240   } else {
241     *disp = smpi_datatype_ub(datatype);
242     retval = MPI_SUCCESS;
243   }
244   return retval;
245 }
246
247 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
248   int retval = 0;
249
250   if (datatype == MPI_DATATYPE_NULL) {
251     retval = MPI_ERR_TYPE;
252   } else {
253     retval = smpi_datatype_dup(datatype, newtype);
254   }
255   return retval;
256 }
257
258 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
259 {
260   int retval = 0;
261
262   if (function == NULL || op == NULL) {
263     retval = MPI_ERR_ARG;
264   } else {
265     *op = smpi_op_new(function, commute);
266     retval = MPI_SUCCESS;
267   }
268   return retval;
269 }
270
271 int PMPI_Op_free(MPI_Op * op)
272 {
273   int retval = 0;
274
275   if (op == NULL) {
276     retval = MPI_ERR_ARG;
277   } else if (*op == MPI_OP_NULL) {
278     retval = MPI_ERR_OP;
279   } else {
280     smpi_op_destroy(*op);
281     *op = MPI_OP_NULL;
282     retval = MPI_SUCCESS;
283   }
284   return retval;
285 }
286
287 int PMPI_Group_free(MPI_Group * group)
288 {
289   int retval = 0;
290
291   if (group == NULL) {
292     retval = MPI_ERR_ARG;
293   } else {
294     smpi_group_destroy(*group);
295     *group = MPI_GROUP_NULL;
296     retval = MPI_SUCCESS;
297   }
298   return retval;
299 }
300
301 int PMPI_Group_size(MPI_Group group, int *size)
302 {
303   int retval = 0;
304
305   if (group == MPI_GROUP_NULL) {
306     retval = MPI_ERR_GROUP;
307   } else if (size == NULL) {
308     retval = MPI_ERR_ARG;
309   } else {
310     *size = smpi_group_size(group);
311     retval = MPI_SUCCESS;
312   }
313   return retval;
314 }
315
316 int PMPI_Group_rank(MPI_Group group, int *rank)
317 {
318   int retval = 0;
319
320   if (group == MPI_GROUP_NULL) {
321     retval = MPI_ERR_GROUP;
322   } else if (rank == NULL) {
323     retval = MPI_ERR_ARG;
324   } else {
325     *rank = smpi_group_rank(group, smpi_process_index());
326     retval = MPI_SUCCESS;
327   }
328   return retval;
329 }
330
331 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2)
332 {
333   int retval, i, index;
334   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
335     retval = MPI_ERR_GROUP;
336   } else {
337     for (i = 0; i < n; i++) {
338       if(ranks1[i]==MPI_PROC_NULL){
339         ranks2[i]=MPI_PROC_NULL;
340       }else{
341         index = smpi_group_index(group1, ranks1[i]);
342         ranks2[i] = smpi_group_rank(group2, index);
343       }
344     }
345     retval = MPI_SUCCESS;
346   }
347   return retval;
348 }
349
350 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
351 {
352   int retval = 0;
353
354   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
355     retval = MPI_ERR_GROUP;
356   } else if (result == NULL) {
357     retval = MPI_ERR_ARG;
358   } else {
359     *result = smpi_group_compare(group1, group2);
360     retval = MPI_SUCCESS;
361   }
362   return retval;
363 }
364
365 int PMPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
366 {
367   int retval, i, proc1, proc2, size, size2;
368
369   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
370     retval = MPI_ERR_GROUP;
371   } else if (newgroup == NULL) {
372     retval = MPI_ERR_ARG;
373   } else {
374     size = smpi_group_size(group1);
375     size2 = smpi_group_size(group2);
376     for (i = 0; i < size2; i++) {
377       proc2 = smpi_group_index(group2, i);
378       proc1 = smpi_group_rank(group1, proc2);
379       if (proc1 == MPI_UNDEFINED) {
380         size++;
381       }
382     }
383     if (size == 0) {
384       *newgroup = MPI_GROUP_EMPTY;
385     } else {
386       *newgroup = smpi_group_new(size);
387       size2 = smpi_group_size(group1);
388       for (i = 0; i < size2; i++) {
389         proc1 = smpi_group_index(group1, i);
390         smpi_group_set_mapping(*newgroup, proc1, i);
391       }
392       for (i = size2; i < size; i++) {
393         proc2 = smpi_group_index(group2, i - size2);
394         smpi_group_set_mapping(*newgroup, proc2, i);
395       }
396     }
397     retval = MPI_SUCCESS;
398   }
399   return retval;
400 }
401
402 int PMPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
403 {
404   int retval, i, proc1, proc2, size;
405
406   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
407     retval = MPI_ERR_GROUP;
408   } else if (newgroup == NULL) {
409     retval = MPI_ERR_ARG;
410   } else {
411     size = smpi_group_size(group2);
412     for (i = 0; i < size; i++) {
413       proc2 = smpi_group_index(group2, i);
414       proc1 = smpi_group_rank(group1, proc2);
415       if (proc1 == MPI_UNDEFINED) {
416         size--;
417       }
418     }
419     if (size == 0) {
420       *newgroup = MPI_GROUP_EMPTY;
421     } else {
422       *newgroup = smpi_group_new(size);
423       int j=0;
424       for (i = 0; i < smpi_group_size(group2); i++) {
425         proc2 = smpi_group_index(group2, i);
426         proc1 = smpi_group_rank(group1, proc2);
427         if (proc1 != MPI_UNDEFINED) {
428           smpi_group_set_mapping(*newgroup, proc2, j);
429           j++;
430         }
431       }
432     }
433     retval = MPI_SUCCESS;
434   }
435   return retval;
436 }
437
438 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
439 {
440   int retval, i, proc1, proc2, size, size2;
441
442   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
443     retval = MPI_ERR_GROUP;
444   } else if (newgroup == NULL) {
445     retval = MPI_ERR_ARG;
446   } else {
447     size = size2 = smpi_group_size(group1);
448     for (i = 0; i < size2; i++) {
449       proc1 = smpi_group_index(group1, i);
450       proc2 = smpi_group_rank(group2, proc1);
451       if (proc2 != MPI_UNDEFINED) {
452         size--;
453       }
454     }
455     if (size == 0) {
456       *newgroup = MPI_GROUP_EMPTY;
457     } else {
458       *newgroup = smpi_group_new(size);
459       for (i = 0; i < size2; i++) {
460         proc1 = smpi_group_index(group1, i);
461         proc2 = smpi_group_rank(group2, proc1);
462         if (proc2 == MPI_UNDEFINED) {
463           smpi_group_set_mapping(*newgroup, proc1, i);
464         }
465       }
466     }
467     retval = MPI_SUCCESS;
468   }
469   return retval;
470 }
471
472 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
473 {
474   int retval;
475
476   if (group == MPI_GROUP_NULL) {
477     retval = MPI_ERR_GROUP;
478   } else if (newgroup == NULL) {
479     retval = MPI_ERR_ARG;
480   } else {
481     retval = smpi_group_incl(group, n, ranks, newgroup);
482   }
483   return retval;
484 }
485
486 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
487 {
488   int retval, i, j, newsize, oldsize, index;
489
490   if (group == MPI_GROUP_NULL) {
491     retval = MPI_ERR_GROUP;
492   } else if (newgroup == NULL) {
493     retval = MPI_ERR_ARG;
494   } else {
495     if (n == 0) {
496       *newgroup = group;
497       if(group!= smpi_comm_group(MPI_COMM_WORLD) && group != MPI_GROUP_NULL
498                 && group != smpi_comm_group(MPI_COMM_SELF) && group != MPI_GROUP_EMPTY)
499       smpi_group_use(group);
500     } else if (n == smpi_group_size(group)) {
501       *newgroup = MPI_GROUP_EMPTY;
502     } else {
503       oldsize=smpi_group_size(group);
504       newsize = oldsize - n;
505       *newgroup = smpi_group_new(newsize);
506
507       int* to_exclude=xbt_new0(int, smpi_group_size(group));
508       for(i=0; i<oldsize; i++)
509         to_exclude[i]=0;
510       for(i=0; i<n; i++)
511         to_exclude[ranks[i]]=1;
512
513       j=0;
514       for(i=0; i<oldsize; i++){
515         if(to_exclude[i]==0){
516           index = smpi_group_index(group, i);
517           smpi_group_set_mapping(*newgroup, index, j);
518           j++;
519         }
520       }
521
522       xbt_free(to_exclude);
523     }
524     retval = MPI_SUCCESS;
525   }
526   return retval;
527 }
528
529 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
530 {
531   int retval, i, j, rank, size, index;
532
533   if (group == MPI_GROUP_NULL) {
534     retval = MPI_ERR_GROUP;
535   } else if (newgroup == NULL) {
536     retval = MPI_ERR_ARG;
537   } else {
538     if (n == 0) {
539       *newgroup = MPI_GROUP_EMPTY;
540     } else {
541       size = 0;
542       for (i = 0; i < n; i++) {
543         for (rank = ranges[i][0];       /* First */
544              rank >= 0 && rank < smpi_group_size(group); /* Last */
545               ) {
546           size++;
547           if(rank == ranges[i][1]){/*already last ?*/
548             break;
549           }
550           rank += ranges[i][2]; /* Stride */
551     if (ranges[i][0]<ranges[i][1]){
552         if(rank > ranges[i][1])
553           break;
554     }else{
555         if(rank < ranges[i][1])
556           break;
557     }
558         }
559       }
560
561       *newgroup = smpi_group_new(size);
562       j = 0;
563       for (i = 0; i < n; i++) {
564         for (rank = ranges[i][0];     /* First */
565              rank >= 0 && rank < smpi_group_size(group); /* Last */
566              ) {
567           index = smpi_group_index(group, rank);
568           smpi_group_set_mapping(*newgroup, index, j);
569           j++;
570           if(rank == ranges[i][1]){/*already last ?*/
571             break;
572           }
573           rank += ranges[i][2]; /* Stride */
574     if (ranges[i][0]<ranges[i][1]){
575       if(rank > ranges[i][1])
576         break;
577     }else{
578       if(rank < ranges[i][1])
579         break;
580     }
581         }
582       }
583     }
584     retval = MPI_SUCCESS;
585   }
586   return retval;
587 }
588
589 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
590 {
591   int retval, i, rank, newrank,oldrank, size, index, add;
592
593   if (group == MPI_GROUP_NULL) {
594     retval = MPI_ERR_GROUP;
595   } else if (newgroup == NULL) {
596     retval = MPI_ERR_ARG;
597   } else {
598     if (n == 0) {
599       *newgroup = group;
600       if(group!= smpi_comm_group(MPI_COMM_WORLD) && group != MPI_GROUP_NULL
601                 && group != smpi_comm_group(MPI_COMM_SELF) && group != MPI_GROUP_EMPTY)
602       smpi_group_use(group);
603     } else {
604       size = smpi_group_size(group);
605       for (i = 0; i < n; i++) {
606         for (rank = ranges[i][0];       /* First */
607              rank >= 0 && rank < smpi_group_size(group); /* Last */
608               ) {
609           size--;
610           if(rank == ranges[i][1]){/*already last ?*/
611             break;
612           }
613           rank += ranges[i][2]; /* Stride */
614     if (ranges[i][0]<ranges[i][1]){
615         if(rank > ranges[i][1])
616           break;
617     }else{
618         if(rank < ranges[i][1])
619           break;
620     }
621         }
622       }
623       if (size == 0) {
624         *newgroup = MPI_GROUP_EMPTY;
625       } else {
626         *newgroup = smpi_group_new(size);
627         newrank=0;
628         oldrank=0;
629         while (newrank < size) {
630           add=1;
631           for (i = 0; i < n; i++) {
632             for (rank = ranges[i][0];
633                 rank >= 0 && rank < smpi_group_size(group);
634                 ){
635               if(rank==oldrank){
636                   add=0;
637                   break;
638               }
639               if(rank == ranges[i][1]){/*already last ?*/
640                 break;
641               }
642               rank += ranges[i][2]; /* Stride */
643               if (ranges[i][0]<ranges[i][1]){
644                   if(rank > ranges[i][1])
645                     break;
646               }else{
647                   if(rank < ranges[i][1])
648                     break;
649               }
650             }
651           }
652           if(add==1){
653             index = smpi_group_index(group, oldrank);
654             smpi_group_set_mapping(*newgroup, index, newrank);
655             newrank++;
656           }
657           oldrank++;
658         }
659       }
660     }
661
662     retval = MPI_SUCCESS;
663   }
664   return retval;
665 }
666
667 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
668 {
669   int retval = 0;
670   if (comm == MPI_COMM_NULL) {
671     retval = MPI_ERR_COMM;
672   } else if (rank == NULL) {
673     retval = MPI_ERR_ARG;
674   } else {
675     *rank = smpi_comm_rank(comm);
676     retval = MPI_SUCCESS;
677   }
678   return retval;
679 }
680
681 int PMPI_Comm_size(MPI_Comm comm, int *size)
682 {
683   int retval = 0;
684   if (comm == MPI_COMM_NULL) {
685     retval = MPI_ERR_COMM;
686   } else if (size == NULL) {
687     retval = MPI_ERR_ARG;
688   } else {
689     *size = smpi_comm_size(comm);
690     retval = MPI_SUCCESS;
691   }
692   return retval;
693 }
694
695 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
696 {
697   int retval = 0;
698
699   if (comm == MPI_COMM_NULL)  {
700     retval = MPI_ERR_COMM;
701   } else if (name == NULL || len == NULL)  {
702     retval = MPI_ERR_ARG;
703   } else {
704     smpi_comm_get_name(comm, name, len);
705     retval = MPI_SUCCESS;
706   }
707   return retval;
708 }
709
710 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
711 {
712   int retval = 0;
713
714   if (comm == MPI_COMM_NULL) {
715     retval = MPI_ERR_COMM;
716   } else if (group == NULL) {
717     retval = MPI_ERR_ARG;
718   } else {
719     *group = smpi_comm_group(comm);
720     if(*group!= smpi_comm_group(MPI_COMM_WORLD) && *group != MPI_GROUP_NULL
721               && *group != MPI_GROUP_EMPTY)
722     smpi_group_use(*group);
723     retval = MPI_SUCCESS;
724   }
725   return retval;
726 }
727
728 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
729 {
730   int retval = 0;
731
732   if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
733     retval = MPI_ERR_COMM;
734   } else if (result == NULL) {
735     retval = MPI_ERR_ARG;
736   } else {
737     if (comm1 == comm2) {       /* Same communicators means same groups */
738       *result = MPI_IDENT;
739     } else {
740       *result = smpi_group_compare(smpi_comm_group(comm1), smpi_comm_group(comm2));
741       if (*result == MPI_IDENT) {
742         *result = MPI_CONGRUENT;
743       }
744     }
745     retval = MPI_SUCCESS;
746   }
747   return retval;
748 }
749
750 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
751 {
752   int retval = 0;
753
754   if (comm == MPI_COMM_NULL) {
755     retval = MPI_ERR_COMM;
756   } else if (newcomm == NULL) {
757     retval = MPI_ERR_ARG;
758   } else {
759     retval = smpi_comm_dup(comm, newcomm);
760     if(retval==MPI_SUCCESS)
761       smpi_group_use(smpi_comm_group(*newcomm));
762   }
763   return retval;
764 }
765
766 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
767 {
768   int retval = 0;
769
770   if (comm == MPI_COMM_NULL) {
771     retval = MPI_ERR_COMM;
772   } else if (group == MPI_GROUP_NULL) {
773     retval = MPI_ERR_GROUP;
774   } else if (newcomm == NULL) {
775     retval = MPI_ERR_ARG;
776   } else if(smpi_group_rank(group,smpi_process_index())==MPI_UNDEFINED){
777     *newcomm= MPI_COMM_NULL;
778     retval = MPI_SUCCESS;
779   }else{
780     smpi_group_use(group);
781     *newcomm = smpi_comm_new(group, NULL);
782     retval = MPI_SUCCESS;
783   }
784   return retval;
785 }
786
787 int PMPI_Comm_free(MPI_Comm * comm)
788 {
789   int retval = 0;
790
791   if (comm == NULL) {
792     retval = MPI_ERR_ARG;
793   } else if (*comm == MPI_COMM_NULL) {
794     retval = MPI_ERR_COMM;
795   } else {
796     smpi_comm_destroy(*comm);
797     *comm = MPI_COMM_NULL;
798     retval = MPI_SUCCESS;
799   }
800   return retval;
801 }
802
803 int PMPI_Comm_disconnect(MPI_Comm * comm)
804 {
805   /* TODO: wait until all communication in comm are done */
806   int retval = 0;
807
808   if (comm == NULL) {
809     retval = MPI_ERR_ARG;
810   } else if (*comm == MPI_COMM_NULL) {
811     retval = MPI_ERR_COMM;
812   } else {
813     smpi_comm_destroy(*comm);
814     *comm = MPI_COMM_NULL;
815     retval = MPI_SUCCESS;
816   }
817   return retval;
818 }
819
820 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
821 {
822   int retval = 0;
823   smpi_bench_end();
824
825   if (comm_out == NULL) {
826     retval = MPI_ERR_ARG;
827   } else if (comm == MPI_COMM_NULL) {
828     retval = MPI_ERR_COMM;
829   } else {
830     *comm_out = smpi_comm_split(comm, color, key);
831     retval = MPI_SUCCESS;
832   }
833   smpi_bench_begin();
834
835   return retval;
836 }
837
838 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
839 {
840   int retval = 0;
841
842   smpi_bench_end();
843   if (request == NULL) {
844       retval = MPI_ERR_ARG;
845   } else if (comm == MPI_COMM_NULL) {
846       retval = MPI_ERR_COMM;
847   } else if (!is_datatype_valid(datatype)) {
848       retval = MPI_ERR_TYPE;
849   } else if (dst == MPI_PROC_NULL) {
850       retval = MPI_SUCCESS;
851   } else {
852       *request = smpi_mpi_send_init(buf, count, datatype, dst, tag, comm);
853       retval = MPI_SUCCESS;
854   }
855   smpi_bench_begin();
856   if (retval != MPI_SUCCESS && request)
857     *request = MPI_REQUEST_NULL;
858   return retval;
859 }
860
861 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
862 {
863   int retval = 0;
864
865   smpi_bench_end();
866   if (request == NULL) {
867     retval = MPI_ERR_ARG;
868   } else if (comm == MPI_COMM_NULL) {
869     retval = MPI_ERR_COMM;
870   } else if (!is_datatype_valid(datatype)) {
871       retval = MPI_ERR_TYPE;
872   } else if (src == MPI_PROC_NULL) {
873     retval = MPI_SUCCESS;
874   } else {
875     *request = smpi_mpi_recv_init(buf, count, datatype, src, tag, comm);
876     retval = MPI_SUCCESS;
877   }
878   smpi_bench_begin();
879   if (retval != MPI_SUCCESS && request)
880     *request = MPI_REQUEST_NULL;
881   return retval;
882 }
883
884 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
885 {
886   int retval = 0;
887
888   smpi_bench_end();
889   if (request == NULL) {
890     retval = MPI_ERR_ARG;
891   } else if (comm == MPI_COMM_NULL) {
892     retval = MPI_ERR_COMM;
893   } else if (!is_datatype_valid(datatype)) {
894       retval = MPI_ERR_TYPE;
895   } else if (dst == MPI_PROC_NULL) {
896     retval = MPI_SUCCESS;
897   } else {
898     *request = smpi_mpi_ssend_init(buf, count, datatype, dst, tag, comm);
899     retval = MPI_SUCCESS;
900   }
901   smpi_bench_begin();
902   if (retval != MPI_SUCCESS && request)
903     *request = MPI_REQUEST_NULL;
904   return retval;
905 }
906
907 int PMPI_Start(MPI_Request * request)
908 {
909   int retval = 0;
910
911   smpi_bench_end();
912   if (request == NULL || *request == MPI_REQUEST_NULL) {
913     retval = MPI_ERR_REQUEST;
914   } else {
915     smpi_mpi_start(*request);
916     retval = MPI_SUCCESS;
917   }
918   smpi_bench_begin();
919   return retval;
920 }
921
922 int PMPI_Startall(int count, MPI_Request * requests)
923 {
924   int retval;
925   int i = 0;
926   smpi_bench_end();
927   if (requests == NULL) {
928     retval = MPI_ERR_ARG;
929   } else {
930     retval = MPI_SUCCESS;
931     for (i = 0 ;  i < count ; i++) {
932       if(requests[i] == MPI_REQUEST_NULL) {
933         retval = MPI_ERR_REQUEST;
934       }
935     }
936     if(retval != MPI_ERR_REQUEST) {
937       smpi_mpi_startall(count, requests);
938     }
939   }
940   smpi_bench_begin();
941   return retval;
942 }
943
944 int PMPI_Request_free(MPI_Request * request)
945 {
946   int retval = 0;
947
948   smpi_bench_end();
949   if (*request == MPI_REQUEST_NULL) {
950     retval = MPI_ERR_ARG;
951   } else {
952     smpi_mpi_request_free(request);
953     retval = MPI_SUCCESS;
954   }
955   smpi_bench_begin();
956   return retval;
957 }
958
959 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
960 {
961   int retval = 0;
962
963   smpi_bench_end();
964
965   if (request == NULL) {
966     retval = MPI_ERR_ARG;
967   } else if (comm == MPI_COMM_NULL) {
968     retval = MPI_ERR_COMM;
969   } else if (src == MPI_PROC_NULL) {
970     *request = MPI_REQUEST_NULL;
971     retval = MPI_SUCCESS;
972   } else if (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0)){
973     retval = MPI_ERR_RANK;
974   } else if (count < 0) {
975     retval = MPI_ERR_COUNT;
976   } else if (buf==NULL && count > 0) {
977     retval = MPI_ERR_COUNT;
978   } else if (!is_datatype_valid(datatype)) {
979       retval = MPI_ERR_TYPE;
980   } else if(tag<0 && tag !=  MPI_ANY_TAG){
981     retval = MPI_ERR_TAG;
982   } else {
983
984     int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
985     int src_traced = smpi_group_index(smpi_comm_group(comm), src);
986
987     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
988     extra->type = TRACING_IRECV;
989     extra->src = src_traced;
990     extra->dst = rank;
991     int known=0;
992     extra->datatype1 = encode_datatype(datatype, &known);
993     int dt_size_send = 1;
994     if(!known)
995       dt_size_send = smpi_datatype_size(datatype);
996     extra->send_size = count*dt_size_send;
997     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
998
999     *request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm);
1000     retval = MPI_SUCCESS;
1001
1002     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
1003     (*request)->recv = 1;
1004   }
1005
1006   smpi_bench_begin();
1007   if (retval != MPI_SUCCESS && request)
1008     *request = MPI_REQUEST_NULL;
1009   return retval;
1010 }
1011
1012
1013 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
1014 {
1015   int retval = 0;
1016
1017   smpi_bench_end();
1018   if (request == NULL) {
1019     retval = MPI_ERR_ARG;
1020   } else if (comm == MPI_COMM_NULL) {
1021     retval = MPI_ERR_COMM;
1022   } else if (dst == MPI_PROC_NULL) {
1023     *request = MPI_REQUEST_NULL;
1024     retval = MPI_SUCCESS;
1025   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1026     retval = MPI_ERR_RANK;
1027   } else if (count < 0) {
1028     retval = MPI_ERR_COUNT;
1029   } else if (buf==NULL && count > 0) {
1030     retval = MPI_ERR_COUNT;
1031   } else if (!is_datatype_valid(datatype)) {
1032       retval = MPI_ERR_TYPE;
1033   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1034     retval = MPI_ERR_TAG;
1035   } else {
1036
1037     int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1038     int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1039     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1040     extra->type = TRACING_ISEND;
1041     extra->src = rank;
1042     extra->dst = dst_traced;
1043     int known=0;
1044     extra->datatype1 = encode_datatype(datatype, &known);
1045     int dt_size_send = 1;
1046     if(!known)
1047       dt_size_send = smpi_datatype_size(datatype);
1048     extra->send_size = count*dt_size_send;
1049     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1050     TRACE_smpi_send(rank, rank, dst_traced, count*smpi_datatype_size(datatype));
1051
1052     *request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
1053     retval = MPI_SUCCESS;
1054
1055     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1056     (*request)->send = 1;
1057   }
1058
1059   smpi_bench_begin();
1060   if (retval != MPI_SUCCESS && request)
1061     *request = MPI_REQUEST_NULL;
1062   return retval;
1063 }
1064
1065 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
1066 {
1067   int retval = 0;
1068
1069   smpi_bench_end();
1070   if (request == NULL) {
1071     retval = MPI_ERR_ARG;
1072   } else if (comm == MPI_COMM_NULL) {
1073     retval = MPI_ERR_COMM;
1074   } else if (dst == MPI_PROC_NULL) {
1075     *request = MPI_REQUEST_NULL;
1076     retval = MPI_SUCCESS;
1077   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1078     retval = MPI_ERR_RANK;
1079   } else if (count < 0) {
1080     retval = MPI_ERR_COUNT;
1081   } else if (buf==NULL && count > 0) {
1082     retval = MPI_ERR_COUNT;
1083   } else if (!is_datatype_valid(datatype)) {
1084       retval = MPI_ERR_TYPE;
1085   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1086     retval = MPI_ERR_TAG;
1087   } else {
1088
1089     int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1090     int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1091     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1092     extra->type = TRACING_ISSEND;
1093     extra->src = rank;
1094     extra->dst = dst_traced;
1095     int known=0;
1096     extra->datatype1 = encode_datatype(datatype, &known);
1097     int dt_size_send = 1;
1098     if(!known)
1099       dt_size_send = smpi_datatype_size(datatype);
1100     extra->send_size = count*dt_size_send;
1101     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1102     TRACE_smpi_send(rank, rank, dst_traced, count*smpi_datatype_size(datatype));
1103
1104     *request = smpi_mpi_issend(buf, count, datatype, dst, tag, comm);
1105     retval = MPI_SUCCESS;
1106
1107     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1108     (*request)->send = 1;
1109   }
1110
1111   smpi_bench_begin();
1112   if (retval != MPI_SUCCESS && request)
1113     *request = MPI_REQUEST_NULL;
1114   return retval;
1115 }
1116
1117 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
1118 {
1119   int retval = 0;
1120
1121   smpi_bench_end();
1122   if (comm == MPI_COMM_NULL) {
1123     retval = MPI_ERR_COMM;
1124   } else if (src == MPI_PROC_NULL) {
1125     smpi_empty_status(status);
1126     status->MPI_SOURCE = MPI_PROC_NULL;
1127     retval = MPI_SUCCESS;
1128   } else if (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0)){
1129     retval = MPI_ERR_RANK;
1130   } else if (count < 0) {
1131     retval = MPI_ERR_COUNT;
1132   } else if (buf==NULL && count > 0) {
1133     retval = MPI_ERR_COUNT;
1134   } else if (!is_datatype_valid(datatype)) {
1135       retval = MPI_ERR_TYPE;
1136   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1137     retval = MPI_ERR_TAG;
1138   } else {
1139   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1140   int src_traced = smpi_group_index(smpi_comm_group(comm), src);
1141   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1142   extra->type = TRACING_RECV;
1143   extra->src = src_traced;
1144   extra->dst = rank;
1145   int known=0;
1146   extra->datatype1 = encode_datatype(datatype, &known);
1147   int dt_size_send = 1;
1148   if(!known)
1149     dt_size_send = smpi_datatype_size(datatype);
1150   extra->send_size = count*dt_size_send;
1151   TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
1152
1153     smpi_mpi_recv(buf, count, datatype, src, tag, comm, status);
1154     retval = MPI_SUCCESS;
1155
1156   //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1157   if(status!=MPI_STATUS_IGNORE){
1158     src_traced = smpi_group_index(smpi_comm_group(comm), status->MPI_SOURCE);
1159     if (!TRACE_smpi_view_internals()) {
1160       TRACE_smpi_recv(rank, src_traced, rank);
1161     }
1162   }
1163   TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
1164   }
1165
1166   smpi_bench_begin();
1167   return retval;
1168 }
1169
1170 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
1171 {
1172   int retval = 0;
1173
1174   smpi_bench_end();
1175
1176   if (comm == MPI_COMM_NULL) {
1177     retval = MPI_ERR_COMM;
1178   } else if (dst == MPI_PROC_NULL) {
1179     retval = MPI_SUCCESS;
1180   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1181     retval = MPI_ERR_RANK;
1182   } else if (count < 0) {
1183     retval = MPI_ERR_COUNT;
1184   } else if (buf==NULL && count > 0) {
1185     retval = MPI_ERR_COUNT;
1186   } else if (!is_datatype_valid(datatype)) {
1187       retval = MPI_ERR_TYPE;
1188   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1189     retval = MPI_ERR_TAG;
1190   } else {
1191
1192   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1193   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1194   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1195   extra->type = TRACING_SEND;
1196   extra->src = rank;
1197   extra->dst = dst_traced;
1198   int known=0;
1199   extra->datatype1 = encode_datatype(datatype, &known);
1200   int dt_size_send = 1;
1201   if(!known)
1202     dt_size_send = smpi_datatype_size(datatype);
1203   extra->send_size = count*dt_size_send;
1204   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1205   if (!TRACE_smpi_view_internals()) {
1206     TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1207   }
1208
1209     smpi_mpi_send(buf, count, datatype, dst, tag, comm);
1210     retval = MPI_SUCCESS;
1211
1212   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1213   }
1214
1215   smpi_bench_begin();
1216   return retval;
1217 }
1218
1219
1220
1221 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
1222   int retval = 0;
1223
1224    smpi_bench_end();
1225
1226    if (comm == MPI_COMM_NULL) {
1227      retval = MPI_ERR_COMM;
1228    } else if (dst == MPI_PROC_NULL) {
1229      retval = MPI_SUCCESS;
1230    } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1231      retval = MPI_ERR_RANK;
1232    } else if (count < 0) {
1233      retval = MPI_ERR_COUNT;
1234    } else if (buf==NULL && count > 0) {
1235      retval = MPI_ERR_COUNT;
1236    } else if (!is_datatype_valid(datatype)){
1237      retval = MPI_ERR_TYPE;
1238    } else if(tag<0 && tag !=  MPI_ANY_TAG){
1239      retval = MPI_ERR_TAG;
1240    } else {
1241
1242    int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1243    int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1244    instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1245    extra->type = TRACING_SSEND;
1246    extra->src = rank;
1247    extra->dst = dst_traced;
1248    int known=0;
1249    extra->datatype1 = encode_datatype(datatype, &known);
1250    int dt_size_send = 1;
1251    if(!known)
1252      dt_size_send = smpi_datatype_size(datatype);
1253    extra->send_size = count*dt_size_send;
1254    TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1255    TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1256
1257      smpi_mpi_ssend(buf, count, datatype, dst, tag, comm);
1258      retval = MPI_SUCCESS;
1259
1260    TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1261    }
1262
1263    smpi_bench_begin();
1264    return retval;}
1265
1266 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void *recvbuf,
1267                  int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status)
1268 {
1269   int retval = 0;
1270
1271   smpi_bench_end();
1272
1273   if (comm == MPI_COMM_NULL) {
1274     retval = MPI_ERR_COMM;
1275   } else if (!is_datatype_valid(sendtype)
1276              || !is_datatype_valid(recvtype)) {
1277     retval = MPI_ERR_TYPE;
1278   } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1279       smpi_empty_status(status);
1280       status->MPI_SOURCE = MPI_PROC_NULL;
1281       retval = MPI_SUCCESS;
1282   }else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0 ||
1283       (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0))){
1284     retval = MPI_ERR_RANK;
1285   } else if (sendcount < 0 || recvcount<0) {
1286       retval = MPI_ERR_COUNT;
1287   } else if ((sendbuf==NULL && sendcount > 0)||(recvbuf==NULL && recvcount>0)) {
1288     retval = MPI_ERR_COUNT;
1289   } else if((sendtag<0 && sendtag !=  MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1290     retval = MPI_ERR_TAG;
1291   } else {
1292
1293   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1294   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1295   int src_traced = smpi_group_index(smpi_comm_group(comm), src);
1296   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1297   extra->type = TRACING_SENDRECV;
1298   extra->src = src_traced;
1299   extra->dst = dst_traced;
1300   int known=0;
1301   extra->datatype1 = encode_datatype(sendtype, &known);
1302   int dt_size_send = 1;
1303   if(!known)
1304     dt_size_send = smpi_datatype_size(sendtype);
1305   extra->send_size = sendcount*dt_size_send;
1306   extra->datatype2 = encode_datatype(recvtype, &known);
1307   int dt_size_recv = 1;
1308   if(!known)
1309     dt_size_recv = smpi_datatype_size(recvtype);
1310   extra->recv_size = recvcount*dt_size_recv;
1311
1312   TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1313   TRACE_smpi_send(rank, rank, dst_traced,sendcount*smpi_datatype_size(sendtype));
1314
1315     smpi_mpi_sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf,
1316                       recvcount, recvtype, src, recvtag, comm, status);
1317     retval = MPI_SUCCESS;
1318
1319   TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1320   TRACE_smpi_recv(rank, src_traced, rank);
1321   }
1322
1323   smpi_bench_begin();
1324   return retval;
1325 }
1326
1327 int PMPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,
1328                          MPI_Comm comm, MPI_Status * status)
1329 {
1330   //TODO: suboptimal implementation
1331   void *recvbuf;
1332   int retval = 0;
1333   if (!is_datatype_valid(datatype)) {
1334       retval = MPI_ERR_TYPE;
1335   } else if (count < 0) {
1336       retval = MPI_ERR_COUNT;
1337   } else {
1338     int size = smpi_datatype_get_extent(datatype) * count;
1339     recvbuf = xbt_new0(char, size);
1340     retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
1341     if(retval==MPI_SUCCESS){
1342         smpi_datatype_copy(recvbuf, count, datatype, buf, count, datatype);
1343     }
1344     xbt_free(recvbuf);
1345
1346   }
1347   return retval;
1348 }
1349
1350 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1351 {
1352   int retval = 0;
1353   smpi_bench_end();
1354   if (request == NULL || flag == NULL) {
1355     retval = MPI_ERR_ARG;
1356   } else if (*request == MPI_REQUEST_NULL) {
1357     *flag= true;
1358     smpi_empty_status(status);
1359     retval = MPI_SUCCESS;
1360   } else {
1361     int rank = request && (*request)->comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1362
1363     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1364     extra->type = TRACING_TEST;
1365     TRACE_smpi_testing_in(rank, extra);
1366
1367     *flag = smpi_mpi_test(request, status);
1368
1369     TRACE_smpi_testing_out(rank);
1370     retval = MPI_SUCCESS;
1371   }
1372   smpi_bench_begin();
1373   return retval;
1374 }
1375
1376 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status)
1377 {
1378   int retval = 0;
1379
1380   smpi_bench_end();
1381   if (index == NULL || flag == NULL) {
1382     retval = MPI_ERR_ARG;
1383   } else {
1384     *flag = smpi_mpi_testany(count, requests, index, status);
1385     retval = MPI_SUCCESS;
1386   }
1387   smpi_bench_begin();
1388   return retval;
1389 }
1390
1391 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1392 {
1393   int retval = 0;
1394
1395   smpi_bench_end();
1396   if (flag == NULL) {
1397     retval = MPI_ERR_ARG;
1398   } else {
1399     *flag = smpi_mpi_testall(count, requests, statuses);
1400     retval = MPI_SUCCESS;
1401   }
1402   smpi_bench_begin();
1403   return retval;
1404 }
1405
1406 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1407   int retval = 0;
1408   smpi_bench_end();
1409
1410   if (status == NULL) {
1411     retval = MPI_ERR_ARG;
1412   } else if (comm == MPI_COMM_NULL) {
1413     retval = MPI_ERR_COMM;
1414   } else if (source == MPI_PROC_NULL) {
1415     smpi_empty_status(status);
1416     status->MPI_SOURCE = MPI_PROC_NULL;
1417     retval = MPI_SUCCESS;
1418   } else {
1419     smpi_mpi_probe(source, tag, comm, status);
1420     retval = MPI_SUCCESS;
1421   }
1422   smpi_bench_begin();
1423   return retval;
1424 }
1425
1426 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1427   int retval = 0;
1428   smpi_bench_end();
1429
1430   if (flag == NULL) {
1431     retval = MPI_ERR_ARG;
1432   } else if (status == NULL) {
1433     retval = MPI_ERR_ARG;
1434   } else if (comm == MPI_COMM_NULL) {
1435     retval = MPI_ERR_COMM;
1436   } else if (source == MPI_PROC_NULL) {
1437     *flag=true;
1438     smpi_empty_status(status);
1439     status->MPI_SOURCE = MPI_PROC_NULL;
1440     retval = MPI_SUCCESS;
1441   } else {
1442     smpi_mpi_iprobe(source, tag, comm, flag, status);
1443     retval = MPI_SUCCESS;
1444   }
1445   smpi_bench_begin();
1446   return retval;
1447 }
1448
1449 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1450 {
1451   int retval = 0;
1452
1453   smpi_bench_end();
1454
1455   smpi_empty_status(status);
1456
1457   if (request == NULL) {
1458     retval = MPI_ERR_ARG;
1459   } else if (*request == MPI_REQUEST_NULL) {
1460     retval = MPI_SUCCESS;
1461   } else {
1462
1463     int rank = request && (*request)->comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1464
1465     int src_traced = (*request)->src;
1466     int dst_traced = (*request)->dst;
1467     MPI_Comm comm = (*request)->comm;
1468     int is_wait_for_receive = (*request)->recv;
1469     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1470     extra->type = TRACING_WAIT;
1471     TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1472
1473     smpi_mpi_wait(request, status);
1474     retval = MPI_SUCCESS;
1475
1476     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1477     TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1478     if (is_wait_for_receive) {
1479       if(src_traced==MPI_ANY_SOURCE)
1480         src_traced = (status!=MPI_STATUS_IGNORE) ?
1481           smpi_group_rank(smpi_comm_group(comm), status->MPI_SOURCE) :
1482           src_traced;
1483       TRACE_smpi_recv(rank, src_traced, dst_traced);
1484     }
1485   }
1486
1487   smpi_bench_begin();
1488   return retval;
1489 }
1490
1491 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1492 {
1493   if (index == NULL)
1494     return MPI_ERR_ARG;
1495
1496   smpi_bench_end();
1497   //save requests information for tracing
1498   int i;
1499   int *srcs = xbt_new0(int, count);
1500   int *dsts = xbt_new0(int, count);
1501   int *recvs = xbt_new0(int, count);
1502   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1503
1504   for (i = 0; i < count; i++) {
1505     MPI_Request req = requests[i];      //already received requests are no longer valid
1506     if (req) {
1507       srcs[i] = req->src;
1508       dsts[i] = req->dst;
1509       recvs[i] = req->recv;
1510       comms[i] = req->comm;
1511     }
1512   }
1513   int rank_traced = smpi_process_index();
1514   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1515   extra->type = TRACING_WAITANY;
1516   extra->send_size=count;
1517   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1518
1519   *index = smpi_mpi_waitany(count, requests, status);
1520
1521   if(*index!=MPI_UNDEFINED){
1522     int src_traced = srcs[*index];
1523     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1524     int dst_traced = dsts[*index];
1525     int is_wait_for_receive = recvs[*index];
1526     if (is_wait_for_receive) {
1527       if(srcs[*index]==MPI_ANY_SOURCE)
1528         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1529                       smpi_group_rank(smpi_comm_group(comms[*index]), status->MPI_SOURCE) : srcs[*index];
1530       TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1531     }
1532     TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1533     xbt_free(srcs);
1534     xbt_free(dsts);
1535     xbt_free(recvs);
1536     xbt_free(comms);
1537
1538   }
1539   smpi_bench_begin();
1540   return MPI_SUCCESS;
1541 }
1542
1543 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1544 {
1545   smpi_bench_end();
1546   //save information from requests
1547   int i;
1548   int *srcs = xbt_new0(int, count);
1549   int *dsts = xbt_new0(int, count);
1550   int *recvs = xbt_new0(int, count);
1551   int *valid = xbt_new0(int, count);
1552   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1553
1554   //int valid_count = 0;
1555   for (i = 0; i < count; i++) {
1556     MPI_Request req = requests[i];
1557     if(req!=MPI_REQUEST_NULL){
1558       srcs[i] = req->src;
1559       dsts[i] = req->dst;
1560       recvs[i] = req->recv;
1561       comms[i] = req->comm;
1562       valid[i]=1;;
1563     }else{
1564       valid[i]=0;
1565     }
1566   }
1567   int rank_traced = smpi_process_index();
1568   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1569   extra->type = TRACING_WAITALL;
1570   extra->send_size=count;
1571   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1572
1573   int retval = smpi_mpi_waitall(count, requests, status);
1574
1575   for (i = 0; i < count; i++) {
1576     if(valid[i]){
1577     //int src_traced = srcs[*index];
1578     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1579       int src_traced = srcs[i];
1580       int dst_traced = dsts[i];
1581       int is_wait_for_receive = recvs[i];
1582       if (is_wait_for_receive) {
1583         if(src_traced==MPI_ANY_SOURCE)
1584         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1585                           smpi_group_rank(smpi_comm_group(comms[i]), status[i].MPI_SOURCE) : srcs[i];
1586         TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1587       }
1588     }
1589   }
1590   TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1591   xbt_free(srcs);
1592   xbt_free(dsts);
1593   xbt_free(recvs);
1594   xbt_free(valid);
1595   xbt_free(comms);
1596
1597   smpi_bench_begin();
1598   return retval;
1599 }
1600
1601 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount, int *indices, MPI_Status status[])
1602 {
1603   int retval = 0;
1604
1605   smpi_bench_end();
1606   if (outcount == NULL) {
1607     retval = MPI_ERR_ARG;
1608   } else {
1609     *outcount = smpi_mpi_waitsome(incount, requests, indices, status);
1610     retval = MPI_SUCCESS;
1611   }
1612   smpi_bench_begin();
1613   return retval;
1614 }
1615
1616 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[])
1617 {
1618   int retval = 0;
1619
1620    smpi_bench_end();
1621    if (outcount == NULL) {
1622      retval = MPI_ERR_ARG;
1623    } else {
1624      *outcount = smpi_mpi_testsome(incount, requests, indices, status);
1625      retval = MPI_SUCCESS;
1626    }
1627    smpi_bench_begin();
1628    return retval;
1629 }
1630
1631
1632 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1633 {
1634   int retval = 0;
1635
1636   smpi_bench_end();
1637
1638   if (comm == MPI_COMM_NULL) {
1639     retval = MPI_ERR_COMM;
1640   } else if (!is_datatype_valid(datatype)) {
1641       retval = MPI_ERR_ARG;
1642   } else {
1643   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1644   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1645
1646   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1647   extra->type = TRACING_BCAST;
1648   extra->root = root_traced;
1649   int known=0;
1650   extra->datatype1 = encode_datatype(datatype, &known);
1651   int dt_size_send = 1;
1652   if(!known)
1653     dt_size_send = smpi_datatype_size(datatype);
1654   extra->send_size = count*dt_size_send;
1655   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1656
1657     mpi_coll_bcast_fun(buf, count, datatype, root, comm);
1658     retval = MPI_SUCCESS;
1659
1660     TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1661   }
1662
1663   smpi_bench_begin();
1664   return retval;
1665 }
1666
1667 int PMPI_Barrier(MPI_Comm comm)
1668 {
1669   int retval = 0;
1670
1671   smpi_bench_end();
1672
1673   if (comm == MPI_COMM_NULL) {
1674     retval = MPI_ERR_COMM;
1675   } else {
1676   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1677   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1678   extra->type = TRACING_BARRIER;
1679   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1680
1681   mpi_coll_barrier_fun(comm);
1682   retval = MPI_SUCCESS;
1683
1684   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1685   }
1686
1687   smpi_bench_begin();
1688   return retval;
1689 }
1690
1691 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
1692                 int root, MPI_Comm comm)
1693 {
1694   int retval = 0;
1695
1696   smpi_bench_end();
1697
1698   if (comm == MPI_COMM_NULL) {
1699     retval = MPI_ERR_COMM;
1700   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1701             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1702     retval = MPI_ERR_TYPE;
1703   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) || ((smpi_comm_rank(comm) == root) && (recvcount <0))){
1704     retval = MPI_ERR_COUNT;
1705   } else {
1706
1707     char* sendtmpbuf = (char*) sendbuf;
1708     int sendtmpcount = sendcount;
1709     MPI_Datatype sendtmptype = sendtype;
1710     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1711       sendtmpcount=0;
1712       sendtmptype=recvtype;
1713     }
1714   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1715   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1716   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1717   extra->type = TRACING_GATHER;
1718   extra->root = root_traced;
1719   int known=0;
1720   extra->datatype1 = encode_datatype(sendtmptype, &known);
1721   int dt_size_send = 1;
1722   if(!known)
1723     dt_size_send = smpi_datatype_size(sendtmptype);
1724   extra->send_size = sendtmpcount*dt_size_send;
1725   extra->datatype2 = encode_datatype(recvtype, &known);
1726   int dt_size_recv = 1;
1727   if((smpi_comm_rank(comm)==root) && !known)
1728     dt_size_recv = smpi_datatype_size(recvtype);
1729   extra->recv_size = recvcount*dt_size_recv;
1730
1731   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1732
1733   mpi_coll_gather_fun(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
1734
1735   retval = MPI_SUCCESS;
1736   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1737   }
1738
1739   smpi_bench_begin();
1740   return retval;
1741 }
1742
1743 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
1744                 MPI_Datatype recvtype, int root, MPI_Comm comm)
1745 {
1746   int retval = 0;
1747
1748   smpi_bench_end();
1749
1750   if (comm == MPI_COMM_NULL) {
1751     retval = MPI_ERR_COMM;
1752   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1753             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1754     retval = MPI_ERR_TYPE;
1755   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1756     retval = MPI_ERR_COUNT;
1757   } else if (recvcounts == NULL || displs == NULL) {
1758     retval = MPI_ERR_ARG;
1759   } else {
1760     char* sendtmpbuf = (char*) sendbuf;
1761     int sendtmpcount = sendcount;
1762     MPI_Datatype sendtmptype = sendtype;
1763     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1764       sendtmpcount=0;
1765       sendtmptype=recvtype;
1766     }
1767
1768   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1769   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1770   int i=0;
1771   int size = smpi_comm_size(comm);
1772   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1773   extra->type = TRACING_GATHERV;
1774   extra->num_processes = size;
1775   extra->root = root_traced;
1776   int known=0;
1777   extra->datatype1 = encode_datatype(sendtmptype, &known);
1778   int dt_size_send = 1;
1779   if(!known)
1780     dt_size_send = smpi_datatype_size(sendtype);
1781   extra->send_size = sendtmpcount*dt_size_send;
1782   extra->datatype2 = encode_datatype(recvtype, &known);
1783   int dt_size_recv = 1;
1784   if(!known)
1785     dt_size_recv = smpi_datatype_size(recvtype);
1786   if((smpi_comm_rank(comm)==root)){
1787   extra->recvcounts= xbt_new(int,size);
1788   for(i=0; i< size; i++)//copy data to avoid bad free
1789     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
1790   }
1791   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1792
1793   smpi_mpi_gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
1794     retval = MPI_SUCCESS;
1795   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1796   }
1797
1798   smpi_bench_begin();
1799   return retval;
1800 }
1801
1802 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1803                    void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
1804 {
1805   int retval = 0;
1806
1807   smpi_bench_end();
1808
1809   if (comm == MPI_COMM_NULL) {
1810     retval = MPI_ERR_COMM;
1811   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1812             (recvtype == MPI_DATATYPE_NULL)){
1813     retval = MPI_ERR_TYPE;
1814   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1815             (recvcount <0)){
1816     retval = MPI_ERR_COUNT;
1817   } else {
1818     if(sendbuf == MPI_IN_PLACE) {
1819       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*recvcount*smpi_comm_rank(comm);
1820       sendcount=recvcount;
1821       sendtype=recvtype;
1822     }
1823   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1824   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1825   extra->type = TRACING_ALLGATHER;
1826   int known=0;
1827   extra->datatype1 = encode_datatype(sendtype, &known);
1828   int dt_size_send = 1;
1829   if(!known)
1830     dt_size_send = smpi_datatype_size(sendtype);
1831   extra->send_size = sendcount*dt_size_send;
1832   extra->datatype2 = encode_datatype(recvtype, &known);
1833   int dt_size_recv = 1;
1834   if(!known)
1835     dt_size_recv = smpi_datatype_size(recvtype);
1836   extra->recv_size = recvcount*dt_size_recv;
1837
1838   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1839
1840   mpi_coll_allgather_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1841     retval = MPI_SUCCESS;
1842   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1843   }
1844   smpi_bench_begin();
1845   return retval;
1846 }
1847
1848 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1849                    void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
1850 {
1851   int retval = 0;
1852
1853   smpi_bench_end();
1854
1855   if (comm == MPI_COMM_NULL) {
1856     retval = MPI_ERR_COMM;
1857   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1858             (recvtype == MPI_DATATYPE_NULL)){
1859     retval = MPI_ERR_TYPE;
1860   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1861     retval = MPI_ERR_COUNT;
1862   } else if (recvcounts == NULL || displs == NULL) {
1863     retval = MPI_ERR_ARG;
1864   } else {
1865
1866     if(sendbuf == MPI_IN_PLACE) {
1867       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*displs[smpi_comm_rank(comm)];
1868       sendcount=recvcounts[smpi_comm_rank(comm)];
1869       sendtype=recvtype;
1870     }
1871   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1872   int i=0;
1873   int size = smpi_comm_size(comm);
1874   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1875   extra->type = TRACING_ALLGATHERV;
1876   extra->num_processes = size;
1877   int known=0;
1878   extra->datatype1 = encode_datatype(sendtype, &known);
1879   int dt_size_send = 1;
1880   if(!known)
1881     dt_size_send = smpi_datatype_size(sendtype);
1882   extra->send_size = sendcount*dt_size_send;
1883   extra->datatype2 = encode_datatype(recvtype, &known);
1884   int dt_size_recv = 1;
1885   if(!known)
1886     dt_size_recv = smpi_datatype_size(recvtype);
1887   extra->recvcounts= xbt_new(int, size);
1888   for(i=0; i< size; i++)//copy data to avoid bad free
1889     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
1890
1891   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
1892
1893     mpi_coll_allgatherv_fun(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1894     retval = MPI_SUCCESS;
1895   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1896   }
1897
1898   smpi_bench_begin();
1899   return retval;
1900 }
1901
1902 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1903                 void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1904 {
1905   int retval = 0;
1906
1907   smpi_bench_end();
1908
1909   if (comm == MPI_COMM_NULL) {
1910     retval = MPI_ERR_COMM;
1911   } else if (((smpi_comm_rank(comm)==root) && (!is_datatype_valid(sendtype)))
1912              || ((recvbuf !=MPI_IN_PLACE) && (!is_datatype_valid(recvtype)))){
1913     retval = MPI_ERR_TYPE;
1914   } else if ((sendbuf == recvbuf) ||
1915       ((smpi_comm_rank(comm)==root) && sendcount>0 && (sendbuf == NULL))){
1916     retval = MPI_ERR_BUFFER;
1917   }else {
1918
1919     if (recvbuf == MPI_IN_PLACE) {
1920         recvtype=sendtype;
1921         recvcount=sendcount;
1922     }
1923   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1924   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1925   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1926   extra->type = TRACING_SCATTER;
1927   extra->root = root_traced;
1928   int known=0;
1929   extra->datatype1 = encode_datatype(sendtype, &known);
1930   int dt_size_send = 1;
1931   if((smpi_comm_rank(comm)==root) && !known)
1932     dt_size_send = smpi_datatype_size(sendtype);
1933   extra->send_size = sendcount*dt_size_send;
1934   extra->datatype2 = encode_datatype(recvtype, &known);
1935   int dt_size_recv = 1;
1936   if(!known)
1937     dt_size_recv = smpi_datatype_size(recvtype);
1938   extra->recv_size = recvcount*dt_size_recv;
1939   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1940
1941   mpi_coll_scatter_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1942     retval = MPI_SUCCESS;
1943   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1944   }
1945
1946   smpi_bench_begin();
1947   return retval;
1948 }
1949
1950 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1951                  MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1952 {
1953   int retval = 0;
1954
1955   smpi_bench_end();
1956
1957   if (comm == MPI_COMM_NULL) {
1958     retval = MPI_ERR_COMM;
1959   } else if (sendcounts == NULL || displs == NULL) {
1960     retval = MPI_ERR_ARG;
1961   } else if (((smpi_comm_rank(comm)==root) && (sendtype == MPI_DATATYPE_NULL))
1962              || ((recvbuf !=MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1963     retval = MPI_ERR_TYPE;
1964   } else {
1965     if (recvbuf == MPI_IN_PLACE) {
1966         recvtype=sendtype;
1967         recvcount=sendcounts[smpi_comm_rank(comm)];
1968     }
1969   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1970   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1971   int i=0;
1972   int size = smpi_comm_size(comm);
1973   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1974   extra->type = TRACING_SCATTERV;
1975   extra->num_processes = size;
1976   extra->root = root_traced;
1977   int known=0;
1978   extra->datatype1 = encode_datatype(sendtype, &known);
1979   int dt_size_send = 1;
1980   if(!known)
1981     dt_size_send = smpi_datatype_size(sendtype);
1982   if((smpi_comm_rank(comm)==root)){
1983   extra->sendcounts= xbt_new(int, size);
1984   for(i=0; i< size; i++)//copy data to avoid bad free
1985     extra->sendcounts[i] = sendcounts[i]*dt_size_send;
1986   }
1987   extra->datatype2 = encode_datatype(recvtype, &known);
1988   int dt_size_recv = 1;
1989   if(!known)
1990     dt_size_recv = smpi_datatype_size(recvtype);
1991   extra->recv_size = recvcount*dt_size_recv;
1992   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1993
1994     smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1995
1996     retval = MPI_SUCCESS;
1997   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1998   }
1999
2000   smpi_bench_begin();
2001   return retval;
2002 }
2003
2004 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
2005 {
2006   int retval = 0;
2007
2008   smpi_bench_end();
2009
2010   if (comm == MPI_COMM_NULL) {
2011     retval = MPI_ERR_COMM;
2012   } else if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2013     retval = MPI_ERR_ARG;
2014   } else {
2015   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2016   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2017   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2018   extra->type = TRACING_REDUCE;
2019   int known=0;
2020   extra->datatype1 = encode_datatype(datatype, &known);
2021   int dt_size_send = 1;
2022   if(!known)
2023     dt_size_send = smpi_datatype_size(datatype);
2024   extra->send_size = count*dt_size_send;
2025   extra->root = root_traced;
2026
2027   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2028
2029   mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, root, comm);
2030
2031     retval = MPI_SUCCESS;
2032   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2033   }
2034
2035   smpi_bench_begin();
2036   return retval;
2037 }
2038
2039 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op){
2040   int retval = 0;
2041
2042     smpi_bench_end();
2043     if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2044       retval = MPI_ERR_ARG;
2045     } else {
2046       smpi_op_apply(op, inbuf, inoutbuf, &count, &datatype);
2047       retval=MPI_SUCCESS;
2048     }
2049     smpi_bench_begin();
2050     return retval;
2051 }
2052
2053 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2054 {
2055   int retval = 0;
2056
2057   smpi_bench_end();
2058
2059   if (comm == MPI_COMM_NULL) {
2060     retval = MPI_ERR_COMM;
2061   } else if (!is_datatype_valid(datatype)) {
2062     retval = MPI_ERR_TYPE;
2063   } else if (op == MPI_OP_NULL) {
2064     retval = MPI_ERR_OP;
2065   } else {
2066
2067     char* sendtmpbuf = (char*) sendbuf;
2068     if( sendbuf == MPI_IN_PLACE ) {
2069       sendtmpbuf = (char *)xbt_malloc(count*smpi_datatype_get_extent(datatype));
2070       smpi_datatype_copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
2071     }
2072   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2073   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2074   extra->type = TRACING_ALLREDUCE;
2075   int known=0;
2076   extra->datatype1 = encode_datatype(datatype, &known);
2077   int dt_size_send = 1;
2078   if(!known)
2079     dt_size_send = smpi_datatype_size(datatype);
2080   extra->send_size = count*dt_size_send;
2081
2082   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2083
2084   mpi_coll_allreduce_fun(sendtmpbuf, recvbuf, count, datatype, op, comm);
2085
2086     if( sendbuf == MPI_IN_PLACE )
2087       xbt_free(sendtmpbuf);
2088
2089     retval = MPI_SUCCESS;
2090   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2091   }
2092
2093   smpi_bench_begin();
2094   return retval;
2095 }
2096
2097 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2098 {
2099   int retval = 0;
2100
2101   smpi_bench_end();
2102
2103   if (comm == MPI_COMM_NULL) {
2104     retval = MPI_ERR_COMM;
2105   } else if (!is_datatype_valid(datatype)) {
2106     retval = MPI_ERR_TYPE;
2107   } else if (op == MPI_OP_NULL) {
2108     retval = MPI_ERR_OP;
2109   } else {
2110   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2111   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2112   extra->type = TRACING_SCAN;
2113   int known=0;
2114   extra->datatype1 = encode_datatype(datatype, &known);
2115   int dt_size_send = 1;
2116   if(!known)
2117     dt_size_send = smpi_datatype_size(datatype);
2118   extra->send_size = count*dt_size_send;
2119
2120   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2121
2122   smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
2123
2124   retval = MPI_SUCCESS;
2125   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2126   }
2127
2128   smpi_bench_begin();
2129   return retval;
2130 }
2131
2132 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
2133   int retval = 0;
2134
2135   smpi_bench_end();
2136
2137   if (comm == MPI_COMM_NULL) {
2138     retval = MPI_ERR_COMM;
2139   } else if (!is_datatype_valid(datatype)) {
2140     retval = MPI_ERR_TYPE;
2141   } else if (op == MPI_OP_NULL) {
2142     retval = MPI_ERR_OP;
2143   } else {
2144   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2145   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2146   extra->type = TRACING_EXSCAN;
2147   int known=0;
2148   extra->datatype1 = encode_datatype(datatype, &known);
2149   int dt_size_send = 1;
2150   if(!known)
2151     dt_size_send = smpi_datatype_size(datatype);
2152   extra->send_size = count*dt_size_send;
2153   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2154
2155   smpi_mpi_exscan(sendbuf, recvbuf, count, datatype, op, comm);
2156     retval = MPI_SUCCESS;
2157   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2158   }
2159
2160   smpi_bench_begin();
2161   return retval;
2162 }
2163
2164 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2165 {
2166   int retval = 0;
2167   smpi_bench_end();
2168
2169   if (comm == MPI_COMM_NULL) {
2170     retval = MPI_ERR_COMM;
2171   } else if (!is_datatype_valid(datatype)) {
2172     retval = MPI_ERR_TYPE;
2173   } else if (op == MPI_OP_NULL) {
2174     retval = MPI_ERR_OP;
2175   } else if (recvcounts == NULL) {
2176     retval = MPI_ERR_ARG;
2177   } else {
2178   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2179   int i=0;
2180   int size = smpi_comm_size(comm);
2181   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2182   extra->type = TRACING_REDUCE_SCATTER;
2183   extra->num_processes = size;
2184   int known=0;
2185   extra->datatype1 = encode_datatype(datatype, &known);
2186   int dt_size_send = 1;
2187   if(!known)
2188     dt_size_send = smpi_datatype_size(datatype);
2189   extra->send_size = 0;
2190   extra->recvcounts= xbt_new(int, size);
2191   for(i=0; i< size; i++)//copy data to avoid bad free
2192     extra->recvcounts[i] = recvcounts[i]*dt_size_send;
2193   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2194
2195   void* sendtmpbuf=sendbuf;
2196     if(sendbuf==MPI_IN_PLACE)
2197       sendtmpbuf=recvbuf;
2198
2199     mpi_coll_reduce_scatter_fun(sendtmpbuf, recvbuf, recvcounts, datatype,  op, comm);
2200     retval = MPI_SUCCESS;
2201   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2202   }
2203
2204   smpi_bench_begin();
2205   return retval;
2206 }
2207
2208 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
2209                               MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2210 {
2211   int retval,i;
2212   smpi_bench_end();
2213
2214   if (comm == MPI_COMM_NULL) {
2215     retval = MPI_ERR_COMM;
2216   } else if (!is_datatype_valid(datatype)) {
2217     retval = MPI_ERR_TYPE;
2218   } else if (op == MPI_OP_NULL) {
2219     retval = MPI_ERR_OP;
2220   } else if (recvcount < 0) {
2221     retval = MPI_ERR_ARG;
2222   } else {
2223     int count=smpi_comm_size(comm);
2224
2225   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2226   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2227   extra->type = TRACING_REDUCE_SCATTER;
2228   extra->num_processes = count;
2229   int known=0;
2230   extra->datatype1 = encode_datatype(datatype, &known);
2231   int dt_size_send = 1;
2232   if(!known)
2233     dt_size_send = smpi_datatype_size(datatype);
2234   extra->send_size = 0;
2235   extra->recvcounts= xbt_new(int, count);
2236   for(i=0; i< count; i++)//copy data to avoid bad free
2237     extra->recvcounts[i] = recvcount*dt_size_send;
2238
2239   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2240
2241   int* recvcounts=(int*)xbt_malloc(count);
2242     for (i=0; i<count;i++)recvcounts[i]=recvcount;
2243     mpi_coll_reduce_scatter_fun(sendbuf, recvbuf, recvcounts, datatype,  op, comm);
2244     xbt_free(recvcounts);
2245     retval = MPI_SUCCESS;
2246
2247     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2248   }
2249
2250   smpi_bench_begin();
2251   return retval;
2252 }
2253
2254 int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
2255                  void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
2256 {
2257   int retval = 0;
2258
2259   smpi_bench_end();
2260
2261   if (comm == MPI_COMM_NULL) {
2262     retval = MPI_ERR_COMM;
2263   } else if (sendtype == MPI_DATATYPE_NULL
2264              || recvtype == MPI_DATATYPE_NULL) {
2265     retval = MPI_ERR_TYPE;
2266   } else {
2267   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2268   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2269   extra->type = TRACING_ALLTOALL;
2270   int known=0;
2271   extra->datatype1 = encode_datatype(sendtype, &known);
2272   if(!known)
2273     extra->send_size = sendcount*smpi_datatype_size(sendtype);
2274   else
2275     extra->send_size = sendcount;
2276   extra->datatype2 = encode_datatype(recvtype, &known);
2277   if(!known)
2278     extra->recv_size = recvcount*smpi_datatype_size(recvtype);
2279   else
2280     extra->recv_size = recvcount;
2281   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2282
2283   retval = mpi_coll_alltoall_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
2284
2285   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2286   }
2287
2288   smpi_bench_begin();
2289   return retval;
2290 }
2291
2292 int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,MPI_Datatype sendtype, void *recvbuf, int *recvcounts,
2293                   int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2294 {
2295   int retval = 0;
2296
2297   smpi_bench_end();
2298
2299   if (comm == MPI_COMM_NULL) {
2300     retval = MPI_ERR_COMM;
2301   } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
2302     retval = MPI_ERR_TYPE;
2303   } else if (sendcounts == NULL || senddisps == NULL || recvcounts == NULL || recvdisps == NULL) {
2304     retval = MPI_ERR_ARG;
2305   } else {
2306   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2307   int i=0;
2308   int size = smpi_comm_size(comm);
2309   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2310   extra->type = TRACING_ALLTOALLV;
2311   extra->send_size = 0;
2312   extra->recv_size = 0;
2313   extra->recvcounts= xbt_new(int, size);
2314   extra->sendcounts= xbt_new(int, size);
2315   int known=0;
2316   extra->datatype1 = encode_datatype(sendtype, &known);
2317   int dt_size_send = 1;
2318   if(!known)
2319     dt_size_send = smpi_datatype_size(sendtype);
2320   int dt_size_recv = 1;
2321   extra->datatype2 = encode_datatype(recvtype, &known);
2322   if(!known)
2323     dt_size_recv = smpi_datatype_size(recvtype);
2324   for(i=0; i< size; i++){//copy data to avoid bad free
2325     extra->send_size += sendcounts[i]*dt_size_send;
2326     extra->recv_size += recvcounts[i]*dt_size_recv;
2327
2328     extra->sendcounts[i] = sendcounts[i]*dt_size_send;
2329     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
2330   }
2331   extra->num_processes = size;
2332   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2333
2334   retval = mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps, sendtype, recvbuf, recvcounts, recvdisps, recvtype,
2335                                   comm);
2336   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2337   }
2338
2339   smpi_bench_begin();
2340   return retval;
2341 }
2342
2343
2344 int PMPI_Get_processor_name(char *name, int *resultlen)
2345 {
2346   int retval = MPI_SUCCESS;
2347
2348   strncpy(name, sg_host_get_name(SIMIX_host_self()),
2349           strlen(sg_host_get_name(SIMIX_host_self())) < MPI_MAX_PROCESSOR_NAME - 1 ?
2350           strlen(sg_host_get_name(SIMIX_host_self())) +1 : MPI_MAX_PROCESSOR_NAME - 1 );
2351   *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2352
2353   return retval;
2354 }
2355
2356 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2357 {
2358   int retval = MPI_SUCCESS;
2359   size_t size;
2360
2361   if (status == NULL || count == NULL) {
2362     retval = MPI_ERR_ARG;
2363   } else if (!is_datatype_valid(datatype)) {
2364     retval = MPI_ERR_TYPE;
2365   } else {
2366     size = smpi_datatype_size(datatype);
2367     if (size == 0) {
2368       *count = 0;
2369     } else if (status->count % size != 0) {
2370       retval = MPI_UNDEFINED;
2371     } else {
2372       *count = smpi_mpi_get_count(status, datatype);
2373     }
2374   }
2375   return retval;
2376 }
2377
2378 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2379   int retval = 0;
2380
2381   if (old_type == MPI_DATATYPE_NULL) {
2382     retval = MPI_ERR_TYPE;
2383   } else if (count<0){
2384     retval = MPI_ERR_COUNT;
2385   } else {
2386     retval = smpi_datatype_contiguous(count, old_type, new_type, 0);
2387   }
2388   return retval;
2389 }
2390
2391 int PMPI_Type_commit(MPI_Datatype* datatype) {
2392   int retval = 0;
2393
2394   if (datatype == NULL || *datatype == MPI_DATATYPE_NULL) {
2395     retval = MPI_ERR_TYPE;
2396   } else {
2397     smpi_datatype_commit(datatype);
2398     retval = MPI_SUCCESS;
2399   }
2400   return retval;
2401 }
2402
2403 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2404   int retval = 0;
2405
2406   if (old_type == MPI_DATATYPE_NULL) {
2407     retval = MPI_ERR_TYPE;
2408   } else if (count<0 || blocklen<0){
2409     retval = MPI_ERR_COUNT;
2410   } else {
2411     retval = smpi_datatype_vector(count, blocklen, stride, old_type, new_type);
2412   }
2413   return retval;
2414 }
2415
2416 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2417   int retval = 0;
2418
2419   if (old_type == MPI_DATATYPE_NULL) {
2420     retval = MPI_ERR_TYPE;
2421   } else if (count<0 || blocklen<0){
2422     retval = MPI_ERR_COUNT;
2423   } else {
2424     retval = smpi_datatype_hvector(count, blocklen, stride, old_type, new_type);
2425   }
2426   return retval;
2427 }
2428
2429 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2430   return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2431 }
2432
2433 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2434   int retval = 0;
2435
2436   if (old_type == MPI_DATATYPE_NULL) {
2437     retval = MPI_ERR_TYPE;
2438   } else if (count<0){
2439     retval = MPI_ERR_COUNT;
2440   } else {
2441     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2442   }
2443   return retval;
2444 }
2445
2446 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2447   int retval = 0;
2448
2449   if (old_type == MPI_DATATYPE_NULL) {
2450     retval = MPI_ERR_TYPE;
2451   } else if (count<0){
2452     retval = MPI_ERR_COUNT;
2453   } else {
2454     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2455   }
2456   return retval;
2457 }
2458
2459 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type,
2460                                    MPI_Datatype* new_type) {
2461   int retval,i;
2462
2463   if (old_type == MPI_DATATYPE_NULL) {
2464     retval = MPI_ERR_TYPE;
2465   } else if (count<0){
2466     retval = MPI_ERR_COUNT;
2467   } else {
2468     int* blocklens=(int*)xbt_malloc(blocklength*count);
2469     for (i=0; i<count;i++)blocklens[i]=blocklength;
2470     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2471     xbt_free(blocklens);
2472   }
2473   return retval;
2474 }
2475
2476 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2477   int retval = 0;
2478
2479   if (old_type == MPI_DATATYPE_NULL) {
2480     retval = MPI_ERR_TYPE;
2481   } else if (count<0){
2482     retval = MPI_ERR_COUNT;
2483   } else {
2484     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2485   }
2486   return retval;
2487 }
2488
2489 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type,
2490                               MPI_Datatype* new_type) {
2491   return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2492 }
2493
2494 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type,
2495                                     MPI_Datatype* new_type) {
2496   int retval,i;
2497
2498   if (old_type == MPI_DATATYPE_NULL) {
2499     retval = MPI_ERR_TYPE;
2500   } else if (count<0){
2501     retval = MPI_ERR_COUNT;
2502   } else {
2503     int* blocklens=(int*)xbt_malloc(blocklength*count);
2504     for (i=0; i<count;i++)blocklens[i]=blocklength;
2505     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2506     xbt_free(blocklens);
2507   }
2508   return retval;
2509 }
2510
2511 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2512   int retval = 0;
2513
2514   if (count<0){
2515     retval = MPI_ERR_COUNT;
2516   } else {
2517     retval = smpi_datatype_struct(count, blocklens, indices, old_types, new_type);
2518   }
2519   return retval;
2520 }
2521
2522 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types,
2523                             MPI_Datatype* new_type) {
2524   return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2525 }
2526
2527 int PMPI_Error_class(int errorcode, int* errorclass) {
2528   // assume smpi uses only standard mpi error codes
2529   *errorclass=errorcode;
2530   return MPI_SUCCESS;
2531 }
2532
2533 int PMPI_Initialized(int* flag) {
2534    *flag=smpi_process_initialized();
2535    return MPI_SUCCESS;
2536 }
2537
2538 /* The topo part of MPI_COMM_WORLD should always be NULL. When other topologies will be implemented, not only should we
2539  * check if the topology is NULL, but we should check if it is the good topology type (so we have to add a
2540  *  MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2541
2542 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2543   int retval = 0;
2544   if (comm_old == MPI_COMM_NULL){
2545     retval =  MPI_ERR_COMM;
2546   } else if (ndims < 0 || (ndims > 0 && (dims == NULL || periodic == NULL)) || comm_cart == NULL) {
2547     retval = MPI_ERR_ARG;
2548   } else{
2549     retval = smpi_mpi_cart_create(comm_old, ndims, dims, periodic, reorder, comm_cart);
2550   }
2551   return retval;
2552 }
2553
2554 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2555   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2556     return MPI_ERR_TOPOLOGY;
2557   }
2558   if (coords == NULL) {
2559     return MPI_ERR_ARG;
2560   }
2561   return smpi_mpi_cart_rank(comm, coords, rank);
2562 }
2563
2564 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2565   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2566     return MPI_ERR_TOPOLOGY;
2567   }
2568   if (source == NULL || dest == NULL || direction < 0 ) {
2569     return MPI_ERR_ARG;
2570   }
2571   return smpi_mpi_cart_shift(comm, direction, displ, source, dest);
2572 }
2573
2574 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2575   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2576     return MPI_ERR_TOPOLOGY;
2577   }
2578   if (rank < 0 || rank >= smpi_comm_size(comm)) {
2579     return MPI_ERR_RANK;
2580   }
2581   if (maxdims <= 0) {
2582     return MPI_ERR_ARG;
2583   }
2584   if(coords == NULL) {
2585     return MPI_ERR_ARG;
2586   }
2587   return smpi_mpi_cart_coords(comm, rank, maxdims, coords);
2588 }
2589
2590 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2591   if(comm == NULL || smpi_comm_topo(comm) == NULL) {
2592     return MPI_ERR_TOPOLOGY;
2593   }
2594   if(maxdims <= 0 || dims == NULL || periods == NULL || coords == NULL) {
2595     return MPI_ERR_ARG;
2596   }
2597   return smpi_mpi_cart_get(comm, maxdims, dims, periods, coords);
2598 }
2599
2600 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2601   if (comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2602     return MPI_ERR_TOPOLOGY;
2603   }
2604   if (ndims == NULL) {
2605     return MPI_ERR_ARG;
2606   }
2607   return smpi_mpi_cartdim_get(comm, ndims);
2608 }
2609
2610 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2611   if(dims == NULL) {
2612     return MPI_ERR_ARG;
2613   }
2614   if (ndims < 1 || nnodes < 1) {
2615     return MPI_ERR_DIMS;
2616   }
2617
2618   return smpi_mpi_dims_create(nnodes, ndims, dims);
2619 }
2620
2621 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2622   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2623     return MPI_ERR_TOPOLOGY;
2624   }
2625   if (comm_new == NULL) {
2626     return MPI_ERR_ARG;
2627   }
2628   return smpi_mpi_cart_sub(comm, remain_dims, comm_new);
2629 }
2630
2631 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2632     if(oldtype == MPI_DATATYPE_NULL) {
2633         return MPI_ERR_TYPE;
2634     }
2635     int blocks[3] = { 1, 1, 1 };
2636     MPI_Aint disps[3] = { lb, 0, lb+extent };
2637     MPI_Datatype types[3] = { MPI_LB, oldtype, MPI_UB };
2638
2639     s_smpi_mpi_struct_t* subtype = smpi_datatype_struct_create( blocks, disps, 3, types);
2640     smpi_datatype_create(newtype,oldtype->size, lb, lb + extent, sizeof(s_smpi_mpi_struct_t) , subtype, DT_FLAG_VECTOR);
2641
2642     (*newtype)->flags &= ~DT_FLAG_COMMITED;
2643     return MPI_SUCCESS;
2644 }
2645
2646 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2647   int retval = 0;
2648   smpi_bench_end();
2649   if (comm == MPI_COMM_NULL) {
2650     retval= MPI_ERR_COMM;
2651   }else if ((base == NULL && size != 0) || disp_unit <= 0 || size < 0 ){
2652     retval= MPI_ERR_OTHER;
2653   }else{
2654     *win = smpi_mpi_win_create( base, size, disp_unit, info, comm);
2655     retval = MPI_SUCCESS;
2656   }
2657   smpi_bench_begin();
2658   return retval;
2659 }
2660
2661 int PMPI_Win_free( MPI_Win* win){
2662   int retval = 0;
2663   smpi_bench_end();
2664   if (win == NULL || *win == MPI_WIN_NULL) {
2665     retval = MPI_ERR_WIN;
2666   }else{
2667     retval=smpi_mpi_win_free(win);
2668   }
2669   smpi_bench_begin();
2670   return retval;
2671 }
2672
2673 int PMPI_Win_set_name(MPI_Win  win, char * name)
2674 {
2675   int retval = 0;
2676   if (win == MPI_WIN_NULL)  {
2677     retval = MPI_ERR_TYPE;
2678   } else if (name == NULL)  {
2679     retval = MPI_ERR_ARG;
2680   } else {
2681     smpi_mpi_win_set_name(win, name);
2682     retval = MPI_SUCCESS;
2683   }
2684   return retval;
2685 }
2686
2687 int PMPI_Win_get_name(MPI_Win  win, char * name, int* len)
2688 {
2689   int retval = MPI_SUCCESS;
2690
2691   if (win == MPI_WIN_NULL)  {
2692     retval = MPI_ERR_WIN;
2693   } else if (name == NULL)  {
2694     retval = MPI_ERR_ARG;
2695   } else {
2696     smpi_mpi_win_get_name(win, name, len);
2697   }
2698   return retval;
2699 }
2700
2701 int PMPI_Win_get_group(MPI_Win  win, MPI_Group * group){
2702   int retval = MPI_SUCCESS;
2703   if (win == MPI_WIN_NULL)  {
2704     retval = MPI_ERR_WIN;
2705   }else {
2706     smpi_mpi_win_get_group(win, group);
2707   }
2708   return retval;
2709 }
2710
2711
2712 int PMPI_Win_fence( int assert,  MPI_Win win){
2713   int retval = 0;
2714   smpi_bench_end();
2715   if (win == MPI_WIN_NULL) {
2716     retval = MPI_ERR_WIN;
2717   } else {
2718   int rank = smpi_process_index();
2719   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2720   retval = smpi_mpi_win_fence(assert, win);
2721   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2722   }
2723   smpi_bench_begin();
2724   return retval;
2725 }
2726
2727 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2728               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2729   int retval = 0;
2730   smpi_bench_end();
2731   if (win == MPI_WIN_NULL) {
2732     retval = MPI_ERR_WIN;
2733   } else if (target_rank == MPI_PROC_NULL) {
2734     retval = MPI_SUCCESS;
2735   } else if (target_rank <0){
2736     retval = MPI_ERR_RANK;
2737   } else if (target_disp <0){
2738       retval = MPI_ERR_ARG;
2739   } else if (origin_count < 0 || target_count < 0) {
2740     retval = MPI_ERR_COUNT;
2741   } else if (origin_addr==NULL && origin_count > 0){
2742     retval = MPI_ERR_COUNT;
2743   } else if ((!is_datatype_valid(origin_datatype)) || (!is_datatype_valid(target_datatype))) {
2744     retval = MPI_ERR_TYPE;
2745   } else {
2746     int rank = smpi_process_index();
2747     MPI_Group group;
2748     smpi_mpi_win_get_group(win, &group);
2749     int src_traced = smpi_group_index(group, target_rank);
2750     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, NULL);
2751
2752     retval = smpi_mpi_get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2753                            target_datatype, win);
2754
2755     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2756   }
2757   smpi_bench_begin();
2758   return retval;
2759 }
2760
2761 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2762               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2763   int retval = 0;
2764   smpi_bench_end();
2765   if (win == MPI_WIN_NULL) {
2766     retval = MPI_ERR_WIN;
2767   } else if (target_rank == MPI_PROC_NULL) {
2768     retval = MPI_SUCCESS;
2769   } else if (target_rank <0){
2770     retval = MPI_ERR_RANK;
2771   } else if (target_disp <0){
2772     retval = MPI_ERR_ARG;
2773   } else if (origin_count < 0 || target_count < 0) {
2774     retval = MPI_ERR_COUNT;
2775   } else if (origin_addr==NULL && origin_count > 0){
2776     retval = MPI_ERR_COUNT;
2777   } else if ((!is_datatype_valid(origin_datatype)) || (!is_datatype_valid(target_datatype))) {
2778     retval = MPI_ERR_TYPE;
2779   } else {
2780     int rank = smpi_process_index();
2781     MPI_Group group;
2782     smpi_mpi_win_get_group(win, &group);
2783     int dst_traced = smpi_group_index(group, target_rank);
2784     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, NULL);
2785     TRACE_smpi_send(rank, rank, dst_traced, origin_count*smpi_datatype_size(origin_datatype));
2786
2787     retval = smpi_mpi_put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2788                            target_datatype, win);
2789
2790     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2791   }
2792   smpi_bench_begin();
2793   return retval;
2794 }
2795
2796 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2797               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2798   int retval = 0;
2799   smpi_bench_end();
2800   if (win == MPI_WIN_NULL) {
2801     retval = MPI_ERR_WIN;
2802   } else if (target_rank == MPI_PROC_NULL) {
2803     retval = MPI_SUCCESS;
2804   } else if (target_rank <0){
2805     retval = MPI_ERR_RANK;
2806   } else if (target_disp <0){
2807     retval = MPI_ERR_ARG;
2808   } else if (origin_count < 0 || target_count < 0) {
2809     retval = MPI_ERR_COUNT;
2810   } else if (origin_addr==NULL && origin_count > 0){
2811     retval = MPI_ERR_COUNT;
2812   } else if ((!is_datatype_valid(origin_datatype)) ||
2813             (!is_datatype_valid(target_datatype))) {
2814     retval = MPI_ERR_TYPE;
2815   } else if (op == MPI_OP_NULL) {
2816     retval = MPI_ERR_OP;
2817   } else {
2818     int rank = smpi_process_index();
2819     MPI_Group group;
2820     smpi_mpi_win_get_group(win, &group);
2821     int src_traced = smpi_group_index(group, target_rank);
2822     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, NULL);
2823
2824     retval = smpi_mpi_accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2825                                   target_datatype, op, win);
2826
2827     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2828   }
2829   smpi_bench_begin();
2830   return retval;
2831 }
2832
2833 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2834   int retval = 0;
2835   smpi_bench_end();
2836   if (win == MPI_WIN_NULL) {
2837     retval = MPI_ERR_WIN;
2838   } else if (group==MPI_GROUP_NULL){
2839     retval = MPI_ERR_GROUP;
2840   }
2841   else {
2842     int rank = smpi_process_index();
2843     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2844     retval = smpi_mpi_win_post(group,assert,win);
2845     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2846   }
2847   smpi_bench_begin();
2848   return retval;
2849 }
2850
2851 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2852   int retval = 0;
2853   smpi_bench_end();
2854   if (win == MPI_WIN_NULL) {
2855     retval = MPI_ERR_WIN;
2856   } else if (group==MPI_GROUP_NULL){
2857     retval = MPI_ERR_GROUP;
2858   }
2859   else {
2860     int rank = smpi_process_index();
2861     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2862     retval = smpi_mpi_win_start(group,assert,win);
2863     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2864   }
2865   smpi_bench_begin();
2866   return retval;
2867 }
2868
2869 int PMPI_Win_complete(MPI_Win win){
2870   int retval = 0;
2871   smpi_bench_end();
2872   if (win == MPI_WIN_NULL) {
2873     retval = MPI_ERR_WIN;
2874   }
2875   else {
2876     int rank = smpi_process_index();
2877     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2878
2879     retval = smpi_mpi_win_complete(win);
2880
2881     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2882   }
2883   smpi_bench_begin();
2884   return retval;
2885 }
2886
2887 int PMPI_Win_wait(MPI_Win win){
2888   int retval = 0;
2889   smpi_bench_end();
2890   if (win == MPI_WIN_NULL) {
2891     retval = MPI_ERR_WIN;
2892   }
2893   else {
2894     int rank = smpi_process_index();
2895     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2896
2897     retval = smpi_mpi_win_wait(win);
2898
2899     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2900   }
2901   smpi_bench_begin();
2902   return retval;
2903 }
2904
2905 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
2906   void *ptr = xbt_malloc(size);
2907   if(!ptr)
2908     return MPI_ERR_NO_MEM;
2909   else {
2910     *(void **)baseptr = ptr;
2911     return MPI_SUCCESS;
2912   }
2913 }
2914
2915 int PMPI_Free_mem(void *baseptr){
2916   xbt_free(baseptr);
2917   return MPI_SUCCESS;
2918 }
2919
2920 int PMPI_Type_set_name(MPI_Datatype  datatype, char * name)
2921 {
2922   int retval = 0;
2923   if (datatype == MPI_DATATYPE_NULL)  {
2924     retval = MPI_ERR_TYPE;
2925   } else if (name == NULL)  {
2926     retval = MPI_ERR_ARG;
2927   } else {
2928     smpi_datatype_set_name(datatype, name);
2929     retval = MPI_SUCCESS;
2930   }
2931   return retval;
2932 }
2933
2934 int PMPI_Type_get_name(MPI_Datatype  datatype, char * name, int* len)
2935 {
2936   int retval = 0;
2937
2938   if (datatype == MPI_DATATYPE_NULL)  {
2939     retval = MPI_ERR_TYPE;
2940   } else if (name == NULL)  {
2941     retval = MPI_ERR_ARG;
2942   } else {
2943     smpi_datatype_get_name(datatype, name, len);
2944     retval = MPI_SUCCESS;
2945   }
2946   return retval;
2947 }
2948
2949 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
2950   return smpi_type_f2c(datatype);
2951 }
2952
2953 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
2954   return smpi_type_c2f( datatype);
2955 }
2956
2957 MPI_Group PMPI_Group_f2c(MPI_Fint group){
2958   return smpi_group_f2c( group);
2959 }
2960
2961 MPI_Fint PMPI_Group_c2f(MPI_Group group){
2962   return smpi_group_c2f(group);
2963 }
2964
2965 MPI_Request PMPI_Request_f2c(MPI_Fint request){
2966   return smpi_request_f2c(request);
2967 }
2968
2969 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
2970   return smpi_request_c2f(request);
2971 }
2972
2973 MPI_Win PMPI_Win_f2c(MPI_Fint win){
2974   return smpi_win_f2c(win);
2975 }
2976
2977 MPI_Fint PMPI_Win_c2f(MPI_Win win){
2978   return smpi_win_c2f(win);
2979 }
2980
2981 MPI_Op PMPI_Op_f2c(MPI_Fint op){
2982   return smpi_op_f2c(op);
2983 }
2984
2985 MPI_Fint PMPI_Op_c2f(MPI_Op op){
2986   return smpi_op_c2f(op);
2987 }
2988
2989 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
2990   return smpi_comm_f2c(comm);
2991 }
2992
2993 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
2994   return smpi_comm_c2f(comm);
2995 }
2996
2997 MPI_Info PMPI_Info_f2c(MPI_Fint info){
2998   return smpi_info_f2c(info);
2999 }
3000
3001 MPI_Fint PMPI_Info_c2f(MPI_Info info){
3002   return smpi_info_c2f(info);
3003 }
3004
3005 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3006   return smpi_comm_keyval_create(copy_fn, delete_fn, keyval, extra_state);
3007 }
3008
3009 int PMPI_Keyval_free(int* keyval) {
3010   return smpi_comm_keyval_free(keyval);
3011 }
3012
3013 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3014   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3015        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3016     return MPI_ERR_ARG;
3017   else if (comm==MPI_COMM_NULL)
3018     return MPI_ERR_COMM;
3019   else
3020     return smpi_comm_attr_delete(comm, keyval);
3021 }
3022
3023 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3024   static int one = 1;
3025   static int zero = 0;
3026   static int tag_ub = 1000000;
3027   static int last_used_code = MPI_ERR_LASTCODE;
3028
3029   if (comm==MPI_COMM_NULL){
3030     *flag = 0;
3031     return MPI_ERR_COMM;
3032   }
3033
3034   switch (keyval) {
3035   case MPI_HOST:
3036   case MPI_IO:
3037   case MPI_APPNUM:
3038     *flag = 1;
3039     *(int**)attr_value = &zero;
3040     return MPI_SUCCESS;
3041   case MPI_UNIVERSE_SIZE:
3042     *flag = 1;
3043     *(int**)attr_value = &smpi_universe_size;
3044     return MPI_SUCCESS;
3045   case MPI_LASTUSEDCODE:
3046     *flag = 1;
3047     *(int**)attr_value = &last_used_code;
3048     return MPI_SUCCESS;
3049   case MPI_TAG_UB:
3050     *flag=1;
3051     *(int**)attr_value = &tag_ub;
3052     return MPI_SUCCESS;
3053   case MPI_WTIME_IS_GLOBAL:
3054     *flag = 1;
3055     *(int**)attr_value = &one;
3056     return MPI_SUCCESS;
3057   default:
3058     return smpi_comm_attr_get(comm, keyval, attr_value, flag);
3059   }
3060 }
3061
3062 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3063   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3064        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3065     return MPI_ERR_ARG;
3066   else if (comm==MPI_COMM_NULL)
3067     return MPI_ERR_COMM;
3068   else
3069   return smpi_comm_attr_put(comm, keyval, attr_value);
3070 }
3071
3072 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3073 {
3074   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3075 }
3076
3077 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3078 {
3079   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3080 }
3081
3082 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3083 {
3084   return PMPI_Attr_delete(comm, comm_keyval);
3085 }
3086
3087 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
3088                             void* extra_state)
3089 {
3090   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3091 }
3092
3093 int PMPI_Comm_free_keyval(int* keyval) {
3094   return PMPI_Keyval_free(keyval);
3095 }
3096
3097 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3098 {
3099   if (type==MPI_DATATYPE_NULL)
3100     return MPI_ERR_TYPE;
3101   else
3102     return smpi_type_attr_get(type, type_keyval, attribute_val, flag);
3103 }
3104
3105 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3106 {
3107   if (type==MPI_DATATYPE_NULL)
3108     return MPI_ERR_TYPE;
3109   else
3110     return smpi_type_attr_put(type, type_keyval, attribute_val);
3111 }
3112
3113 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3114 {
3115   if (type==MPI_DATATYPE_NULL)
3116     return MPI_ERR_TYPE;
3117   else
3118     return smpi_type_attr_delete(type, type_keyval);
3119 }
3120
3121 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
3122                             void* extra_state)
3123 {
3124   return smpi_type_keyval_create(copy_fn, delete_fn, keyval, extra_state);
3125 }
3126
3127 int PMPI_Type_free_keyval(int* keyval) {
3128   return smpi_type_keyval_free(keyval);
3129 }
3130
3131 int PMPI_Info_create( MPI_Info *info){
3132   if (info == NULL)
3133     return MPI_ERR_ARG;
3134   *info = xbt_new(s_smpi_mpi_info_t, 1);
3135   (*info)->info_dict= xbt_dict_new_homogeneous(NULL);
3136   (*info)->refcount=1;
3137   return MPI_SUCCESS;
3138 }
3139
3140 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3141   if (info == NULL || key == NULL || value == NULL)
3142     return MPI_ERR_ARG;
3143
3144   xbt_dict_set(info->info_dict, key, (void*)value, NULL);
3145   return MPI_SUCCESS;
3146 }
3147
3148 int PMPI_Info_free( MPI_Info *info){
3149   if (info == NULL || *info==NULL)
3150     return MPI_ERR_ARG;
3151   (*info)->refcount--;
3152   if((*info)->refcount==0){
3153     xbt_dict_free(&((*info)->info_dict));
3154     xbt_free(*info);
3155   }
3156   *info=MPI_INFO_NULL;
3157   return MPI_SUCCESS;
3158 }
3159
3160 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3161   *flag=false;
3162   if (info == NULL || key == NULL || valuelen <0)
3163     return MPI_ERR_ARG;
3164   if (value == NULL)
3165     return MPI_ERR_INFO_VALUE;
3166   char* tmpvalue=(char*)xbt_dict_get_or_null(info->info_dict, key);
3167   if(tmpvalue){
3168     memcpy(value,tmpvalue, (strlen(tmpvalue) + 1 < static_cast<size_t>(valuelen)) ? strlen(tmpvalue) + 1 : valuelen);
3169     *flag=true;
3170   }
3171   return MPI_SUCCESS;
3172 }
3173
3174 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3175   if (info == NULL || newinfo==NULL)
3176     return MPI_ERR_ARG;
3177   *newinfo = xbt_new(s_smpi_mpi_info_t, 1);
3178   (*newinfo)->info_dict= xbt_dict_new_homogeneous(NULL);
3179   xbt_dict_cursor_t cursor = NULL;
3180   int *key;
3181   void* data;
3182   xbt_dict_foreach(info->info_dict,cursor,key,data){
3183     xbt_dict_set((*newinfo)->info_dict, (char*)key, data, NULL);
3184   }
3185   return MPI_SUCCESS;
3186 }
3187
3188 int PMPI_Info_delete(MPI_Info info, char *key){
3189   xbt_ex_t e;
3190   if (info == NULL || key==NULL)
3191     return MPI_ERR_ARG;
3192   TRY {
3193     xbt_dict_remove(info->info_dict, key);
3194   }CATCH(e){
3195     xbt_ex_free(e);
3196     return MPI_ERR_INFO_NOKEY;
3197   }
3198   return MPI_SUCCESS;
3199 }
3200
3201 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3202   if (info == NULL || nkeys==NULL)
3203     return MPI_ERR_ARG;
3204   *nkeys=xbt_dict_size(info->info_dict);
3205   return MPI_SUCCESS;
3206 }
3207
3208 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3209   if (info == NULL || key==NULL || n<0 || n> MPI_MAX_INFO_KEY)
3210     return MPI_ERR_ARG;
3211
3212   xbt_dict_cursor_t cursor = NULL;
3213   char *keyn;
3214   void* data;
3215   int num=0;
3216   xbt_dict_foreach(info->info_dict,cursor,keyn,data){
3217     if(num==n){
3218      strcpy(key,keyn);
3219       return MPI_SUCCESS;
3220     }
3221     num++;
3222   }
3223   return MPI_ERR_ARG;
3224 }
3225
3226 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3227   *flag=false;
3228   if (info == NULL || key == NULL || valuelen==NULL)
3229     return MPI_ERR_ARG;
3230   char* tmpvalue=(char*)xbt_dict_get_or_null(info->info_dict, key);
3231   if(tmpvalue){
3232     *valuelen=strlen(tmpvalue);
3233     *flag=true;
3234   }
3235   return MPI_SUCCESS;
3236 }
3237
3238 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3239   if(incount<0 || outcount < 0 || inbuf==NULL || outbuf==NULL)
3240     return MPI_ERR_ARG;
3241   if(!is_datatype_valid(type))
3242     return MPI_ERR_TYPE;
3243   if(comm==MPI_COMM_NULL)
3244     return MPI_ERR_COMM;
3245   return smpi_mpi_unpack(inbuf, incount, position, outbuf,outcount,type, comm);
3246 }
3247
3248 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3249   if(incount<0 || outcount < 0|| inbuf==NULL || outbuf==NULL)
3250     return MPI_ERR_ARG;
3251   if(!is_datatype_valid(type))
3252     return MPI_ERR_TYPE;
3253   if(comm==MPI_COMM_NULL)
3254     return MPI_ERR_COMM;
3255   return smpi_mpi_pack(inbuf, incount, type, outbuf,outcount,position, comm);
3256 }
3257
3258 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3259   if(incount<0)
3260     return MPI_ERR_ARG;
3261   if(!is_datatype_valid(datatype))
3262     return MPI_ERR_TYPE;
3263   if(comm==MPI_COMM_NULL)
3264     return MPI_ERR_COMM;
3265
3266   *size=incount*smpi_datatype_size(datatype);
3267
3268   return MPI_SUCCESS;
3269 }
3270