1 /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
2 * All rights reserved. */
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. */
8 #include "smpi_coll_private.h"
9 #include "smpi_mpi_dt_private.h"
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi,
12 "Logging specific to SMPI (mpi)");
14 /* MPI User level calls */
16 int MPI_Init(int* argc, char*** argv) {
17 smpi_process_init(argc, argv);
18 smpi_bench_begin(-1, NULL);
20 TRACE_smpi_init(smpi_process_index());
25 int MPI_Finalize(void) {
27 TRACE_smpi_finalize(smpi_process_index());
29 smpi_bench_end(-1, NULL);
30 smpi_process_destroy();
34 int MPI_Init_thread(int* argc, char*** argv, int required, int* provided) {
35 if(provided != NULL) {
36 *provided = MPI_THREAD_MULTIPLE;
38 return MPI_Init(argc, argv);
41 int MPI_Query_thread(int* provided) {
44 smpi_bench_end(-1, NULL);
45 if(provided == NULL) {
48 *provided = MPI_THREAD_MULTIPLE;
51 smpi_bench_begin(-1, NULL);
55 int MPI_Is_thread_main(int* flag) {
58 smpi_bench_end(-1, NULL);
62 *flag = smpi_process_index() == 0;
65 smpi_bench_begin(-1, NULL);
69 int MPI_Abort(MPI_Comm comm, int errorcode) {
70 smpi_bench_end(-1, NULL);
71 smpi_process_destroy();
72 // FIXME: should kill all processes in comm instead
73 SIMIX_process_kill(SIMIX_process_self());
77 double MPI_Wtime(void) {
80 smpi_bench_end(-1, NULL);
81 time = SIMIX_get_clock();
82 smpi_bench_begin(-1, NULL);
86 int MPI_Address(void *location, MPI_Aint *address) {
89 smpi_bench_end(-1, NULL);
93 *address = (MPI_Aint)location;
95 smpi_bench_begin(-1, NULL);
99 int MPI_Type_free(MPI_Datatype* datatype) {
102 smpi_bench_end(-1, NULL);
104 retval = MPI_ERR_ARG;
106 // FIXME: always fail for now
107 retval = MPI_ERR_TYPE;
109 smpi_bench_begin(-1, NULL);
113 int MPI_Type_size(MPI_Datatype datatype, size_t* size) {
116 smpi_bench_end(-1, NULL);
117 if(datatype == MPI_DATATYPE_NULL) {
118 retval = MPI_ERR_TYPE;
119 } else if(size == NULL) {
120 retval = MPI_ERR_ARG;
122 *size = smpi_datatype_size(datatype);
123 retval = MPI_SUCCESS;
125 smpi_bench_begin(-1, NULL);
129 int MPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint* lb, MPI_Aint* extent) {
132 smpi_bench_end(-1, NULL);
133 if(datatype == MPI_DATATYPE_NULL) {
134 retval = MPI_ERR_TYPE;
135 } else if(lb == NULL || extent == NULL) {
136 retval = MPI_ERR_ARG;
138 retval = smpi_datatype_extent(datatype, lb, extent);
140 smpi_bench_begin(-1, NULL);
144 int MPI_Type_extent(MPI_Datatype datatype, MPI_Aint* extent) {
148 smpi_bench_end(-1, NULL);
149 if(datatype == MPI_DATATYPE_NULL) {
150 retval = MPI_ERR_TYPE;
151 } else if(extent == NULL) {
152 retval = MPI_ERR_ARG;
154 retval = smpi_datatype_extent(datatype, &dummy, extent);
156 smpi_bench_begin(-1, NULL);
160 int MPI_Type_lb(MPI_Datatype datatype, MPI_Aint* disp) {
163 smpi_bench_end(-1, NULL);
164 if(datatype == MPI_DATATYPE_NULL) {
165 retval = MPI_ERR_TYPE;
166 } else if(disp == NULL) {
167 retval = MPI_ERR_ARG;
169 *disp = smpi_datatype_lb(datatype);
170 retval = MPI_SUCCESS;
172 smpi_bench_begin(-1, NULL);
176 int MPI_Type_ub(MPI_Datatype datatype, MPI_Aint* disp) {
179 smpi_bench_end(-1, NULL);
180 if(datatype == MPI_DATATYPE_NULL) {
181 retval = MPI_ERR_TYPE;
182 } else if(disp == NULL) {
183 retval = MPI_ERR_ARG;
185 *disp = smpi_datatype_ub(datatype);
186 retval = MPI_SUCCESS;
188 smpi_bench_begin(-1, NULL);
192 int MPI_Op_create(MPI_User_function* function, int commute, MPI_Op* op) {
195 smpi_bench_end(-1, NULL);
196 if(function == NULL || op == NULL) {
197 retval = MPI_ERR_ARG;
199 *op = smpi_op_new(function, commute);
200 retval = MPI_SUCCESS;
202 smpi_bench_begin(-1, NULL);
206 int MPI_Op_free(MPI_Op* op) {
209 smpi_bench_end(-1, NULL);
211 retval = MPI_ERR_ARG;
212 } else if(*op == MPI_OP_NULL) {
215 smpi_op_destroy(*op);
217 retval = MPI_SUCCESS;
219 smpi_bench_begin(-1, NULL);
223 int MPI_Group_free(MPI_Group *group) {
226 smpi_bench_end(-1, NULL);
228 retval = MPI_ERR_ARG;
230 smpi_group_destroy(*group);
231 *group = MPI_GROUP_NULL;
232 retval = MPI_SUCCESS;
234 smpi_bench_begin(-1, NULL);
238 int MPI_Group_size(MPI_Group group, int* size) {
241 smpi_bench_end(-1, NULL);
242 if(group == MPI_GROUP_NULL) {
243 retval = MPI_ERR_GROUP;
244 } else if(size == NULL) {
245 retval = MPI_ERR_ARG;
247 *size = smpi_group_size(group);
248 retval = MPI_SUCCESS;
250 smpi_bench_begin(-1, NULL);
254 int MPI_Group_rank(MPI_Group group, int* rank) {
257 smpi_bench_end(-1, NULL);
258 if(group == MPI_GROUP_NULL) {
259 retval = MPI_ERR_GROUP;
260 } else if(rank == NULL) {
261 retval = MPI_ERR_ARG;
263 *rank = smpi_group_rank(group, smpi_process_index());
264 retval = MPI_SUCCESS;
266 smpi_bench_begin(-1, NULL);
270 int MPI_Group_translate_ranks (MPI_Group group1, int n, int* ranks1, MPI_Group group2, int* ranks2) {
271 int retval, i, index;
273 smpi_bench_end(-1, NULL);
274 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
275 retval = MPI_ERR_GROUP;
277 for(i = 0; i < n; i++) {
278 index = smpi_group_index(group1, ranks1[i]);
279 ranks2[i] = smpi_group_rank(group2, index);
281 retval = MPI_SUCCESS;
283 smpi_bench_begin(-1, NULL);
287 int MPI_Group_compare(MPI_Group group1, MPI_Group group2, int* result) {
290 smpi_bench_end(-1, NULL);
291 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
292 retval = MPI_ERR_GROUP;
293 } else if(result == NULL) {
294 retval = MPI_ERR_ARG;
296 *result = smpi_group_compare(group1, group2);
297 retval = MPI_SUCCESS;
299 smpi_bench_begin(-1, NULL);
303 int MPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) {
304 int retval, i, proc1, proc2, size, size2;
306 smpi_bench_end(-1, NULL);
307 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
308 retval = MPI_ERR_GROUP;
309 } else if(newgroup == NULL) {
310 retval = MPI_ERR_ARG;
312 size = smpi_group_size(group1);
313 size2 = smpi_group_size(group2);
314 for(i = 0; i < size2; i++) {
315 proc2 = smpi_group_index(group2, i);
316 proc1 = smpi_group_rank(group1, proc2);
317 if(proc1 == MPI_UNDEFINED) {
322 *newgroup = MPI_GROUP_EMPTY;
324 *newgroup = smpi_group_new(size);
325 size2 = smpi_group_size(group1);
326 for(i = 0; i < size2; i++) {
327 proc1 = smpi_group_index(group1, i);
328 smpi_group_set_mapping(*newgroup, proc1, i);
330 for(i = size2; i < size; i++) {
331 proc2 = smpi_group_index(group2, i - size2);
332 smpi_group_set_mapping(*newgroup, proc2, i);
335 smpi_group_use(*newgroup);
336 retval = MPI_SUCCESS;
338 smpi_bench_begin(-1, NULL);
342 int MPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) {
343 int retval, i, proc1, proc2, size, size2;
345 smpi_bench_end(-1, NULL);
346 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
347 retval = MPI_ERR_GROUP;
348 } else if(newgroup == NULL) {
349 retval = MPI_ERR_ARG;
351 size = smpi_group_size(group1);
352 size2 = smpi_group_size(group2);
353 for(i = 0; i < size2; i++) {
354 proc2 = smpi_group_index(group2, i);
355 proc1 = smpi_group_rank(group1, proc2);
356 if(proc1 == MPI_UNDEFINED) {
361 *newgroup = MPI_GROUP_EMPTY;
363 *newgroup = smpi_group_new(size);
364 size2 = smpi_group_size(group1);
365 for(i = 0; i < size2; i++) {
366 proc1 = smpi_group_index(group1, i);
367 proc2 = smpi_group_rank(group2, proc1);
368 if(proc2 != MPI_UNDEFINED) {
369 smpi_group_set_mapping(*newgroup, proc1, i);
373 smpi_group_use(*newgroup);
374 retval = MPI_SUCCESS;
376 smpi_bench_begin(-1, NULL);
380 int MPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) {
381 int retval, i, proc1, proc2, size, size2;
383 smpi_bench_end(-1, NULL);
384 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
385 retval = MPI_ERR_GROUP;
386 } else if(newgroup == NULL) {
387 retval = MPI_ERR_ARG;
389 size = size2 = smpi_group_size(group1);
390 for(i = 0; i < size2; i++) {
391 proc1 = smpi_group_index(group1, i);
392 proc2 = smpi_group_rank(group2, proc1);
393 if(proc2 != MPI_UNDEFINED) {
398 *newgroup = MPI_GROUP_EMPTY;
400 *newgroup = smpi_group_new(size);
401 for(i = 0; i < size2; i++) {
402 proc1 = smpi_group_index(group1, i);
403 proc2 = smpi_group_rank(group2, proc1);
404 if(proc2 == MPI_UNDEFINED) {
405 smpi_group_set_mapping(*newgroup, proc1, i);
409 smpi_group_use(*newgroup);
410 retval = MPI_SUCCESS;
412 smpi_bench_begin(-1, NULL);
416 int MPI_Group_incl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup) {
417 int retval, i, index;
419 smpi_bench_end(-1, NULL);
420 if(group == MPI_GROUP_NULL) {
421 retval = MPI_ERR_GROUP;
422 } else if(newgroup == NULL) {
423 retval = MPI_ERR_ARG;
426 *newgroup = MPI_GROUP_EMPTY;
427 } else if(n == smpi_group_size(group)) {
430 *newgroup = smpi_group_new(n);
431 for(i = 0; i < n; i++) {
432 index = smpi_group_index(group, ranks[i]);
433 smpi_group_set_mapping(*newgroup, index, i);
436 smpi_group_use(*newgroup);
437 retval = MPI_SUCCESS;
439 smpi_bench_begin(-1, NULL);
443 int MPI_Group_excl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup) {
444 int retval, i, size, rank, index;
446 smpi_bench_end(-1, NULL);
447 if(group == MPI_GROUP_NULL) {
448 retval = MPI_ERR_GROUP;
449 } else if(newgroup == NULL) {
450 retval = MPI_ERR_ARG;
454 } else if(n == smpi_group_size(group)) {
455 *newgroup = MPI_GROUP_EMPTY;
457 size = smpi_group_size(group) - n;
458 *newgroup = smpi_group_new(size);
461 for(i = 0; i < n; i++) {
462 if(ranks[i] == rank) {
467 index = smpi_group_index(group, rank);
468 smpi_group_set_mapping(*newgroup, index, rank);
473 smpi_group_use(*newgroup);
474 retval = MPI_SUCCESS;
476 smpi_bench_begin(-1, NULL);
480 int MPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group* newgroup) {
481 int retval, i, j, rank, size, index;
483 smpi_bench_end(-1, NULL);
484 if(group == MPI_GROUP_NULL) {
485 retval = MPI_ERR_GROUP;
486 } else if(newgroup == NULL) {
487 retval = MPI_ERR_ARG;
490 *newgroup = MPI_GROUP_EMPTY;
493 for(i = 0; i < n; i++) {
494 for(rank = ranges[i][0]; /* First */
495 rank >= 0 && rank <= ranges[i][1]; /* Last */
496 rank += ranges[i][2] /* Stride */) {
500 if(size == smpi_group_size(group)) {
503 *newgroup = smpi_group_new(size);
505 for(i = 0; i < n; i++) {
506 for(rank = ranges[i][0]; /* First */
507 rank >= 0 && rank <= ranges[i][1]; /* Last */
508 rank += ranges[i][2] /* Stride */) {
509 index = smpi_group_index(group, rank);
510 smpi_group_set_mapping(*newgroup, index, j);
516 smpi_group_use(*newgroup);
517 retval = MPI_SUCCESS;
519 smpi_bench_begin(-1, NULL);
523 int MPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group* newgroup) {
524 int retval, i, newrank, rank, size, index, add;
526 smpi_bench_end(-1, NULL);
527 if(group == MPI_GROUP_NULL) {
528 retval = MPI_ERR_GROUP;
529 } else if(newgroup == NULL) {
530 retval = MPI_ERR_ARG;
535 size = smpi_group_size(group);
536 for(i = 0; i < n; i++) {
537 for(rank = ranges[i][0]; /* First */
538 rank >= 0 && rank <= ranges[i][1]; /* Last */
539 rank += ranges[i][2] /* Stride */) {
544 *newgroup = MPI_GROUP_EMPTY;
546 *newgroup = smpi_group_new(size);
548 while(newrank < size) {
549 for(i = 0; i < n; i++) {
551 for(rank = ranges[i][0]; /* First */
552 rank >= 0 && rank <= ranges[i][1]; /* Last */
553 rank += ranges[i][2] /* Stride */) {
554 if(rank == newrank) {
560 index = smpi_group_index(group, newrank);
561 smpi_group_set_mapping(*newgroup, index, newrank);
567 smpi_group_use(*newgroup);
568 retval = MPI_SUCCESS;
570 smpi_bench_begin(-1, NULL);
574 int MPI_Comm_rank(MPI_Comm comm, int* rank) {
577 smpi_bench_end(-1, NULL);
578 if(comm == MPI_COMM_NULL) {
579 retval = MPI_ERR_COMM;
581 *rank = smpi_comm_rank(comm);
582 retval = MPI_SUCCESS;
584 smpi_bench_begin(-1, NULL);
588 int MPI_Comm_size(MPI_Comm comm, int* size) {
591 smpi_bench_end(-1, NULL);
592 if(comm == MPI_COMM_NULL) {
593 retval = MPI_ERR_COMM;
594 } else if(size == NULL) {
595 retval = MPI_ERR_ARG;
597 *size = smpi_comm_size(comm);
598 retval = MPI_SUCCESS;
600 smpi_bench_begin(-1, NULL);
604 int MPI_Comm_group(MPI_Comm comm, MPI_Group* group) {
607 smpi_bench_end(-1, NULL);
608 if(comm == MPI_COMM_NULL) {
609 retval = MPI_ERR_COMM;
610 } else if(group == NULL) {
611 retval = MPI_ERR_ARG;
613 *group = smpi_comm_group(comm);
614 retval = MPI_SUCCESS;
616 smpi_bench_begin(-1, NULL);
620 int MPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int* result) {
623 smpi_bench_end(-1, NULL);
624 if(comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
625 retval = MPI_ERR_COMM;
626 } else if(result == NULL) {
627 retval = MPI_ERR_ARG;
629 if(comm1 == comm2) { /* Same communicators means same groups */
632 *result = smpi_group_compare(smpi_comm_group(comm1), smpi_comm_group(comm2));
633 if(*result == MPI_IDENT) {
634 *result = MPI_CONGRUENT;
637 retval = MPI_SUCCESS;
639 smpi_bench_begin(-1, NULL);
643 int MPI_Comm_dup(MPI_Comm comm, MPI_Comm* newcomm) {
646 smpi_bench_end(-1, NULL);
647 if(comm == MPI_COMM_NULL) {
648 retval = MPI_ERR_COMM;
649 } else if(newcomm == NULL) {
650 retval = MPI_ERR_ARG;
652 *newcomm = smpi_comm_new(smpi_comm_group(comm));
653 retval = MPI_SUCCESS;
655 smpi_bench_begin(-1, NULL);
659 int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm* newcomm) {
662 smpi_bench_end(-1, NULL);
663 if(comm == MPI_COMM_NULL) {
664 retval = MPI_ERR_COMM;
665 } else if(group == MPI_GROUP_NULL) {
666 retval = MPI_ERR_GROUP;
667 } else if(newcomm == NULL) {
668 retval = MPI_ERR_ARG;
670 *newcomm = smpi_comm_new(group);
671 retval = MPI_SUCCESS;
673 smpi_bench_begin(-1, NULL);
677 int MPI_Comm_free(MPI_Comm* comm) {
680 smpi_bench_end(-1, NULL);
682 retval = MPI_ERR_ARG;
683 } else if(*comm == MPI_COMM_NULL) {
684 retval = MPI_ERR_COMM;
686 smpi_comm_destroy(*comm);
687 *comm = MPI_COMM_NULL;
688 retval = MPI_SUCCESS;
690 smpi_bench_begin(-1, NULL);
694 int MPI_Send_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request) {
696 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
698 smpi_bench_end(rank, "Send_init");
699 if(request == NULL) {
700 retval = MPI_ERR_ARG;
701 } else if (comm == MPI_COMM_NULL) {
702 retval = MPI_ERR_COMM;
704 *request = smpi_mpi_send_init(buf, count, datatype, dst, tag, comm);
705 retval = MPI_SUCCESS;
707 smpi_bench_begin(rank, "Send_init");
711 int MPI_Recv_init(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request* request) {
713 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
715 smpi_bench_end(rank, "Recv_init");
716 if(request == NULL) {
717 retval = MPI_ERR_ARG;
718 } else if (comm == MPI_COMM_NULL) {
719 retval = MPI_ERR_COMM;
721 *request = smpi_mpi_recv_init(buf, count, datatype, src, tag, comm);
722 retval = MPI_SUCCESS;
724 smpi_bench_begin(rank, "Recv_init");
728 int MPI_Start(MPI_Request* request) {
730 MPI_Comm comm = (*request)->comm;
731 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
733 smpi_bench_end(rank, "Start");
734 if(request == NULL) {
735 retval = MPI_ERR_ARG;
737 smpi_mpi_start(*request);
738 retval = MPI_SUCCESS;
740 smpi_bench_begin(rank, "Start");
744 int MPI_Startall(int count, MPI_Request* requests) {
746 MPI_Comm comm = count > 0 && requests ? requests[0]->comm : MPI_COMM_NULL;
747 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
749 smpi_bench_end(rank, "Startall");
750 if(requests == NULL) {
751 retval = MPI_ERR_ARG;
753 smpi_mpi_startall(count, requests);
754 retval = MPI_SUCCESS;
756 smpi_bench_begin(rank, "Startall");
760 int MPI_Request_free(MPI_Request* request) {
762 MPI_Comm comm = (*request)->comm;
763 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
765 smpi_bench_end(rank, "Request_free");
766 if(request == NULL) {
767 retval = MPI_ERR_ARG;
769 smpi_mpi_request_free(request);
770 retval = MPI_SUCCESS;
772 smpi_bench_begin(rank, "Request_free");
776 int MPI_Irecv(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request* request) {
778 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
780 smpi_bench_end(rank, "Irecv");
781 if(request == NULL) {
782 retval = MPI_ERR_ARG;
783 } else if (comm == MPI_COMM_NULL) {
784 retval = MPI_ERR_COMM;
786 *request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm);
787 retval = MPI_SUCCESS;
789 smpi_bench_begin(rank, "Irecv");
793 int MPI_Isend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request) {
795 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
797 smpi_bench_end(rank, "Isend");
798 if(request == NULL) {
799 retval = MPI_ERR_ARG;
800 } else if (comm == MPI_COMM_NULL) {
801 retval = MPI_ERR_COMM;
803 *request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
804 retval = MPI_SUCCESS;
806 smpi_bench_begin(rank, "Isend");
810 int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status* status) {
812 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
814 smpi_bench_end(rank, "Recv");
815 if (comm == MPI_COMM_NULL) {
816 retval = MPI_ERR_COMM;
818 smpi_mpi_recv(buf, count, datatype, src, tag, comm, status);
819 retval = MPI_SUCCESS;
821 smpi_bench_begin(rank, "Recv");
825 int MPI_Send(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
827 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
829 smpi_bench_end(rank, "Send");
830 if (comm == MPI_COMM_NULL) {
831 retval = MPI_ERR_COMM;
833 smpi_mpi_send(buf, count, datatype, dst, tag, comm);
834 retval = MPI_SUCCESS;
836 smpi_bench_begin(rank, "Send");
840 int MPI_Sendrecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status* status) {
842 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
844 smpi_bench_end(rank, "Sendrecv");
845 if (comm == MPI_COMM_NULL) {
846 retval = MPI_ERR_COMM;
847 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
848 retval = MPI_ERR_TYPE;
850 smpi_mpi_sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm, status);
851 retval = MPI_SUCCESS;
853 smpi_bench_begin(rank, "Sendrecv");
857 int MPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag, MPI_Comm comm, MPI_Status* status) {
858 //TODO: suboptimal implementation
862 size = smpi_datatype_size(datatype) * count;
863 recvbuf = xbt_new(char, size);
864 retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
865 memcpy(buf, recvbuf, size * sizeof(char));
870 int MPI_Test(MPI_Request* request, int* flag, MPI_Status* status) {
872 int rank = request && (*request)->comm != MPI_COMM_NULL
873 ? smpi_comm_rank((*request)->comm)
876 smpi_bench_end(rank, "Test");
877 if(request == NULL || flag == NULL) {
878 retval = MPI_ERR_ARG;
879 } else if(*request == MPI_REQUEST_NULL) {
880 retval = MPI_ERR_REQUEST;
882 *flag = smpi_mpi_test(request, status);
883 retval = MPI_SUCCESS;
885 smpi_bench_begin(rank, "Test");
889 int MPI_Testany(int count, MPI_Request requests[], int* index, int* flag, MPI_Status* status) {
892 smpi_bench_end(-1, NULL); //FIXME
893 if(index == NULL || flag == NULL) {
894 retval = MPI_ERR_ARG;
896 *flag = smpi_mpi_testany(count, requests, index, status);
897 retval = MPI_SUCCESS;
899 smpi_bench_begin(-1, NULL);
903 int MPI_Wait(MPI_Request* request, MPI_Status* status) {
905 int rank = request && (*request)->comm != MPI_COMM_NULL
906 ? smpi_comm_rank((*request)->comm)
909 smpi_bench_end(rank, "Wait");
910 if(request == NULL) {
911 retval = MPI_ERR_ARG;
912 } else if(*request == MPI_REQUEST_NULL) {
913 retval = MPI_ERR_REQUEST;
915 smpi_mpi_wait(request, status);
916 retval = MPI_SUCCESS;
918 smpi_bench_begin(rank, "Wait");
922 int MPI_Waitany(int count, MPI_Request requests[], int* index, MPI_Status* status) {
925 smpi_bench_end(-1, NULL); //FIXME
927 retval = MPI_ERR_ARG;
929 *index = smpi_mpi_waitany(count, requests, status);
930 retval = MPI_SUCCESS;
932 smpi_bench_begin(-1, NULL);
936 int MPI_Waitall(int count, MPI_Request requests[], MPI_Status status[]) {
937 smpi_bench_end(-1, NULL); //FIXME
938 smpi_mpi_waitall(count, requests, status);
939 smpi_bench_begin(-1, NULL);
943 int MPI_Waitsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[]) {
946 smpi_bench_end(-1, NULL); //FIXME
947 if(outcount == NULL || indices == NULL) {
948 retval = MPI_ERR_ARG;
950 *outcount = smpi_mpi_waitsome(incount, requests, indices, status);
951 retval = MPI_SUCCESS;
953 smpi_bench_begin(-1, NULL);
957 int MPI_Bcast(void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) {
959 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
961 smpi_bench_end(rank, "Bcast");
962 if(comm == MPI_COMM_NULL) {
963 retval = MPI_ERR_COMM;
965 smpi_mpi_bcast(buf, count, datatype, root, comm);
966 retval = MPI_SUCCESS;
968 smpi_bench_begin(rank, "Bcast");
972 int MPI_Barrier(MPI_Comm comm) {
974 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
976 smpi_bench_end(rank, "Barrier");
977 if(comm == MPI_COMM_NULL) {
978 retval = MPI_ERR_COMM;
980 smpi_mpi_barrier(comm);
981 retval = MPI_SUCCESS;
983 smpi_bench_begin(rank, "Barrier");
987 int MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) {
989 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
991 smpi_bench_end(rank, "Gather");
992 if(comm == MPI_COMM_NULL) {
993 retval = MPI_ERR_COMM;
994 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
995 retval = MPI_ERR_TYPE;
997 smpi_mpi_gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
998 retval = MPI_SUCCESS;
1000 smpi_bench_begin(rank, "Gather");
1004 int MPI_Gatherv(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int* recvcounts, int* displs, MPI_Datatype recvtype, int root, MPI_Comm comm) {
1006 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1008 smpi_bench_end(rank, "Gatherv");
1009 if(comm == MPI_COMM_NULL) {
1010 retval = MPI_ERR_COMM;
1011 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1012 retval = MPI_ERR_TYPE;
1013 } else if(recvcounts == NULL || displs == NULL) {
1014 retval = MPI_ERR_ARG;
1016 smpi_mpi_gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm);
1017 retval = MPI_SUCCESS;
1019 smpi_bench_begin(rank, "Gatherv");
1023 int MPI_Allgather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) {
1025 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1027 smpi_bench_end(rank, "Allgather");
1028 if(comm == MPI_COMM_NULL) {
1029 retval = MPI_ERR_COMM;
1030 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1031 retval = MPI_ERR_TYPE;
1033 smpi_mpi_allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1034 retval = MPI_SUCCESS;
1036 smpi_bench_begin(rank, "Allgather");
1040 int MPI_Allgatherv(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int* recvcounts, int* displs, MPI_Datatype recvtype, MPI_Comm comm) {
1042 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1044 smpi_bench_end(rank, "Allgatherv");
1045 if(comm == MPI_COMM_NULL) {
1046 retval = MPI_ERR_COMM;
1047 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1048 retval = MPI_ERR_TYPE;
1049 } else if(recvcounts == NULL || displs == NULL) {
1050 retval = MPI_ERR_ARG;
1052 smpi_mpi_allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1053 retval = MPI_SUCCESS;
1055 smpi_bench_begin(rank, "Allgatherv");
1059 int MPI_Scatter(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) {
1061 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1063 smpi_bench_end(rank, "Scatter");
1064 if(comm == MPI_COMM_NULL) {
1065 retval = MPI_ERR_COMM;
1066 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1067 retval = MPI_ERR_TYPE;
1069 smpi_mpi_scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1070 retval = MPI_SUCCESS;
1072 smpi_bench_begin(rank, "Scatter");
1076 int MPI_Scatterv(void* sendbuf, int* sendcounts, int* displs, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) {
1078 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1080 smpi_bench_end(rank, "Scatterv");
1081 if(comm == MPI_COMM_NULL) {
1082 retval = MPI_ERR_COMM;
1083 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1084 retval = MPI_ERR_TYPE;
1085 } else if(sendcounts == NULL || displs == NULL) {
1086 retval = MPI_ERR_ARG;
1088 smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1089 retval = MPI_SUCCESS;
1091 smpi_bench_begin(rank, "Scatterv");
1095 int MPI_Reduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) {
1097 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1099 smpi_bench_end(rank, "Reduce");
1100 if(comm == MPI_COMM_NULL) {
1101 retval = MPI_ERR_COMM;
1102 } else if(datatype == MPI_DATATYPE_NULL || op == MPI_OP_NULL) {
1103 retval = MPI_ERR_ARG;
1105 smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1106 retval = MPI_SUCCESS;
1108 smpi_bench_begin(rank, "Reduce");
1112 int MPI_Allreduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) {
1114 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1116 smpi_bench_end(rank, "Allreduce");
1117 if(comm == MPI_COMM_NULL) {
1118 retval = MPI_ERR_COMM;
1119 } else if(datatype == MPI_DATATYPE_NULL) {
1120 retval = MPI_ERR_TYPE;
1121 } else if(op == MPI_OP_NULL) {
1122 retval = MPI_ERR_OP;
1124 smpi_mpi_allreduce(sendbuf, recvbuf, count, datatype, op, comm);
1125 retval = MPI_SUCCESS;
1127 smpi_bench_begin(rank, "Allreduce");
1131 int MPI_Scan(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) {
1133 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1135 smpi_bench_end(rank, "Scan");
1136 if(comm == MPI_COMM_NULL) {
1137 retval = MPI_ERR_COMM;
1138 } else if(datatype == MPI_DATATYPE_NULL) {
1139 retval = MPI_ERR_TYPE;
1140 } else if(op == MPI_OP_NULL) {
1141 retval = MPI_ERR_OP;
1143 smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
1144 retval = MPI_SUCCESS;
1146 smpi_bench_begin(rank, "Scan");
1150 int MPI_Reduce_scatter(void* sendbuf, void* recvbuf, int* recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) {
1151 int retval, i, size, count;
1153 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1155 smpi_bench_end(rank, "Reduce_scatter");
1156 if(comm == MPI_COMM_NULL) {
1157 retval = MPI_ERR_COMM;
1158 } else if(datatype == MPI_DATATYPE_NULL) {
1159 retval = MPI_ERR_TYPE;
1160 } else if(op == MPI_OP_NULL) {
1161 retval = MPI_ERR_OP;
1162 } else if(recvcounts == NULL) {
1163 retval = MPI_ERR_ARG;
1165 /* arbitrarily choose root as rank 0 */
1166 /* TODO: faster direct implementation ? */
1167 size = smpi_comm_size(comm);
1169 displs = xbt_new(int, size);
1170 for(i = 0; i < size; i++) {
1171 count += recvcounts[i];
1174 smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, 0, comm);
1175 smpi_mpi_scatterv(recvbuf, recvcounts, displs, datatype, recvbuf, recvcounts[rank], datatype, 0, comm);
1177 retval = MPI_SUCCESS;
1179 smpi_bench_begin(rank, "Reduce_scatter");
1183 int MPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) {
1184 int retval, size, sendsize;
1185 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1187 smpi_bench_end(rank, "Alltoall");
1188 if(comm == MPI_COMM_NULL) {
1189 retval = MPI_ERR_COMM;
1190 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1191 retval = MPI_ERR_TYPE;
1193 size = smpi_comm_size(comm);
1194 sendsize = smpi_datatype_size(sendtype) * sendcount;
1195 if(sendsize < 200 && size > 12) {
1196 retval = smpi_coll_tuned_alltoall_bruck(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1197 } else if(sendsize < 3000) {
1198 retval = smpi_coll_tuned_alltoall_basic_linear(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1200 retval = smpi_coll_tuned_alltoall_pairwise(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1203 smpi_bench_begin(rank, "Alltoall");
1207 int MPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf, int *recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm) {
1209 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1211 smpi_bench_end(rank, "Alltoallv");
1212 if(comm == MPI_COMM_NULL) {
1213 retval = MPI_ERR_COMM;
1214 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1215 retval = MPI_ERR_TYPE;
1216 } else if(sendcounts == NULL || senddisps == NULL || recvcounts == NULL || recvdisps == NULL) {
1217 retval = MPI_ERR_ARG;
1219 retval = smpi_coll_basic_alltoallv(sendbuf, sendcounts, senddisps, sendtype, recvbuf, recvcounts, recvdisps, recvtype, comm);
1221 smpi_bench_begin(rank, "Alltoallv");
1226 int MPI_Get_processor_name( char *name, int *resultlen ) {
1227 int retval = MPI_SUCCESS;
1228 smpi_bench_end(-1, NULL);
1229 strncpy( name , SIMIX_host_get_name(SIMIX_host_self()), MPI_MAX_PROCESSOR_NAME-1);
1230 *resultlen= strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
1232 smpi_bench_begin(-1, NULL);