Logo AND Algorithmique Numérique Distribuée

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