Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[trace] replace IS_TRACING by TRACE_is_active() function
[simgrid.git] / src / smpi / smpi_pmpi.c
1 /* Copyright (c) 2007, 2008, 2009, 2010. 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_coll_private.h"
9 #include "smpi_mpi_dt_private.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi,
12                                 "Logging specific to SMPI (pmpi)");
13
14 #ifdef HAVE_TRACING
15 //this function need to be here because of the calls to smpi_bench
16 int TRACE_smpi_set_category(const char *category)
17 {
18   //need to end bench otherwise categories for execution tasks are wrong
19   smpi_bench_end();
20   int ret;
21   if (!TRACE_is_enabled()){
22     ret = 1;
23   }else{
24     if (category != NULL) {
25       ret = TRACE_category(category);
26       TRACE_category_set(SIMIX_process_self(), category);
27     }else{
28       //if category is NULL, trace of platform is disabled for this process
29       TRACE_category_unset(SIMIX_process_self());
30       ret = 0;
31     }
32   }
33   //begin bench after changing process's category
34   smpi_bench_begin();
35   return ret;
36 }
37 #endif
38
39 /* PMPI User level calls */
40
41 int PMPI_Init(int *argc, char ***argv)
42 {
43   smpi_process_init(argc, argv);
44 #ifdef HAVE_TRACING
45   TRACE_smpi_init(smpi_process_index());
46 #endif
47   smpi_bench_begin();
48   return MPI_SUCCESS;
49 }
50
51 int PMPI_Finalize(void)
52 {
53   smpi_bench_end();
54 #ifdef HAVE_TRACING
55   TRACE_smpi_finalize(smpi_process_index());
56 #endif
57   smpi_process_destroy();
58   return MPI_SUCCESS;
59 }
60
61 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
62 {
63   if (provided != NULL) {
64     *provided = MPI_THREAD_MULTIPLE;
65   }
66   return MPI_Init(argc, argv);
67 }
68
69 int PMPI_Query_thread(int *provided)
70 {
71   int retval;
72
73   smpi_bench_end();
74   if (provided == NULL) {
75     retval = MPI_ERR_ARG;
76   } else {
77     *provided = MPI_THREAD_MULTIPLE;
78     retval = MPI_SUCCESS;
79   }
80   smpi_bench_begin();
81   return retval;
82 }
83
84 int PMPI_Is_thread_main(int *flag)
85 {
86   int retval;
87
88   smpi_bench_end();
89   if (flag == NULL) {
90     retval = MPI_ERR_ARG;
91   } else {
92     *flag = smpi_process_index() == 0;
93     retval = MPI_SUCCESS;
94   }
95   smpi_bench_begin();
96   return retval;
97 }
98
99 int PMPI_Abort(MPI_Comm comm, int errorcode)
100 {
101   smpi_bench_end();
102   smpi_process_destroy();
103   // FIXME: should kill all processes in comm instead
104   SIMIX_req_process_kill(SIMIX_process_self());
105   return MPI_SUCCESS;
106 }
107
108 double PMPI_Wtime(void)
109 {
110   double time;
111
112   smpi_bench_end();
113   time = SIMIX_get_clock();
114   smpi_bench_begin();
115   return time;
116 }
117
118 int PMPI_Address(void *location, MPI_Aint * address)
119 {
120   int retval;
121
122   smpi_bench_end();
123   if (!address) {
124     retval = MPI_ERR_ARG;
125   } else {
126     *address = (MPI_Aint) location;
127   }
128   smpi_bench_begin();
129   return retval;
130 }
131
132 int PMPI_Type_free(MPI_Datatype * datatype)
133 {
134   int retval;
135
136   smpi_bench_end();
137   if (!datatype) {
138     retval = MPI_ERR_ARG;
139   } else {
140     // FIXME: always fail for now
141     retval = MPI_ERR_TYPE;
142   }
143   smpi_bench_begin();
144   return retval;
145 }
146
147 int PMPI_Type_size(MPI_Datatype datatype, int *size)
148 {
149   int retval;
150
151   smpi_bench_end();
152   if (datatype == MPI_DATATYPE_NULL) {
153     retval = MPI_ERR_TYPE;
154   } else if (size == NULL) {
155     retval = MPI_ERR_ARG;
156   } else {
157     *size = (int) smpi_datatype_size(datatype);
158     retval = MPI_SUCCESS;
159   }
160   smpi_bench_begin();
161   return retval;
162 }
163
164 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
165 {
166   int retval;
167
168   smpi_bench_end();
169   if (datatype == MPI_DATATYPE_NULL) {
170     retval = MPI_ERR_TYPE;
171   } else if (lb == NULL || extent == NULL) {
172     retval = MPI_ERR_ARG;
173   } else {
174     retval = smpi_datatype_extent(datatype, lb, extent);
175   }
176   smpi_bench_begin();
177   return retval;
178 }
179
180 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
181 {
182   int retval;
183   MPI_Aint dummy;
184
185   smpi_bench_end();
186   if (datatype == MPI_DATATYPE_NULL) {
187     retval = MPI_ERR_TYPE;
188   } else if (extent == NULL) {
189     retval = MPI_ERR_ARG;
190   } else {
191     retval = smpi_datatype_extent(datatype, &dummy, extent);
192   }
193   smpi_bench_begin();
194   return retval;
195 }
196
197 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
198 {
199   int retval;
200
201   smpi_bench_end();
202   if (datatype == MPI_DATATYPE_NULL) {
203     retval = MPI_ERR_TYPE;
204   } else if (disp == NULL) {
205     retval = MPI_ERR_ARG;
206   } else {
207     *disp = smpi_datatype_lb(datatype);
208     retval = MPI_SUCCESS;
209   }
210   smpi_bench_begin();
211   return retval;
212 }
213
214 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
215 {
216   int retval;
217
218   smpi_bench_end();
219   if (datatype == MPI_DATATYPE_NULL) {
220     retval = MPI_ERR_TYPE;
221   } else if (disp == NULL) {
222     retval = MPI_ERR_ARG;
223   } else {
224     *disp = smpi_datatype_ub(datatype);
225     retval = MPI_SUCCESS;
226   }
227   smpi_bench_begin();
228   return retval;
229 }
230
231 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
232 {
233   int retval;
234
235   smpi_bench_end();
236   if (function == NULL || op == NULL) {
237     retval = MPI_ERR_ARG;
238   } else {
239     *op = smpi_op_new(function, commute);
240     retval = MPI_SUCCESS;
241   }
242   smpi_bench_begin();
243   return retval;
244 }
245
246 int PMPI_Op_free(MPI_Op * op)
247 {
248   int retval;
249
250   smpi_bench_end();
251   if (op == NULL) {
252     retval = MPI_ERR_ARG;
253   } else if (*op == MPI_OP_NULL) {
254     retval = MPI_ERR_OP;
255   } else {
256     smpi_op_destroy(*op);
257     *op = MPI_OP_NULL;
258     retval = MPI_SUCCESS;
259   }
260   smpi_bench_begin();
261   return retval;
262 }
263
264 int PMPI_Group_free(MPI_Group * group)
265 {
266   int retval;
267
268   smpi_bench_end();
269   if (group == NULL) {
270     retval = MPI_ERR_ARG;
271   } else {
272     smpi_group_destroy(*group);
273     *group = MPI_GROUP_NULL;
274     retval = MPI_SUCCESS;
275   }
276   smpi_bench_begin();
277   return retval;
278 }
279
280 int PMPI_Group_size(MPI_Group group, int *size)
281 {
282   int retval;
283
284   smpi_bench_end();
285   if (group == MPI_GROUP_NULL) {
286     retval = MPI_ERR_GROUP;
287   } else if (size == NULL) {
288     retval = MPI_ERR_ARG;
289   } else {
290     *size = smpi_group_size(group);
291     retval = MPI_SUCCESS;
292   }
293   smpi_bench_begin();
294   return retval;
295 }
296
297 int PMPI_Group_rank(MPI_Group group, int *rank)
298 {
299   int retval;
300
301   smpi_bench_end();
302   if (group == MPI_GROUP_NULL) {
303     retval = MPI_ERR_GROUP;
304   } else if (rank == NULL) {
305     retval = MPI_ERR_ARG;
306   } else {
307     *rank = smpi_group_rank(group, smpi_process_index());
308     retval = MPI_SUCCESS;
309   }
310   smpi_bench_begin();
311   return retval;
312 }
313
314 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1,
315                               MPI_Group group2, int *ranks2)
316 {
317   int retval, i, index;
318
319   smpi_bench_end();
320   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
321     retval = MPI_ERR_GROUP;
322   } else {
323     for (i = 0; i < n; i++) {
324       index = smpi_group_index(group1, ranks1[i]);
325       ranks2[i] = smpi_group_rank(group2, index);
326     }
327     retval = MPI_SUCCESS;
328   }
329   smpi_bench_begin();
330   return retval;
331 }
332
333 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
334 {
335   int retval;
336
337   smpi_bench_end();
338   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
339     retval = MPI_ERR_GROUP;
340   } else if (result == NULL) {
341     retval = MPI_ERR_ARG;
342   } else {
343     *result = smpi_group_compare(group1, group2);
344     retval = MPI_SUCCESS;
345   }
346   smpi_bench_begin();
347   return retval;
348 }
349
350 int PMPI_Group_union(MPI_Group group1, MPI_Group group2,
351                     MPI_Group * newgroup)
352 {
353   int retval, i, proc1, proc2, size, size2;
354
355   smpi_bench_end();
356   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
357     retval = MPI_ERR_GROUP;
358   } else if (newgroup == NULL) {
359     retval = MPI_ERR_ARG;
360   } else {
361     size = smpi_group_size(group1);
362     size2 = smpi_group_size(group2);
363     for (i = 0; i < size2; i++) {
364       proc2 = smpi_group_index(group2, i);
365       proc1 = smpi_group_rank(group1, proc2);
366       if (proc1 == MPI_UNDEFINED) {
367         size++;
368       }
369     }
370     if (size == 0) {
371       *newgroup = MPI_GROUP_EMPTY;
372     } else {
373       *newgroup = smpi_group_new(size);
374       size2 = smpi_group_size(group1);
375       for (i = 0; i < size2; i++) {
376         proc1 = smpi_group_index(group1, i);
377         smpi_group_set_mapping(*newgroup, proc1, i);
378       }
379       for (i = size2; i < size; i++) {
380         proc2 = smpi_group_index(group2, i - size2);
381         smpi_group_set_mapping(*newgroup, proc2, i);
382       }
383     }
384     smpi_group_use(*newgroup);
385     retval = MPI_SUCCESS;
386   }
387   smpi_bench_begin();
388   return retval;
389 }
390
391 int PMPI_Group_intersection(MPI_Group group1, MPI_Group group2,
392                            MPI_Group * newgroup)
393 {
394   int retval, i, proc1, proc2, size, size2;
395
396   smpi_bench_end();
397   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
398     retval = MPI_ERR_GROUP;
399   } else if (newgroup == NULL) {
400     retval = MPI_ERR_ARG;
401   } else {
402     size = smpi_group_size(group1);
403     size2 = smpi_group_size(group2);
404     for (i = 0; i < size2; i++) {
405       proc2 = smpi_group_index(group2, i);
406       proc1 = smpi_group_rank(group1, proc2);
407       if (proc1 == MPI_UNDEFINED) {
408         size--;
409       }
410     }
411     if (size == 0) {
412       *newgroup = MPI_GROUP_EMPTY;
413     } else {
414       *newgroup = smpi_group_new(size);
415       size2 = smpi_group_size(group1);
416       for (i = 0; i < size2; i++) {
417         proc1 = smpi_group_index(group1, i);
418         proc2 = smpi_group_rank(group2, proc1);
419         if (proc2 != MPI_UNDEFINED) {
420           smpi_group_set_mapping(*newgroup, proc1, i);
421         }
422       }
423     }
424     smpi_group_use(*newgroup);
425     retval = MPI_SUCCESS;
426   }
427   smpi_bench_begin();
428   return retval;
429 }
430
431 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
432 {
433   int retval, i, proc1, proc2, size, size2;
434
435   smpi_bench_end();
436   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
437     retval = MPI_ERR_GROUP;
438   } else if (newgroup == NULL) {
439     retval = MPI_ERR_ARG;
440   } else {
441     size = size2 = smpi_group_size(group1);
442     for (i = 0; i < size2; i++) {
443       proc1 = smpi_group_index(group1, i);
444       proc2 = smpi_group_rank(group2, proc1);
445       if (proc2 != MPI_UNDEFINED) {
446         size--;
447       }
448     }
449     if (size == 0) {
450       *newgroup = MPI_GROUP_EMPTY;
451     } else {
452       *newgroup = smpi_group_new(size);
453       for (i = 0; i < size2; i++) {
454         proc1 = smpi_group_index(group1, i);
455         proc2 = smpi_group_rank(group2, proc1);
456         if (proc2 == MPI_UNDEFINED) {
457           smpi_group_set_mapping(*newgroup, proc1, i);
458         }
459       }
460     }
461     smpi_group_use(*newgroup);
462     retval = MPI_SUCCESS;
463   }
464   smpi_bench_begin();
465   return retval;
466 }
467
468 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
469 {
470   int retval, i, index;
471
472   smpi_bench_end();
473   if (group == MPI_GROUP_NULL) {
474     retval = MPI_ERR_GROUP;
475   } else if (newgroup == NULL) {
476     retval = MPI_ERR_ARG;
477   } else {
478     if (n == 0) {
479       *newgroup = MPI_GROUP_EMPTY;
480     } else if (n == smpi_group_size(group)) {
481       *newgroup = group;
482     } else {
483       *newgroup = smpi_group_new(n);
484       for (i = 0; i < n; i++) {
485         index = smpi_group_index(group, ranks[i]);
486         smpi_group_set_mapping(*newgroup, index, i);
487       }
488     }
489     smpi_group_use(*newgroup);
490     retval = MPI_SUCCESS;
491   }
492   smpi_bench_begin();
493   return retval;
494 }
495
496 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
497 {
498   int retval, i, size, rank, index;
499
500   smpi_bench_end();
501   if (group == MPI_GROUP_NULL) {
502     retval = MPI_ERR_GROUP;
503   } else if (newgroup == NULL) {
504     retval = MPI_ERR_ARG;
505   } else {
506     if (n == 0) {
507       *newgroup = group;
508     } else if (n == smpi_group_size(group)) {
509       *newgroup = MPI_GROUP_EMPTY;
510     } else {
511       size = smpi_group_size(group) - n;
512       *newgroup = smpi_group_new(size);
513       rank = 0;
514       while (rank < size) {
515         for (i = 0; i < n; i++) {
516           if (ranks[i] == rank) {
517             break;
518           }
519         }
520         if (i >= n) {
521           index = smpi_group_index(group, rank);
522           smpi_group_set_mapping(*newgroup, index, rank);
523           rank++;
524         }
525       }
526     }
527     smpi_group_use(*newgroup);
528     retval = MPI_SUCCESS;
529   }
530   smpi_bench_begin();
531   return retval;
532 }
533
534 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3],
535                          MPI_Group * newgroup)
536 {
537   int retval, i, j, rank, size, index;
538
539   smpi_bench_end();
540   if (group == MPI_GROUP_NULL) {
541     retval = MPI_ERR_GROUP;
542   } else if (newgroup == NULL) {
543     retval = MPI_ERR_ARG;
544   } else {
545     if (n == 0) {
546       *newgroup = MPI_GROUP_EMPTY;
547     } else {
548       size = 0;
549       for (i = 0; i < n; i++) {
550         for (rank = ranges[i][0];       /* First */
551              rank >= 0 && rank <= ranges[i][1]; /* Last */
552              rank += ranges[i][2] /* Stride */ ) {
553           size++;
554         }
555       }
556       if (size == smpi_group_size(group)) {
557         *newgroup = group;
558       } else {
559         *newgroup = smpi_group_new(size);
560         j = 0;
561         for (i = 0; i < n; i++) {
562           for (rank = ranges[i][0];     /* First */
563                rank >= 0 && rank <= ranges[i][1];       /* Last */
564                rank += ranges[i][2] /* Stride */ ) {
565             index = smpi_group_index(group, rank);
566             smpi_group_set_mapping(*newgroup, index, j);
567             j++;
568           }
569         }
570       }
571     }
572     smpi_group_use(*newgroup);
573     retval = MPI_SUCCESS;
574   }
575   smpi_bench_begin();
576   return retval;
577 }
578
579 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3],
580                          MPI_Group * newgroup)
581 {
582   int retval, i, newrank, rank, size, index, add;
583
584   smpi_bench_end();
585   if (group == MPI_GROUP_NULL) {
586     retval = MPI_ERR_GROUP;
587   } else if (newgroup == NULL) {
588     retval = MPI_ERR_ARG;
589   } else {
590     if (n == 0) {
591       *newgroup = group;
592     } else {
593       size = smpi_group_size(group);
594       for (i = 0; i < n; i++) {
595         for (rank = ranges[i][0];       /* First */
596              rank >= 0 && rank <= ranges[i][1]; /* Last */
597              rank += ranges[i][2] /* Stride */ ) {
598           size--;
599         }
600       }
601       if (size == 0) {
602         *newgroup = MPI_GROUP_EMPTY;
603       } else {
604         *newgroup = smpi_group_new(size);
605         newrank = 0;
606         while (newrank < size) {
607           for (i = 0; i < n; i++) {
608             add = 1;
609             for (rank = ranges[i][0];   /* First */
610                  rank >= 0 && rank <= ranges[i][1];     /* Last */
611                  rank += ranges[i][2] /* Stride */ ) {
612               if (rank == newrank) {
613                 add = 0;
614                 break;
615               }
616             }
617             if (add == 1) {
618               index = smpi_group_index(group, newrank);
619               smpi_group_set_mapping(*newgroup, index, newrank);
620             }
621           }
622         }
623       }
624     }
625     smpi_group_use(*newgroup);
626     retval = MPI_SUCCESS;
627   }
628   smpi_bench_begin();
629   return retval;
630 }
631
632 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
633 {
634   int retval;
635
636   smpi_bench_end();
637   if (comm == MPI_COMM_NULL) {
638     retval = MPI_ERR_COMM;
639   } else {
640     *rank = smpi_comm_rank(comm);
641     retval = MPI_SUCCESS;
642   }
643   smpi_bench_begin();
644   return retval;
645 }
646
647 int PMPI_Comm_size(MPI_Comm comm, int *size)
648 {
649   int retval;
650
651   smpi_bench_end();
652   if (comm == MPI_COMM_NULL) {
653     retval = MPI_ERR_COMM;
654   } else if (size == NULL) {
655     retval = MPI_ERR_ARG;
656   } else {
657     *size = smpi_comm_size(comm);
658     retval = MPI_SUCCESS;
659   }
660   smpi_bench_begin();
661   return retval;
662 }
663
664 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
665 {
666   int retval;
667
668   smpi_bench_end();
669   if (comm == MPI_COMM_NULL) {
670     retval = MPI_ERR_COMM;
671   } else if (group == NULL) {
672     retval = MPI_ERR_ARG;
673   } else {
674     *group = smpi_comm_group(comm);
675     retval = MPI_SUCCESS;
676   }
677   smpi_bench_begin();
678   return retval;
679 }
680
681 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
682 {
683   int retval;
684
685   smpi_bench_end();
686   if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
687     retval = MPI_ERR_COMM;
688   } else if (result == NULL) {
689     retval = MPI_ERR_ARG;
690   } else {
691     if (comm1 == comm2) {       /* Same communicators means same groups */
692       *result = MPI_IDENT;
693     } else {
694       *result =
695           smpi_group_compare(smpi_comm_group(comm1),
696                              smpi_comm_group(comm2));
697       if (*result == MPI_IDENT) {
698         *result = MPI_CONGRUENT;
699       }
700     }
701     retval = MPI_SUCCESS;
702   }
703   smpi_bench_begin();
704   return retval;
705 }
706
707 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
708 {
709   int retval;
710
711   smpi_bench_end();
712   if (comm == MPI_COMM_NULL) {
713     retval = MPI_ERR_COMM;
714   } else if (newcomm == NULL) {
715     retval = MPI_ERR_ARG;
716   } else {
717     *newcomm = smpi_comm_new(smpi_comm_group(comm));
718     retval = MPI_SUCCESS;
719   }
720   smpi_bench_begin();
721   return retval;
722 }
723
724 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
725 {
726   int retval;
727
728   smpi_bench_end();
729   if (comm == MPI_COMM_NULL) {
730     retval = MPI_ERR_COMM;
731   } else if (group == MPI_GROUP_NULL) {
732     retval = MPI_ERR_GROUP;
733   } else if (newcomm == NULL) {
734     retval = MPI_ERR_ARG;
735   } else {
736     *newcomm = smpi_comm_new(group);
737     retval = MPI_SUCCESS;
738   }
739   smpi_bench_begin();
740   return retval;
741 }
742
743 int PMPI_Comm_free(MPI_Comm * comm)
744 {
745   int retval;
746
747   smpi_bench_end();
748   if (comm == NULL) {
749     retval = MPI_ERR_ARG;
750   } else if (*comm == MPI_COMM_NULL) {
751     retval = MPI_ERR_COMM;
752   } else {
753     smpi_comm_destroy(*comm);
754     *comm = MPI_COMM_NULL;
755     retval = MPI_SUCCESS;
756   }
757   smpi_bench_begin();
758   return retval;
759 }
760
761 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
762 {
763   int retval;
764
765   smpi_bench_end();
766   if (comm_out == NULL) {
767     retval = MPI_ERR_ARG;
768   } else if (comm == MPI_COMM_NULL) {
769     retval = MPI_ERR_COMM;
770   } else {
771     *comm_out = smpi_comm_split(comm, color, key);
772     retval = MPI_SUCCESS;
773   }
774   smpi_bench_begin();
775   return retval;
776 }
777
778 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst,
779                   int tag, MPI_Comm comm, MPI_Request * request)
780 {
781   int retval;
782
783   smpi_bench_end();
784   if (request == NULL) {
785     retval = MPI_ERR_ARG;
786   } else if (comm == MPI_COMM_NULL) {
787     retval = MPI_ERR_COMM;
788   } else {
789     *request = smpi_mpi_send_init(buf, count, datatype, dst, tag, comm);
790     retval = MPI_SUCCESS;
791   }
792   smpi_bench_begin();
793   return retval;
794 }
795
796 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src,
797                   int tag, MPI_Comm comm, MPI_Request * request)
798 {
799   int retval;
800
801   smpi_bench_end();
802   if (request == NULL) {
803     retval = MPI_ERR_ARG;
804   } else if (comm == MPI_COMM_NULL) {
805     retval = MPI_ERR_COMM;
806   } else {
807     *request = smpi_mpi_recv_init(buf, count, datatype, src, tag, comm);
808     retval = MPI_SUCCESS;
809   }
810   smpi_bench_begin();
811   return retval;
812 }
813
814 int PMPI_Start(MPI_Request * request)
815 {
816   int retval;
817
818   smpi_bench_end();
819   if (request == NULL) {
820     retval = MPI_ERR_ARG;
821   } else {
822     smpi_mpi_start(*request);
823     retval = MPI_SUCCESS;
824   }
825   smpi_bench_begin();
826   return retval;
827 }
828
829 int PMPI_Startall(int count, MPI_Request * requests)
830 {
831   int retval;
832
833   smpi_bench_end();
834   if (requests == NULL) {
835     retval = MPI_ERR_ARG;
836   } else {
837     smpi_mpi_startall(count, requests);
838     retval = MPI_SUCCESS;
839   }
840   smpi_bench_begin();
841   return retval;
842 }
843
844 int PMPI_Request_free(MPI_Request * request)
845 {
846   int retval;
847
848   smpi_bench_end();
849   if (request == NULL) {
850     retval = MPI_ERR_ARG;
851   } else {
852     smpi_mpi_request_free(request);
853     retval = MPI_SUCCESS;
854   }
855   smpi_bench_begin();
856   return retval;
857 }
858
859 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src,
860               int tag, MPI_Comm comm, MPI_Request * request)
861 {
862   int retval;
863
864   smpi_bench_end();
865 #ifdef HAVE_TRACING
866   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
867   int src_traced = smpi_group_rank(smpi_comm_group(comm), src);
868   TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
869 #endif
870   if (request == NULL) {
871     retval = MPI_ERR_ARG;
872   } else if (comm == MPI_COMM_NULL) {
873     retval = MPI_ERR_COMM;
874   } else {
875     *request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm);
876     retval = MPI_SUCCESS;
877   }
878 #ifdef HAVE_TRACING
879   TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
880   (*request)->recv = 1;
881 #endif
882   smpi_bench_begin();
883   return retval;
884 }
885
886 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst,
887               int tag, MPI_Comm comm, MPI_Request * request)
888 {
889   int retval;
890
891   smpi_bench_end();
892 #ifdef HAVE_TRACING
893   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
894   int dst_traced = smpi_group_rank(smpi_comm_group(comm), dst);
895   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
896   TRACE_smpi_send(rank, rank, dst_traced);
897 #endif
898   if (request == NULL) {
899     retval = MPI_ERR_ARG;
900   } else if (comm == MPI_COMM_NULL) {
901     retval = MPI_ERR_COMM;
902   } else {
903     *request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
904     retval = MPI_SUCCESS;
905   }
906 #ifdef HAVE_TRACING
907   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
908   (*request)->send = 1;
909 #endif
910   smpi_bench_begin();
911   return retval;
912 }
913
914 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag,
915              MPI_Comm comm, MPI_Status * status)
916 {
917   int retval;
918
919   smpi_bench_end();
920 #ifdef HAVE_TRACING
921   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
922   int src_traced = smpi_group_rank(smpi_comm_group(comm), src);
923   TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
924 #endif
925   if (comm == MPI_COMM_NULL) {
926     retval = MPI_ERR_COMM;
927   } else {
928     smpi_mpi_recv(buf, count, datatype, src, tag, comm, status);
929     retval = MPI_SUCCESS;
930   }
931 #ifdef HAVE_TRACING
932   TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
933   TRACE_smpi_recv(rank, src_traced, rank);
934 #endif
935   smpi_bench_begin();
936   return retval;
937 }
938
939 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag,
940              MPI_Comm comm)
941 {
942   int retval;
943
944   smpi_bench_end();
945 #ifdef HAVE_TRACING
946   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
947   int dst_traced = smpi_group_rank(smpi_comm_group(comm), dst);
948   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
949   TRACE_smpi_send(rank, rank, dst_traced);
950 #endif
951   if (comm == MPI_COMM_NULL) {
952     retval = MPI_ERR_COMM;
953   } else {
954     smpi_mpi_send(buf, count, datatype, dst, tag, comm);
955     retval = MPI_SUCCESS;
956   }
957 #ifdef HAVE_TRACING
958   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
959 #endif
960   smpi_bench_begin();
961   return retval;
962 }
963
964 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
965                  int dst, int sendtag, void *recvbuf, int recvcount,
966                  MPI_Datatype recvtype, int src, int recvtag,
967                  MPI_Comm comm, MPI_Status * status)
968 {
969   int retval;
970
971   smpi_bench_end();
972 #ifdef HAVE_TRACING
973   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
974   int dst_traced = smpi_group_rank(smpi_comm_group(comm), dst);
975   int src_traced = smpi_group_rank(smpi_comm_group(comm), src);
976   TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__);
977   TRACE_smpi_send(rank, rank, dst_traced);
978   TRACE_smpi_send(rank, src_traced, rank);
979 #endif
980   if (comm == MPI_COMM_NULL) {
981     retval = MPI_ERR_COMM;
982   } else if (sendtype == MPI_DATATYPE_NULL
983              || recvtype == MPI_DATATYPE_NULL) {
984     retval = MPI_ERR_TYPE;
985   } else {
986     smpi_mpi_sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf,
987                       recvcount, recvtype, src, recvtag, comm, status);
988     retval = MPI_SUCCESS;
989   }
990 #ifdef HAVE_TRACING
991   TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
992   TRACE_smpi_recv(rank, rank, dst_traced);
993   TRACE_smpi_recv(rank, src_traced, rank);
994 #endif
995   smpi_bench_begin();
996   return retval;
997 }
998
999 int PMPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,
1000                          int dst, int sendtag, int src, int recvtag,
1001                          MPI_Comm comm, MPI_Status * status)
1002 {
1003   //TODO: suboptimal implementation
1004   void *recvbuf;
1005   int retval, size;
1006
1007   size = smpi_datatype_size(datatype) * count;
1008   recvbuf = xbt_new(char, size);
1009   retval =
1010       MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count,
1011                    datatype, src, recvtag, comm, status);
1012   memcpy(buf, recvbuf, size * sizeof(char));
1013   xbt_free(recvbuf);
1014   return retval;
1015 }
1016
1017 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1018 {
1019   int retval;
1020
1021   smpi_bench_end();
1022   if (request == NULL || flag == NULL) {
1023     retval = MPI_ERR_ARG;
1024   } else if (*request == MPI_REQUEST_NULL) {
1025     retval = MPI_ERR_REQUEST;
1026   } else {
1027     *flag = smpi_mpi_test(request, status);
1028     retval = MPI_SUCCESS;
1029   }
1030   smpi_bench_begin();
1031   return retval;
1032 }
1033
1034 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag,
1035                 MPI_Status * status)
1036 {
1037   int retval;
1038
1039   smpi_bench_end();
1040   if (index == NULL || flag == NULL) {
1041     retval = MPI_ERR_ARG;
1042   } else {
1043     *flag = smpi_mpi_testany(count, requests, index, status);
1044     retval = MPI_SUCCESS;
1045   }
1046   smpi_bench_begin();
1047   return retval;
1048 }
1049
1050 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1051 {
1052   int retval;
1053
1054   smpi_bench_end();
1055 #ifdef HAVE_TRACING
1056   int rank = request && (*request)->comm != MPI_COMM_NULL
1057       ? smpi_comm_rank((*request)->comm)
1058       : -1;
1059   MPI_Group group = smpi_comm_group((*request)->comm);
1060   int src_traced = smpi_group_rank(group, (*request)->src);
1061   int dst_traced = smpi_group_rank(group, (*request)->dst);
1062   int is_wait_for_receive = (*request)->recv;
1063   TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__);
1064 #endif
1065   if (request == NULL) {
1066     retval = MPI_ERR_ARG;
1067   } else if (*request == MPI_REQUEST_NULL) {
1068     retval = MPI_ERR_REQUEST;
1069   } else {
1070     smpi_mpi_wait(request, status);
1071     retval = MPI_SUCCESS;
1072   }
1073 #ifdef HAVE_TRACING
1074   TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1075   if (is_wait_for_receive) {
1076     TRACE_smpi_recv(rank, src_traced, dst_traced);
1077   }
1078 #endif
1079   smpi_bench_begin();
1080   return retval;
1081 }
1082
1083 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1084 {
1085   int retval;
1086
1087   smpi_bench_end();
1088 #ifdef HAVE_TRACING
1089   //save requests information for tracing
1090   int i;
1091   xbt_dynar_t srcs = xbt_dynar_new(sizeof(int), xbt_free);
1092   xbt_dynar_t dsts = xbt_dynar_new(sizeof(int), xbt_free);
1093   xbt_dynar_t recvs = xbt_dynar_new(sizeof(int), xbt_free);
1094   for (i = 0; i < count; i++) {
1095     MPI_Request req = requests[i];      //already received requests are no longer valid
1096     if (req) {
1097       int *asrc = xbt_new(int, 1);
1098       int *adst = xbt_new(int, 1);
1099       int *arecv = xbt_new(int, 1);
1100       *asrc = req->src;
1101       *adst = req->dst;
1102       *arecv = req->recv;
1103       xbt_dynar_insert_at(srcs, i, asrc);
1104       xbt_dynar_insert_at(dsts, i, adst);
1105       xbt_dynar_insert_at(recvs, i, arecv);
1106     } else {
1107       int *t = xbt_new(int, 1);
1108       xbt_dynar_insert_at(srcs, i, t);
1109       xbt_dynar_insert_at(dsts, i, t);
1110       xbt_dynar_insert_at(recvs, i, t);
1111     }
1112   }
1113   int rank_traced = smpi_comm_rank(MPI_COMM_WORLD);
1114   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__);
1115 #endif
1116   if (index == NULL) {
1117     retval = MPI_ERR_ARG;
1118   } else {
1119     *index = smpi_mpi_waitany(count, requests, status);
1120     retval = MPI_SUCCESS;
1121   }
1122 #ifdef HAVE_TRACING
1123   int src_traced, dst_traced, is_wait_for_receive;
1124   xbt_dynar_get_cpy(srcs, *index, &src_traced);
1125   xbt_dynar_get_cpy(dsts, *index, &dst_traced);
1126   xbt_dynar_get_cpy(recvs, *index, &is_wait_for_receive);
1127   if (is_wait_for_receive) {
1128     TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1129   }
1130   TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1131   //clean-up of dynars
1132   xbt_free(srcs);
1133   xbt_free(dsts);
1134   xbt_free(recvs);
1135 #endif
1136   smpi_bench_begin();
1137   return retval;
1138 }
1139
1140 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1141 {
1142
1143   smpi_bench_end();
1144 #ifdef HAVE_TRACING
1145   //save information from requests
1146   int i;
1147   xbt_dynar_t srcs = xbt_dynar_new(sizeof(int), xbt_free);
1148   xbt_dynar_t dsts = xbt_dynar_new(sizeof(int), xbt_free);
1149   xbt_dynar_t recvs = xbt_dynar_new(sizeof(int), xbt_free);
1150   for (i = 0; i < count; i++) {
1151     MPI_Request req = requests[i];      //all req should be valid in Waitall
1152     int *asrc = xbt_new(int, 1);
1153     int *adst = xbt_new(int, 1);
1154     int *arecv = xbt_new(int, 1);
1155     *asrc = req->src;
1156     *adst = req->dst;
1157     *arecv = req->recv;
1158     xbt_dynar_insert_at(srcs, i, asrc);
1159     xbt_dynar_insert_at(dsts, i, adst);
1160     xbt_dynar_insert_at(recvs, i, arecv);
1161   }
1162   int rank_traced = smpi_comm_rank (MPI_COMM_WORLD);
1163   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__);
1164 #endif
1165   smpi_mpi_waitall(count, requests, status);
1166 #ifdef HAVE_TRACING
1167   for (i = 0; i < count; i++) {
1168     int src_traced, dst_traced, is_wait_for_receive;
1169     xbt_dynar_get_cpy(srcs, i, &src_traced);
1170     xbt_dynar_get_cpy(dsts, i, &dst_traced);
1171     xbt_dynar_get_cpy(recvs, i, &is_wait_for_receive);
1172     if (is_wait_for_receive) {
1173       TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1174     }
1175   }
1176   TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1177   //clean-up of dynars
1178   xbt_free(srcs);
1179   xbt_free(dsts);
1180   xbt_free(recvs);
1181 #endif
1182   smpi_bench_begin();
1183   return MPI_SUCCESS;
1184 }
1185
1186 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount,
1187                  int *indices, MPI_Status status[])
1188 {
1189   int retval;
1190
1191   smpi_bench_end();
1192   if (outcount == NULL || indices == NULL) {
1193     retval = MPI_ERR_ARG;
1194   } else {
1195     *outcount = smpi_mpi_waitsome(incount, requests, indices, status);
1196     retval = MPI_SUCCESS;
1197   }
1198   smpi_bench_begin();
1199   return retval;
1200 }
1201
1202 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1203 {
1204   int retval;
1205
1206   smpi_bench_end();
1207 #ifdef HAVE_TRACING
1208   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1209   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
1210   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
1211 #endif
1212   if (comm == MPI_COMM_NULL) {
1213     retval = MPI_ERR_COMM;
1214   } else {
1215     smpi_mpi_bcast(buf, count, datatype, root, comm);
1216     retval = MPI_SUCCESS;
1217   }
1218 #ifdef HAVE_TRACING
1219   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1220 #endif
1221   smpi_bench_begin();
1222   return retval;
1223 }
1224
1225 int PMPI_Barrier(MPI_Comm comm)
1226 {
1227   int retval;
1228
1229   smpi_bench_end();
1230 #ifdef HAVE_TRACING
1231   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1232   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1233 #endif
1234   if (comm == MPI_COMM_NULL) {
1235     retval = MPI_ERR_COMM;
1236   } else {
1237     smpi_mpi_barrier(comm);
1238     retval = MPI_SUCCESS;
1239   }
1240 #ifdef HAVE_TRACING
1241   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1242 #endif
1243   smpi_bench_begin();
1244   return retval;
1245 }
1246
1247 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1248                void *recvbuf, int recvcount, MPI_Datatype recvtype,
1249                int root, MPI_Comm comm)
1250 {
1251   int retval;
1252
1253   smpi_bench_end();
1254 #ifdef HAVE_TRACING
1255   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1256   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
1257   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
1258 #endif
1259   if (comm == MPI_COMM_NULL) {
1260     retval = MPI_ERR_COMM;
1261   } else if (sendtype == MPI_DATATYPE_NULL
1262              || recvtype == MPI_DATATYPE_NULL) {
1263     retval = MPI_ERR_TYPE;
1264   } else {
1265     smpi_mpi_gather(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1266                     recvtype, root, comm);
1267     retval = MPI_SUCCESS;
1268   }
1269 #ifdef HAVE_TRACING
1270   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1271 #endif
1272   smpi_bench_begin();
1273   return retval;
1274 }
1275
1276 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1277                 void *recvbuf, int *recvcounts, int *displs,
1278                 MPI_Datatype recvtype, int root, MPI_Comm comm)
1279 {
1280   int retval;
1281
1282   smpi_bench_end();
1283 #ifdef HAVE_TRACING
1284   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1285   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
1286   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
1287 #endif
1288   if (comm == MPI_COMM_NULL) {
1289     retval = MPI_ERR_COMM;
1290   } else if (sendtype == MPI_DATATYPE_NULL
1291              || recvtype == MPI_DATATYPE_NULL) {
1292     retval = MPI_ERR_TYPE;
1293   } else if (recvcounts == NULL || displs == NULL) {
1294     retval = MPI_ERR_ARG;
1295   } else {
1296     smpi_mpi_gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
1297                      displs, recvtype, root, comm);
1298     retval = MPI_SUCCESS;
1299   }
1300 #ifdef HAVE_TRACING
1301   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1302 #endif
1303   smpi_bench_begin();
1304   return retval;
1305 }
1306
1307 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1308                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
1309                   MPI_Comm comm)
1310 {
1311   int retval;
1312
1313   smpi_bench_end();
1314 #ifdef HAVE_TRACING
1315   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1316   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1317 #endif
1318   if (comm == MPI_COMM_NULL) {
1319     retval = MPI_ERR_COMM;
1320   } else if (sendtype == MPI_DATATYPE_NULL
1321              || recvtype == MPI_DATATYPE_NULL) {
1322     retval = MPI_ERR_TYPE;
1323   } else {
1324     smpi_mpi_allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1325                        recvtype, comm);
1326     retval = MPI_SUCCESS;
1327   }
1328 #ifdef HAVE_TRACING
1329   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1330 #endif
1331   smpi_bench_begin();
1332   return retval;
1333 }
1334
1335 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1336                    void *recvbuf, int *recvcounts, int *displs,
1337                    MPI_Datatype recvtype, MPI_Comm comm)
1338 {
1339   int retval;
1340
1341   smpi_bench_end();
1342 #ifdef HAVE_TRACING
1343   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1344   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1345 #endif
1346   if (comm == MPI_COMM_NULL) {
1347     retval = MPI_ERR_COMM;
1348   } else if (sendtype == MPI_DATATYPE_NULL
1349              || recvtype == MPI_DATATYPE_NULL) {
1350     retval = MPI_ERR_TYPE;
1351   } else if (recvcounts == NULL || displs == NULL) {
1352     retval = MPI_ERR_ARG;
1353   } else {
1354     smpi_mpi_allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
1355                         displs, recvtype, comm);
1356     retval = MPI_SUCCESS;
1357   }
1358 #ifdef HAVE_TRACING
1359   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1360 #endif
1361   smpi_bench_begin();
1362   return retval;
1363 }
1364
1365 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1366                 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1367                 int root, MPI_Comm comm)
1368 {
1369   int retval;
1370
1371   smpi_bench_end();
1372 #ifdef HAVE_TRACING
1373   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1374   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
1375   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
1376 #endif
1377   if (comm == MPI_COMM_NULL) {
1378     retval = MPI_ERR_COMM;
1379   } else if (sendtype == MPI_DATATYPE_NULL
1380              || recvtype == MPI_DATATYPE_NULL) {
1381     retval = MPI_ERR_TYPE;
1382   } else {
1383     smpi_mpi_scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1384                      recvtype, root, comm);
1385     retval = MPI_SUCCESS;
1386   }
1387 #ifdef HAVE_TRACING
1388   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1389 #endif
1390   smpi_bench_begin();
1391   return retval;
1392 }
1393
1394 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1395                  MPI_Datatype sendtype, void *recvbuf, int recvcount,
1396                  MPI_Datatype recvtype, int root, MPI_Comm comm)
1397 {
1398   int retval;
1399
1400   smpi_bench_end();
1401 #ifdef HAVE_TRACING
1402   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1403   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
1404   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
1405 #endif
1406   if (comm == MPI_COMM_NULL) {
1407     retval = MPI_ERR_COMM;
1408   } else if (sendtype == MPI_DATATYPE_NULL
1409              || recvtype == MPI_DATATYPE_NULL) {
1410     retval = MPI_ERR_TYPE;
1411   } else if (sendcounts == NULL || displs == NULL) {
1412     retval = MPI_ERR_ARG;
1413   } else {
1414     smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf,
1415                       recvcount, recvtype, root, comm);
1416     retval = MPI_SUCCESS;
1417   }
1418 #ifdef HAVE_TRACING
1419   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1420 #endif
1421   smpi_bench_begin();
1422   return retval;
1423 }
1424
1425 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
1426                MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
1427 {
1428   int retval;
1429
1430   smpi_bench_end();
1431 #ifdef HAVE_TRACING
1432   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1433   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
1434   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
1435 #endif
1436   if (comm == MPI_COMM_NULL) {
1437     retval = MPI_ERR_COMM;
1438   } else if (datatype == MPI_DATATYPE_NULL || op == MPI_OP_NULL) {
1439     retval = MPI_ERR_ARG;
1440   } else {
1441     smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1442     retval = MPI_SUCCESS;
1443   }
1444 #ifdef HAVE_TRACING
1445   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1446 #endif
1447   smpi_bench_begin();
1448   return retval;
1449 }
1450
1451 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
1452                   MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1453 {
1454   int retval;
1455
1456   smpi_bench_end();
1457 #ifdef HAVE_TRACING
1458   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1459   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1460 #endif
1461   if (comm == MPI_COMM_NULL) {
1462     retval = MPI_ERR_COMM;
1463   } else if (datatype == MPI_DATATYPE_NULL) {
1464     retval = MPI_ERR_TYPE;
1465   } else if (op == MPI_OP_NULL) {
1466     retval = MPI_ERR_OP;
1467   } else {
1468     smpi_mpi_allreduce(sendbuf, recvbuf, count, datatype, op, comm);
1469     retval = MPI_SUCCESS;
1470   }
1471 #ifdef HAVE_TRACING
1472   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1473 #endif
1474   smpi_bench_begin();
1475   return retval;
1476 }
1477
1478 int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
1479              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1480 {
1481   int retval;
1482
1483   smpi_bench_end();
1484 #ifdef HAVE_TRACING
1485   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1486   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1487 #endif
1488   if (comm == MPI_COMM_NULL) {
1489     retval = MPI_ERR_COMM;
1490   } else if (datatype == MPI_DATATYPE_NULL) {
1491     retval = MPI_ERR_TYPE;
1492   } else if (op == MPI_OP_NULL) {
1493     retval = MPI_ERR_OP;
1494   } else {
1495     smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
1496     retval = MPI_SUCCESS;
1497   }
1498 #ifdef HAVE_TRACING
1499   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1500 #endif
1501   smpi_bench_begin();
1502   return retval;
1503 }
1504
1505 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
1506                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1507 {
1508   int retval, i, size, count;
1509   int *displs;
1510   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1511
1512   smpi_bench_end();
1513 #ifdef HAVE_TRACING
1514   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1515 #endif
1516   if (comm == MPI_COMM_NULL) {
1517     retval = MPI_ERR_COMM;
1518   } else if (datatype == MPI_DATATYPE_NULL) {
1519     retval = MPI_ERR_TYPE;
1520   } else if (op == MPI_OP_NULL) {
1521     retval = MPI_ERR_OP;
1522   } else if (recvcounts == NULL) {
1523     retval = MPI_ERR_ARG;
1524   } else {
1525     /* arbitrarily choose root as rank 0 */
1526     /* TODO: faster direct implementation ? */
1527     size = smpi_comm_size(comm);
1528     count = 0;
1529     displs = xbt_new(int, size);
1530     for (i = 0; i < size; i++) {
1531       count += recvcounts[i];
1532       displs[i] = 0;
1533     }
1534     smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, 0, comm);
1535     smpi_mpi_scatterv(recvbuf, recvcounts, displs, datatype, recvbuf,
1536                       recvcounts[rank], datatype, 0, comm);
1537     xbt_free(displs);
1538     retval = MPI_SUCCESS;
1539   }
1540 #ifdef HAVE_TRACING
1541   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1542 #endif
1543   smpi_bench_begin();
1544   return retval;
1545 }
1546
1547 int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1548                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
1549                  MPI_Comm comm)
1550 {
1551   int retval, size, sendsize;
1552
1553   smpi_bench_end();
1554 #ifdef HAVE_TRACING
1555   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1556   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1557 #endif
1558   if (comm == MPI_COMM_NULL) {
1559     retval = MPI_ERR_COMM;
1560   } else if (sendtype == MPI_DATATYPE_NULL
1561              || recvtype == MPI_DATATYPE_NULL) {
1562     retval = MPI_ERR_TYPE;
1563   } else {
1564     size = smpi_comm_size(comm);
1565     sendsize = smpi_datatype_size(sendtype) * sendcount;
1566     if (sendsize < 200 && size > 12) {
1567       retval =
1568           smpi_coll_tuned_alltoall_bruck(sendbuf, sendcount, sendtype,
1569                                          recvbuf, recvcount, recvtype,
1570                                          comm);
1571     } else if (sendsize < 3000) {
1572       retval =
1573           smpi_coll_tuned_alltoall_basic_linear(sendbuf, sendcount,
1574                                                 sendtype, recvbuf,
1575                                                 recvcount, recvtype, comm);
1576     } else {
1577       retval =
1578           smpi_coll_tuned_alltoall_pairwise(sendbuf, sendcount, sendtype,
1579                                             recvbuf, recvcount, recvtype,
1580                                             comm);
1581     }
1582   }
1583 #ifdef HAVE_TRACING
1584   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1585 #endif
1586   smpi_bench_begin();
1587   return retval;
1588 }
1589
1590 int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
1591                   MPI_Datatype sendtype, void *recvbuf, int *recvcounts,
1592                   int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
1593 {
1594   int retval;
1595
1596   smpi_bench_end();
1597 #ifdef HAVE_TRACING
1598   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1599   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
1600 #endif
1601   if (comm == MPI_COMM_NULL) {
1602     retval = MPI_ERR_COMM;
1603   } else if (sendtype == MPI_DATATYPE_NULL
1604              || recvtype == MPI_DATATYPE_NULL) {
1605     retval = MPI_ERR_TYPE;
1606   } else if (sendcounts == NULL || senddisps == NULL || recvcounts == NULL
1607              || recvdisps == NULL) {
1608     retval = MPI_ERR_ARG;
1609   } else {
1610     retval =
1611         smpi_coll_basic_alltoallv(sendbuf, sendcounts, senddisps, sendtype,
1612                                   recvbuf, recvcounts, recvdisps, recvtype,
1613                                   comm);
1614   }
1615 #ifdef HAVE_TRACING
1616   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1617 #endif
1618   smpi_bench_begin();
1619   return retval;
1620 }
1621
1622
1623 int PMPI_Get_processor_name(char *name, int *resultlen)
1624 {
1625   int retval = MPI_SUCCESS;
1626
1627   smpi_bench_end();
1628   strncpy(name, SIMIX_host_get_name(SIMIX_host_self()),
1629           MPI_MAX_PROCESSOR_NAME - 1);
1630   *resultlen =
1631       strlen(name) >
1632       MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
1633
1634   smpi_bench_begin();
1635   return retval;
1636 }
1637
1638 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
1639 {
1640   int retval = MPI_SUCCESS;
1641   size_t size;
1642
1643   smpi_bench_end();
1644   if (status == NULL || count == NULL) {
1645     retval = MPI_ERR_ARG;
1646   } else if (datatype == MPI_DATATYPE_NULL) {
1647     retval = MPI_ERR_TYPE;
1648   } else {
1649     size = smpi_datatype_size(datatype);
1650     if (size == 0) {
1651       *count = 0;
1652     } else if (status->count % size != 0) {
1653       retval = MPI_UNDEFINED;
1654     } else {
1655       *count = smpi_mpi_get_count(status, datatype);
1656     }
1657   }
1658   smpi_bench_begin();
1659   return retval;
1660 }
1661
1662 /* The following calls are not yet implemented and will fail at runtime. */
1663 /* Once implemented, please move them above this notice. */
1664
1665 static int not_yet_implemented(void) {
1666    xbt_die("Not yet implemented");
1667    return MPI_ERR_OTHER;
1668 }
1669
1670 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
1671    return not_yet_implemented();
1672 }
1673
1674 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
1675    return not_yet_implemented();
1676 }
1677
1678 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periods, int reorder, MPI_Comm* comm_cart) {
1679    return not_yet_implemented();
1680 }
1681
1682 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
1683    return not_yet_implemented();
1684 }
1685
1686 int PMPI_Cart_map(MPI_Comm comm_old, int ndims, int* dims, int* periods, int* newrank) {
1687    return not_yet_implemented();
1688 }
1689
1690 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
1691    return not_yet_implemented();
1692 }
1693
1694 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
1695    return not_yet_implemented();
1696 }
1697
1698 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
1699    return not_yet_implemented();
1700 }
1701
1702 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
1703    return not_yet_implemented();
1704 }
1705
1706 int PMPI_Graph_create(MPI_Comm comm_old, int nnodes, int* index, int* edges, int reorder, MPI_Comm* comm_graph) {
1707    return not_yet_implemented();
1708 }
1709
1710 int PMPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int* index, int* edges) {
1711    return not_yet_implemented();
1712 }
1713
1714 int PMPI_Graph_map(MPI_Comm comm_old, int nnodes, int* index, int* edges, int* newrank) {
1715    return not_yet_implemented();
1716 }
1717
1718 int PMPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int* neighbors) {
1719    return not_yet_implemented();
1720 }
1721
1722 int PMPI_Graph_neighbors_count(MPI_Comm comm, int rank, int* nneighbors) {
1723    return not_yet_implemented();
1724 }
1725
1726 int PMPI_Graphdims_get(MPI_Comm comm, int* nnodes, int* nedges) {
1727    return not_yet_implemented();
1728 }
1729
1730 int PMPI_Topo_test(MPI_Comm comm, int* top_type) {
1731    return not_yet_implemented();
1732 }
1733
1734 int PMPI_Error_class(int errorcode, int* errorclass) {
1735    return not_yet_implemented();
1736 }
1737
1738 int PMPI_Errhandler_create(MPI_Handler_function* function, MPI_Errhandler* errhandler) {
1739    return not_yet_implemented();
1740 }
1741
1742 int PMPI_Errhandler_free(MPI_Errhandler* errhandler) {
1743    return not_yet_implemented();
1744 }
1745
1746 int PMPI_Errhandler_get(MPI_Comm comm, MPI_Errhandler* errhandler) {
1747    return not_yet_implemented();
1748 }
1749
1750 int PMPI_Error_string(int errorcode, char* string, int* resultlen) {
1751    return not_yet_implemented();
1752 }
1753
1754 int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler) {
1755    return not_yet_implemented();
1756 }
1757
1758 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* newtype) {
1759    return not_yet_implemented();
1760 }
1761
1762 int PMPI_Cancel(MPI_Request* request) {
1763    return not_yet_implemented();
1764 }
1765
1766 int PMPI_Buffer_attach(void* buffer, int size) {
1767    return not_yet_implemented();
1768 }
1769
1770 int PMPI_Buffer_detach(void* buffer, int* size) {
1771    return not_yet_implemented();
1772 }
1773
1774 int PMPI_Testsome(int incount, MPI_Request* requests, int* outcount, int* indices, MPI_Status* statuses) {
1775    return not_yet_implemented();
1776 }
1777
1778 int PMPI_Comm_test_inter(MPI_Comm comm, int* flag) {
1779    return not_yet_implemented();
1780 }
1781
1782 int PMPI_Unpack(void* inbuf, int insize, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
1783    return not_yet_implemented();
1784 }
1785
1786 int PMPI_Type_commit(MPI_Datatype* datatype) {
1787    return not_yet_implemented();
1788 }
1789
1790 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* newtype) {
1791    return not_yet_implemented();
1792 }
1793
1794 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* newtype) {
1795    return not_yet_implemented();
1796 }
1797
1798 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* newtype) {
1799    return not_yet_implemented();
1800 }
1801
1802 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* newtype) {
1803    return not_yet_implemented();
1804 }
1805
1806 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* newtype) {
1807    return not_yet_implemented();
1808 }
1809
1810 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
1811    return not_yet_implemented();
1812 }
1813
1814 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
1815    return not_yet_implemented();
1816 }
1817
1818 int PMPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out) {
1819    return not_yet_implemented();
1820 }
1821
1822 int PMPI_Intercomm_merge(MPI_Comm comm, int high, MPI_Comm* comm_out) {
1823    return not_yet_implemented();
1824 }
1825
1826 int PMPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
1827    return not_yet_implemented();
1828 }
1829
1830 int PMPI_Bsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
1831    return not_yet_implemented();
1832 }
1833
1834 int PMPI_Ibsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
1835    return not_yet_implemented();
1836 }
1837
1838 int PMPI_Comm_remote_group(MPI_Comm comm, MPI_Group* group) {
1839    return not_yet_implemented();
1840 }
1841
1842 int PMPI_Comm_remote_size(MPI_Comm comm, int* size) {
1843    return not_yet_implemented();
1844 }
1845
1846 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
1847    return not_yet_implemented();
1848 }
1849
1850 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1851    return not_yet_implemented();
1852 }
1853
1854 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
1855    return not_yet_implemented();
1856 }
1857
1858 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
1859    return not_yet_implemented();
1860 }
1861
1862 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
1863    return not_yet_implemented();
1864 }
1865
1866 int PMPI_Rsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
1867    return not_yet_implemented();
1868 }
1869
1870 int PMPI_Rsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
1871    return not_yet_implemented();
1872 }
1873
1874 int PMPI_Irsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
1875    return not_yet_implemented();
1876 }
1877
1878 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
1879    return not_yet_implemented();
1880 }
1881
1882 int PMPI_Keyval_free(int* keyval) {
1883    return not_yet_implemented();
1884 }
1885
1886 int PMPI_Test_cancelled(MPI_Status* status, int* flag) {
1887    return not_yet_implemented();
1888 }
1889
1890 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
1891    return not_yet_implemented();
1892 }
1893
1894 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses) {
1895    return not_yet_implemented();
1896 }
1897
1898 int PMPI_Get_elements(MPI_Status* status, MPI_Datatype datatype, int* elements) {
1899    return not_yet_implemented();
1900 }
1901
1902 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
1903    return not_yet_implemented();
1904 }
1905
1906 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1907    return not_yet_implemented();
1908 }
1909
1910 int PMPI_Initialized(int* flag) {
1911    return not_yet_implemented();
1912 }