Logo AND Algorithmique Numérique Distribuée

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