Logo AND Algorithmique Numérique Distribuée

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