1 /* Copyright (c) 2007-2017. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include <simgrid/s4u/host.hpp>
10 #include "smpi_mpi_dt_private.h"
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi, "Logging specific to SMPI (pmpi)");
14 //this function need to be here because of the calls to smpi_bench
15 void TRACE_smpi_set_category(const char *category)
17 //need to end bench otherwise categories for execution tasks are wrong
19 TRACE_internal_smpi_set_category (category);
20 //begin bench after changing process's category
24 /* PMPI User level calls */
25 extern "C" { // Obviously, the C MPI interface should use the C linkage
27 int PMPI_Init(int *argc, char ***argv)
29 // PMPI_Init is call only one time by only by SMPI process
31 MPI_Initialized(&already_init);
32 if(already_init == 0){
33 smpi_process_init(argc, argv);
34 smpi_process_mark_as_initialized();
35 int rank = smpi_process_index();
36 TRACE_smpi_init(rank);
37 TRACE_smpi_computing_init(rank);
38 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
39 extra->type = TRACING_INIT;
40 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
41 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
53 int rank = smpi_process_index();
54 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
55 extra->type = TRACING_FINALIZE;
56 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
58 smpi_process_finalize();
60 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
61 TRACE_smpi_finalize(smpi_process_index());
62 smpi_process_destroy();
66 int PMPI_Finalized(int* flag)
68 *flag=smpi_process_finalized();
72 int PMPI_Get_version (int *version,int *subversion){
73 *version = MPI_VERSION;
74 *subversion= MPI_SUBVERSION;
78 int PMPI_Get_library_version (char *version,int *len){
80 snprintf(version,MPI_MAX_LIBRARY_VERSION_STRING,"SMPI Version %d.%d. Copyright The Simgrid Team 2007-2015",
81 SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR);
82 *len = strlen(version) > MPI_MAX_LIBRARY_VERSION_STRING ? MPI_MAX_LIBRARY_VERSION_STRING : strlen(version);
87 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
89 if (provided != nullptr) {
90 *provided = MPI_THREAD_SINGLE;
92 return MPI_Init(argc, argv);
95 int PMPI_Query_thread(int *provided)
97 if (provided == nullptr) {
100 *provided = MPI_THREAD_SINGLE;
105 int PMPI_Is_thread_main(int *flag)
107 if (flag == nullptr) {
110 *flag = smpi_process_index() == 0;
115 int PMPI_Abort(MPI_Comm comm, int errorcode)
118 smpi_process_destroy();
119 // FIXME: should kill all processes in comm instead
120 simcall_process_kill(SIMIX_process_self());
126 return smpi_mpi_wtime();
129 extern double sg_maxmin_precision;
132 return sg_maxmin_precision;
135 int PMPI_Address(void *location, MPI_Aint * address)
137 if (address==nullptr) {
140 *address = reinterpret_cast<MPI_Aint>(location);
145 int PMPI_Get_address(void *location, MPI_Aint * address)
147 return PMPI_Address(location, address);
150 int PMPI_Type_free(MPI_Datatype * datatype)
152 /* Free a predefined datatype is an error according to the standard, and should be checked for */
153 if (*datatype == MPI_DATATYPE_NULL) {
156 smpi_datatype_unuse(*datatype);
161 int PMPI_Type_size(MPI_Datatype datatype, int *size)
163 if (datatype == MPI_DATATYPE_NULL) {
165 } else if (size == nullptr) {
168 *size = static_cast<int>(smpi_datatype_size(datatype));
173 int PMPI_Type_size_x(MPI_Datatype datatype, MPI_Count *size)
175 if (datatype == MPI_DATATYPE_NULL) {
177 } else if (size == nullptr) {
180 *size = static_cast<MPI_Count>(smpi_datatype_size(datatype));
185 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
187 if (datatype == MPI_DATATYPE_NULL) {
189 } else if (lb == nullptr || extent == nullptr) {
192 return smpi_datatype_extent(datatype, lb, extent);
196 int PMPI_Type_get_true_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
198 return PMPI_Type_get_extent(datatype, lb, extent);
201 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
203 if (datatype == MPI_DATATYPE_NULL) {
205 } else if (extent == nullptr) {
208 *extent = smpi_datatype_get_extent(datatype);
213 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
215 if (datatype == MPI_DATATYPE_NULL) {
217 } else if (disp == nullptr) {
220 *disp = smpi_datatype_lb(datatype);
225 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
227 if (datatype == MPI_DATATYPE_NULL) {
229 } else if (disp == nullptr) {
232 *disp = smpi_datatype_ub(datatype);
237 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
238 if (datatype == MPI_DATATYPE_NULL) {
241 return smpi_datatype_dup(datatype, newtype);
245 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
247 if (function == nullptr || op == nullptr) {
250 *op = new Op(function, (commute!=0));
255 int PMPI_Op_free(MPI_Op * op)
259 } else if (*op == MPI_OP_NULL) {
268 int PMPI_Group_free(MPI_Group * group)
270 if (group == nullptr) {
274 *group = MPI_GROUP_NULL;
279 int PMPI_Group_size(MPI_Group group, int *size)
281 if (group == MPI_GROUP_NULL) {
282 return MPI_ERR_GROUP;
283 } else if (size == nullptr) {
286 *size = group->size();
291 int PMPI_Group_rank(MPI_Group group, int *rank)
293 if (group == MPI_GROUP_NULL) {
294 return MPI_ERR_GROUP;
295 } else if (rank == nullptr) {
298 *rank = group->rank(smpi_process_index());
303 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2)
305 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
306 return MPI_ERR_GROUP;
308 for (int i = 0; i < n; i++) {
309 if(ranks1[i]==MPI_PROC_NULL){
310 ranks2[i]=MPI_PROC_NULL;
312 int index = group1->index(ranks1[i]);
313 ranks2[i] = group2->rank(index);
320 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
322 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
323 return MPI_ERR_GROUP;
324 } else if (result == nullptr) {
327 *result = group1->compare(group2);
332 int PMPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
335 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
336 return MPI_ERR_GROUP;
337 } else if (newgroup == nullptr) {
340 return group1->group_union(group2, newgroup);
344 int PMPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
347 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
348 return MPI_ERR_GROUP;
349 } else if (newgroup == nullptr) {
352 return group1->intersection(group2,newgroup);
356 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
358 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
359 return MPI_ERR_GROUP;
360 } else if (newgroup == nullptr) {
363 return group1->difference(group2,newgroup);
367 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
369 if (group == MPI_GROUP_NULL) {
370 return MPI_ERR_GROUP;
371 } else if (newgroup == nullptr) {
374 return group->incl(n, ranks, newgroup);
378 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
380 if (group == MPI_GROUP_NULL) {
381 return MPI_ERR_GROUP;
382 } else if (newgroup == nullptr) {
387 if (group != MPI_COMM_WORLD->group()
388 && group != MPI_COMM_SELF->group() && group != MPI_GROUP_EMPTY)
391 } else if (n == group->size()) {
392 *newgroup = MPI_GROUP_EMPTY;
395 return group->excl(n,ranks,newgroup);
400 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
402 if (group == MPI_GROUP_NULL) {
403 return MPI_ERR_GROUP;
404 } else if (newgroup == nullptr) {
408 *newgroup = MPI_GROUP_EMPTY;
411 return group->range_incl(n,ranges,newgroup);
416 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
418 if (group == MPI_GROUP_NULL) {
419 return MPI_ERR_GROUP;
420 } else if (newgroup == nullptr) {
425 if (group != MPI_COMM_WORLD->group() && group != MPI_COMM_SELF->group() &&
426 group != MPI_GROUP_EMPTY)
430 return group->range_excl(n,ranges,newgroup);
435 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
437 if (comm == MPI_COMM_NULL) {
439 } else if (rank == nullptr) {
442 *rank = comm->rank();
447 int PMPI_Comm_size(MPI_Comm comm, int *size)
449 if (comm == MPI_COMM_NULL) {
451 } else if (size == nullptr) {
454 *size = comm->size();
459 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
461 if (comm == MPI_COMM_NULL) {
463 } else if (name == nullptr || len == nullptr) {
466 comm->get_name(name, len);
471 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
473 if (comm == MPI_COMM_NULL) {
475 } else if (group == nullptr) {
478 *group = comm->group();
479 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
485 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
487 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
489 } else if (result == nullptr) {
492 if (comm1 == comm2) { /* Same communicators means same groups */
495 *result = comm1->group()->compare(comm2->group());
496 if (*result == MPI_IDENT) {
497 *result = MPI_CONGRUENT;
504 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
506 if (comm == MPI_COMM_NULL) {
508 } else if (newcomm == nullptr) {
511 return comm->dup(newcomm);
515 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
517 if (comm == MPI_COMM_NULL) {
519 } else if (group == MPI_GROUP_NULL) {
520 return MPI_ERR_GROUP;
521 } else if (newcomm == nullptr) {
523 } else if(group->rank(smpi_process_index())==MPI_UNDEFINED){
524 *newcomm= MPI_COMM_NULL;
528 *newcomm = new Comm(group, nullptr);
533 int PMPI_Comm_free(MPI_Comm * comm)
535 if (comm == nullptr) {
537 } else if (*comm == MPI_COMM_NULL) {
541 *comm = MPI_COMM_NULL;
546 int PMPI_Comm_disconnect(MPI_Comm * comm)
548 /* TODO: wait until all communication in comm are done */
549 if (comm == nullptr) {
551 } else if (*comm == MPI_COMM_NULL) {
555 *comm = MPI_COMM_NULL;
560 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
565 if (comm_out == nullptr) {
566 retval = MPI_ERR_ARG;
567 } else if (comm == MPI_COMM_NULL) {
568 retval = MPI_ERR_COMM;
570 *comm_out = comm->split(color, key);
571 retval = MPI_SUCCESS;
578 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
583 if (comm_out == nullptr) {
584 retval = MPI_ERR_ARG;
585 } else if (comm == MPI_COMM_NULL) {
586 retval = MPI_ERR_COMM;
588 retval = MPI_Comm_create(comm, group, comm_out);
595 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
600 if (request == nullptr) {
601 retval = MPI_ERR_ARG;
602 } else if (comm == MPI_COMM_NULL) {
603 retval = MPI_ERR_COMM;
604 } else if (!is_datatype_valid(datatype)) {
605 retval = MPI_ERR_TYPE;
606 } else if (dst == MPI_PROC_NULL) {
607 retval = MPI_SUCCESS;
609 *request = Request::send_init(buf, count, datatype, dst, tag, comm);
610 retval = MPI_SUCCESS;
613 if (retval != MPI_SUCCESS && request != nullptr)
614 *request = MPI_REQUEST_NULL;
618 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
623 if (request == nullptr) {
624 retval = MPI_ERR_ARG;
625 } else if (comm == MPI_COMM_NULL) {
626 retval = MPI_ERR_COMM;
627 } else if (!is_datatype_valid(datatype)) {
628 retval = MPI_ERR_TYPE;
629 } else if (src == MPI_PROC_NULL) {
630 retval = MPI_SUCCESS;
632 *request = Request::recv_init(buf, count, datatype, src, tag, comm);
633 retval = MPI_SUCCESS;
636 if (retval != MPI_SUCCESS && request != nullptr)
637 *request = MPI_REQUEST_NULL;
641 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
646 if (request == nullptr) {
647 retval = MPI_ERR_ARG;
648 } else if (comm == MPI_COMM_NULL) {
649 retval = MPI_ERR_COMM;
650 } else if (!is_datatype_valid(datatype)) {
651 retval = MPI_ERR_TYPE;
652 } else if (dst == MPI_PROC_NULL) {
653 retval = MPI_SUCCESS;
655 *request = Request::ssend_init(buf, count, datatype, dst, tag, comm);
656 retval = MPI_SUCCESS;
659 if (retval != MPI_SUCCESS && request != nullptr)
660 *request = MPI_REQUEST_NULL;
664 int PMPI_Start(MPI_Request * request)
669 if (request == nullptr || *request == MPI_REQUEST_NULL) {
670 retval = MPI_ERR_REQUEST;
673 retval = MPI_SUCCESS;
679 int PMPI_Startall(int count, MPI_Request * requests)
683 if (requests == nullptr) {
684 retval = MPI_ERR_ARG;
686 retval = MPI_SUCCESS;
687 for (int i = 0; i < count; i++) {
688 if(requests[i] == MPI_REQUEST_NULL) {
689 retval = MPI_ERR_REQUEST;
692 if(retval != MPI_ERR_REQUEST) {
693 Request::startall(count, requests);
700 int PMPI_Request_free(MPI_Request * request)
705 if (*request == MPI_REQUEST_NULL) {
706 retval = MPI_ERR_ARG;
708 Request::unuse(request);
709 retval = MPI_SUCCESS;
715 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
721 if (request == nullptr) {
722 retval = MPI_ERR_ARG;
723 } else if (comm == MPI_COMM_NULL) {
724 retval = MPI_ERR_COMM;
725 } else if (src == MPI_PROC_NULL) {
726 *request = MPI_REQUEST_NULL;
727 retval = MPI_SUCCESS;
728 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
729 retval = MPI_ERR_RANK;
730 } else if ((count < 0) || (buf==nullptr && count > 0)) {
731 retval = MPI_ERR_COUNT;
732 } else if (!is_datatype_valid(datatype)) {
733 retval = MPI_ERR_TYPE;
734 } else if(tag<0 && tag != MPI_ANY_TAG){
735 retval = MPI_ERR_TAG;
738 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
739 int src_traced = comm->group()->index(src);
741 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
742 extra->type = TRACING_IRECV;
743 extra->src = src_traced;
746 extra->datatype1 = encode_datatype(datatype, &known);
747 int dt_size_send = 1;
749 dt_size_send = smpi_datatype_size(datatype);
750 extra->send_size = count*dt_size_send;
751 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
753 *request = Request::irecv(buf, count, datatype, src, tag, comm);
754 retval = MPI_SUCCESS;
756 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
760 if (retval != MPI_SUCCESS && request != nullptr)
761 *request = MPI_REQUEST_NULL;
766 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
771 if (request == nullptr) {
772 retval = MPI_ERR_ARG;
773 } else if (comm == MPI_COMM_NULL) {
774 retval = MPI_ERR_COMM;
775 } else if (dst == MPI_PROC_NULL) {
776 *request = MPI_REQUEST_NULL;
777 retval = MPI_SUCCESS;
778 } else if (dst >= comm->group()->size() || dst <0){
779 retval = MPI_ERR_RANK;
780 } else if ((count < 0) || (buf==nullptr && count > 0)) {
781 retval = MPI_ERR_COUNT;
782 } else if (!is_datatype_valid(datatype)) {
783 retval = MPI_ERR_TYPE;
784 } else if(tag<0 && tag != MPI_ANY_TAG){
785 retval = MPI_ERR_TAG;
787 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
788 int dst_traced = comm->group()->index(dst);
789 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
790 extra->type = TRACING_ISEND;
792 extra->dst = dst_traced;
794 extra->datatype1 = encode_datatype(datatype, &known);
795 int dt_size_send = 1;
797 dt_size_send = smpi_datatype_size(datatype);
798 extra->send_size = count*dt_size_send;
799 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
800 TRACE_smpi_send(rank, rank, dst_traced, tag, count*smpi_datatype_size(datatype));
802 *request = Request::isend(buf, count, datatype, dst, tag, comm);
803 retval = MPI_SUCCESS;
805 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
809 if (retval != MPI_SUCCESS && request!=nullptr)
810 *request = MPI_REQUEST_NULL;
814 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
819 if (request == nullptr) {
820 retval = MPI_ERR_ARG;
821 } else if (comm == MPI_COMM_NULL) {
822 retval = MPI_ERR_COMM;
823 } else if (dst == MPI_PROC_NULL) {
824 *request = MPI_REQUEST_NULL;
825 retval = MPI_SUCCESS;
826 } else if (dst >= comm->group()->size() || dst <0){
827 retval = MPI_ERR_RANK;
828 } else if ((count < 0)|| (buf==nullptr && count > 0)) {
829 retval = MPI_ERR_COUNT;
830 } else if (!is_datatype_valid(datatype)) {
831 retval = MPI_ERR_TYPE;
832 } else if(tag<0 && tag != MPI_ANY_TAG){
833 retval = MPI_ERR_TAG;
835 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
836 int dst_traced = comm->group()->index(dst);
837 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
838 extra->type = TRACING_ISSEND;
840 extra->dst = dst_traced;
842 extra->datatype1 = encode_datatype(datatype, &known);
843 int dt_size_send = 1;
845 dt_size_send = smpi_datatype_size(datatype);
846 extra->send_size = count*dt_size_send;
847 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
848 TRACE_smpi_send(rank, rank, dst_traced, tag, count*smpi_datatype_size(datatype));
850 *request = Request::issend(buf, count, datatype, dst, tag, comm);
851 retval = MPI_SUCCESS;
853 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
857 if (retval != MPI_SUCCESS && request!=nullptr)
858 *request = MPI_REQUEST_NULL;
862 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
867 if (comm == MPI_COMM_NULL) {
868 retval = MPI_ERR_COMM;
869 } else if (src == MPI_PROC_NULL) {
870 smpi_empty_status(status);
871 status->MPI_SOURCE = MPI_PROC_NULL;
872 retval = MPI_SUCCESS;
873 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
874 retval = MPI_ERR_RANK;
875 } else if ((count < 0) || (buf==nullptr && count > 0)) {
876 retval = MPI_ERR_COUNT;
877 } else if (!is_datatype_valid(datatype)) {
878 retval = MPI_ERR_TYPE;
879 } else if(tag<0 && tag != MPI_ANY_TAG){
880 retval = MPI_ERR_TAG;
882 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
883 int src_traced = comm->group()->index(src);
884 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
885 extra->type = TRACING_RECV;
886 extra->src = src_traced;
889 extra->datatype1 = encode_datatype(datatype, &known);
890 int dt_size_send = 1;
892 dt_size_send = smpi_datatype_size(datatype);
893 extra->send_size = count * dt_size_send;
894 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
896 Request::recv(buf, count, datatype, src, tag, comm, status);
897 retval = MPI_SUCCESS;
899 // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
900 if (status != MPI_STATUS_IGNORE) {
901 src_traced = comm->group()->index(status->MPI_SOURCE);
902 if (!TRACE_smpi_view_internals()) {
903 TRACE_smpi_recv(rank, src_traced, rank, tag);
906 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
913 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
919 if (comm == MPI_COMM_NULL) {
920 retval = MPI_ERR_COMM;
921 } else if (dst == MPI_PROC_NULL) {
922 retval = MPI_SUCCESS;
923 } else if (dst >= comm->group()->size() || dst <0){
924 retval = MPI_ERR_RANK;
925 } else if ((count < 0) || (buf == nullptr && count > 0)) {
926 retval = MPI_ERR_COUNT;
927 } else if (!is_datatype_valid(datatype)) {
928 retval = MPI_ERR_TYPE;
929 } else if(tag < 0 && tag != MPI_ANY_TAG){
930 retval = MPI_ERR_TAG;
932 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
933 int dst_traced = comm->group()->index(dst);
934 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
935 extra->type = TRACING_SEND;
937 extra->dst = dst_traced;
939 extra->datatype1 = encode_datatype(datatype, &known);
940 int dt_size_send = 1;
942 dt_size_send = smpi_datatype_size(datatype);
944 extra->send_size = count*dt_size_send;
945 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
946 if (!TRACE_smpi_view_internals()) {
947 TRACE_smpi_send(rank, rank, dst_traced, tag,count*smpi_datatype_size(datatype));
950 Request::send(buf, count, datatype, dst, tag, comm);
951 retval = MPI_SUCCESS;
953 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
960 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
965 if (comm == MPI_COMM_NULL) {
966 retval = MPI_ERR_COMM;
967 } else if (dst == MPI_PROC_NULL) {
968 retval = MPI_SUCCESS;
969 } else if (dst >= comm->group()->size() || dst <0){
970 retval = MPI_ERR_RANK;
971 } else if ((count < 0) || (buf==nullptr && count > 0)) {
972 retval = MPI_ERR_COUNT;
973 } else if (!is_datatype_valid(datatype)){
974 retval = MPI_ERR_TYPE;
975 } else if(tag<0 && tag != MPI_ANY_TAG){
976 retval = MPI_ERR_TAG;
978 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
979 int dst_traced = comm->group()->index(dst);
980 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
981 extra->type = TRACING_SSEND;
983 extra->dst = dst_traced;
985 extra->datatype1 = encode_datatype(datatype, &known);
986 int dt_size_send = 1;
988 dt_size_send = smpi_datatype_size(datatype);
990 extra->send_size = count*dt_size_send;
991 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
992 TRACE_smpi_send(rank, rank, dst_traced, tag,count*smpi_datatype_size(datatype));
994 Request::ssend(buf, count, datatype, dst, tag, comm);
995 retval = MPI_SUCCESS;
997 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1004 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void *recvbuf,
1005 int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status)
1011 if (comm == MPI_COMM_NULL) {
1012 retval = MPI_ERR_COMM;
1013 } else if (!is_datatype_valid(sendtype) || !is_datatype_valid(recvtype)) {
1014 retval = MPI_ERR_TYPE;
1015 } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1016 smpi_empty_status(status);
1017 status->MPI_SOURCE = MPI_PROC_NULL;
1018 retval = MPI_SUCCESS;
1019 }else if (dst >= comm->group()->size() || dst <0 ||
1020 (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0))){
1021 retval = MPI_ERR_RANK;
1022 } else if ((sendcount < 0 || recvcount<0) ||
1023 (sendbuf==nullptr && sendcount > 0) || (recvbuf==nullptr && recvcount>0)) {
1024 retval = MPI_ERR_COUNT;
1025 } else if((sendtag<0 && sendtag != MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1026 retval = MPI_ERR_TAG;
1029 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1030 int dst_traced = comm->group()->index(dst);
1031 int src_traced = comm->group()->index(src);
1032 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1033 extra->type = TRACING_SENDRECV;
1034 extra->src = src_traced;
1035 extra->dst = dst_traced;
1037 extra->datatype1 = encode_datatype(sendtype, &known);
1038 int dt_size_send = 1;
1040 dt_size_send = smpi_datatype_size(sendtype);
1041 extra->send_size = sendcount*dt_size_send;
1042 extra->datatype2 = encode_datatype(recvtype, &known);
1043 int dt_size_recv = 1;
1045 dt_size_recv = smpi_datatype_size(recvtype);
1046 extra->recv_size = recvcount*dt_size_recv;
1048 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1049 TRACE_smpi_send(rank, rank, dst_traced, sendtag,sendcount*smpi_datatype_size(sendtype));
1051 Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm,
1053 retval = MPI_SUCCESS;
1055 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1056 TRACE_smpi_recv(rank, src_traced, rank, recvtag);
1063 int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,
1064 MPI_Comm comm, MPI_Status* status)
1067 if (!is_datatype_valid(datatype)) {
1068 return MPI_ERR_TYPE;
1069 } else if (count < 0) {
1070 return MPI_ERR_COUNT;
1072 int size = smpi_datatype_get_extent(datatype) * count;
1073 void* recvbuf = xbt_new0(char, size);
1074 retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
1075 if(retval==MPI_SUCCESS){
1076 smpi_datatype_copy(recvbuf, count, datatype, buf, count, datatype);
1084 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1088 if (request == nullptr || flag == nullptr) {
1089 retval = MPI_ERR_ARG;
1090 } else if (*request == MPI_REQUEST_NULL) {
1092 smpi_empty_status(status);
1093 retval = MPI_SUCCESS;
1095 int rank = ((*request)->comm() != MPI_COMM_NULL) ? smpi_process_index() : -1;
1097 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1098 extra->type = TRACING_TEST;
1099 TRACE_smpi_testing_in(rank, extra);
1101 *flag = Request::test(request,status);
1103 TRACE_smpi_testing_out(rank);
1104 retval = MPI_SUCCESS;
1110 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status)
1115 if (index == nullptr || flag == nullptr) {
1116 retval = MPI_ERR_ARG;
1118 *flag = Request::testany(count, requests, index, status);
1119 retval = MPI_SUCCESS;
1125 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1130 if (flag == nullptr) {
1131 retval = MPI_ERR_ARG;
1133 *flag = Request::testall(count, requests, statuses);
1134 retval = MPI_SUCCESS;
1140 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1144 if (status == nullptr) {
1145 retval = MPI_ERR_ARG;
1146 } else if (comm == MPI_COMM_NULL) {
1147 retval = MPI_ERR_COMM;
1148 } else if (source == MPI_PROC_NULL) {
1149 smpi_empty_status(status);
1150 status->MPI_SOURCE = MPI_PROC_NULL;
1151 retval = MPI_SUCCESS;
1153 Request::probe(source, tag, comm, status);
1154 retval = MPI_SUCCESS;
1160 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1164 if ((flag == nullptr) || (status == nullptr)) {
1165 retval = MPI_ERR_ARG;
1166 } else if (comm == MPI_COMM_NULL) {
1167 retval = MPI_ERR_COMM;
1168 } else if (source == MPI_PROC_NULL) {
1170 smpi_empty_status(status);
1171 status->MPI_SOURCE = MPI_PROC_NULL;
1172 retval = MPI_SUCCESS;
1174 Request::iprobe(source, tag, comm, flag, status);
1175 retval = MPI_SUCCESS;
1181 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1187 smpi_empty_status(status);
1189 if (request == nullptr) {
1190 retval = MPI_ERR_ARG;
1191 } else if (*request == MPI_REQUEST_NULL) {
1192 retval = MPI_SUCCESS;
1195 int rank = (request!=nullptr && (*request)->comm() != MPI_COMM_NULL) ? smpi_process_index() : -1;
1197 int src_traced = (*request)->src();
1198 int dst_traced = (*request)->dst();
1199 int tag_traced= (*request)->tag();
1200 MPI_Comm comm = (*request)->comm();
1201 int is_wait_for_receive = ((*request)->flags() & RECV);
1202 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1203 extra->type = TRACING_WAIT;
1204 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1206 Request::wait(request, status);
1207 retval = MPI_SUCCESS;
1209 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1210 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1211 if (is_wait_for_receive) {
1212 if(src_traced==MPI_ANY_SOURCE)
1213 src_traced = (status!=MPI_STATUS_IGNORE) ?
1214 comm->group()->rank(status->MPI_SOURCE) :
1216 TRACE_smpi_recv(rank, src_traced, dst_traced, tag_traced);
1224 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1226 if (index == nullptr)
1230 //save requests information for tracing
1238 savedvalstype* savedvals=nullptr;
1240 savedvals = xbt_new0(savedvalstype, count);
1242 for (int i = 0; i < count; i++) {
1243 MPI_Request req = requests[i]; //already received requests are no longer valid
1245 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), req->comm()};
1248 int rank_traced = smpi_process_index();
1249 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1250 extra->type = TRACING_WAITANY;
1251 extra->send_size=count;
1252 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1254 *index = Request::waitany(count, requests, status);
1256 if(*index!=MPI_UNDEFINED){
1257 int src_traced = savedvals[*index].src;
1258 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1259 int dst_traced = savedvals[*index].dst;
1260 int is_wait_for_receive = savedvals[*index].recv;
1261 if (is_wait_for_receive) {
1262 if(savedvals[*index].src==MPI_ANY_SOURCE)
1263 src_traced = (status != MPI_STATUSES_IGNORE)
1264 ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
1265 : savedvals[*index].src;
1266 TRACE_smpi_recv(rank_traced, src_traced, dst_traced, savedvals[*index].tag);
1268 TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1270 xbt_free(savedvals);
1276 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1279 //save information from requests
1288 savedvalstype* savedvals=xbt_new0(savedvalstype, count);
1290 for (int i = 0; i < count; i++) {
1291 MPI_Request req = requests[i];
1292 if(req!=MPI_REQUEST_NULL){
1293 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), 1, req->comm()};
1295 savedvals[i].valid=0;
1298 int rank_traced = smpi_process_index();
1299 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1300 extra->type = TRACING_WAITALL;
1301 extra->send_size=count;
1302 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1304 int retval =Request::waitall(count, requests, status);
1306 for (int i = 0; i < count; i++) {
1307 if(savedvals[i].valid){
1308 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1309 int src_traced = savedvals[i].src;
1310 int dst_traced = savedvals[i].dst;
1311 int is_wait_for_receive = savedvals[i].recv;
1312 if (is_wait_for_receive) {
1313 if(src_traced==MPI_ANY_SOURCE)
1314 src_traced = (status!=MPI_STATUSES_IGNORE) ?
1315 savedvals[i].comm->group()->rank(status[i].MPI_SOURCE) : savedvals[i].src;
1316 TRACE_smpi_recv(rank_traced, src_traced, dst_traced,savedvals[i].tag);
1320 TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1321 xbt_free(savedvals);
1327 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount, int *indices, MPI_Status status[])
1332 if (outcount == nullptr) {
1333 retval = MPI_ERR_ARG;
1335 *outcount = Request::waitsome(incount, requests, indices, status);
1336 retval = MPI_SUCCESS;
1342 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[])
1347 if (outcount == nullptr) {
1348 retval = MPI_ERR_ARG;
1350 *outcount = Request::testsome(incount, requests, indices, status);
1351 retval = MPI_SUCCESS;
1358 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1364 if (comm == MPI_COMM_NULL) {
1365 retval = MPI_ERR_COMM;
1366 } else if (!is_datatype_valid(datatype)) {
1367 retval = MPI_ERR_ARG;
1369 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1370 int root_traced = comm->group()->index(root);
1372 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1373 extra->type = TRACING_BCAST;
1374 extra->root = root_traced;
1376 extra->datatype1 = encode_datatype(datatype, &known);
1377 int dt_size_send = 1;
1379 dt_size_send = smpi_datatype_size(datatype);
1380 extra->send_size = count * dt_size_send;
1381 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1382 if (comm->size() > 1)
1383 mpi_coll_bcast_fun(buf, count, datatype, root, comm);
1384 retval = MPI_SUCCESS;
1386 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1392 int PMPI_Barrier(MPI_Comm comm)
1398 if (comm == MPI_COMM_NULL) {
1399 retval = MPI_ERR_COMM;
1401 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1402 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1403 extra->type = TRACING_BARRIER;
1404 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1406 mpi_coll_barrier_fun(comm);
1407 retval = MPI_SUCCESS;
1409 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1416 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
1417 int root, MPI_Comm comm)
1423 if (comm == MPI_COMM_NULL) {
1424 retval = MPI_ERR_COMM;
1425 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1426 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1427 retval = MPI_ERR_TYPE;
1428 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) || ((comm->rank() == root) && (recvcount <0))){
1429 retval = MPI_ERR_COUNT;
1432 char* sendtmpbuf = static_cast<char*>(sendbuf);
1433 int sendtmpcount = sendcount;
1434 MPI_Datatype sendtmptype = sendtype;
1435 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1437 sendtmptype=recvtype;
1439 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1440 int root_traced = comm->group()->index(root);
1441 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1442 extra->type = TRACING_GATHER;
1443 extra->root = root_traced;
1445 extra->datatype1 = encode_datatype(sendtmptype, &known);
1446 int dt_size_send = 1;
1448 dt_size_send = smpi_datatype_size(sendtmptype);
1449 extra->send_size = sendtmpcount * dt_size_send;
1450 extra->datatype2 = encode_datatype(recvtype, &known);
1451 int dt_size_recv = 1;
1452 if ((comm->rank() == root) && known == 0)
1453 dt_size_recv = smpi_datatype_size(recvtype);
1454 extra->recv_size = recvcount * dt_size_recv;
1456 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1458 mpi_coll_gather_fun(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
1460 retval = MPI_SUCCESS;
1461 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1468 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
1469 MPI_Datatype recvtype, int root, MPI_Comm comm)
1475 if (comm == MPI_COMM_NULL) {
1476 retval = MPI_ERR_COMM;
1477 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1478 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1479 retval = MPI_ERR_TYPE;
1480 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1481 retval = MPI_ERR_COUNT;
1482 } else if (recvcounts == nullptr || displs == nullptr) {
1483 retval = MPI_ERR_ARG;
1485 char* sendtmpbuf = static_cast<char*>(sendbuf);
1486 int sendtmpcount = sendcount;
1487 MPI_Datatype sendtmptype = sendtype;
1488 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1490 sendtmptype=recvtype;
1493 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1494 int root_traced = comm->group()->index(root);
1496 int size = comm->size();
1497 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1498 extra->type = TRACING_GATHERV;
1499 extra->num_processes = size;
1500 extra->root = root_traced;
1502 extra->datatype1 = encode_datatype(sendtmptype, &known);
1503 int dt_size_send = 1;
1505 dt_size_send = smpi_datatype_size(sendtype);
1506 extra->send_size = sendtmpcount * dt_size_send;
1507 extra->datatype2 = encode_datatype(recvtype, &known);
1508 int dt_size_recv = 1;
1510 dt_size_recv = smpi_datatype_size(recvtype);
1511 if ((comm->rank() == root)) {
1512 extra->recvcounts = xbt_new(int, size);
1513 for (i = 0; i < size; i++) // copy data to avoid bad free
1514 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1516 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1518 smpi_mpi_gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
1519 retval = MPI_SUCCESS;
1520 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1527 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1528 void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
1534 if (comm == MPI_COMM_NULL) {
1535 retval = MPI_ERR_COMM;
1536 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1537 (recvtype == MPI_DATATYPE_NULL)){
1538 retval = MPI_ERR_TYPE;
1539 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1541 retval = MPI_ERR_COUNT;
1543 if(sendbuf == MPI_IN_PLACE) {
1544 sendbuf=static_cast<char*>(recvbuf)+smpi_datatype_get_extent(recvtype)*recvcount*comm->rank();
1545 sendcount=recvcount;
1548 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1549 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1550 extra->type = TRACING_ALLGATHER;
1552 extra->datatype1 = encode_datatype(sendtype, &known);
1553 int dt_size_send = 1;
1555 dt_size_send = smpi_datatype_size(sendtype);
1556 extra->send_size = sendcount * dt_size_send;
1557 extra->datatype2 = encode_datatype(recvtype, &known);
1558 int dt_size_recv = 1;
1560 dt_size_recv = smpi_datatype_size(recvtype);
1561 extra->recv_size = recvcount * dt_size_recv;
1563 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1565 mpi_coll_allgather_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1566 retval = MPI_SUCCESS;
1567 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1573 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1574 void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
1580 if (comm == MPI_COMM_NULL) {
1581 retval = MPI_ERR_COMM;
1582 } else if (((sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) || (recvtype == MPI_DATATYPE_NULL)) {
1583 retval = MPI_ERR_TYPE;
1584 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1585 retval = MPI_ERR_COUNT;
1586 } else if (recvcounts == nullptr || displs == nullptr) {
1587 retval = MPI_ERR_ARG;
1590 if(sendbuf == MPI_IN_PLACE) {
1591 sendbuf=static_cast<char*>(recvbuf)+smpi_datatype_get_extent(recvtype)*displs[comm->rank()];
1592 sendcount=recvcounts[comm->rank()];
1595 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1597 int size = comm->size();
1598 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1599 extra->type = TRACING_ALLGATHERV;
1600 extra->num_processes = size;
1602 extra->datatype1 = encode_datatype(sendtype, &known);
1603 int dt_size_send = 1;
1605 dt_size_send = smpi_datatype_size(sendtype);
1606 extra->send_size = sendcount * dt_size_send;
1607 extra->datatype2 = encode_datatype(recvtype, &known);
1608 int dt_size_recv = 1;
1610 dt_size_recv = smpi_datatype_size(recvtype);
1611 extra->recvcounts = xbt_new(int, size);
1612 for (i = 0; i < size; i++) // copy data to avoid bad free
1613 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1615 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1617 mpi_coll_allgatherv_fun(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1618 retval = MPI_SUCCESS;
1619 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1626 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1627 void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1633 if (comm == MPI_COMM_NULL) {
1634 retval = MPI_ERR_COMM;
1635 } else if (((comm->rank() == root) && (!is_datatype_valid(sendtype))) ||
1636 ((recvbuf != MPI_IN_PLACE) && (!is_datatype_valid(recvtype)))) {
1637 retval = MPI_ERR_TYPE;
1638 } else if ((sendbuf == recvbuf) ||
1639 ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
1640 retval = MPI_ERR_BUFFER;
1643 if (recvbuf == MPI_IN_PLACE) {
1644 recvtype = sendtype;
1645 recvcount = sendcount;
1647 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1648 int root_traced = comm->group()->index(root);
1649 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1650 extra->type = TRACING_SCATTER;
1651 extra->root = root_traced;
1653 extra->datatype1 = encode_datatype(sendtype, &known);
1654 int dt_size_send = 1;
1655 if ((comm->rank() == root) && known == 0)
1656 dt_size_send = smpi_datatype_size(sendtype);
1657 extra->send_size = sendcount * dt_size_send;
1658 extra->datatype2 = encode_datatype(recvtype, &known);
1659 int dt_size_recv = 1;
1661 dt_size_recv = smpi_datatype_size(recvtype);
1662 extra->recv_size = recvcount * dt_size_recv;
1663 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1665 mpi_coll_scatter_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1666 retval = MPI_SUCCESS;
1667 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1674 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1675 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1681 if (comm == MPI_COMM_NULL) {
1682 retval = MPI_ERR_COMM;
1683 } else if (sendcounts == nullptr || displs == nullptr) {
1684 retval = MPI_ERR_ARG;
1685 } else if (((comm->rank() == root) && (sendtype == MPI_DATATYPE_NULL)) ||
1686 ((recvbuf != MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1687 retval = MPI_ERR_TYPE;
1689 if (recvbuf == MPI_IN_PLACE) {
1690 recvtype = sendtype;
1691 recvcount = sendcounts[comm->rank()];
1693 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1694 int root_traced = comm->group()->index(root);
1696 int size = comm->size();
1697 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1698 extra->type = TRACING_SCATTERV;
1699 extra->num_processes = size;
1700 extra->root = root_traced;
1702 extra->datatype1 = encode_datatype(sendtype, &known);
1703 int dt_size_send = 1;
1705 dt_size_send = smpi_datatype_size(sendtype);
1706 if ((comm->rank() == root)) {
1707 extra->sendcounts = xbt_new(int, size);
1708 for (i = 0; i < size; i++) // copy data to avoid bad free
1709 extra->sendcounts[i] = sendcounts[i] * dt_size_send;
1711 extra->datatype2 = encode_datatype(recvtype, &known);
1712 int dt_size_recv = 1;
1714 dt_size_recv = smpi_datatype_size(recvtype);
1715 extra->recv_size = recvcount * dt_size_recv;
1716 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1718 smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1720 retval = MPI_SUCCESS;
1721 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1728 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
1734 if (comm == MPI_COMM_NULL) {
1735 retval = MPI_ERR_COMM;
1736 } else if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
1737 retval = MPI_ERR_ARG;
1739 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1740 int root_traced = comm->group()->index(root);
1741 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1742 extra->type = TRACING_REDUCE;
1744 extra->datatype1 = encode_datatype(datatype, &known);
1745 int dt_size_send = 1;
1747 dt_size_send = smpi_datatype_size(datatype);
1748 extra->send_size = count * dt_size_send;
1749 extra->root = root_traced;
1751 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1753 mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, root, comm);
1755 retval = MPI_SUCCESS;
1756 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1763 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op){
1767 if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
1768 retval = MPI_ERR_ARG;
1770 if(op!=MPI_OP_NULL) op->apply( inbuf, inoutbuf, &count, &datatype);
1771 retval = MPI_SUCCESS;
1777 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1783 if (comm == MPI_COMM_NULL) {
1784 retval = MPI_ERR_COMM;
1785 } else if (!is_datatype_valid(datatype)) {
1786 retval = MPI_ERR_TYPE;
1787 } else if (op == MPI_OP_NULL) {
1788 retval = MPI_ERR_OP;
1791 char* sendtmpbuf = static_cast<char*>(sendbuf);
1792 if( sendbuf == MPI_IN_PLACE ) {
1793 sendtmpbuf = static_cast<char*>(xbt_malloc(count*smpi_datatype_get_extent(datatype)));
1794 smpi_datatype_copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
1796 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1797 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1798 extra->type = TRACING_ALLREDUCE;
1800 extra->datatype1 = encode_datatype(datatype, &known);
1801 int dt_size_send = 1;
1803 dt_size_send = smpi_datatype_size(datatype);
1804 extra->send_size = count * dt_size_send;
1806 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1808 mpi_coll_allreduce_fun(sendtmpbuf, recvbuf, count, datatype, op, comm);
1810 if( sendbuf == MPI_IN_PLACE )
1811 xbt_free(sendtmpbuf);
1813 retval = MPI_SUCCESS;
1814 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1821 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1827 if (comm == MPI_COMM_NULL) {
1828 retval = MPI_ERR_COMM;
1829 } else if (!is_datatype_valid(datatype)) {
1830 retval = MPI_ERR_TYPE;
1831 } else if (op == MPI_OP_NULL) {
1832 retval = MPI_ERR_OP;
1834 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1835 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1836 extra->type = TRACING_SCAN;
1838 extra->datatype1 = encode_datatype(datatype, &known);
1839 int dt_size_send = 1;
1841 dt_size_send = smpi_datatype_size(datatype);
1842 extra->send_size = count * dt_size_send;
1844 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1846 smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
1848 retval = MPI_SUCCESS;
1849 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1856 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
1861 if (comm == MPI_COMM_NULL) {
1862 retval = MPI_ERR_COMM;
1863 } else if (!is_datatype_valid(datatype)) {
1864 retval = MPI_ERR_TYPE;
1865 } else if (op == MPI_OP_NULL) {
1866 retval = MPI_ERR_OP;
1868 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1869 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1870 extra->type = TRACING_EXSCAN;
1872 extra->datatype1 = encode_datatype(datatype, &known);
1873 int dt_size_send = 1;
1875 dt_size_send = smpi_datatype_size(datatype);
1876 extra->send_size = count * dt_size_send;
1877 void* sendtmpbuf = sendbuf;
1878 if (sendbuf == MPI_IN_PLACE) {
1879 sendtmpbuf = static_cast<void*>(xbt_malloc(count * smpi_datatype_size(datatype)));
1880 memcpy(sendtmpbuf, recvbuf, count * smpi_datatype_size(datatype));
1882 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1884 smpi_mpi_exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
1885 retval = MPI_SUCCESS;
1886 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1887 if (sendbuf == MPI_IN_PLACE)
1888 xbt_free(sendtmpbuf);
1895 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1900 if (comm == MPI_COMM_NULL) {
1901 retval = MPI_ERR_COMM;
1902 } else if (!is_datatype_valid(datatype)) {
1903 retval = MPI_ERR_TYPE;
1904 } else if (op == MPI_OP_NULL) {
1905 retval = MPI_ERR_OP;
1906 } else if (recvcounts == nullptr) {
1907 retval = MPI_ERR_ARG;
1909 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1911 int size = comm->size();
1912 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1913 extra->type = TRACING_REDUCE_SCATTER;
1914 extra->num_processes = size;
1916 extra->datatype1 = encode_datatype(datatype, &known);
1917 int dt_size_send = 1;
1919 dt_size_send = smpi_datatype_size(datatype);
1920 extra->send_size = 0;
1921 extra->recvcounts = xbt_new(int, size);
1923 for (i = 0; i < size; i++) { // copy data to avoid bad free
1924 extra->recvcounts[i] = recvcounts[i] * dt_size_send;
1925 totalcount += recvcounts[i];
1927 void* sendtmpbuf = sendbuf;
1928 if (sendbuf == MPI_IN_PLACE) {
1929 sendtmpbuf = static_cast<void*>(xbt_malloc(totalcount * smpi_datatype_size(datatype)));
1930 memcpy(sendtmpbuf, recvbuf, totalcount * smpi_datatype_size(datatype));
1933 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1935 mpi_coll_reduce_scatter_fun(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1936 retval = MPI_SUCCESS;
1937 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1939 if (sendbuf == MPI_IN_PLACE)
1940 xbt_free(sendtmpbuf);
1947 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
1948 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1953 if (comm == MPI_COMM_NULL) {
1954 retval = MPI_ERR_COMM;
1955 } else if (!is_datatype_valid(datatype)) {
1956 retval = MPI_ERR_TYPE;
1957 } else if (op == MPI_OP_NULL) {
1958 retval = MPI_ERR_OP;
1959 } else if (recvcount < 0) {
1960 retval = MPI_ERR_ARG;
1962 int count = comm->size();
1964 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1965 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1966 extra->type = TRACING_REDUCE_SCATTER;
1967 extra->num_processes = count;
1969 extra->datatype1 = encode_datatype(datatype, &known);
1970 int dt_size_send = 1;
1972 dt_size_send = smpi_datatype_size(datatype);
1973 extra->send_size = 0;
1974 extra->recvcounts = xbt_new(int, count);
1975 for (int i = 0; i < count; i++) // copy data to avoid bad free
1976 extra->recvcounts[i] = recvcount * dt_size_send;
1977 void* sendtmpbuf = sendbuf;
1978 if (sendbuf == MPI_IN_PLACE) {
1979 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * count * smpi_datatype_size(datatype)));
1980 memcpy(sendtmpbuf, recvbuf, recvcount * count * smpi_datatype_size(datatype));
1983 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1985 int* recvcounts = static_cast<int*>(xbt_malloc(count * sizeof(int)));
1986 for (int i = 0; i < count; i++)
1987 recvcounts[i] = recvcount;
1988 mpi_coll_reduce_scatter_fun(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1989 xbt_free(recvcounts);
1990 retval = MPI_SUCCESS;
1992 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1994 if (sendbuf == MPI_IN_PLACE)
1995 xbt_free(sendtmpbuf);
2002 int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
2003 MPI_Datatype recvtype, MPI_Comm comm)
2008 if (comm == MPI_COMM_NULL) {
2009 retval = MPI_ERR_COMM;
2010 } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL) || recvtype == MPI_DATATYPE_NULL) {
2011 retval = MPI_ERR_TYPE;
2013 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2014 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2015 extra->type = TRACING_ALLTOALL;
2017 void* sendtmpbuf = static_cast<char*>(sendbuf);
2018 int sendtmpcount = sendcount;
2019 MPI_Datatype sendtmptype = sendtype;
2020 if (sendbuf == MPI_IN_PLACE) {
2021 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * comm->size() * smpi_datatype_size(recvtype)));
2022 memcpy(sendtmpbuf, recvbuf, recvcount * comm->size() * smpi_datatype_size(recvtype));
2023 sendtmpcount = recvcount;
2024 sendtmptype = recvtype;
2028 extra->datatype1 = encode_datatype(sendtmptype, &known);
2030 extra->send_size = sendtmpcount * smpi_datatype_size(sendtmptype);
2032 extra->send_size = sendtmpcount;
2033 extra->datatype2 = encode_datatype(recvtype, &known);
2035 extra->recv_size = recvcount * smpi_datatype_size(recvtype);
2037 extra->recv_size = recvcount;
2039 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2041 retval = mpi_coll_alltoall_fun(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
2043 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2045 if (sendbuf == MPI_IN_PLACE)
2046 xbt_free(sendtmpbuf);
2053 int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
2054 int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2060 if (comm == MPI_COMM_NULL) {
2061 retval = MPI_ERR_COMM;
2062 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
2063 retval = MPI_ERR_TYPE;
2064 } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
2065 recvdisps == nullptr) {
2066 retval = MPI_ERR_ARG;
2068 int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2070 int size = comm->size();
2071 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2072 extra->type = TRACING_ALLTOALLV;
2073 extra->send_size = 0;
2074 extra->recv_size = 0;
2075 extra->recvcounts = xbt_new(int, size);
2076 extra->sendcounts = xbt_new(int, size);
2078 int dt_size_recv = 1;
2079 extra->datatype2 = encode_datatype(recvtype, &known);
2080 dt_size_recv = smpi_datatype_size(recvtype);
2082 void* sendtmpbuf = static_cast<char*>(sendbuf);
2083 int* sendtmpcounts = sendcounts;
2084 int* sendtmpdisps = senddisps;
2085 MPI_Datatype sendtmptype = sendtype;
2087 for (i = 0; i < size; i++) { // copy data to avoid bad free
2088 extra->recv_size += recvcounts[i] * dt_size_recv;
2089 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
2090 if (((recvdisps[i] + recvcounts[i]) * dt_size_recv) > maxsize)
2091 maxsize = (recvdisps[i] + recvcounts[i]) * dt_size_recv;
2094 if (sendbuf == MPI_IN_PLACE) {
2095 sendtmpbuf = static_cast<void*>(xbt_malloc(maxsize));
2096 memcpy(sendtmpbuf, recvbuf, maxsize);
2097 sendtmpcounts = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2098 memcpy(sendtmpcounts, recvcounts, size * sizeof(int));
2099 sendtmpdisps = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2100 memcpy(sendtmpdisps, recvdisps, size * sizeof(int));
2101 sendtmptype = recvtype;
2104 extra->datatype1 = encode_datatype(sendtmptype, &known);
2105 int dt_size_send = 1;
2106 dt_size_send = smpi_datatype_size(sendtmptype);
2108 for (i = 0; i < size; i++) { // copy data to avoid bad free
2109 extra->send_size += sendtmpcounts[i] * dt_size_send;
2110 extra->sendcounts[i] = sendtmpcounts[i] * dt_size_send;
2112 extra->num_processes = size;
2113 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2114 retval = mpi_coll_alltoallv_fun(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
2115 recvdisps, recvtype, comm);
2116 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2118 if (sendbuf == MPI_IN_PLACE) {
2119 xbt_free(sendtmpbuf);
2120 xbt_free(sendtmpcounts);
2121 xbt_free(sendtmpdisps);
2130 int PMPI_Get_processor_name(char *name, int *resultlen)
2132 strncpy(name, SIMIX_host_self()->cname(), strlen(SIMIX_host_self()->cname()) < MPI_MAX_PROCESSOR_NAME - 1
2133 ? strlen(SIMIX_host_self()->cname()) + 1
2134 : MPI_MAX_PROCESSOR_NAME - 1);
2135 *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2140 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2142 if (status == nullptr || count == nullptr) {
2144 } else if (!is_datatype_valid(datatype)) {
2145 return MPI_ERR_TYPE;
2147 size_t size = smpi_datatype_size(datatype);
2151 } else if (status->count % size != 0) {
2152 return MPI_UNDEFINED;
2154 *count = smpi_mpi_get_count(status, datatype);
2160 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2161 if (old_type == MPI_DATATYPE_NULL) {
2162 return MPI_ERR_TYPE;
2163 } else if (count<0){
2164 return MPI_ERR_COUNT;
2166 return smpi_datatype_contiguous(count, old_type, new_type, 0);
2170 int PMPI_Type_commit(MPI_Datatype* datatype) {
2171 if (datatype == nullptr || *datatype == MPI_DATATYPE_NULL) {
2172 return MPI_ERR_TYPE;
2174 smpi_datatype_commit(datatype);
2179 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2180 if (old_type == MPI_DATATYPE_NULL) {
2181 return MPI_ERR_TYPE;
2182 } else if (count<0 || blocklen<0){
2183 return MPI_ERR_COUNT;
2185 return smpi_datatype_vector(count, blocklen, stride, old_type, new_type);
2189 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2190 if (old_type == MPI_DATATYPE_NULL) {
2191 return MPI_ERR_TYPE;
2192 } else if (count<0 || blocklen<0){
2193 return MPI_ERR_COUNT;
2195 return smpi_datatype_hvector(count, blocklen, stride, old_type, new_type);
2199 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2200 return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2203 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2204 if (old_type == MPI_DATATYPE_NULL) {
2205 return MPI_ERR_TYPE;
2206 } else if (count<0){
2207 return MPI_ERR_COUNT;
2209 return smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2213 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2214 if (old_type == MPI_DATATYPE_NULL) {
2215 return MPI_ERR_TYPE;
2216 } else if (count<0){
2217 return MPI_ERR_COUNT;
2219 return smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2223 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type,
2224 MPI_Datatype* new_type)
2226 if (old_type == MPI_DATATYPE_NULL) {
2227 return MPI_ERR_TYPE;
2228 } else if (count<0){
2229 return MPI_ERR_COUNT;
2231 int* blocklens=static_cast<int*>(xbt_malloc(blocklength*count*sizeof(int)));
2232 for (int i = 0; i < count; i++)
2233 blocklens[i]=blocklength;
2234 int retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2235 xbt_free(blocklens);
2240 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
2242 if (old_type == MPI_DATATYPE_NULL) {
2243 return MPI_ERR_TYPE;
2244 } else if (count<0){
2245 return MPI_ERR_COUNT;
2247 return smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2251 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type,
2252 MPI_Datatype* new_type) {
2253 return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2256 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type,
2257 MPI_Datatype* new_type) {
2258 if (old_type == MPI_DATATYPE_NULL) {
2259 return MPI_ERR_TYPE;
2260 } else if (count<0){
2261 return MPI_ERR_COUNT;
2263 int* blocklens=(int*)xbt_malloc(blocklength*count*sizeof(int));
2264 for (int i = 0; i < count; i++)
2265 blocklens[i] = blocklength;
2266 int retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2267 xbt_free(blocklens);
2272 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2274 return MPI_ERR_COUNT;
2276 return smpi_datatype_struct(count, blocklens, indices, old_types, new_type);
2280 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types,
2281 MPI_Datatype* new_type) {
2282 return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2285 int PMPI_Error_class(int errorcode, int* errorclass) {
2286 // assume smpi uses only standard mpi error codes
2287 *errorclass=errorcode;
2291 int PMPI_Initialized(int* flag) {
2292 *flag=smpi_process_initialized();
2296 /* The topo part of MPI_COMM_WORLD should always be nullptr. When other topologies will be implemented, not only should we
2297 * check if the topology is nullptr, but we should check if it is the good topology type (so we have to add a
2298 * MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2300 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2301 if (comm_old == MPI_COMM_NULL){
2302 return MPI_ERR_COMM;
2303 } else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
2306 new Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
2311 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2312 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2313 return MPI_ERR_TOPOLOGY;
2315 if (coords == nullptr) {
2318 Cart* topo = static_cast<Cart*>(comm->topo());
2319 if (topo==nullptr) {
2322 return topo->rank(coords, rank);
2325 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2326 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2327 return MPI_ERR_TOPOLOGY;
2329 if (source == nullptr || dest == nullptr || direction < 0 ) {
2332 Cart* topo = static_cast<Cart*>(comm->topo());
2333 if (topo==nullptr) {
2336 return topo->shift(direction, displ, source, dest);
2339 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2340 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2341 return MPI_ERR_TOPOLOGY;
2343 if (rank < 0 || rank >= comm->size()) {
2344 return MPI_ERR_RANK;
2349 if(coords == nullptr) {
2352 Cart* topo = static_cast<Cart*>(comm->topo());
2353 if (topo==nullptr) {
2356 return topo->coords(rank, maxdims, coords);
2359 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2360 if(comm == nullptr || comm->topo() == nullptr) {
2361 return MPI_ERR_TOPOLOGY;
2363 if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
2366 Cart* topo = static_cast<Cart*>(comm->topo());
2367 if (topo==nullptr) {
2370 return topo->get(maxdims, dims, periods, coords);
2373 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2374 if (comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2375 return MPI_ERR_TOPOLOGY;
2377 if (ndims == nullptr) {
2380 Cart* topo = static_cast<Cart*>(comm->topo());
2381 if (topo==nullptr) {
2384 return topo->dim_get(ndims);
2387 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2388 if(dims == nullptr) {
2391 if (ndims < 1 || nnodes < 1) {
2392 return MPI_ERR_DIMS;
2394 return Dims_create(nnodes, ndims, dims);
2397 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2398 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2399 return MPI_ERR_TOPOLOGY;
2401 if (comm_new == nullptr) {
2404 Cart* topo = static_cast<Cart*>(comm->topo());
2405 if (topo==nullptr) {
2408 Cart* cart = topo->sub(remain_dims, comm_new);
2414 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2415 if (oldtype == MPI_DATATYPE_NULL) {
2416 return MPI_ERR_TYPE;
2418 int blocks[3] = {1, 1, 1};
2419 MPI_Aint disps[3] = {lb, 0, lb + extent};
2420 MPI_Datatype types[3] = {MPI_LB, oldtype, MPI_UB};
2422 s_smpi_mpi_struct_t* subtype = smpi_datatype_struct_create(blocks, disps, 3, types);
2423 smpi_datatype_create(newtype, oldtype->size, lb, lb + extent, sizeof(s_smpi_mpi_struct_t), subtype, DT_FLAG_VECTOR);
2425 (*newtype)->flags &= ~DT_FLAG_COMMITED;
2429 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2432 if (comm == MPI_COMM_NULL) {
2433 retval= MPI_ERR_COMM;
2434 }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
2435 retval= MPI_ERR_OTHER;
2437 *win = new Win( base, size, disp_unit, info, comm);
2438 retval = MPI_SUCCESS;
2444 int PMPI_Win_free( MPI_Win* win){
2447 if (win == nullptr || *win == MPI_WIN_NULL) {
2448 retval = MPI_ERR_WIN;
2457 int PMPI_Win_set_name(MPI_Win win, char * name)
2459 if (win == MPI_WIN_NULL) {
2460 return MPI_ERR_TYPE;
2461 } else if (name == nullptr) {
2464 win->set_name(name);
2469 int PMPI_Win_get_name(MPI_Win win, char * name, int* len)
2471 if (win == MPI_WIN_NULL) {
2473 } else if (name == nullptr) {
2476 win->get_name(name, len);
2481 int PMPI_Win_get_group(MPI_Win win, MPI_Group * group){
2482 if (win == MPI_WIN_NULL) {
2485 win->get_group(group);
2491 int PMPI_Win_fence( int assert, MPI_Win win){
2494 if (win == MPI_WIN_NULL) {
2495 retval = MPI_ERR_WIN;
2497 int rank = smpi_process_index();
2498 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2499 retval = win->fence(assert);
2500 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2506 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2507 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2510 if (win == MPI_WIN_NULL) {
2511 retval = MPI_ERR_WIN;
2512 } else if (target_rank == MPI_PROC_NULL) {
2513 retval = MPI_SUCCESS;
2514 } else if (target_rank <0){
2515 retval = MPI_ERR_RANK;
2516 } else if (target_disp <0){
2517 retval = MPI_ERR_ARG;
2518 } else if ((origin_count < 0 || target_count < 0) ||
2519 (origin_addr==nullptr && origin_count > 0)){
2520 retval = MPI_ERR_COUNT;
2521 } else if ((!is_datatype_valid(origin_datatype)) || (!is_datatype_valid(target_datatype))) {
2522 retval = MPI_ERR_TYPE;
2524 int rank = smpi_process_index();
2526 win->get_group(&group);
2527 int src_traced = group->index(target_rank);
2528 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2530 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2533 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2539 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2540 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2543 if (win == MPI_WIN_NULL) {
2544 retval = MPI_ERR_WIN;
2545 } else if (target_rank == MPI_PROC_NULL) {
2546 retval = MPI_SUCCESS;
2547 } else if (target_rank <0){
2548 retval = MPI_ERR_RANK;
2549 } else if (target_disp <0){
2550 retval = MPI_ERR_ARG;
2551 } else if ((origin_count < 0 || target_count < 0) ||
2552 (origin_addr==nullptr && origin_count > 0)){
2553 retval = MPI_ERR_COUNT;
2554 } else if ((!is_datatype_valid(origin_datatype)) || (!is_datatype_valid(target_datatype))) {
2555 retval = MPI_ERR_TYPE;
2557 int rank = smpi_process_index();
2559 win->get_group(&group);
2560 int dst_traced = group->index(target_rank);
2561 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2562 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*smpi_datatype_size(origin_datatype));
2564 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2567 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2573 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2574 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2577 if (win == MPI_WIN_NULL) {
2578 retval = MPI_ERR_WIN;
2579 } else if (target_rank == MPI_PROC_NULL) {
2580 retval = MPI_SUCCESS;
2581 } else if (target_rank <0){
2582 retval = MPI_ERR_RANK;
2583 } else if (target_disp <0){
2584 retval = MPI_ERR_ARG;
2585 } else if ((origin_count < 0 || target_count < 0) ||
2586 (origin_addr==nullptr && origin_count > 0)){
2587 retval = MPI_ERR_COUNT;
2588 } else if ((!is_datatype_valid(origin_datatype)) ||
2589 (!is_datatype_valid(target_datatype))) {
2590 retval = MPI_ERR_TYPE;
2591 } else if (op == MPI_OP_NULL) {
2592 retval = MPI_ERR_OP;
2594 int rank = smpi_process_index();
2596 win->get_group(&group);
2597 int src_traced = group->index(target_rank);
2598 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2600 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2601 target_datatype, op);
2603 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2609 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2612 if (win == MPI_WIN_NULL) {
2613 retval = MPI_ERR_WIN;
2614 } else if (group==MPI_GROUP_NULL){
2615 retval = MPI_ERR_GROUP;
2617 int rank = smpi_process_index();
2618 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2619 retval = win->post(group,assert);
2620 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2626 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2629 if (win == MPI_WIN_NULL) {
2630 retval = MPI_ERR_WIN;
2631 } else if (group==MPI_GROUP_NULL){
2632 retval = MPI_ERR_GROUP;
2634 int rank = smpi_process_index();
2635 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2636 retval = win->start(group,assert);
2637 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2643 int PMPI_Win_complete(MPI_Win win){
2646 if (win == MPI_WIN_NULL) {
2647 retval = MPI_ERR_WIN;
2649 int rank = smpi_process_index();
2650 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2652 retval = win->complete();
2654 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2660 int PMPI_Win_wait(MPI_Win win){
2663 if (win == MPI_WIN_NULL) {
2664 retval = MPI_ERR_WIN;
2666 int rank = smpi_process_index();
2667 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2669 retval = win->wait();
2671 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2677 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
2678 void *ptr = xbt_malloc(size);
2680 return MPI_ERR_NO_MEM;
2682 *static_cast<void**>(baseptr) = ptr;
2687 int PMPI_Free_mem(void *baseptr){
2692 int PMPI_Type_set_name(MPI_Datatype datatype, char * name)
2694 if (datatype == MPI_DATATYPE_NULL) {
2695 return MPI_ERR_TYPE;
2696 } else if (name == nullptr) {
2699 smpi_datatype_set_name(datatype, name);
2704 int PMPI_Type_get_name(MPI_Datatype datatype, char * name, int* len)
2706 if (datatype == MPI_DATATYPE_NULL) {
2707 return MPI_ERR_TYPE;
2708 } else if (name == nullptr) {
2711 smpi_datatype_get_name(datatype, name, len);
2716 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
2717 return smpi_type_f2c(datatype);
2720 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
2721 return smpi_type_c2f( datatype);
2724 MPI_Group PMPI_Group_f2c(MPI_Fint group){
2725 return smpi_group_f2c( group);
2728 MPI_Fint PMPI_Group_c2f(MPI_Group group){
2729 return smpi_group_c2f(group);
2732 MPI_Request PMPI_Request_f2c(MPI_Fint request){
2733 return smpi_request_f2c(request);
2736 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
2737 return smpi_request_c2f(request);
2740 MPI_Win PMPI_Win_f2c(MPI_Fint win){
2741 return smpi_win_f2c(win);
2744 MPI_Fint PMPI_Win_c2f(MPI_Win win){
2745 return smpi_win_c2f(win);
2748 MPI_Op PMPI_Op_f2c(MPI_Fint op){
2749 return smpi_op_f2c(op);
2752 MPI_Fint PMPI_Op_c2f(MPI_Op op){
2753 return smpi_op_c2f(op);
2756 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
2757 return smpi_comm_f2c(comm);
2760 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
2761 return smpi_comm_c2f(comm);
2764 MPI_Info PMPI_Info_f2c(MPI_Fint info){
2765 return smpi_info_f2c(info);
2768 MPI_Fint PMPI_Info_c2f(MPI_Info info){
2769 return smpi_info_c2f(info);
2772 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
2773 return smpi_comm_keyval_create(copy_fn, delete_fn, keyval, extra_state);
2776 int PMPI_Keyval_free(int* keyval) {
2777 return smpi_comm_keyval_free(keyval);
2780 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
2781 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
2782 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
2784 else if (comm==MPI_COMM_NULL)
2785 return MPI_ERR_COMM;
2787 return comm->attr_delete(keyval);
2790 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
2792 static int zero = 0;
2793 static int tag_ub = 1000000;
2794 static int last_used_code = MPI_ERR_LASTCODE;
2796 if (comm==MPI_COMM_NULL){
2798 return MPI_ERR_COMM;
2806 *static_cast<int**>(attr_value) = &zero;
2808 case MPI_UNIVERSE_SIZE:
2810 *static_cast<int**>(attr_value) = &smpi_universe_size;
2812 case MPI_LASTUSEDCODE:
2814 *static_cast<int**>(attr_value) = &last_used_code;
2818 *static_cast<int**>(attr_value) = &tag_ub;
2820 case MPI_WTIME_IS_GLOBAL:
2822 *static_cast<int**>(attr_value) = &one;
2825 return comm->attr_get(keyval, attr_value, flag);
2829 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
2830 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
2831 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
2833 else if (comm==MPI_COMM_NULL)
2834 return MPI_ERR_COMM;
2836 return comm->attr_put(keyval, attr_value);
2839 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
2841 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
2844 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
2846 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
2849 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
2851 return PMPI_Attr_delete(comm, comm_keyval);
2854 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
2857 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
2860 int PMPI_Comm_free_keyval(int* keyval) {
2861 return PMPI_Keyval_free(keyval);
2864 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
2866 if (type==MPI_DATATYPE_NULL)
2867 return MPI_ERR_TYPE;
2869 return smpi_type_attr_get(type, type_keyval, attribute_val, flag);
2872 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
2874 if (type==MPI_DATATYPE_NULL)
2875 return MPI_ERR_TYPE;
2877 return smpi_type_attr_put(type, type_keyval, attribute_val);
2880 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
2882 if (type==MPI_DATATYPE_NULL)
2883 return MPI_ERR_TYPE;
2885 return smpi_type_attr_delete(type, type_keyval);
2888 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
2891 return smpi_type_keyval_create(copy_fn, delete_fn, keyval, extra_state);
2894 int PMPI_Type_free_keyval(int* keyval) {
2895 return smpi_type_keyval_free(keyval);
2898 int PMPI_Info_create( MPI_Info *info){
2899 if (info == nullptr)
2901 *info = xbt_new(s_smpi_mpi_info_t, 1);
2902 (*info)->info_dict= xbt_dict_new_homogeneous(xbt_free_f);
2903 (*info)->refcount=1;
2907 int PMPI_Info_set( MPI_Info info, char *key, char *value){
2908 if (info == nullptr || key == nullptr || value == nullptr)
2911 xbt_dict_set(info->info_dict, key, xbt_strdup(value), nullptr);
2915 int PMPI_Info_free( MPI_Info *info){
2916 if (info == nullptr || *info==nullptr)
2918 (*info)->refcount--;
2919 if((*info)->refcount==0){
2920 xbt_dict_free(&((*info)->info_dict));
2923 *info=MPI_INFO_NULL;
2927 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
2929 if (info == nullptr || key == nullptr || valuelen <0)
2931 if (value == nullptr)
2932 return MPI_ERR_INFO_VALUE;
2933 char* tmpvalue=static_cast<char*>(xbt_dict_get_or_null(info->info_dict, key));
2935 memset(value, 0, valuelen);
2936 memcpy(value,tmpvalue, (strlen(tmpvalue) + 1 < static_cast<size_t>(valuelen)) ? strlen(tmpvalue) + 1 : valuelen);
2942 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
2943 if (info == nullptr || newinfo==nullptr)
2945 *newinfo = xbt_new(s_smpi_mpi_info_t, 1);
2946 (*newinfo)->info_dict= xbt_dict_new_homogeneous(xbt_free_f);
2947 (*newinfo)->refcount=1;
2948 xbt_dict_cursor_t cursor = nullptr;
2951 xbt_dict_foreach(info->info_dict,cursor,key,data){
2952 xbt_dict_set((*newinfo)->info_dict, key, xbt_strdup(static_cast<char*>(data)), nullptr);
2957 int PMPI_Info_delete(MPI_Info info, char *key){
2958 if (info == nullptr || key==nullptr)
2961 xbt_dict_remove(info->info_dict, key);
2964 return MPI_ERR_INFO_NOKEY;
2969 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
2970 if (info == nullptr || nkeys==nullptr)
2972 *nkeys=xbt_dict_size(info->info_dict);
2976 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
2977 if (info == nullptr || key==nullptr || n<0 || n> MPI_MAX_INFO_KEY)
2980 xbt_dict_cursor_t cursor = nullptr;
2984 xbt_dict_foreach(info->info_dict,cursor,keyn,data){
2986 strncpy(key,keyn,strlen(keyn)+1);
2987 xbt_dict_cursor_free(&cursor);
2995 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
2997 if (info == nullptr || key == nullptr || valuelen==nullptr)
2999 char* tmpvalue=(char*)xbt_dict_get_or_null(info->info_dict, key);
3001 *valuelen=strlen(tmpvalue);
3007 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3008 if(incount<0 || outcount < 0 || inbuf==nullptr || outbuf==nullptr)
3010 if(!is_datatype_valid(type))
3011 return MPI_ERR_TYPE;
3012 if(comm==MPI_COMM_NULL)
3013 return MPI_ERR_COMM;
3014 return smpi_mpi_unpack(inbuf, incount, position, outbuf,outcount,type, comm);
3017 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3018 if(incount<0 || outcount < 0|| inbuf==nullptr || outbuf==nullptr)
3020 if(!is_datatype_valid(type))
3021 return MPI_ERR_TYPE;
3022 if(comm==MPI_COMM_NULL)
3023 return MPI_ERR_COMM;
3024 return smpi_mpi_pack(inbuf, incount, type, outbuf,outcount,position, comm);
3027 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3030 if(!is_datatype_valid(datatype))
3031 return MPI_ERR_TYPE;
3032 if(comm==MPI_COMM_NULL)
3033 return MPI_ERR_COMM;
3035 *size=incount*smpi_datatype_size(datatype);