Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Make functions public, they are need by macros SMPI_SAMPLE_{DELAY,FLOPS}.
[simgrid.git] / src / smpi / smpi_pmpi.c
1 /* Copyright (c) 2007-2013. 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)src_traced = smpi_group_index(smpi_comm_group(comm), status->MPI_SOURCE);
1234   TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
1235   TRACE_smpi_recv(rank, src_traced, rank);
1236 #endif
1237   }
1238
1239   smpi_bench_begin();
1240   return retval;
1241 }
1242
1243 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag,
1244              MPI_Comm comm)
1245 {
1246   int retval = 0;
1247
1248   smpi_bench_end();
1249
1250   if (comm == MPI_COMM_NULL) {
1251     retval = MPI_ERR_COMM;
1252   } else if (dst == MPI_PROC_NULL) {
1253     retval = MPI_SUCCESS;
1254   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1255     retval = MPI_ERR_RANK;
1256   } else if (count < 0) {
1257     retval = MPI_ERR_COUNT;
1258   } else if (buf==NULL && count > 0) {
1259     retval = MPI_ERR_COUNT;
1260   } else if (datatype == MPI_DATATYPE_NULL){
1261     retval = MPI_ERR_TYPE;
1262   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1263     retval = MPI_ERR_TAG;
1264   } else {
1265
1266 #ifdef HAVE_TRACING
1267   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1268   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1269   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1270   extra->type = TRACING_SEND;
1271   extra->send_size = count;
1272   extra->src = rank;
1273   extra->dst = dst_traced;
1274   extra->datatype1 = encode_datatype(datatype);
1275   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1276   TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1277 #endif
1278
1279     smpi_mpi_send(buf, count, datatype, dst, tag, comm);
1280     retval = MPI_SUCCESS;
1281
1282 #ifdef HAVE_TRACING
1283   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1284 #endif
1285   }
1286
1287   smpi_bench_begin();
1288   return retval;
1289 }
1290
1291
1292
1293 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
1294   int retval = 0;
1295
1296    smpi_bench_end();
1297
1298    if (comm == MPI_COMM_NULL) {
1299      retval = MPI_ERR_COMM;
1300    } else if (dst == MPI_PROC_NULL) {
1301      retval = MPI_SUCCESS;
1302    } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1303      retval = MPI_ERR_RANK;
1304    } else if (count < 0) {
1305      retval = MPI_ERR_COUNT;
1306    } else if (buf==NULL && count > 0) {
1307      retval = MPI_ERR_COUNT;
1308    } else if (datatype == MPI_DATATYPE_NULL){
1309      retval = MPI_ERR_TYPE;
1310    } else if(tag<0 && tag !=  MPI_ANY_TAG){
1311      retval = MPI_ERR_TAG;
1312    } else {
1313
1314  #ifdef HAVE_TRACING
1315    int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1316    int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1317    instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1318    extra->type = TRACING_SSEND;
1319    extra->send_size = count;
1320    extra->src = rank;
1321    extra->dst = dst_traced;
1322    extra->datatype1 = encode_datatype(datatype);
1323    TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);   TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1324  #endif
1325
1326      smpi_mpi_ssend(buf, count, datatype, dst, tag, comm);
1327      retval = MPI_SUCCESS;
1328
1329  #ifdef HAVE_TRACING
1330    TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1331  #endif
1332    }
1333
1334    smpi_bench_begin();
1335    return retval;}
1336
1337
1338 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1339                  int dst, int sendtag, void *recvbuf, int recvcount,
1340                  MPI_Datatype recvtype, int src, int recvtag,
1341                  MPI_Comm comm, MPI_Status * status)
1342 {
1343   int retval = 0;
1344
1345   smpi_bench_end();
1346
1347   if (comm == MPI_COMM_NULL) {
1348     retval = MPI_ERR_COMM;
1349   } else if (sendtype == MPI_DATATYPE_NULL
1350              || recvtype == MPI_DATATYPE_NULL) {
1351     retval = MPI_ERR_TYPE;
1352   } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1353       smpi_empty_status(status);
1354       status->MPI_SOURCE = MPI_PROC_NULL;
1355       retval = MPI_SUCCESS;
1356   }else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0 ||
1357       (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0))){
1358     retval = MPI_ERR_RANK;
1359   } else if (sendcount < 0 || recvcount<0) {
1360       retval = MPI_ERR_COUNT;
1361   } else if ((sendbuf==NULL && sendcount > 0)||(recvbuf==NULL && recvcount>0)) {
1362     retval = MPI_ERR_COUNT;
1363   } else if((sendtag<0 && sendtag !=  MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1364     retval = MPI_ERR_TAG;
1365   } else {
1366
1367 #ifdef HAVE_TRACING
1368   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1369   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1370   int src_traced = smpi_group_index(smpi_comm_group(comm), src);
1371   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1372   extra->type = TRACING_SENDRECV;
1373   extra->send_size = sendcount;
1374   extra->recv_size = recvcount;
1375   extra->src = src_traced;
1376   extra->dst = dst_traced;
1377   extra->datatype1 = encode_datatype(sendtype);
1378   extra->datatype2 = encode_datatype(recvtype);
1379
1380   TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1381   TRACE_smpi_send(rank, rank, dst_traced,sendcount*smpi_datatype_size(sendtype));
1382 #endif
1383
1384
1385     smpi_mpi_sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf,
1386                       recvcount, recvtype, src, recvtag, comm, status);
1387     retval = MPI_SUCCESS;
1388
1389 #ifdef HAVE_TRACING
1390   TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1391   TRACE_smpi_recv(rank, src_traced, rank);
1392 #endif
1393
1394   }
1395
1396   smpi_bench_begin();
1397   return retval;
1398 }
1399
1400 int PMPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,
1401                          int dst, int sendtag, int src, int recvtag,
1402                          MPI_Comm comm, MPI_Status * status)
1403 {
1404   //TODO: suboptimal implementation
1405   void *recvbuf;
1406   int retval = 0;
1407   if (datatype == MPI_DATATYPE_NULL) {
1408       retval = MPI_ERR_TYPE;
1409   } else if (count < 0) {
1410       retval = MPI_ERR_COUNT;
1411   } else {
1412     int size = smpi_datatype_get_extent(datatype) * count;
1413     recvbuf = xbt_new0(char, size);
1414     retval =
1415         MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count,
1416                      datatype, src, recvtag, comm, status);
1417     if(retval==MPI_SUCCESS){
1418         smpi_datatype_copy(recvbuf, count, datatype, buf, count, datatype);
1419     }
1420     xbt_free(recvbuf);
1421
1422   }
1423   return retval;
1424 }
1425
1426 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1427 {
1428   int retval = 0;
1429
1430   smpi_bench_end();
1431   if (request == NULL || flag == NULL) {
1432     retval = MPI_ERR_ARG;
1433   } else if (*request == MPI_REQUEST_NULL) {
1434     *flag= TRUE;
1435     smpi_empty_status(status);
1436     retval = MPI_ERR_REQUEST;
1437   } else {
1438     *flag = smpi_mpi_test(request, status);
1439     retval = MPI_SUCCESS;
1440   }
1441   smpi_bench_begin();
1442   return retval;
1443 }
1444
1445 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag,
1446                 MPI_Status * status)
1447 {
1448   int retval = 0;
1449
1450   smpi_bench_end();
1451   if (index == NULL || flag == NULL) {
1452     retval = MPI_ERR_ARG;
1453   } else {
1454     *flag = smpi_mpi_testany(count, requests, index, status);
1455     retval = MPI_SUCCESS;
1456   }
1457   smpi_bench_begin();
1458   return retval;
1459 }
1460
1461 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1462 {
1463   int retval = 0;
1464
1465   smpi_bench_end();
1466   if (flag == NULL) {
1467     retval = MPI_ERR_ARG;
1468   } else {
1469     *flag = smpi_mpi_testall(count, requests, statuses);
1470     retval = MPI_SUCCESS;
1471   }
1472   smpi_bench_begin();
1473   return retval;
1474 }
1475
1476 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1477   int retval = 0;
1478   smpi_bench_end();
1479
1480   if (status == NULL) {
1481     retval = MPI_ERR_ARG;
1482   } else if (comm == MPI_COMM_NULL) {
1483     retval = MPI_ERR_COMM;
1484   } else if (source == MPI_PROC_NULL) {
1485     smpi_empty_status(status);
1486     status->MPI_SOURCE = MPI_PROC_NULL;
1487     retval = MPI_SUCCESS;
1488   } else {
1489     smpi_mpi_probe(source, tag, comm, status);
1490     retval = MPI_SUCCESS;
1491   }
1492   smpi_bench_begin();
1493   return retval;
1494 }
1495
1496
1497 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1498   int retval = 0;
1499   smpi_bench_end();
1500
1501   if (flag == NULL) {
1502     retval = MPI_ERR_ARG;
1503   } else if (status == NULL) {
1504     retval = MPI_ERR_ARG;
1505   } else if (comm == MPI_COMM_NULL) {
1506     retval = MPI_ERR_COMM;
1507   } else if (source == MPI_PROC_NULL) {
1508     *flag=TRUE;
1509     smpi_empty_status(status);
1510     status->MPI_SOURCE = MPI_PROC_NULL;
1511     retval = MPI_SUCCESS;
1512   } else {
1513     smpi_mpi_iprobe(source, tag, comm, flag, status);
1514     retval = MPI_SUCCESS;
1515   }
1516   smpi_bench_begin();
1517   return retval;
1518 }
1519
1520 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1521 {
1522   int retval = 0;
1523
1524   smpi_bench_end();
1525
1526   smpi_empty_status(status);
1527
1528   if (request == NULL) {
1529     retval = MPI_ERR_ARG;
1530   } else if (*request == MPI_REQUEST_NULL) {
1531     retval = MPI_ERR_REQUEST;
1532   } else {
1533
1534 #ifdef HAVE_TRACING
1535     int rank = request && (*request)->comm != MPI_COMM_NULL
1536       ? smpi_process_index()
1537       : -1;
1538
1539     int src_traced = (*request)->src;
1540     int dst_traced = (*request)->dst;
1541     MPI_Comm comm = (*request)->comm;
1542     int is_wait_for_receive = (*request)->recv;
1543     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1544     extra->type = TRACING_WAIT;
1545     TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1546 #endif
1547
1548     smpi_mpi_wait(request, status);
1549     retval = MPI_SUCCESS;
1550
1551 #ifdef HAVE_TRACING
1552     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1553     TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1554     if (is_wait_for_receive) {
1555       if(src_traced==MPI_ANY_SOURCE)
1556         src_traced = (status!=MPI_STATUS_IGNORE) ?
1557           smpi_group_rank(smpi_comm_group(comm), status->MPI_SOURCE) :
1558           src_traced;
1559       TRACE_smpi_recv(rank, src_traced, dst_traced);
1560     }
1561 #endif
1562
1563   }
1564
1565   smpi_bench_begin();
1566   return retval;
1567 }
1568
1569 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1570 {
1571   if (index == NULL)
1572     return MPI_ERR_ARG;
1573
1574   smpi_bench_end();
1575 #ifdef HAVE_TRACING
1576   //save requests information for tracing
1577   int i;
1578   int *srcs = xbt_new0(int, count);
1579   int *dsts = xbt_new0(int, count);
1580   int *recvs = xbt_new0(int, count);
1581   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1582
1583   for (i = 0; i < count; i++) {
1584     MPI_Request req = requests[i];      //already received requests are no longer valid
1585     if (req) {
1586       srcs[i] = req->src;
1587       dsts[i] = req->dst;
1588       recvs[i] = req->recv;
1589       comms[i] = req->comm;
1590     }
1591   }
1592   int rank_traced = smpi_process_index();
1593   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1594   extra->type = TRACING_WAITANY;
1595   extra->send_size=count;
1596   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1597
1598 #endif
1599   *index = smpi_mpi_waitany(count, requests, status);
1600 #ifdef HAVE_TRACING
1601   if(*index!=MPI_UNDEFINED){
1602     int src_traced = srcs[*index];
1603     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1604     int dst_traced = dsts[*index];
1605     int is_wait_for_receive = recvs[*index];
1606     if (is_wait_for_receive) {
1607       if(srcs[*index]==MPI_ANY_SOURCE)
1608         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1609                       smpi_group_rank(smpi_comm_group(comms[*index]), status->MPI_SOURCE) :
1610                       srcs[*index];
1611       TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1612     }
1613     TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1614     xbt_free(srcs);
1615     xbt_free(dsts);
1616     xbt_free(recvs);
1617     xbt_free(comms);
1618
1619   }
1620 #endif
1621   smpi_bench_begin();
1622   return MPI_SUCCESS;
1623 }
1624
1625 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1626 {
1627
1628   smpi_bench_end();
1629 #ifdef HAVE_TRACING
1630   //save information from requests
1631   int i;
1632   int *srcs = xbt_new0(int, count);
1633   int *dsts = xbt_new0(int, count);
1634   int *recvs = xbt_new0(int, count);
1635   int *valid = xbt_new0(int, count);
1636   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1637
1638   //int valid_count = 0;
1639   for (i = 0; i < count; i++) {
1640     MPI_Request req = requests[i];
1641     if(req!=MPI_REQUEST_NULL){
1642       srcs[i] = req->src;
1643       dsts[i] = req->dst;
1644       recvs[i] = req->recv;
1645       comms[i] = req->comm;
1646       valid[i]=1;;
1647     }else{
1648       valid[i]=0;
1649     }
1650   }
1651   int rank_traced = smpi_process_index();
1652   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1653   extra->type = TRACING_WAITALL;
1654   extra->send_size=count;
1655   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1656 #endif
1657   int retval = smpi_mpi_waitall(count, requests, status);
1658 #ifdef HAVE_TRACING
1659   for (i = 0; i < count; i++) {
1660     if(valid[i]){
1661     //int src_traced = srcs[*index];
1662     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1663       int src_traced = srcs[i];
1664       int dst_traced = dsts[i];
1665       int is_wait_for_receive = recvs[i];
1666       if (is_wait_for_receive) {
1667         if(src_traced==MPI_ANY_SOURCE)
1668         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1669                           smpi_group_rank(smpi_comm_group(comms[i]), status[i].MPI_SOURCE) :
1670                           srcs[i];
1671         TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1672       }
1673     }
1674   }
1675   TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1676   xbt_free(srcs);
1677   xbt_free(dsts);
1678   xbt_free(recvs);
1679   xbt_free(valid);
1680   xbt_free(comms);
1681
1682 #endif
1683   smpi_bench_begin();
1684   return retval;
1685 }
1686
1687 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount,
1688                  int *indices, MPI_Status status[])
1689 {
1690   int retval = 0;
1691
1692   smpi_bench_end();
1693   if (outcount == NULL) {
1694     retval = MPI_ERR_ARG;
1695   } else {
1696     *outcount = smpi_mpi_waitsome(incount, requests, indices, status);
1697     retval = MPI_SUCCESS;
1698   }
1699   smpi_bench_begin();
1700   return retval;
1701 }
1702
1703 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount,
1704                  int* indices, MPI_Status status[])
1705 {
1706   int retval = 0;
1707
1708    smpi_bench_end();
1709    if (outcount == NULL) {
1710      retval = MPI_ERR_ARG;
1711    } else {
1712      *outcount = smpi_mpi_testsome(incount, requests, indices, status);
1713      retval = MPI_SUCCESS;
1714    }
1715    smpi_bench_begin();
1716    return retval;
1717 }
1718
1719
1720 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1721 {
1722   int retval = 0;
1723
1724   smpi_bench_end();
1725
1726   if (comm == MPI_COMM_NULL) {
1727     retval = MPI_ERR_COMM;
1728   } else {
1729 #ifdef HAVE_TRACING
1730   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1731   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1732
1733   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1734   extra->type = TRACING_BCAST;
1735   extra->send_size = count;
1736   extra->root = root_traced;
1737   extra->datatype1 = encode_datatype(datatype);
1738   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1739
1740 #endif
1741     mpi_coll_bcast_fun(buf, count, datatype, root, comm);
1742     retval = MPI_SUCCESS;
1743 #ifdef HAVE_TRACING
1744   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1745 #endif
1746   }
1747
1748   smpi_bench_begin();
1749   return retval;
1750 }
1751
1752 int PMPI_Barrier(MPI_Comm comm)
1753 {
1754   int retval = 0;
1755
1756   smpi_bench_end();
1757
1758   if (comm == MPI_COMM_NULL) {
1759     retval = MPI_ERR_COMM;
1760   } else {
1761 #ifdef HAVE_TRACING
1762   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1763   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1764   extra->type = TRACING_BARRIER;
1765   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1766 #endif
1767     mpi_coll_barrier_fun(comm);
1768     retval = MPI_SUCCESS;
1769 #ifdef HAVE_TRACING
1770   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1771 #endif
1772   }
1773
1774   smpi_bench_begin();
1775   return retval;
1776 }
1777
1778 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1779                void *recvbuf, int recvcount, MPI_Datatype recvtype,
1780                int root, MPI_Comm comm)
1781 {
1782   int retval = 0;
1783
1784   smpi_bench_end();
1785
1786   if (comm == MPI_COMM_NULL) {
1787     retval = MPI_ERR_COMM;
1788   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1789             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1790     retval = MPI_ERR_TYPE;
1791   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1792             ((smpi_comm_rank(comm) == root) && (recvcount <0))){
1793     retval = MPI_ERR_COUNT;
1794   } else {
1795
1796     char* sendtmpbuf = (char*) sendbuf;
1797     int sendtmpcount = sendcount;
1798     MPI_Datatype sendtmptype = sendtype;
1799     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1800       sendtmpcount=0;
1801       sendtmptype=recvtype;
1802     }
1803 #ifdef HAVE_TRACING
1804   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1805   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1806   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1807   extra->type = TRACING_GATHER;
1808   extra->send_size = sendtmpcount;
1809   extra->recv_size = recvcount;
1810   extra->root = root_traced;
1811   extra->datatype1 = encode_datatype(sendtmptype);
1812   extra->datatype2 = encode_datatype(recvtype);
1813
1814   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1815 #endif
1816     mpi_coll_gather_fun(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount,
1817                     recvtype, root, comm);
1818
1819
1820     retval = MPI_SUCCESS;
1821 #ifdef HAVE_TRACING
1822   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1823 #endif
1824   }
1825
1826   smpi_bench_begin();
1827   return retval;
1828 }
1829
1830 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1831                 void *recvbuf, int *recvcounts, int *displs,
1832                 MPI_Datatype recvtype, int root, MPI_Comm comm)
1833 {
1834   int retval = 0;
1835
1836   smpi_bench_end();
1837
1838   if (comm == MPI_COMM_NULL) {
1839     retval = MPI_ERR_COMM;
1840   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1841             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1842     retval = MPI_ERR_TYPE;
1843   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1844     retval = MPI_ERR_COUNT;
1845   } else if (recvcounts == NULL || displs == NULL) {
1846     retval = MPI_ERR_ARG;
1847   } else {
1848     char* sendtmpbuf = (char*) sendbuf;
1849     int sendtmpcount = sendcount;
1850     MPI_Datatype sendtmptype = sendtype;
1851     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1852       sendtmpcount=0;
1853       sendtmptype=recvtype;
1854     }
1855
1856 #ifdef HAVE_TRACING
1857   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1858   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1859   int i=0;
1860   int size = smpi_comm_size(comm);
1861   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1862   extra->type = TRACING_GATHERV;
1863   extra->send_size = sendtmpcount;
1864   extra->recvcounts= xbt_malloc(size*sizeof(int));
1865   for(i=0; i< size; i++)//copy data to avoid bad free
1866     extra->recvcounts[i] = recvcounts[i];
1867   extra->num_processes = size;
1868   extra->root = root_traced;
1869   extra->datatype1 = encode_datatype(sendtmptype);
1870   extra->datatype2 = encode_datatype(recvtype);
1871
1872   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1873 #endif
1874     smpi_mpi_gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts,
1875                      displs, recvtype, root, comm);
1876     retval = MPI_SUCCESS;
1877 #ifdef HAVE_TRACING
1878   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1879 #endif
1880   }
1881
1882   smpi_bench_begin();
1883   return retval;
1884 }
1885
1886 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1887                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
1888                   MPI_Comm comm)
1889 {
1890   int retval = 0;
1891
1892   smpi_bench_end();
1893
1894   if (comm == MPI_COMM_NULL) {
1895     retval = MPI_ERR_COMM;
1896   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1897             (recvtype == MPI_DATATYPE_NULL)){
1898     retval = MPI_ERR_TYPE;
1899   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1900             (recvcount <0)){
1901     retval = MPI_ERR_COUNT;
1902   } else {
1903     if(sendbuf == MPI_IN_PLACE) {
1904       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*recvcount*smpi_comm_rank(comm);
1905       sendcount=recvcount;
1906       sendtype=recvtype;
1907     }
1908 #ifdef HAVE_TRACING
1909   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1910   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1911   extra->type = TRACING_ALLGATHER;
1912   extra->send_size = sendcount;
1913   extra->recv_size = recvcount;
1914   extra->datatype1 = encode_datatype(sendtype);
1915   extra->datatype2 = encode_datatype(recvtype);
1916
1917   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1918 #endif
1919     mpi_coll_allgather_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1920                            recvtype, comm);
1921     retval = MPI_SUCCESS;
1922
1923 #ifdef HAVE_TRACING
1924   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1925 #endif
1926   }
1927   smpi_bench_begin();
1928   return retval;
1929 }
1930
1931 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1932                    void *recvbuf, int *recvcounts, int *displs,
1933                    MPI_Datatype recvtype, MPI_Comm comm)
1934 {
1935   int retval = 0;
1936
1937   smpi_bench_end();
1938
1939   if (comm == MPI_COMM_NULL) {
1940     retval = MPI_ERR_COMM;
1941   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1942             (recvtype == MPI_DATATYPE_NULL)){
1943     retval = MPI_ERR_TYPE;
1944   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1945     retval = MPI_ERR_COUNT;
1946   } else if (recvcounts == NULL || displs == NULL) {
1947     retval = MPI_ERR_ARG;
1948   } else {
1949
1950     if(sendbuf == MPI_IN_PLACE) {
1951       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*displs[smpi_comm_rank(comm)];
1952       sendcount=recvcounts[smpi_comm_rank(comm)];
1953       sendtype=recvtype;
1954     }
1955 #ifdef HAVE_TRACING
1956   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1957   int i=0;
1958   int size = smpi_comm_size(comm);
1959   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1960   extra->type = TRACING_ALLGATHERV;
1961   extra->send_size = sendcount;
1962   extra->recvcounts= xbt_malloc(size*sizeof(int));
1963   for(i=0; i< size; i++)//copy data to avoid bad free
1964     extra->recvcounts[i] = recvcounts[i];
1965   extra->num_processes = size;
1966   extra->datatype1 = encode_datatype(sendtype);
1967   extra->datatype2 = encode_datatype(recvtype);
1968
1969   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
1970 #endif
1971     mpi_coll_allgatherv_fun(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
1972                         displs, recvtype, comm);
1973     retval = MPI_SUCCESS;
1974 #ifdef HAVE_TRACING
1975   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1976 #endif
1977   }
1978
1979   smpi_bench_begin();
1980   return retval;
1981 }
1982
1983 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1984                 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1985                 int root, MPI_Comm comm)
1986 {
1987   int retval = 0;
1988
1989   smpi_bench_end();
1990
1991   if (comm == MPI_COMM_NULL) {
1992     retval = MPI_ERR_COMM;
1993   } else if (((smpi_comm_rank(comm)==root) && (sendtype == MPI_DATATYPE_NULL))
1994              || ((recvbuf !=MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1995     retval = MPI_ERR_TYPE;
1996   } else {
1997
1998     if (recvbuf == MPI_IN_PLACE) {
1999         recvtype=sendtype;
2000         recvcount=sendcount;
2001     }
2002 #ifdef HAVE_TRACING
2003   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2004   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2005   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2006   extra->type = TRACING_SCATTER;
2007   extra->send_size = sendcount;
2008   extra->recv_size= recvcount;
2009   extra->root = root_traced;
2010   extra->datatype1 = encode_datatype(sendtype);
2011   extra->datatype2 = encode_datatype(recvtype);
2012
2013   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2014 #endif
2015     mpi_coll_scatter_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
2016                      recvtype, root, comm);
2017     retval = MPI_SUCCESS;
2018 #ifdef HAVE_TRACING
2019   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2020 #endif
2021   }
2022
2023   smpi_bench_begin();
2024   return retval;
2025 }
2026
2027 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
2028                  MPI_Datatype sendtype, void *recvbuf, int recvcount,
2029                  MPI_Datatype recvtype, int root, MPI_Comm comm)
2030 {
2031   int retval = 0;
2032
2033   smpi_bench_end();
2034
2035   if (comm == MPI_COMM_NULL) {
2036     retval = MPI_ERR_COMM;
2037   } else if (sendcounts == NULL || displs == NULL) {
2038     retval = MPI_ERR_ARG;
2039   } else if (((smpi_comm_rank(comm)==root) && (sendtype == MPI_DATATYPE_NULL))
2040              || ((recvbuf !=MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
2041     retval = MPI_ERR_TYPE;
2042   } else {
2043     if (recvbuf == MPI_IN_PLACE) {
2044         recvtype=sendtype;
2045         recvcount=sendcounts[smpi_comm_rank(comm)];
2046     }
2047 #ifdef HAVE_TRACING
2048   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2049   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2050   int i=0;
2051   int size = smpi_comm_size(comm);
2052   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2053   extra->type = TRACING_SCATTERV;
2054   extra->recv_size = recvcount;
2055   extra->sendcounts= xbt_malloc(size*sizeof(int));
2056   for(i=0; i< size; i++)//copy data to avoid bad free
2057     extra->sendcounts[i] = sendcounts[i];
2058   extra->num_processes = size;
2059   extra->root = root_traced;
2060   extra->datatype1 = encode_datatype(sendtype);
2061   extra->datatype2 = encode_datatype(recvtype);
2062
2063   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2064
2065 #endif
2066     smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf,
2067                       recvcount, recvtype, root, comm);
2068     retval = MPI_SUCCESS;
2069 #ifdef HAVE_TRACING
2070   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2071 #endif
2072   }
2073
2074   smpi_bench_begin();
2075   return retval;
2076 }
2077
2078 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
2079                MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
2080 {
2081   int retval = 0;
2082
2083   smpi_bench_end();
2084
2085   if (comm == MPI_COMM_NULL) {
2086     retval = MPI_ERR_COMM;
2087   } else if (datatype == MPI_DATATYPE_NULL || op == MPI_OP_NULL) {
2088     retval = MPI_ERR_ARG;
2089   } else {
2090 #ifdef HAVE_TRACING
2091   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2092   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2093   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2094   extra->type = TRACING_REDUCE;
2095   extra->send_size = count;
2096   extra->datatype1 = encode_datatype(datatype);
2097   extra->root = root_traced;
2098
2099   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2100 #endif
2101     mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, root, comm);
2102
2103     retval = MPI_SUCCESS;
2104 #ifdef HAVE_TRACING
2105   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2106 #endif
2107   }
2108
2109   smpi_bench_begin();
2110   return retval;
2111 }
2112
2113 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count,
2114     MPI_Datatype datatype, MPI_Op op){
2115   int retval = 0;
2116
2117     smpi_bench_end();
2118     if (datatype == MPI_DATATYPE_NULL || op == MPI_OP_NULL) {
2119       retval = MPI_ERR_ARG;
2120     } else {
2121       smpi_op_apply(op, inbuf, inoutbuf, &count, &datatype);
2122       retval=MPI_SUCCESS;
2123     }
2124     smpi_bench_begin();
2125     return retval;
2126 }
2127
2128 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
2129                   MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2130 {
2131   int retval = 0;
2132
2133   smpi_bench_end();
2134
2135   if (comm == MPI_COMM_NULL) {
2136     retval = MPI_ERR_COMM;
2137   } else if (datatype == MPI_DATATYPE_NULL) {
2138     retval = MPI_ERR_TYPE;
2139   } else if (op == MPI_OP_NULL) {
2140     retval = MPI_ERR_OP;
2141   } else {
2142
2143     char* sendtmpbuf = (char*) sendbuf;
2144     if( sendbuf == MPI_IN_PLACE ) {
2145       sendtmpbuf = (char *)xbt_malloc(count*smpi_datatype_get_extent(datatype));
2146       smpi_datatype_copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
2147     }
2148 #ifdef HAVE_TRACING
2149   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2150   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2151   extra->type = TRACING_ALLREDUCE;
2152   extra->send_size = count;
2153   extra->datatype1 = encode_datatype(datatype);
2154
2155   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2156 #endif
2157     mpi_coll_allreduce_fun(sendtmpbuf, recvbuf, count, datatype, op, comm);
2158
2159     if( sendbuf == MPI_IN_PLACE ) {
2160       xbt_free(sendtmpbuf);
2161     }
2162
2163     retval = MPI_SUCCESS;
2164 #ifdef HAVE_TRACING
2165   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2166 #endif
2167   }
2168
2169   smpi_bench_begin();
2170   return retval;
2171 }
2172
2173 int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
2174              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2175 {
2176   int retval = 0;
2177
2178   smpi_bench_end();
2179
2180   if (comm == MPI_COMM_NULL) {
2181     retval = MPI_ERR_COMM;
2182   } else if (datatype == MPI_DATATYPE_NULL) {
2183     retval = MPI_ERR_TYPE;
2184   } else if (op == MPI_OP_NULL) {
2185     retval = MPI_ERR_OP;
2186   } else {
2187 #ifdef HAVE_TRACING
2188   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2189   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2190   extra->type = TRACING_SCAN;
2191   extra->send_size = count;
2192   extra->datatype1 = encode_datatype(datatype);
2193
2194   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2195 #endif
2196     smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
2197     retval = MPI_SUCCESS;
2198 #ifdef HAVE_TRACING
2199   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2200 #endif
2201   }
2202
2203   smpi_bench_begin();
2204   return retval;
2205 }
2206
2207 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
2208                 MPI_Op op, MPI_Comm comm){
2209   int retval = 0;
2210
2211   smpi_bench_end();
2212
2213   if (comm == MPI_COMM_NULL) {
2214     retval = MPI_ERR_COMM;
2215   } else if (datatype == MPI_DATATYPE_NULL) {
2216     retval = MPI_ERR_TYPE;
2217   } else if (op == MPI_OP_NULL) {
2218     retval = MPI_ERR_OP;
2219   } else {
2220 #ifdef HAVE_TRACING
2221   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2222   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2223   extra->type = TRACING_EXSCAN;
2224   extra->send_size = count;
2225   extra->datatype1 = encode_datatype(datatype);
2226
2227   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2228 #endif
2229     smpi_mpi_exscan(sendbuf, recvbuf, count, datatype, op, comm);
2230     retval = MPI_SUCCESS;
2231 #ifdef HAVE_TRACING
2232   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2233 #endif
2234   }
2235
2236   smpi_bench_begin();
2237   return retval;
2238 }
2239
2240 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
2241                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2242 {
2243   int retval = 0;
2244   smpi_bench_end();
2245
2246   if (comm == MPI_COMM_NULL) {
2247     retval = MPI_ERR_COMM;
2248   } else if (datatype == MPI_DATATYPE_NULL) {
2249     retval = MPI_ERR_TYPE;
2250   } else if (op == MPI_OP_NULL) {
2251     retval = MPI_ERR_OP;
2252   } else if (recvcounts == NULL) {
2253     retval = MPI_ERR_ARG;
2254   } else {
2255 #ifdef HAVE_TRACING
2256   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2257   int i=0;
2258   int size = smpi_comm_size(comm);
2259   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2260   extra->type = TRACING_REDUCE_SCATTER;
2261   extra->send_size = 0;
2262   extra->recvcounts= xbt_malloc(size*sizeof(int));
2263   for(i=0; i< size; i++)//copy data to avoid bad free
2264     extra->recvcounts[i] = recvcounts[i];
2265   extra->num_processes = size;
2266   extra->datatype1 = encode_datatype(datatype);
2267
2268   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2269 #endif
2270     void* sendtmpbuf=sendbuf;
2271     if(sendbuf==MPI_IN_PLACE){
2272       sendtmpbuf=recvbuf;
2273     }
2274
2275     mpi_coll_reduce_scatter_fun(sendtmpbuf, recvbuf, recvcounts,
2276                        datatype,  op, comm);
2277     retval = MPI_SUCCESS;
2278 #ifdef HAVE_TRACING
2279   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2280 #endif
2281   }
2282
2283   smpi_bench_begin();
2284   return retval;
2285 }
2286
2287 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
2288                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2289 {
2290   int retval,i;
2291   smpi_bench_end();
2292
2293   if (comm == MPI_COMM_NULL) {
2294     retval = MPI_ERR_COMM;
2295   } else if (datatype == MPI_DATATYPE_NULL) {
2296     retval = MPI_ERR_TYPE;
2297   } else if (op == MPI_OP_NULL) {
2298     retval = MPI_ERR_OP;
2299   } else if (recvcount < 0) {
2300     retval = MPI_ERR_ARG;
2301   } else {
2302     int count=smpi_comm_size(comm);
2303
2304 #ifdef HAVE_TRACING
2305   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2306   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2307   extra->type = TRACING_REDUCE_SCATTER;
2308   extra->send_size = 0;
2309   extra->recvcounts= xbt_malloc(count*sizeof(int));
2310   for(i=0; i< count; i++)//copy data to avoid bad free
2311     extra->recvcounts[i] = recvcount;
2312   extra->num_processes = count;
2313   extra->datatype1 = encode_datatype(datatype);
2314
2315   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2316 #endif
2317     int* recvcounts=(int*)xbt_malloc(count);
2318     for (i=0; i<count;i++)recvcounts[i]=recvcount;
2319     mpi_coll_reduce_scatter_fun(sendbuf, recvbuf, recvcounts,
2320                        datatype,  op, comm);
2321     xbt_free(recvcounts);
2322     retval = MPI_SUCCESS;
2323 #ifdef HAVE_TRACING
2324   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2325 #endif
2326   }
2327
2328   smpi_bench_begin();
2329   return retval;
2330 }
2331
2332 int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
2333                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
2334                  MPI_Comm comm)
2335 {
2336   int retval = 0;
2337
2338   smpi_bench_end();
2339
2340   if (comm == MPI_COMM_NULL) {
2341     retval = MPI_ERR_COMM;
2342   } else if (sendtype == MPI_DATATYPE_NULL
2343              || recvtype == MPI_DATATYPE_NULL) {
2344     retval = MPI_ERR_TYPE;
2345   } else {
2346 #ifdef HAVE_TRACING
2347   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2348   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2349   extra->type = TRACING_ALLTOALL;
2350   extra->send_size = sendcount;
2351   extra->recv_size = recvcount;
2352   extra->datatype1 = encode_datatype(sendtype);
2353   extra->datatype2 = encode_datatype(recvtype);
2354
2355   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2356 #endif
2357     retval = mpi_coll_alltoall_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
2358 #ifdef HAVE_TRACING
2359   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2360 #endif
2361   }
2362
2363   smpi_bench_begin();
2364   return retval;
2365 }
2366
2367 int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
2368                   MPI_Datatype sendtype, void *recvbuf, int *recvcounts,
2369                   int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2370 {
2371   int retval = 0;
2372
2373   smpi_bench_end();
2374
2375   if (comm == MPI_COMM_NULL) {
2376     retval = MPI_ERR_COMM;
2377   } else if (sendtype == MPI_DATATYPE_NULL
2378              || recvtype == MPI_DATATYPE_NULL) {
2379     retval = MPI_ERR_TYPE;
2380   } else if (sendcounts == NULL || senddisps == NULL || recvcounts == NULL
2381              || recvdisps == NULL) {
2382     retval = MPI_ERR_ARG;
2383   } else {
2384 #ifdef HAVE_TRACING
2385   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2386   int i=0;
2387   int size = smpi_comm_size(comm);
2388   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2389   extra->type = TRACING_ALLTOALLV;
2390   extra->send_size = 0;
2391   extra->recv_size = 0;
2392   extra->recvcounts= xbt_malloc(size*sizeof(int));
2393   extra->sendcounts= xbt_malloc(size*sizeof(int));
2394
2395   for(i=0; i< size; i++){//copy data to avoid bad free
2396     extra->send_size += sendcounts[i];
2397     extra->recv_size += recvcounts[i];
2398
2399     extra->sendcounts[i] = sendcounts[i];
2400     extra->recvcounts[i] = recvcounts[i];
2401   }
2402   extra->num_processes = size;
2403
2404   extra->datatype1 = encode_datatype(sendtype);
2405   extra->datatype2 = encode_datatype(recvtype);
2406
2407   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2408 #endif
2409     retval =
2410         mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps, sendtype,
2411                                   recvbuf, recvcounts, recvdisps, recvtype,
2412                                   comm);
2413 #ifdef HAVE_TRACING
2414   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2415 #endif
2416   }
2417
2418   smpi_bench_begin();
2419   return retval;
2420 }
2421
2422
2423 int PMPI_Get_processor_name(char *name, int *resultlen)
2424 {
2425   int retval = MPI_SUCCESS;
2426
2427   smpi_bench_end();
2428   strncpy(name, SIMIX_host_get_name(SIMIX_host_self()),
2429           strlen(SIMIX_host_get_name(SIMIX_host_self())) < MPI_MAX_PROCESSOR_NAME - 1 ?
2430           strlen(SIMIX_host_get_name(SIMIX_host_self())) +1 :
2431           MPI_MAX_PROCESSOR_NAME - 1 );
2432   *resultlen =
2433       strlen(name) >
2434       MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2435
2436   smpi_bench_begin();
2437   return retval;
2438 }
2439
2440 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2441 {
2442   int retval = MPI_SUCCESS;
2443   size_t size;
2444
2445   smpi_bench_end();
2446   if (status == NULL || count == NULL) {
2447     retval = MPI_ERR_ARG;
2448   } else if (datatype == MPI_DATATYPE_NULL) {
2449     retval = MPI_ERR_TYPE;
2450   } else {
2451     size = smpi_datatype_size(datatype);
2452     if (size == 0) {
2453       *count = 0;
2454     } else if (status->count % size != 0) {
2455       retval = MPI_UNDEFINED;
2456     } else {
2457       *count = smpi_mpi_get_count(status, datatype);
2458     }
2459   }
2460   smpi_bench_begin();
2461   return retval;
2462 }
2463
2464 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2465   int retval = 0;
2466
2467   smpi_bench_end();
2468   if (old_type == MPI_DATATYPE_NULL) {
2469     retval = MPI_ERR_TYPE;
2470   } else if (count<0){
2471     retval = MPI_ERR_COUNT;
2472   } else {
2473     retval = smpi_datatype_contiguous(count, old_type, new_type, 0);
2474   }
2475   smpi_bench_begin();
2476   return retval;
2477 }
2478
2479 int PMPI_Type_commit(MPI_Datatype* datatype) {
2480   int retval = 0;
2481
2482   smpi_bench_end();
2483   if (datatype == NULL || *datatype == MPI_DATATYPE_NULL) {
2484     retval = MPI_ERR_TYPE;
2485   } else {
2486     smpi_datatype_commit(datatype);
2487     retval = MPI_SUCCESS;
2488   }
2489   smpi_bench_begin();
2490   return retval;
2491 }
2492
2493
2494 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2495   int retval = 0;
2496
2497   smpi_bench_end();
2498   if (old_type == MPI_DATATYPE_NULL) {
2499     retval = MPI_ERR_TYPE;
2500   } else if (count<0 || blocklen<0){
2501     retval = MPI_ERR_COUNT;
2502   } else {
2503     retval = smpi_datatype_vector(count, blocklen, stride, old_type, new_type);
2504   }
2505   smpi_bench_begin();
2506   return retval;
2507 }
2508
2509 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2510   int retval = 0;
2511
2512   smpi_bench_end();
2513   if (old_type == MPI_DATATYPE_NULL) {
2514     retval = MPI_ERR_TYPE;
2515   } else if (count<0 || blocklen<0){
2516     retval = MPI_ERR_COUNT;
2517   } else {
2518     retval = smpi_datatype_hvector(count, blocklen, stride, old_type, new_type);
2519   }
2520   smpi_bench_begin();
2521   return retval;
2522 }
2523
2524 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2525   return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2526 }
2527
2528 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2529   int retval = 0;
2530
2531   smpi_bench_end();
2532   if (old_type == MPI_DATATYPE_NULL) {
2533     retval = MPI_ERR_TYPE;
2534   } else if (count<0){
2535     retval = MPI_ERR_COUNT;
2536   } else {
2537     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2538   }
2539   smpi_bench_begin();
2540   return retval;
2541 }
2542
2543 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2544   int retval = 0;
2545
2546   smpi_bench_end();
2547   if (old_type == MPI_DATATYPE_NULL) {
2548     retval = MPI_ERR_TYPE;
2549   } else if (count<0){
2550     retval = MPI_ERR_COUNT;
2551   } else {
2552     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2553   }
2554   smpi_bench_begin();
2555   return retval;
2556 }
2557
2558 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2559   int retval,i;
2560
2561   smpi_bench_end();
2562   if (old_type == MPI_DATATYPE_NULL) {
2563     retval = MPI_ERR_TYPE;
2564   } else if (count<0){
2565     retval = MPI_ERR_COUNT;
2566   } else {
2567     int* blocklens=(int*)xbt_malloc(blocklength*count);
2568     for (i=0; i<count;i++)blocklens[i]=blocklength;
2569     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2570     xbt_free(blocklens);
2571   }
2572   smpi_bench_begin();
2573   return retval;
2574 }
2575
2576
2577 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2578   int retval = 0;
2579
2580   smpi_bench_end();
2581   if (old_type == MPI_DATATYPE_NULL) {
2582     retval = MPI_ERR_TYPE;
2583   } else if (count<0){
2584     retval = MPI_ERR_COUNT;
2585   } else {
2586     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2587   }
2588   smpi_bench_begin();
2589   return retval;
2590 }
2591
2592 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2593   return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2594 }
2595
2596 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2597   int retval,i;
2598
2599   smpi_bench_end();
2600   if (old_type == MPI_DATATYPE_NULL) {
2601     retval = MPI_ERR_TYPE;
2602   } else if (count<0){
2603     retval = MPI_ERR_COUNT;
2604   } else {
2605     int* blocklens=(int*)xbt_malloc(blocklength*count);
2606     for (i=0; i<count;i++)blocklens[i]=blocklength;
2607     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2608     xbt_free(blocklens);
2609   }
2610   smpi_bench_begin();
2611   return retval;
2612 }
2613
2614
2615 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2616   int retval = 0;
2617
2618   smpi_bench_end();
2619   if (count<0){
2620     retval = MPI_ERR_COUNT;
2621   } else {
2622     retval = smpi_datatype_struct(count, blocklens, indices, old_types, new_type);
2623   }
2624   smpi_bench_begin();
2625   return retval;
2626 }
2627
2628 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2629   return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2630 }
2631
2632
2633 int PMPI_Error_class(int errorcode, int* errorclass) {
2634   // assume smpi uses only standard mpi error codes
2635   *errorclass=errorcode;
2636   return MPI_SUCCESS;
2637 }
2638
2639
2640 int PMPI_Initialized(int* flag) {
2641    *flag=smpi_process_initialized();
2642    return MPI_SUCCESS;
2643 }
2644
2645 /* The following calls are not yet implemented and will fail at runtime. */
2646 /* Once implemented, please move them above this notice. */
2647
2648 #define NOT_YET_IMPLEMENTED {\
2649         XBT_WARN("Not yet implemented : %s. Please contact the Simgrid team if support is needed", __FUNCTION__);\
2650         return MPI_SUCCESS;\
2651         }
2652
2653
2654 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
2655   NOT_YET_IMPLEMENTED
2656 }
2657
2658 int PMPI_Type_set_name(MPI_Datatype  datatype, char * name)
2659 {
2660   NOT_YET_IMPLEMENTED
2661 }
2662
2663 int PMPI_Type_get_name(MPI_Datatype  datatype, char * name, int* len)
2664 {
2665   NOT_YET_IMPLEMENTED
2666 }
2667
2668 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
2669    NOT_YET_IMPLEMENTED
2670 }
2671
2672 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2673    NOT_YET_IMPLEMENTED
2674 }
2675
2676 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periods, int reorder, MPI_Comm* comm_cart) {
2677    NOT_YET_IMPLEMENTED
2678 }
2679
2680 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2681    NOT_YET_IMPLEMENTED
2682 }
2683
2684 int PMPI_Cart_map(MPI_Comm comm_old, int ndims, int* dims, int* periods, int* newrank) {
2685    NOT_YET_IMPLEMENTED
2686 }
2687
2688 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2689    NOT_YET_IMPLEMENTED
2690 }
2691
2692 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2693    NOT_YET_IMPLEMENTED
2694 }
2695
2696 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2697    NOT_YET_IMPLEMENTED
2698 }
2699
2700 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2701    NOT_YET_IMPLEMENTED
2702 }
2703
2704 int PMPI_Graph_create(MPI_Comm comm_old, int nnodes, int* index, int* edges, int reorder, MPI_Comm* comm_graph) {
2705    NOT_YET_IMPLEMENTED
2706 }
2707
2708 int PMPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int* index, int* edges) {
2709    NOT_YET_IMPLEMENTED
2710 }
2711
2712 int PMPI_Graph_map(MPI_Comm comm_old, int nnodes, int* index, int* edges, int* newrank) {
2713    NOT_YET_IMPLEMENTED
2714 }
2715
2716 int PMPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int* neighbors) {
2717    NOT_YET_IMPLEMENTED
2718 }
2719
2720 int PMPI_Graph_neighbors_count(MPI_Comm comm, int rank, int* nneighbors) {
2721    NOT_YET_IMPLEMENTED
2722 }
2723
2724 int PMPI_Graphdims_get(MPI_Comm comm, int* nnodes, int* nedges) {
2725    NOT_YET_IMPLEMENTED
2726 }
2727
2728 int PMPI_Topo_test(MPI_Comm comm, int* top_type) {
2729    NOT_YET_IMPLEMENTED
2730 }
2731
2732 int PMPI_Errhandler_create(MPI_Handler_function* function, MPI_Errhandler* errhandler) {
2733    NOT_YET_IMPLEMENTED
2734 }
2735
2736 int PMPI_Errhandler_free(MPI_Errhandler* errhandler) {
2737    NOT_YET_IMPLEMENTED
2738 }
2739
2740 int PMPI_Errhandler_get(MPI_Comm comm, MPI_Errhandler* errhandler) {
2741    NOT_YET_IMPLEMENTED
2742 }
2743
2744 int PMPI_Error_string(int errorcode, char* string, int* resultlen) {
2745    NOT_YET_IMPLEMENTED
2746 }
2747
2748 int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler) {
2749    NOT_YET_IMPLEMENTED
2750 }
2751
2752 int PMPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler) {
2753    NOT_YET_IMPLEMENTED
2754 }
2755
2756 int PMPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler* errhandler) {
2757    NOT_YET_IMPLEMENTED
2758 }
2759
2760 int PMPI_Cancel(MPI_Request* request) {
2761    NOT_YET_IMPLEMENTED
2762 }
2763
2764 int PMPI_Buffer_attach(void* buffer, int size) {
2765    NOT_YET_IMPLEMENTED
2766 }
2767
2768 int PMPI_Buffer_detach(void* buffer, int* size) {
2769    NOT_YET_IMPLEMENTED
2770 }
2771
2772 int PMPI_Comm_test_inter(MPI_Comm comm, int* flag) {
2773    NOT_YET_IMPLEMENTED
2774 }
2775
2776 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
2777 {
2778    NOT_YET_IMPLEMENTED
2779 }
2780
2781 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
2782 {
2783    NOT_YET_IMPLEMENTED
2784 }
2785
2786 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
2787 {
2788    NOT_YET_IMPLEMENTED
2789 }
2790
2791 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval, void* extra_state)
2792 {
2793    NOT_YET_IMPLEMENTED
2794 }
2795
2796 int PMPI_Comm_free_keyval(int* keyval) {
2797    NOT_YET_IMPLEMENTED
2798 }
2799
2800 int PMPI_Pcontrol(const int level )
2801 {
2802    NOT_YET_IMPLEMENTED
2803 }
2804
2805 int PMPI_Unpack(void* inbuf, int insize, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
2806    NOT_YET_IMPLEMENTED
2807 }
2808
2809 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
2810 {
2811   NOT_YET_IMPLEMENTED
2812 }
2813
2814 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
2815 {
2816   NOT_YET_IMPLEMENTED
2817 }
2818
2819 int PMPI_Type_delete_attr (MPI_Datatype type, int comm_keyval)
2820 {
2821   NOT_YET_IMPLEMENTED
2822 }
2823
2824 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state)
2825 {
2826   NOT_YET_IMPLEMENTED
2827 }
2828
2829 int PMPI_Type_free_keyval(int* keyval) {
2830   NOT_YET_IMPLEMENTED
2831 }
2832
2833 int PMPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out) {
2834    NOT_YET_IMPLEMENTED
2835 }
2836
2837 int PMPI_Intercomm_merge(MPI_Comm comm, int high, MPI_Comm* comm_out) {
2838    NOT_YET_IMPLEMENTED
2839 }
2840
2841 int PMPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
2842    NOT_YET_IMPLEMENTED
2843 }
2844
2845 int PMPI_Bsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
2846    NOT_YET_IMPLEMENTED
2847 }
2848
2849 int PMPI_Ibsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
2850    NOT_YET_IMPLEMENTED
2851 }
2852
2853 int PMPI_Comm_remote_group(MPI_Comm comm, MPI_Group* group) {
2854    NOT_YET_IMPLEMENTED
2855 }
2856
2857 int PMPI_Comm_remote_size(MPI_Comm comm, int* size) {
2858    NOT_YET_IMPLEMENTED
2859 }
2860
2861 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
2862    NOT_YET_IMPLEMENTED
2863 }
2864
2865 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
2866    NOT_YET_IMPLEMENTED
2867 }
2868
2869 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
2870    NOT_YET_IMPLEMENTED
2871 }
2872
2873 int PMPI_Rsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
2874    NOT_YET_IMPLEMENTED
2875 }
2876
2877 int PMPI_Rsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
2878    NOT_YET_IMPLEMENTED
2879 }
2880
2881 int PMPI_Irsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
2882    NOT_YET_IMPLEMENTED
2883 }
2884
2885 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
2886    NOT_YET_IMPLEMENTED
2887 }
2888
2889 int PMPI_Keyval_free(int* keyval) {
2890    NOT_YET_IMPLEMENTED
2891 }
2892
2893 int PMPI_Test_cancelled(MPI_Status* status, int* flag) {
2894    NOT_YET_IMPLEMENTED
2895 }
2896
2897 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
2898    NOT_YET_IMPLEMENTED
2899 }
2900
2901 int PMPI_Pack_external_size(char *datarep, int incount, MPI_Datatype datatype, MPI_Aint *size){
2902   NOT_YET_IMPLEMENTED
2903 }
2904
2905 int PMPI_Pack_external(char *datarep, void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, MPI_Aint outcount, MPI_Aint *position){
2906   NOT_YET_IMPLEMENTED
2907 }
2908
2909 int PMPI_Unpack_external( char *datarep, void *inbuf, MPI_Aint insize, MPI_Aint *position, void *outbuf, int outcount, MPI_Datatype datatype){
2910   NOT_YET_IMPLEMENTED
2911 }
2912
2913 int PMPI_Get_elements(MPI_Status* status, MPI_Datatype datatype, int* elements) {
2914    NOT_YET_IMPLEMENTED
2915 }
2916
2917 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2918    NOT_YET_IMPLEMENTED
2919 }
2920
2921 int PMPI_Win_fence( int assert,  MPI_Win win){
2922    NOT_YET_IMPLEMENTED
2923 }
2924
2925 int PMPI_Win_free( MPI_Win* win){
2926    NOT_YET_IMPLEMENTED
2927 }
2928
2929 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2930   NOT_YET_IMPLEMENTED
2931 }
2932
2933 int PMPI_Info_create( MPI_Info *info){
2934   NOT_YET_IMPLEMENTED
2935 }
2936
2937 int PMPI_Info_set( MPI_Info info, char *key, char *value){
2938   NOT_YET_IMPLEMENTED
2939 }
2940
2941 int PMPI_Info_free( MPI_Info *info){
2942   NOT_YET_IMPLEMENTED
2943 }
2944
2945 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2946     MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2947   NOT_YET_IMPLEMENTED
2948 }
2949
2950 int PMPI_Type_get_envelope( MPI_Datatype datatype, int *num_integers,
2951                           int *num_addresses, int *num_datatypes, int *combiner){
2952   NOT_YET_IMPLEMENTED
2953 }
2954
2955 int PMPI_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses,
2956                           int max_datatypes, int* array_of_integers, MPI_Aint* array_of_addresses,
2957                           MPI_Datatype* array_of_datatypes){
2958   NOT_YET_IMPLEMENTED
2959 }
2960
2961 int PMPI_Type_create_darray(int size, int rank, int ndims, int* array_of_gsizes,
2962                             int* array_of_distribs, int* array_of_dargs, int* array_of_psizes,
2963                             int order, MPI_Datatype oldtype, MPI_Datatype *newtype) {
2964   NOT_YET_IMPLEMENTED
2965 }
2966
2967 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2968   NOT_YET_IMPLEMENTED
2969 }
2970
2971 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){
2972   NOT_YET_IMPLEMENTED
2973 }
2974
2975 int PMPI_Type_match_size(int typeclass,int size,MPI_Datatype *datatype){
2976   NOT_YET_IMPLEMENTED
2977 }
2978
2979 int PMPI_Alltoallw( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes,
2980                    void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes,
2981                    MPI_Comm comm){
2982   NOT_YET_IMPLEMENTED
2983 }
2984
2985 int PMPI_Comm_set_name(MPI_Comm comm, char* name){
2986   NOT_YET_IMPLEMENTED
2987 }
2988
2989 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm){
2990   NOT_YET_IMPLEMENTED
2991 }
2992
2993 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm){
2994   NOT_YET_IMPLEMENTED
2995 }
2996
2997 int PMPI_Comm_set_info (MPI_Comm comm, MPI_Info info){
2998   NOT_YET_IMPLEMENTED
2999 }
3000
3001 int PMPI_Comm_get_info (MPI_Comm comm, MPI_Info* info){
3002   NOT_YET_IMPLEMENTED
3003 }
3004
3005 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3006   NOT_YET_IMPLEMENTED
3007 }
3008
3009 int PMPI_Comm_create_errhandler( MPI_Comm_errhandler_fn *function, MPI_Errhandler *errhandler){
3010   NOT_YET_IMPLEMENTED
3011 }
3012
3013 int PMPI_Add_error_class( int *errorclass){
3014   NOT_YET_IMPLEMENTED
3015 }
3016
3017 int PMPI_Add_error_code(  int errorclass, int *errorcode){
3018   NOT_YET_IMPLEMENTED
3019 }
3020
3021 int PMPI_Add_error_string( int errorcode, char *string){
3022   NOT_YET_IMPLEMENTED
3023 }
3024
3025 int PMPI_Comm_call_errhandler(MPI_Comm comm,int errorcode){
3026   NOT_YET_IMPLEMENTED
3027 }
3028
3029 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3030   NOT_YET_IMPLEMENTED
3031 }
3032
3033 int PMPI_Info_delete(MPI_Info info, char *key){
3034   NOT_YET_IMPLEMENTED
3035 }
3036
3037 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3038   NOT_YET_IMPLEMENTED
3039 }
3040
3041 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3042   NOT_YET_IMPLEMENTED
3043 }
3044
3045 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3046   NOT_YET_IMPLEMENTED
3047 }
3048
3049 int PMPI_Request_get_status( MPI_Request request, int *flag, MPI_Status *status){
3050   NOT_YET_IMPLEMENTED
3051 }
3052
3053 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){
3054   NOT_YET_IMPLEMENTED
3055 }
3056
3057 int PMPI_Grequest_complete( MPI_Request request){
3058   NOT_YET_IMPLEMENTED
3059 }
3060
3061 int PMPI_Status_set_cancelled(MPI_Status *status,int flag){
3062   NOT_YET_IMPLEMENTED
3063 }
3064
3065 int PMPI_Status_set_elements( MPI_Status *status, MPI_Datatype datatype, int count){
3066   NOT_YET_IMPLEMENTED
3067 }
3068
3069 int PMPI_Comm_connect( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3070   NOT_YET_IMPLEMENTED
3071 }
3072
3073 int PMPI_Publish_name( char *service_name, MPI_Info info, char *port_name){
3074   NOT_YET_IMPLEMENTED
3075 }
3076
3077 int PMPI_Unpublish_name( char *service_name, MPI_Info info, char *port_name){
3078   NOT_YET_IMPLEMENTED
3079 }
3080
3081 int PMPI_Lookup_name( char *service_name, MPI_Info info, char *port_name){
3082   NOT_YET_IMPLEMENTED
3083 }
3084
3085 int PMPI_Comm_join( int fd, MPI_Comm *intercomm){
3086   NOT_YET_IMPLEMENTED
3087 }
3088
3089 int PMPI_Open_port( MPI_Info info, char *port_name){
3090   NOT_YET_IMPLEMENTED
3091 }
3092
3093 int PMPI_Close_port(char *port_name){
3094   NOT_YET_IMPLEMENTED
3095 }
3096
3097 int PMPI_Comm_accept( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3098   NOT_YET_IMPLEMENTED
3099 }
3100
3101 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){
3102   NOT_YET_IMPLEMENTED
3103 }
3104
3105 int PMPI_Comm_spawn_multiple( int count, char **array_of_commands, char*** array_of_argv,
3106                              int* array_of_maxprocs, MPI_Info* array_of_info, int root,
3107                              MPI_Comm comm, MPI_Comm *intercomm, int* array_of_errcodes){
3108   NOT_YET_IMPLEMENTED
3109 }
3110
3111 int PMPI_Comm_get_parent( MPI_Comm *parent){
3112   NOT_YET_IMPLEMENTED
3113 }