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);
22 int MPI_Finalize(void) {
23 smpi_bench_end(-1, NULL);
24 smpi_process_destroy();
28 int MPI_Init_thread(int* argc, char*** argv, int required, int* provided) {
29 if(provided != NULL) {
30 *provided = MPI_THREAD_MULTIPLE;
32 return MPI_Init(argc, argv);
35 int MPI_Query_thread(int* provided) {
38 smpi_bench_end(-1, NULL);
39 if(provided == NULL) {
42 *provided = MPI_THREAD_MULTIPLE;
45 smpi_bench_begin(-1, NULL);
49 int MPI_Is_thread_main(int* flag) {
52 smpi_bench_end(-1, NULL);
56 *flag = smpi_process_index() == 0;
59 smpi_bench_begin(-1, NULL);
63 int MPI_Abort(MPI_Comm comm, int errorcode) {
64 smpi_bench_end(-1, NULL);
65 smpi_process_destroy();
66 // FIXME: should kill all processes in comm instead
67 SIMIX_process_kill(SIMIX_process_self());
71 double MPI_Wtime(void) {
74 smpi_bench_end(-1, NULL);
75 time = SIMIX_get_clock();
76 smpi_bench_begin(-1, NULL);
80 int MPI_Address(void *location, MPI_Aint *address) {
83 smpi_bench_end(-1, NULL);
87 *address = (MPI_Aint)location;
89 smpi_bench_begin(-1, NULL);
93 int MPI_Type_free(MPI_Datatype* datatype) {
96 smpi_bench_end(-1, NULL);
100 // FIXME: always fail for now
101 retval = MPI_ERR_TYPE;
103 smpi_bench_begin(-1, NULL);
107 int MPI_Type_size(MPI_Datatype datatype, size_t* size) {
110 smpi_bench_end(-1, NULL);
111 if(datatype == MPI_DATATYPE_NULL) {
112 retval = MPI_ERR_TYPE;
113 } else if(size == NULL) {
114 retval = MPI_ERR_ARG;
116 *size = smpi_datatype_size(datatype);
117 retval = MPI_SUCCESS;
119 smpi_bench_begin(-1, NULL);
123 int MPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint* lb, MPI_Aint* extent) {
126 smpi_bench_end(-1, NULL);
127 if(datatype == MPI_DATATYPE_NULL) {
128 retval = MPI_ERR_TYPE;
129 } else if(lb == NULL || extent == NULL) {
130 retval = MPI_ERR_ARG;
132 retval = smpi_datatype_extent(datatype, lb, extent);
134 smpi_bench_begin(-1, NULL);
138 int MPI_Type_extent(MPI_Datatype datatype, MPI_Aint* extent) {
142 smpi_bench_end(-1, NULL);
143 if(datatype == MPI_DATATYPE_NULL) {
144 retval = MPI_ERR_TYPE;
145 } else if(extent == NULL) {
146 retval = MPI_ERR_ARG;
148 retval = smpi_datatype_extent(datatype, &dummy, extent);
150 smpi_bench_begin(-1, NULL);
154 int MPI_Type_lb(MPI_Datatype datatype, MPI_Aint* disp) {
157 smpi_bench_end(-1, NULL);
158 if(datatype == MPI_DATATYPE_NULL) {
159 retval = MPI_ERR_TYPE;
160 } else if(disp == NULL) {
161 retval = MPI_ERR_ARG;
163 *disp = smpi_datatype_lb(datatype);
164 retval = MPI_SUCCESS;
166 smpi_bench_begin(-1, NULL);
170 int MPI_Type_ub(MPI_Datatype datatype, MPI_Aint* disp) {
173 smpi_bench_end(-1, NULL);
174 if(datatype == MPI_DATATYPE_NULL) {
175 retval = MPI_ERR_TYPE;
176 } else if(disp == NULL) {
177 retval = MPI_ERR_ARG;
179 *disp = smpi_datatype_ub(datatype);
180 retval = MPI_SUCCESS;
182 smpi_bench_begin(-1, NULL);
186 int MPI_Op_create(MPI_User_function* function, int commute, MPI_Op* op) {
189 smpi_bench_end(-1, NULL);
190 if(function == NULL || op == NULL) {
191 retval = MPI_ERR_ARG;
193 *op = smpi_op_new(function, commute);
194 retval = MPI_SUCCESS;
196 smpi_bench_begin(-1, NULL);
200 int MPI_Op_free(MPI_Op* op) {
203 smpi_bench_end(-1, NULL);
205 retval = MPI_ERR_ARG;
206 } else if(*op == MPI_OP_NULL) {
209 smpi_op_destroy(*op);
211 retval = MPI_SUCCESS;
213 smpi_bench_begin(-1, NULL);
217 int MPI_Group_free(MPI_Group *group) {
220 smpi_bench_end(-1, NULL);
222 retval = MPI_ERR_ARG;
224 smpi_group_destroy(*group);
225 *group = MPI_GROUP_NULL;
226 retval = MPI_SUCCESS;
228 smpi_bench_begin(-1, NULL);
232 int MPI_Group_size(MPI_Group group, int* size) {
235 smpi_bench_end(-1, NULL);
236 if(group == MPI_GROUP_NULL) {
237 retval = MPI_ERR_GROUP;
238 } else if(size == NULL) {
239 retval = MPI_ERR_ARG;
241 *size = smpi_group_size(group);
242 retval = MPI_SUCCESS;
244 smpi_bench_begin(-1, NULL);
248 int MPI_Group_rank(MPI_Group group, int* rank) {
251 smpi_bench_end(-1, NULL);
252 if(group == MPI_GROUP_NULL) {
253 retval = MPI_ERR_GROUP;
254 } else if(rank == NULL) {
255 retval = MPI_ERR_ARG;
257 *rank = smpi_group_rank(group, smpi_process_index());
258 retval = MPI_SUCCESS;
260 smpi_bench_begin(-1, NULL);
264 int MPI_Group_translate_ranks (MPI_Group group1, int n, int* ranks1, MPI_Group group2, int* ranks2) {
265 int retval, i, index;
267 smpi_bench_end(-1, NULL);
268 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
269 retval = MPI_ERR_GROUP;
271 for(i = 0; i < n; i++) {
272 index = smpi_group_index(group1, ranks1[i]);
273 ranks2[i] = smpi_group_rank(group2, index);
275 retval = MPI_SUCCESS;
277 smpi_bench_begin(-1, NULL);
281 int MPI_Group_compare(MPI_Group group1, MPI_Group group2, int* result) {
284 smpi_bench_end(-1, NULL);
285 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
286 retval = MPI_ERR_GROUP;
287 } else if(result == NULL) {
288 retval = MPI_ERR_ARG;
290 *result = smpi_group_compare(group1, group2);
291 retval = MPI_SUCCESS;
293 smpi_bench_begin(-1, NULL);
297 int MPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) {
298 int retval, i, proc1, proc2, size, size2;
300 smpi_bench_end(-1, NULL);
301 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
302 retval = MPI_ERR_GROUP;
303 } else if(newgroup == NULL) {
304 retval = MPI_ERR_ARG;
306 size = smpi_group_size(group1);
307 size2 = smpi_group_size(group2);
308 for(i = 0; i < size2; i++) {
309 proc2 = smpi_group_index(group2, i);
310 proc1 = smpi_group_rank(group1, proc2);
311 if(proc1 == MPI_UNDEFINED) {
316 *newgroup = MPI_GROUP_EMPTY;
318 *newgroup = smpi_group_new(size);
319 size2 = smpi_group_size(group1);
320 for(i = 0; i < size2; i++) {
321 proc1 = smpi_group_index(group1, i);
322 smpi_group_set_mapping(*newgroup, proc1, i);
324 for(i = size2; i < size; i++) {
325 proc2 = smpi_group_index(group2, i - size2);
326 smpi_group_set_mapping(*newgroup, proc2, i);
329 smpi_group_use(*newgroup);
330 retval = MPI_SUCCESS;
332 smpi_bench_begin(-1, NULL);
336 int MPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) {
337 int retval, i, proc1, proc2, size, size2;
339 smpi_bench_end(-1, NULL);
340 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
341 retval = MPI_ERR_GROUP;
342 } else if(newgroup == NULL) {
343 retval = MPI_ERR_ARG;
345 size = smpi_group_size(group1);
346 size2 = smpi_group_size(group2);
347 for(i = 0; i < size2; i++) {
348 proc2 = smpi_group_index(group2, i);
349 proc1 = smpi_group_rank(group1, proc2);
350 if(proc1 == MPI_UNDEFINED) {
355 *newgroup = MPI_GROUP_EMPTY;
357 *newgroup = smpi_group_new(size);
358 size2 = smpi_group_size(group1);
359 for(i = 0; i < size2; i++) {
360 proc1 = smpi_group_index(group1, i);
361 proc2 = smpi_group_rank(group2, proc1);
362 if(proc2 != MPI_UNDEFINED) {
363 smpi_group_set_mapping(*newgroup, proc1, i);
367 smpi_group_use(*newgroup);
368 retval = MPI_SUCCESS;
370 smpi_bench_begin(-1, NULL);
374 int MPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) {
375 int retval, i, proc1, proc2, size, size2;
377 smpi_bench_end(-1, NULL);
378 if(group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
379 retval = MPI_ERR_GROUP;
380 } else if(newgroup == NULL) {
381 retval = MPI_ERR_ARG;
383 size = size2 = smpi_group_size(group1);
384 for(i = 0; i < size2; i++) {
385 proc1 = smpi_group_index(group1, i);
386 proc2 = smpi_group_rank(group2, proc1);
387 if(proc2 != MPI_UNDEFINED) {
392 *newgroup = MPI_GROUP_EMPTY;
394 *newgroup = smpi_group_new(size);
395 for(i = 0; i < size2; i++) {
396 proc1 = smpi_group_index(group1, i);
397 proc2 = smpi_group_rank(group2, proc1);
398 if(proc2 == MPI_UNDEFINED) {
399 smpi_group_set_mapping(*newgroup, proc1, i);
403 smpi_group_use(*newgroup);
404 retval = MPI_SUCCESS;
406 smpi_bench_begin(-1, NULL);
410 int MPI_Group_incl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup) {
411 int retval, i, index;
413 smpi_bench_end(-1, NULL);
414 if(group == MPI_GROUP_NULL) {
415 retval = MPI_ERR_GROUP;
416 } else if(newgroup == NULL) {
417 retval = MPI_ERR_ARG;
420 *newgroup = MPI_GROUP_EMPTY;
421 } else if(n == smpi_group_size(group)) {
424 *newgroup = smpi_group_new(n);
425 for(i = 0; i < n; i++) {
426 index = smpi_group_index(group, ranks[i]);
427 smpi_group_set_mapping(*newgroup, index, i);
430 smpi_group_use(*newgroup);
431 retval = MPI_SUCCESS;
433 smpi_bench_begin(-1, NULL);
437 int MPI_Group_excl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup) {
438 int retval, i, size, rank, index;
440 smpi_bench_end(-1, NULL);
441 if(group == MPI_GROUP_NULL) {
442 retval = MPI_ERR_GROUP;
443 } else if(newgroup == NULL) {
444 retval = MPI_ERR_ARG;
448 } else if(n == smpi_group_size(group)) {
449 *newgroup = MPI_GROUP_EMPTY;
451 size = smpi_group_size(group) - n;
452 *newgroup = smpi_group_new(size);
455 for(i = 0; i < n; i++) {
456 if(ranks[i] == rank) {
461 index = smpi_group_index(group, rank);
462 smpi_group_set_mapping(*newgroup, index, rank);
467 smpi_group_use(*newgroup);
468 retval = MPI_SUCCESS;
470 smpi_bench_begin(-1, NULL);
474 int MPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group* newgroup) {
475 int retval, i, j, rank, size, index;
477 smpi_bench_end(-1, NULL);
478 if(group == MPI_GROUP_NULL) {
479 retval = MPI_ERR_GROUP;
480 } else if(newgroup == NULL) {
481 retval = MPI_ERR_ARG;
484 *newgroup = MPI_GROUP_EMPTY;
487 for(i = 0; i < n; i++) {
488 for(rank = ranges[i][0]; /* First */
489 rank >= 0 && rank <= ranges[i][1]; /* Last */
490 rank += ranges[i][2] /* Stride */) {
494 if(size == smpi_group_size(group)) {
497 *newgroup = smpi_group_new(size);
499 for(i = 0; i < n; i++) {
500 for(rank = ranges[i][0]; /* First */
501 rank >= 0 && rank <= ranges[i][1]; /* Last */
502 rank += ranges[i][2] /* Stride */) {
503 index = smpi_group_index(group, rank);
504 smpi_group_set_mapping(*newgroup, index, j);
510 smpi_group_use(*newgroup);
511 retval = MPI_SUCCESS;
513 smpi_bench_begin(-1, NULL);
517 int MPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group* newgroup) {
518 int retval, i, newrank, rank, size, index, add;
520 smpi_bench_end(-1, NULL);
521 if(group == MPI_GROUP_NULL) {
522 retval = MPI_ERR_GROUP;
523 } else if(newgroup == NULL) {
524 retval = MPI_ERR_ARG;
529 size = smpi_group_size(group);
530 for(i = 0; i < n; i++) {
531 for(rank = ranges[i][0]; /* First */
532 rank >= 0 && rank <= ranges[i][1]; /* Last */
533 rank += ranges[i][2] /* Stride */) {
538 *newgroup = MPI_GROUP_EMPTY;
540 *newgroup = smpi_group_new(size);
542 while(newrank < size) {
543 for(i = 0; i < n; i++) {
545 for(rank = ranges[i][0]; /* First */
546 rank >= 0 && rank <= ranges[i][1]; /* Last */
547 rank += ranges[i][2] /* Stride */) {
548 if(rank == newrank) {
554 index = smpi_group_index(group, newrank);
555 smpi_group_set_mapping(*newgroup, index, newrank);
561 smpi_group_use(*newgroup);
562 retval = MPI_SUCCESS;
564 smpi_bench_begin(-1, NULL);
568 int MPI_Comm_rank(MPI_Comm comm, int* rank) {
571 smpi_bench_end(-1, NULL);
572 if(comm == MPI_COMM_NULL) {
573 retval = MPI_ERR_COMM;
575 *rank = smpi_comm_rank(comm);
576 retval = MPI_SUCCESS;
578 smpi_bench_begin(-1, NULL);
582 int MPI_Comm_size(MPI_Comm comm, int* size) {
585 smpi_bench_end(-1, NULL);
586 if(comm == MPI_COMM_NULL) {
587 retval = MPI_ERR_COMM;
588 } else if(size == NULL) {
589 retval = MPI_ERR_ARG;
591 *size = smpi_comm_size(comm);
592 retval = MPI_SUCCESS;
594 smpi_bench_begin(-1, NULL);
598 int MPI_Comm_group(MPI_Comm comm, MPI_Group* group) {
601 smpi_bench_end(-1, NULL);
602 if(comm == MPI_COMM_NULL) {
603 retval = MPI_ERR_COMM;
604 } else if(group == NULL) {
605 retval = MPI_ERR_ARG;
607 *group = smpi_comm_group(comm);
608 retval = MPI_SUCCESS;
610 smpi_bench_begin(-1, NULL);
614 int MPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int* result) {
617 smpi_bench_end(-1, NULL);
618 if(comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
619 retval = MPI_ERR_COMM;
620 } else if(result == NULL) {
621 retval = MPI_ERR_ARG;
623 if(comm1 == comm2) { /* Same communicators means same groups */
626 *result = smpi_group_compare(smpi_comm_group(comm1), smpi_comm_group(comm2));
627 if(*result == MPI_IDENT) {
628 *result = MPI_CONGRUENT;
631 retval = MPI_SUCCESS;
633 smpi_bench_begin(-1, NULL);
637 int MPI_Comm_dup(MPI_Comm comm, MPI_Comm* newcomm) {
640 smpi_bench_end(-1, NULL);
641 if(comm == MPI_COMM_NULL) {
642 retval = MPI_ERR_COMM;
643 } else if(newcomm == NULL) {
644 retval = MPI_ERR_ARG;
646 *newcomm = smpi_comm_new(smpi_comm_group(comm));
647 retval = MPI_SUCCESS;
649 smpi_bench_begin(-1, NULL);
653 int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm* newcomm) {
656 smpi_bench_end(-1, NULL);
657 if(comm == MPI_COMM_NULL) {
658 retval = MPI_ERR_COMM;
659 } else if(group == MPI_GROUP_NULL) {
660 retval = MPI_ERR_GROUP;
661 } else if(newcomm == NULL) {
662 retval = MPI_ERR_ARG;
664 *newcomm = smpi_comm_new(group);
665 retval = MPI_SUCCESS;
667 smpi_bench_begin(-1, NULL);
671 int MPI_Comm_free(MPI_Comm* comm) {
674 smpi_bench_end(-1, NULL);
676 retval = MPI_ERR_ARG;
677 } else if(*comm == MPI_COMM_NULL) {
678 retval = MPI_ERR_COMM;
680 smpi_comm_destroy(*comm);
681 *comm = MPI_COMM_NULL;
682 retval = MPI_SUCCESS;
684 smpi_bench_begin(-1, NULL);
688 int MPI_Send_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request) {
690 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
692 smpi_bench_end(rank, "Send_init");
693 if(request == NULL) {
694 retval = MPI_ERR_ARG;
695 } else if (comm == MPI_COMM_NULL) {
696 retval = MPI_ERR_COMM;
698 *request = smpi_mpi_send_init(buf, count, datatype, dst, tag, comm);
699 retval = MPI_SUCCESS;
701 smpi_bench_begin(rank, "Send_init");
705 int MPI_Recv_init(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request* request) {
707 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
709 smpi_bench_end(rank, "Recv_init");
710 if(request == NULL) {
711 retval = MPI_ERR_ARG;
712 } else if (comm == MPI_COMM_NULL) {
713 retval = MPI_ERR_COMM;
715 *request = smpi_mpi_recv_init(buf, count, datatype, src, tag, comm);
716 retval = MPI_SUCCESS;
718 smpi_bench_begin(rank, "Recv_init");
722 int MPI_Start(MPI_Request* request) {
724 MPI_Comm comm = (*request)->comm;
725 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
727 smpi_bench_end(rank, "Start");
728 if(request == NULL) {
729 retval = MPI_ERR_ARG;
731 smpi_mpi_start(*request);
732 retval = MPI_SUCCESS;
734 smpi_bench_begin(rank, "Start");
738 int MPI_Startall(int count, MPI_Request* requests) {
740 MPI_Comm comm = count > 0 && requests ? requests[0]->comm : MPI_COMM_NULL;
741 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
743 smpi_bench_end(rank, "Startall");
744 if(requests == NULL) {
745 retval = MPI_ERR_ARG;
747 smpi_mpi_startall(count, requests);
748 retval = MPI_SUCCESS;
750 smpi_bench_begin(rank, "Startall");
754 int MPI_Request_free(MPI_Request* request) {
756 MPI_Comm comm = (*request)->comm;
757 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
759 smpi_bench_end(rank, "Request_free");
760 if(request == NULL) {
761 retval = MPI_ERR_ARG;
763 smpi_mpi_request_free(request);
764 retval = MPI_SUCCESS;
766 smpi_bench_begin(rank, "Request_free");
770 int MPI_Irecv(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request* request) {
772 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
774 smpi_bench_end(rank, "Irecv");
775 if(request == NULL) {
776 retval = MPI_ERR_ARG;
777 } else if (comm == MPI_COMM_NULL) {
778 retval = MPI_ERR_COMM;
780 *request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm);
781 retval = MPI_SUCCESS;
783 smpi_bench_begin(rank, "Irecv");
787 int MPI_Isend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request) {
789 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
791 smpi_bench_end(rank, "Isend");
792 if(request == NULL) {
793 retval = MPI_ERR_ARG;
794 } else if (comm == MPI_COMM_NULL) {
795 retval = MPI_ERR_COMM;
797 *request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
798 retval = MPI_SUCCESS;
800 smpi_bench_begin(rank, "Isend");
804 int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status* status) {
806 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
808 smpi_bench_end(rank, "Recv");
809 if (comm == MPI_COMM_NULL) {
810 retval = MPI_ERR_COMM;
812 smpi_mpi_recv(buf, count, datatype, src, tag, comm, status);
813 retval = MPI_SUCCESS;
815 smpi_bench_begin(rank, "Recv");
819 int MPI_Send(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
821 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
823 smpi_bench_end(rank, "Send");
824 if (comm == MPI_COMM_NULL) {
825 retval = MPI_ERR_COMM;
827 smpi_mpi_send(buf, count, datatype, dst, tag, comm);
828 retval = MPI_SUCCESS;
830 smpi_bench_begin(rank, "Send");
834 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) {
836 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
838 smpi_bench_end(rank, "Sendrecv");
839 if (comm == MPI_COMM_NULL) {
840 retval = MPI_ERR_COMM;
841 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
842 retval = MPI_ERR_TYPE;
844 smpi_mpi_sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm, status);
845 retval = MPI_SUCCESS;
847 smpi_bench_begin(rank, "Sendrecv");
851 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) {
852 //TODO: suboptimal implementation
856 size = smpi_datatype_size(datatype) * count;
857 recvbuf = xbt_new(char, size);
858 retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
859 memcpy(buf, recvbuf, size * sizeof(char));
864 int MPI_Test(MPI_Request* request, int* flag, MPI_Status* status) {
866 int rank = request && (*request)->comm != MPI_COMM_NULL
867 ? smpi_comm_rank((*request)->comm)
870 smpi_bench_end(rank, "Test");
871 if(request == NULL || flag == NULL) {
872 retval = MPI_ERR_ARG;
873 } else if(*request == MPI_REQUEST_NULL) {
874 retval = MPI_ERR_REQUEST;
876 *flag = smpi_mpi_test(request, status);
877 retval = MPI_SUCCESS;
879 smpi_bench_begin(rank, "Test");
883 int MPI_Testany(int count, MPI_Request requests[], int* index, int* flag, MPI_Status* status) {
886 smpi_bench_end(-1, NULL); //FIXME
887 if(index == NULL || flag == NULL) {
888 retval = MPI_ERR_ARG;
890 *flag = smpi_mpi_testany(count, requests, index, status);
891 retval = MPI_SUCCESS;
893 smpi_bench_begin(-1, NULL);
897 int MPI_Wait(MPI_Request* request, MPI_Status* status) {
899 int rank = request && (*request)->comm != MPI_COMM_NULL
900 ? smpi_comm_rank((*request)->comm)
903 smpi_bench_end(rank, "Wait");
904 if(request == NULL) {
905 retval = MPI_ERR_ARG;
906 } else if(*request == MPI_REQUEST_NULL) {
907 retval = MPI_ERR_REQUEST;
909 smpi_mpi_wait(request, status);
910 retval = MPI_SUCCESS;
912 smpi_bench_begin(rank, "Wait");
916 int MPI_Waitany(int count, MPI_Request requests[], int* index, MPI_Status* status) {
919 smpi_bench_end(-1, NULL); //FIXME
921 retval = MPI_ERR_ARG;
923 *index = smpi_mpi_waitany(count, requests, status);
924 retval = MPI_SUCCESS;
926 smpi_bench_begin(-1, NULL);
930 int MPI_Waitall(int count, MPI_Request requests[], MPI_Status status[]) {
931 smpi_bench_end(-1, NULL); //FIXME
932 smpi_mpi_waitall(count, requests, status);
933 smpi_bench_begin(-1, NULL);
937 int MPI_Waitsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[]) {
940 smpi_bench_end(-1, NULL); //FIXME
941 if(outcount == NULL || indices == NULL) {
942 retval = MPI_ERR_ARG;
944 *outcount = smpi_mpi_waitsome(incount, requests, indices, status);
945 retval = MPI_SUCCESS;
947 smpi_bench_begin(-1, NULL);
951 int MPI_Bcast(void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) {
953 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
955 smpi_bench_end(rank, "Bcast");
956 if(comm == MPI_COMM_NULL) {
957 retval = MPI_ERR_COMM;
959 smpi_mpi_bcast(buf, count, datatype, root, comm);
960 retval = MPI_SUCCESS;
962 smpi_bench_begin(rank, "Bcast");
966 int MPI_Barrier(MPI_Comm comm) {
968 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
970 smpi_bench_end(rank, "Barrier");
971 if(comm == MPI_COMM_NULL) {
972 retval = MPI_ERR_COMM;
974 smpi_mpi_barrier(comm);
975 retval = MPI_SUCCESS;
977 smpi_bench_begin(rank, "Barrier");
981 int MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) {
983 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
985 smpi_bench_end(rank, "Gather");
986 if(comm == MPI_COMM_NULL) {
987 retval = MPI_ERR_COMM;
988 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
989 retval = MPI_ERR_TYPE;
991 smpi_mpi_gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
992 retval = MPI_SUCCESS;
994 smpi_bench_begin(rank, "Gather");
998 int MPI_Gatherv(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int* recvcounts, int* displs, MPI_Datatype recvtype, int root, MPI_Comm comm) {
1000 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1002 smpi_bench_end(rank, "Gatherv");
1003 if(comm == MPI_COMM_NULL) {
1004 retval = MPI_ERR_COMM;
1005 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1006 retval = MPI_ERR_TYPE;
1007 } else if(recvcounts == NULL || displs == NULL) {
1008 retval = MPI_ERR_ARG;
1010 smpi_mpi_gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm);
1011 retval = MPI_SUCCESS;
1013 smpi_bench_begin(rank, "Gatherv");
1017 int MPI_Allgather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) {
1019 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1021 smpi_bench_end(rank, "Allgather");
1022 if(comm == MPI_COMM_NULL) {
1023 retval = MPI_ERR_COMM;
1024 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1025 retval = MPI_ERR_TYPE;
1027 smpi_mpi_allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1028 retval = MPI_SUCCESS;
1030 smpi_bench_begin(rank, "Allgather");
1034 int MPI_Allgatherv(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int* recvcounts, int* displs, MPI_Datatype recvtype, MPI_Comm comm) {
1036 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1038 smpi_bench_end(rank, "Allgatherv");
1039 if(comm == MPI_COMM_NULL) {
1040 retval = MPI_ERR_COMM;
1041 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1042 retval = MPI_ERR_TYPE;
1043 } else if(recvcounts == NULL || displs == NULL) {
1044 retval = MPI_ERR_ARG;
1046 smpi_mpi_allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1047 retval = MPI_SUCCESS;
1049 smpi_bench_begin(rank, "Allgatherv");
1053 int MPI_Scatter(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) {
1055 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1057 smpi_bench_end(rank, "Scatter");
1058 if(comm == MPI_COMM_NULL) {
1059 retval = MPI_ERR_COMM;
1060 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1061 retval = MPI_ERR_TYPE;
1063 smpi_mpi_scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1064 retval = MPI_SUCCESS;
1066 smpi_bench_begin(rank, "Scatter");
1070 int MPI_Scatterv(void* sendbuf, int* sendcounts, int* displs, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) {
1072 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1074 smpi_bench_end(rank, "Scatterv");
1075 if(comm == MPI_COMM_NULL) {
1076 retval = MPI_ERR_COMM;
1077 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1078 retval = MPI_ERR_TYPE;
1079 } else if(sendcounts == NULL || displs == NULL) {
1080 retval = MPI_ERR_ARG;
1082 smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1083 retval = MPI_SUCCESS;
1085 smpi_bench_begin(rank, "Scatterv");
1089 int MPI_Reduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm) {
1091 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1093 smpi_bench_end(rank, "Reduce");
1094 if(comm == MPI_COMM_NULL) {
1095 retval = MPI_ERR_COMM;
1096 } else if(datatype == MPI_DATATYPE_NULL || op == MPI_OP_NULL) {
1097 retval = MPI_ERR_ARG;
1099 smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1100 retval = MPI_SUCCESS;
1102 smpi_bench_begin(rank, "Reduce");
1106 int MPI_Allreduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) {
1108 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1110 smpi_bench_end(rank, "Allreduce");
1111 if(comm == MPI_COMM_NULL) {
1112 retval = MPI_ERR_COMM;
1113 } else if(datatype == MPI_DATATYPE_NULL) {
1114 retval = MPI_ERR_TYPE;
1115 } else if(op == MPI_OP_NULL) {
1116 retval = MPI_ERR_OP;
1118 smpi_mpi_allreduce(sendbuf, recvbuf, count, datatype, op, comm);
1119 retval = MPI_SUCCESS;
1121 smpi_bench_begin(rank, "Allreduce");
1125 int MPI_Scan(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) {
1127 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1129 smpi_bench_end(rank, "Scan");
1130 if(comm == MPI_COMM_NULL) {
1131 retval = MPI_ERR_COMM;
1132 } else if(datatype == MPI_DATATYPE_NULL) {
1133 retval = MPI_ERR_TYPE;
1134 } else if(op == MPI_OP_NULL) {
1135 retval = MPI_ERR_OP;
1137 smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
1138 retval = MPI_SUCCESS;
1140 smpi_bench_begin(rank, "Scan");
1144 int MPI_Reduce_scatter(void* sendbuf, void* recvbuf, int* recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) {
1145 int retval, i, size, count;
1147 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1149 smpi_bench_end(rank, "Reduce_scatter");
1150 if(comm == MPI_COMM_NULL) {
1151 retval = MPI_ERR_COMM;
1152 } else if(datatype == MPI_DATATYPE_NULL) {
1153 retval = MPI_ERR_TYPE;
1154 } else if(op == MPI_OP_NULL) {
1155 retval = MPI_ERR_OP;
1156 } else if(recvcounts == NULL) {
1157 retval = MPI_ERR_ARG;
1159 /* arbitrarily choose root as rank 0 */
1160 /* TODO: faster direct implementation ? */
1161 size = smpi_comm_size(comm);
1163 displs = xbt_new(int, size);
1164 for(i = 0; i < size; i++) {
1165 count += recvcounts[i];
1168 smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, 0, comm);
1169 smpi_mpi_scatterv(recvbuf, recvcounts, displs, datatype, recvbuf, recvcounts[rank], datatype, 0, comm);
1171 retval = MPI_SUCCESS;
1173 smpi_bench_begin(rank, "Reduce_scatter");
1177 int MPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) {
1178 int retval, size, sendsize;
1179 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1181 smpi_bench_end(rank, "Alltoall");
1182 if(comm == MPI_COMM_NULL) {
1183 retval = MPI_ERR_COMM;
1184 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1185 retval = MPI_ERR_TYPE;
1187 size = smpi_comm_size(comm);
1188 sendsize = smpi_datatype_size(sendtype) * sendcount;
1189 if(sendsize < 200 && size > 12) {
1190 retval = smpi_coll_tuned_alltoall_bruck(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1191 } else if(sendsize < 3000) {
1192 retval = smpi_coll_tuned_alltoall_basic_linear(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1194 retval = smpi_coll_tuned_alltoall_pairwise(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1197 smpi_bench_begin(rank, "Alltoall");
1201 int MPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf, int *recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm) {
1203 int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
1205 smpi_bench_end(rank, "Alltoallv");
1206 if(comm == MPI_COMM_NULL) {
1207 retval = MPI_ERR_COMM;
1208 } else if(sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
1209 retval = MPI_ERR_TYPE;
1210 } else if(sendcounts == NULL || senddisps == NULL || recvcounts == NULL || recvdisps == NULL) {
1211 retval = MPI_ERR_ARG;
1213 retval = smpi_coll_basic_alltoallv(sendbuf, sendcounts, senddisps, sendtype, recvbuf, recvcounts, recvdisps, recvtype, comm);
1215 smpi_bench_begin(rank, "Alltoallv");
1220 int MPI_Get_processor_name( char *name, int *resultlen ) {
1221 int retval = MPI_SUCCESS;
1222 smpi_bench_end(-1, NULL);
1223 strncpy( name , SIMIX_host_get_name(SIMIX_host_self()), MPI_MAX_PROCESSOR_NAME-1);
1224 *resultlen= strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
1226 smpi_bench_begin(-1, NULL);