Logo AND Algorithmique Numérique Distribuée

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