Logo AND Algorithmique Numérique Distribuée

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