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 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi, "Logging specific to SMPI (pmpi)");
12 //this function need to be here because of the calls to smpi_bench
13 void TRACE_smpi_set_category(const char *category)
15 //need to end bench otherwise categories for execution tasks are wrong
17 TRACE_internal_smpi_set_category (category);
18 //begin bench after changing process's category
22 /* PMPI User level calls */
23 extern "C" { // Obviously, the C MPI interface should use the C linkage
25 int PMPI_Init(int *argc, char ***argv)
27 // PMPI_Init is call only one time by only by SMPI process
29 MPI_Initialized(&already_init);
30 if(already_init == 0){
31 simgrid::smpi::Process::init(argc, argv);
32 smpi_process()->mark_as_initialized();
33 int rank = smpi_process()->index();
34 TRACE_smpi_init(rank);
35 TRACE_smpi_computing_init(rank);
36 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
37 extra->type = TRACING_INIT;
38 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
39 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
51 int rank = smpi_process()->index();
52 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
53 extra->type = TRACING_FINALIZE;
54 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
56 smpi_process()->finalize();
58 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
59 TRACE_smpi_finalize(smpi_process()->index());
60 smpi_process()->destroy();
64 int PMPI_Finalized(int* flag)
66 *flag=smpi_process()!=nullptr ? smpi_process()->finalized() : 0;
70 int PMPI_Get_version (int *version,int *subversion){
71 *version = MPI_VERSION;
72 *subversion= MPI_SUBVERSION;
76 int PMPI_Get_library_version (char *version,int *len){
78 snprintf(version,MPI_MAX_LIBRARY_VERSION_STRING,"SMPI Version %d.%d. Copyright The Simgrid Team 2007-2015",
79 SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR);
80 *len = strlen(version) > MPI_MAX_LIBRARY_VERSION_STRING ? MPI_MAX_LIBRARY_VERSION_STRING : strlen(version);
85 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
87 if (provided != nullptr) {
88 *provided = MPI_THREAD_SINGLE;
90 return MPI_Init(argc, argv);
93 int PMPI_Query_thread(int *provided)
95 if (provided == nullptr) {
98 *provided = MPI_THREAD_SINGLE;
103 int PMPI_Is_thread_main(int *flag)
105 if (flag == nullptr) {
108 *flag = smpi_process()->index() == 0;
113 int PMPI_Abort(MPI_Comm comm, int errorcode)
116 smpi_process()->destroy();
117 // FIXME: should kill all processes in comm instead
118 simcall_process_kill(SIMIX_process_self());
124 return smpi_mpi_wtime();
127 extern double sg_maxmin_precision;
130 return sg_maxmin_precision;
133 int PMPI_Address(void *location, MPI_Aint * address)
135 if (address==nullptr) {
138 *address = reinterpret_cast<MPI_Aint>(location);
143 int PMPI_Get_address(void *location, MPI_Aint * address)
145 return PMPI_Address(location, address);
148 int PMPI_Type_free(MPI_Datatype * datatype)
150 /* Free a predefined datatype is an error according to the standard, and should be checked for */
151 if (*datatype == MPI_DATATYPE_NULL) {
154 simgrid::smpi::Datatype::unref(*datatype);
159 int PMPI_Type_size(MPI_Datatype datatype, int *size)
161 if (datatype == MPI_DATATYPE_NULL) {
163 } else if (size == nullptr) {
166 *size = static_cast<int>(datatype->size());
171 int PMPI_Type_size_x(MPI_Datatype datatype, MPI_Count *size)
173 if (datatype == MPI_DATATYPE_NULL) {
175 } else if (size == nullptr) {
178 *size = static_cast<MPI_Count>(datatype->size());
183 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
185 if (datatype == MPI_DATATYPE_NULL) {
187 } else if (lb == nullptr || extent == nullptr) {
190 return datatype->extent(lb, extent);
194 int PMPI_Type_get_true_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
196 return PMPI_Type_get_extent(datatype, lb, extent);
199 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
201 if (datatype == MPI_DATATYPE_NULL) {
203 } else if (extent == nullptr) {
206 *extent = datatype->get_extent();
211 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
213 if (datatype == MPI_DATATYPE_NULL) {
215 } else if (disp == nullptr) {
218 *disp = datatype->lb();
223 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
225 if (datatype == MPI_DATATYPE_NULL) {
227 } else if (disp == nullptr) {
230 *disp = datatype->ub();
235 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
236 int retval = MPI_SUCCESS;
237 if (datatype == MPI_DATATYPE_NULL) {
240 *newtype = new simgrid::smpi::Datatype(datatype, &retval);
241 //error when duplicating, free the new datatype
242 if(retval!=MPI_SUCCESS){
243 simgrid::smpi::Datatype::unref(*newtype);
244 *newtype = MPI_DATATYPE_NULL;
250 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
252 if (function == nullptr || op == nullptr) {
255 *op = new simgrid::smpi::Op(function, (commute!=0));
260 int PMPI_Op_free(MPI_Op * op)
264 } else if (*op == MPI_OP_NULL) {
273 int PMPI_Op_commutative(MPI_Op op, int* commute){
274 if (op == MPI_OP_NULL) {
276 } else if (commute==nullptr){
279 *commute = op->is_commutative();
284 int PMPI_Group_free(MPI_Group * group)
286 if (group == nullptr) {
289 if(*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_EMPTY)
290 simgrid::smpi::Group::unref(*group);
291 *group = MPI_GROUP_NULL;
296 int PMPI_Group_size(MPI_Group group, int *size)
298 if (group == MPI_GROUP_NULL) {
299 return MPI_ERR_GROUP;
300 } else if (size == nullptr) {
303 *size = group->size();
308 int PMPI_Group_rank(MPI_Group group, int *rank)
310 if (group == MPI_GROUP_NULL) {
311 return MPI_ERR_GROUP;
312 } else if (rank == nullptr) {
315 *rank = group->rank(smpi_process()->index());
320 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2)
322 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
323 return MPI_ERR_GROUP;
325 for (int i = 0; i < n; i++) {
326 if(ranks1[i]==MPI_PROC_NULL){
327 ranks2[i]=MPI_PROC_NULL;
329 int index = group1->index(ranks1[i]);
330 ranks2[i] = group2->rank(index);
337 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
339 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
340 return MPI_ERR_GROUP;
341 } else if (result == nullptr) {
344 *result = group1->compare(group2);
349 int PMPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
352 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
353 return MPI_ERR_GROUP;
354 } else if (newgroup == nullptr) {
357 return group1->group_union(group2, newgroup);
361 int PMPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
364 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
365 return MPI_ERR_GROUP;
366 } else if (newgroup == nullptr) {
369 return group1->intersection(group2,newgroup);
373 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
375 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
376 return MPI_ERR_GROUP;
377 } else if (newgroup == nullptr) {
380 return group1->difference(group2,newgroup);
384 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
386 if (group == MPI_GROUP_NULL) {
387 return MPI_ERR_GROUP;
388 } else if (newgroup == nullptr) {
391 return group->incl(n, ranks, newgroup);
395 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
397 if (group == MPI_GROUP_NULL) {
398 return MPI_ERR_GROUP;
399 } else if (newgroup == nullptr) {
404 if (group != MPI_COMM_WORLD->group()
405 && group != MPI_COMM_SELF->group() && group != MPI_GROUP_EMPTY)
408 } else if (n == group->size()) {
409 *newgroup = MPI_GROUP_EMPTY;
412 return group->excl(n,ranks,newgroup);
417 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
419 if (group == MPI_GROUP_NULL) {
420 return MPI_ERR_GROUP;
421 } else if (newgroup == nullptr) {
425 *newgroup = MPI_GROUP_EMPTY;
428 return group->range_incl(n,ranges,newgroup);
433 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
435 if (group == MPI_GROUP_NULL) {
436 return MPI_ERR_GROUP;
437 } else if (newgroup == nullptr) {
442 if (group != MPI_COMM_WORLD->group() && group != MPI_COMM_SELF->group() &&
443 group != MPI_GROUP_EMPTY)
447 return group->range_excl(n,ranges,newgroup);
452 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
454 if (comm == MPI_COMM_NULL) {
456 } else if (rank == nullptr) {
459 *rank = comm->rank();
464 int PMPI_Comm_size(MPI_Comm comm, int *size)
466 if (comm == MPI_COMM_NULL) {
468 } else if (size == nullptr) {
471 *size = comm->size();
476 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
478 if (comm == MPI_COMM_NULL) {
480 } else if (name == nullptr || len == nullptr) {
483 comm->get_name(name, len);
488 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
490 if (comm == MPI_COMM_NULL) {
492 } else if (group == nullptr) {
495 *group = comm->group();
496 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
502 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
504 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
506 } else if (result == nullptr) {
509 if (comm1 == comm2) { /* Same communicators means same groups */
512 *result = comm1->group()->compare(comm2->group());
513 if (*result == MPI_IDENT) {
514 *result = MPI_CONGRUENT;
521 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
523 if (comm == MPI_COMM_NULL) {
525 } else if (newcomm == nullptr) {
528 return comm->dup(newcomm);
532 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
534 if (comm == MPI_COMM_NULL) {
536 } else if (group == MPI_GROUP_NULL) {
537 return MPI_ERR_GROUP;
538 } else if (newcomm == nullptr) {
540 } else if(group->rank(smpi_process()->index())==MPI_UNDEFINED){
541 *newcomm= MPI_COMM_NULL;
545 *newcomm = new simgrid::smpi::Comm(group, nullptr);
550 int PMPI_Comm_free(MPI_Comm * comm)
552 if (comm == nullptr) {
554 } else if (*comm == MPI_COMM_NULL) {
557 simgrid::smpi::Comm::destroy(*comm);
558 *comm = MPI_COMM_NULL;
563 int PMPI_Comm_disconnect(MPI_Comm * comm)
565 /* TODO: wait until all communication in comm are done */
566 if (comm == nullptr) {
568 } else if (*comm == MPI_COMM_NULL) {
571 simgrid::smpi::Comm::destroy(*comm);
572 *comm = MPI_COMM_NULL;
577 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
582 if (comm_out == nullptr) {
583 retval = MPI_ERR_ARG;
584 } else if (comm == MPI_COMM_NULL) {
585 retval = MPI_ERR_COMM;
587 *comm_out = comm->split(color, key);
588 retval = MPI_SUCCESS;
595 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
600 if (comm_out == nullptr) {
601 retval = MPI_ERR_ARG;
602 } else if (comm == MPI_COMM_NULL) {
603 retval = MPI_ERR_COMM;
605 retval = MPI_Comm_create(comm, group, comm_out);
612 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
617 if (request == nullptr) {
618 retval = MPI_ERR_ARG;
619 } else if (comm == MPI_COMM_NULL) {
620 retval = MPI_ERR_COMM;
621 } else if (!datatype->is_valid()) {
622 retval = MPI_ERR_TYPE;
623 } else if (dst == MPI_PROC_NULL) {
624 retval = MPI_SUCCESS;
626 *request = simgrid::smpi::Request::send_init(buf, count, datatype, dst, tag, comm);
627 retval = MPI_SUCCESS;
630 if (retval != MPI_SUCCESS && request != nullptr)
631 *request = MPI_REQUEST_NULL;
635 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
640 if (request == nullptr) {
641 retval = MPI_ERR_ARG;
642 } else if (comm == MPI_COMM_NULL) {
643 retval = MPI_ERR_COMM;
644 } else if (!datatype->is_valid()) {
645 retval = MPI_ERR_TYPE;
646 } else if (src == MPI_PROC_NULL) {
647 retval = MPI_SUCCESS;
649 *request = simgrid::smpi::Request::recv_init(buf, count, datatype, src, tag, comm);
650 retval = MPI_SUCCESS;
653 if (retval != MPI_SUCCESS && request != nullptr)
654 *request = MPI_REQUEST_NULL;
658 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
663 if (request == nullptr) {
664 retval = MPI_ERR_ARG;
665 } else if (comm == MPI_COMM_NULL) {
666 retval = MPI_ERR_COMM;
667 } else if (!datatype->is_valid()) {
668 retval = MPI_ERR_TYPE;
669 } else if (dst == MPI_PROC_NULL) {
670 retval = MPI_SUCCESS;
672 *request = simgrid::smpi::Request::ssend_init(buf, count, datatype, dst, tag, comm);
673 retval = MPI_SUCCESS;
676 if (retval != MPI_SUCCESS && request != nullptr)
677 *request = MPI_REQUEST_NULL;
681 int PMPI_Start(MPI_Request * request)
686 if (request == nullptr || *request == MPI_REQUEST_NULL) {
687 retval = MPI_ERR_REQUEST;
690 retval = MPI_SUCCESS;
696 int PMPI_Startall(int count, MPI_Request * requests)
700 if (requests == nullptr) {
701 retval = MPI_ERR_ARG;
703 retval = MPI_SUCCESS;
704 for (int i = 0; i < count; i++) {
705 if(requests[i] == MPI_REQUEST_NULL) {
706 retval = MPI_ERR_REQUEST;
709 if(retval != MPI_ERR_REQUEST) {
710 simgrid::smpi::Request::startall(count, requests);
717 int PMPI_Request_free(MPI_Request * request)
722 if (*request == MPI_REQUEST_NULL) {
723 retval = MPI_ERR_ARG;
725 simgrid::smpi::Request::unref(request);
726 retval = MPI_SUCCESS;
732 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
738 if (request == nullptr) {
739 retval = MPI_ERR_ARG;
740 } else if (comm == MPI_COMM_NULL) {
741 retval = MPI_ERR_COMM;
742 } else if (src == MPI_PROC_NULL) {
743 *request = MPI_REQUEST_NULL;
744 retval = MPI_SUCCESS;
745 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
746 retval = MPI_ERR_RANK;
747 } else if ((count < 0) || (buf==nullptr && count > 0)) {
748 retval = MPI_ERR_COUNT;
749 } else if (!datatype->is_valid()) {
750 retval = MPI_ERR_TYPE;
751 } else if(tag<0 && tag != MPI_ANY_TAG){
752 retval = MPI_ERR_TAG;
755 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
756 int src_traced = comm->group()->index(src);
758 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
759 extra->type = TRACING_IRECV;
760 extra->src = src_traced;
763 extra->datatype1 = encode_datatype(datatype, &known);
764 int dt_size_send = 1;
766 dt_size_send = datatype->size();
767 extra->send_size = count*dt_size_send;
768 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
770 *request = simgrid::smpi::Request::irecv(buf, count, datatype, src, tag, comm);
771 retval = MPI_SUCCESS;
773 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
777 if (retval != MPI_SUCCESS && request != nullptr)
778 *request = MPI_REQUEST_NULL;
783 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
788 if (request == nullptr) {
789 retval = MPI_ERR_ARG;
790 } else if (comm == MPI_COMM_NULL) {
791 retval = MPI_ERR_COMM;
792 } else if (dst == MPI_PROC_NULL) {
793 *request = MPI_REQUEST_NULL;
794 retval = MPI_SUCCESS;
795 } else if (dst >= comm->group()->size() || dst <0){
796 retval = MPI_ERR_RANK;
797 } else if ((count < 0) || (buf==nullptr && count > 0)) {
798 retval = MPI_ERR_COUNT;
799 } else if (!datatype->is_valid()) {
800 retval = MPI_ERR_TYPE;
801 } else if(tag<0 && tag != MPI_ANY_TAG){
802 retval = MPI_ERR_TAG;
804 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
805 int dst_traced = comm->group()->index(dst);
806 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
807 extra->type = TRACING_ISEND;
809 extra->dst = dst_traced;
811 extra->datatype1 = encode_datatype(datatype, &known);
812 int dt_size_send = 1;
814 dt_size_send = datatype->size();
815 extra->send_size = count*dt_size_send;
816 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
817 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
819 *request = simgrid::smpi::Request::isend(buf, count, datatype, dst, tag, comm);
820 retval = MPI_SUCCESS;
822 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
826 if (retval != MPI_SUCCESS && request!=nullptr)
827 *request = MPI_REQUEST_NULL;
831 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
836 if (request == nullptr) {
837 retval = MPI_ERR_ARG;
838 } else if (comm == MPI_COMM_NULL) {
839 retval = MPI_ERR_COMM;
840 } else if (dst == MPI_PROC_NULL) {
841 *request = MPI_REQUEST_NULL;
842 retval = MPI_SUCCESS;
843 } else if (dst >= comm->group()->size() || dst <0){
844 retval = MPI_ERR_RANK;
845 } else if ((count < 0)|| (buf==nullptr && count > 0)) {
846 retval = MPI_ERR_COUNT;
847 } else if (!datatype->is_valid()) {
848 retval = MPI_ERR_TYPE;
849 } else if(tag<0 && tag != MPI_ANY_TAG){
850 retval = MPI_ERR_TAG;
852 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
853 int dst_traced = comm->group()->index(dst);
854 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
855 extra->type = TRACING_ISSEND;
857 extra->dst = dst_traced;
859 extra->datatype1 = encode_datatype(datatype, &known);
860 int dt_size_send = 1;
862 dt_size_send = datatype->size();
863 extra->send_size = count*dt_size_send;
864 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
865 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
867 *request = simgrid::smpi::Request::issend(buf, count, datatype, dst, tag, comm);
868 retval = MPI_SUCCESS;
870 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
874 if (retval != MPI_SUCCESS && request!=nullptr)
875 *request = MPI_REQUEST_NULL;
879 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
884 if (comm == MPI_COMM_NULL) {
885 retval = MPI_ERR_COMM;
886 } else if (src == MPI_PROC_NULL) {
887 simgrid::smpi::Status::empty(status);
888 status->MPI_SOURCE = MPI_PROC_NULL;
889 retval = MPI_SUCCESS;
890 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
891 retval = MPI_ERR_RANK;
892 } else if ((count < 0) || (buf==nullptr && count > 0)) {
893 retval = MPI_ERR_COUNT;
894 } else if (!datatype->is_valid()) {
895 retval = MPI_ERR_TYPE;
896 } else if(tag<0 && tag != MPI_ANY_TAG){
897 retval = MPI_ERR_TAG;
899 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
900 int src_traced = comm->group()->index(src);
901 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
902 extra->type = TRACING_RECV;
903 extra->src = src_traced;
906 extra->datatype1 = encode_datatype(datatype, &known);
907 int dt_size_send = 1;
909 dt_size_send = datatype->size();
910 extra->send_size = count * dt_size_send;
911 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
913 simgrid::smpi::Request::recv(buf, count, datatype, src, tag, comm, status);
914 retval = MPI_SUCCESS;
916 // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
917 if (status != MPI_STATUS_IGNORE) {
918 src_traced = comm->group()->index(status->MPI_SOURCE);
919 if (!TRACE_smpi_view_internals()) {
920 TRACE_smpi_recv(rank, src_traced, rank, tag);
923 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
930 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
936 if (comm == MPI_COMM_NULL) {
937 retval = MPI_ERR_COMM;
938 } else if (dst == MPI_PROC_NULL) {
939 retval = MPI_SUCCESS;
940 } else if (dst >= comm->group()->size() || dst <0){
941 retval = MPI_ERR_RANK;
942 } else if ((count < 0) || (buf == nullptr && count > 0)) {
943 retval = MPI_ERR_COUNT;
944 } else if (!datatype->is_valid()) {
945 retval = MPI_ERR_TYPE;
946 } else if(tag < 0 && tag != MPI_ANY_TAG){
947 retval = MPI_ERR_TAG;
949 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
950 int dst_traced = comm->group()->index(dst);
951 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
952 extra->type = TRACING_SEND;
954 extra->dst = dst_traced;
956 extra->datatype1 = encode_datatype(datatype, &known);
957 int dt_size_send = 1;
959 dt_size_send = datatype->size();
961 extra->send_size = count*dt_size_send;
962 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
963 if (!TRACE_smpi_view_internals()) {
964 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
967 simgrid::smpi::Request::send(buf, count, datatype, dst, tag, comm);
968 retval = MPI_SUCCESS;
970 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
977 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
982 if (comm == MPI_COMM_NULL) {
983 retval = MPI_ERR_COMM;
984 } else if (dst == MPI_PROC_NULL) {
985 retval = MPI_SUCCESS;
986 } else if (dst >= comm->group()->size() || dst <0){
987 retval = MPI_ERR_RANK;
988 } else if ((count < 0) || (buf==nullptr && count > 0)) {
989 retval = MPI_ERR_COUNT;
990 } else if (!datatype->is_valid()){
991 retval = MPI_ERR_TYPE;
992 } else if(tag<0 && tag != MPI_ANY_TAG){
993 retval = MPI_ERR_TAG;
995 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
996 int dst_traced = comm->group()->index(dst);
997 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
998 extra->type = TRACING_SSEND;
1000 extra->dst = dst_traced;
1002 extra->datatype1 = encode_datatype(datatype, &known);
1003 int dt_size_send = 1;
1005 dt_size_send = datatype->size();
1007 extra->send_size = count*dt_size_send;
1008 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1009 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
1011 simgrid::smpi::Request::ssend(buf, count, datatype, dst, tag, comm);
1012 retval = MPI_SUCCESS;
1014 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1021 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void *recvbuf,
1022 int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status)
1028 if (comm == MPI_COMM_NULL) {
1029 retval = MPI_ERR_COMM;
1030 } else if (!sendtype->is_valid() || !recvtype->is_valid()) {
1031 retval = MPI_ERR_TYPE;
1032 } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1033 simgrid::smpi::Status::empty(status);
1034 status->MPI_SOURCE = MPI_PROC_NULL;
1035 retval = MPI_SUCCESS;
1036 }else if (dst >= comm->group()->size() || dst <0 ||
1037 (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0))){
1038 retval = MPI_ERR_RANK;
1039 } else if ((sendcount < 0 || recvcount<0) ||
1040 (sendbuf==nullptr && sendcount > 0) || (recvbuf==nullptr && recvcount>0)) {
1041 retval = MPI_ERR_COUNT;
1042 } else if((sendtag<0 && sendtag != MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1043 retval = MPI_ERR_TAG;
1046 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1047 int dst_traced = comm->group()->index(dst);
1048 int src_traced = comm->group()->index(src);
1049 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1050 extra->type = TRACING_SENDRECV;
1051 extra->src = src_traced;
1052 extra->dst = dst_traced;
1054 extra->datatype1 = encode_datatype(sendtype, &known);
1055 int dt_size_send = 1;
1057 dt_size_send = sendtype->size();
1058 extra->send_size = sendcount*dt_size_send;
1059 extra->datatype2 = encode_datatype(recvtype, &known);
1060 int dt_size_recv = 1;
1062 dt_size_recv = recvtype->size();
1063 extra->recv_size = recvcount*dt_size_recv;
1065 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1066 TRACE_smpi_send(rank, rank, dst_traced, sendtag,sendcount*sendtype->size());
1068 simgrid::smpi::Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm,
1070 retval = MPI_SUCCESS;
1072 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1073 TRACE_smpi_recv(rank, src_traced, rank, recvtag);
1080 int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,
1081 MPI_Comm comm, MPI_Status* status)
1084 if (!datatype->is_valid()) {
1085 return MPI_ERR_TYPE;
1086 } else if (count < 0) {
1087 return MPI_ERR_COUNT;
1089 int size = datatype->get_extent() * count;
1090 void* recvbuf = xbt_new0(char, size);
1091 retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
1092 if(retval==MPI_SUCCESS){
1093 simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
1101 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1105 if (request == nullptr || flag == nullptr) {
1106 retval = MPI_ERR_ARG;
1107 } else if (*request == MPI_REQUEST_NULL) {
1109 simgrid::smpi::Status::empty(status);
1110 retval = MPI_SUCCESS;
1112 int rank = ((*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1114 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1115 extra->type = TRACING_TEST;
1116 TRACE_smpi_testing_in(rank, extra);
1118 *flag = simgrid::smpi::Request::test(request,status);
1120 TRACE_smpi_testing_out(rank);
1121 retval = MPI_SUCCESS;
1127 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status)
1132 if (index == nullptr || flag == nullptr) {
1133 retval = MPI_ERR_ARG;
1135 *flag = simgrid::smpi::Request::testany(count, requests, index, status);
1136 retval = MPI_SUCCESS;
1142 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1147 if (flag == nullptr) {
1148 retval = MPI_ERR_ARG;
1150 *flag = simgrid::smpi::Request::testall(count, requests, statuses);
1151 retval = MPI_SUCCESS;
1157 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1161 if (status == nullptr) {
1162 retval = MPI_ERR_ARG;
1163 } else if (comm == MPI_COMM_NULL) {
1164 retval = MPI_ERR_COMM;
1165 } else if (source == MPI_PROC_NULL) {
1166 simgrid::smpi::Status::empty(status);
1167 status->MPI_SOURCE = MPI_PROC_NULL;
1168 retval = MPI_SUCCESS;
1170 simgrid::smpi::Request::probe(source, tag, comm, status);
1171 retval = MPI_SUCCESS;
1177 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1181 if (flag == nullptr) {
1182 retval = MPI_ERR_ARG;
1183 } else if (comm == MPI_COMM_NULL) {
1184 retval = MPI_ERR_COMM;
1185 } else if (source == MPI_PROC_NULL) {
1187 simgrid::smpi::Status::empty(status);
1188 status->MPI_SOURCE = MPI_PROC_NULL;
1189 retval = MPI_SUCCESS;
1191 simgrid::smpi::Request::iprobe(source, tag, comm, flag, status);
1192 retval = MPI_SUCCESS;
1198 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1204 simgrid::smpi::Status::empty(status);
1206 if (request == nullptr) {
1207 retval = MPI_ERR_ARG;
1208 } else if (*request == MPI_REQUEST_NULL) {
1209 retval = MPI_SUCCESS;
1212 int rank = (request!=nullptr && (*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1214 int src_traced = (*request)->src();
1215 int dst_traced = (*request)->dst();
1216 int tag_traced= (*request)->tag();
1217 MPI_Comm comm = (*request)->comm();
1218 int is_wait_for_receive = ((*request)->flags() & RECV);
1219 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1220 extra->type = TRACING_WAIT;
1221 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1223 simgrid::smpi::Request::wait(request, status);
1224 retval = MPI_SUCCESS;
1226 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1227 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1228 if (is_wait_for_receive) {
1229 if(src_traced==MPI_ANY_SOURCE)
1230 src_traced = (status!=MPI_STATUS_IGNORE) ?
1231 comm->group()->rank(status->MPI_SOURCE) :
1233 TRACE_smpi_recv(rank, src_traced, dst_traced, tag_traced);
1241 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1243 if (index == nullptr)
1247 //save requests information for tracing
1255 savedvalstype* savedvals=nullptr;
1257 savedvals = xbt_new0(savedvalstype, count);
1259 for (int i = 0; i < count; i++) {
1260 MPI_Request req = requests[i]; //already received requests are no longer valid
1262 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), req->comm()};
1265 int rank_traced = smpi_process()->index();
1266 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1267 extra->type = TRACING_WAITANY;
1268 extra->send_size=count;
1269 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1271 *index = simgrid::smpi::Request::waitany(count, requests, status);
1273 if(*index!=MPI_UNDEFINED){
1274 int src_traced = savedvals[*index].src;
1275 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1276 int dst_traced = savedvals[*index].dst;
1277 int is_wait_for_receive = savedvals[*index].recv;
1278 if (is_wait_for_receive) {
1279 if(savedvals[*index].src==MPI_ANY_SOURCE)
1280 src_traced = (status != MPI_STATUSES_IGNORE)
1281 ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
1282 : savedvals[*index].src;
1283 TRACE_smpi_recv(rank_traced, src_traced, dst_traced, savedvals[*index].tag);
1285 TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1287 xbt_free(savedvals);
1293 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1296 //save information from requests
1305 savedvalstype* savedvals=xbt_new0(savedvalstype, count);
1307 for (int i = 0; i < count; i++) {
1308 MPI_Request req = requests[i];
1309 if(req!=MPI_REQUEST_NULL){
1310 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), 1, req->comm()};
1312 savedvals[i].valid=0;
1315 int rank_traced = smpi_process()->index();
1316 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1317 extra->type = TRACING_WAITALL;
1318 extra->send_size=count;
1319 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1321 int retval = simgrid::smpi::Request::waitall(count, requests, status);
1323 for (int i = 0; i < count; i++) {
1324 if(savedvals[i].valid){
1325 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1326 int src_traced = savedvals[i].src;
1327 int dst_traced = savedvals[i].dst;
1328 int is_wait_for_receive = savedvals[i].recv;
1329 if (is_wait_for_receive) {
1330 if(src_traced==MPI_ANY_SOURCE)
1331 src_traced = (status!=MPI_STATUSES_IGNORE) ?
1332 savedvals[i].comm->group()->rank(status[i].MPI_SOURCE) : savedvals[i].src;
1333 TRACE_smpi_recv(rank_traced, src_traced, dst_traced,savedvals[i].tag);
1337 TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1338 xbt_free(savedvals);
1344 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount, int *indices, MPI_Status status[])
1349 if (outcount == nullptr) {
1350 retval = MPI_ERR_ARG;
1352 *outcount = simgrid::smpi::Request::waitsome(incount, requests, indices, status);
1353 retval = MPI_SUCCESS;
1359 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[])
1364 if (outcount == nullptr) {
1365 retval = MPI_ERR_ARG;
1367 *outcount = simgrid::smpi::Request::testsome(incount, requests, indices, status);
1368 retval = MPI_SUCCESS;
1375 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1381 if (comm == MPI_COMM_NULL) {
1382 retval = MPI_ERR_COMM;
1383 } else if (!datatype->is_valid()) {
1384 retval = MPI_ERR_ARG;
1386 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1387 int root_traced = comm->group()->index(root);
1389 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1390 extra->type = TRACING_BCAST;
1391 extra->root = root_traced;
1393 extra->datatype1 = encode_datatype(datatype, &known);
1394 int dt_size_send = 1;
1396 dt_size_send = datatype->size();
1397 extra->send_size = count * dt_size_send;
1398 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1399 if (comm->size() > 1)
1400 simgrid::smpi::Colls::bcast(buf, count, datatype, root, comm);
1401 retval = MPI_SUCCESS;
1403 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1409 int PMPI_Barrier(MPI_Comm comm)
1415 if (comm == MPI_COMM_NULL) {
1416 retval = MPI_ERR_COMM;
1418 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1419 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1420 extra->type = TRACING_BARRIER;
1421 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1423 simgrid::smpi::Colls::barrier(comm);
1425 //Barrier can be used to synchronize RMA calls. Finish all requests from comm before.
1426 comm->finish_rma_calls();
1428 retval = MPI_SUCCESS;
1430 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1437 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
1438 int root, MPI_Comm comm)
1444 if (comm == MPI_COMM_NULL) {
1445 retval = MPI_ERR_COMM;
1446 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1447 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1448 retval = MPI_ERR_TYPE;
1449 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) || ((comm->rank() == root) && (recvcount <0))){
1450 retval = MPI_ERR_COUNT;
1453 char* sendtmpbuf = static_cast<char*>(sendbuf);
1454 int sendtmpcount = sendcount;
1455 MPI_Datatype sendtmptype = sendtype;
1456 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1458 sendtmptype=recvtype;
1460 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1461 int root_traced = comm->group()->index(root);
1462 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1463 extra->type = TRACING_GATHER;
1464 extra->root = root_traced;
1466 extra->datatype1 = encode_datatype(sendtmptype, &known);
1467 int dt_size_send = 1;
1469 dt_size_send = sendtmptype->size();
1470 extra->send_size = sendtmpcount * dt_size_send;
1471 extra->datatype2 = encode_datatype(recvtype, &known);
1472 int dt_size_recv = 1;
1473 if ((comm->rank() == root) && known == 0)
1474 dt_size_recv = recvtype->size();
1475 extra->recv_size = recvcount * dt_size_recv;
1477 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1479 simgrid::smpi::Colls::gather(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
1481 retval = MPI_SUCCESS;
1482 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1489 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
1490 MPI_Datatype recvtype, int root, MPI_Comm comm)
1496 if (comm == MPI_COMM_NULL) {
1497 retval = MPI_ERR_COMM;
1498 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1499 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1500 retval = MPI_ERR_TYPE;
1501 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1502 retval = MPI_ERR_COUNT;
1503 } else if (recvcounts == nullptr || displs == nullptr) {
1504 retval = MPI_ERR_ARG;
1506 char* sendtmpbuf = static_cast<char*>(sendbuf);
1507 int sendtmpcount = sendcount;
1508 MPI_Datatype sendtmptype = sendtype;
1509 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1511 sendtmptype=recvtype;
1514 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1515 int root_traced = comm->group()->index(root);
1517 int size = comm->size();
1518 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1519 extra->type = TRACING_GATHERV;
1520 extra->num_processes = size;
1521 extra->root = root_traced;
1523 extra->datatype1 = encode_datatype(sendtmptype, &known);
1524 int dt_size_send = 1;
1526 dt_size_send = sendtype->size();
1527 extra->send_size = sendtmpcount * dt_size_send;
1528 extra->datatype2 = encode_datatype(recvtype, &known);
1529 int dt_size_recv = 1;
1531 dt_size_recv = recvtype->size();
1532 if ((comm->rank() == root)) {
1533 extra->recvcounts = xbt_new(int, size);
1534 for (i = 0; i < size; i++) // copy data to avoid bad free
1535 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1537 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1539 retval = simgrid::smpi::Colls::gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
1540 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1547 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1548 void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
1554 if (comm == MPI_COMM_NULL) {
1555 retval = MPI_ERR_COMM;
1556 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1557 (recvtype == MPI_DATATYPE_NULL)){
1558 retval = MPI_ERR_TYPE;
1559 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1561 retval = MPI_ERR_COUNT;
1563 if(sendbuf == MPI_IN_PLACE) {
1564 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*recvcount*comm->rank();
1565 sendcount=recvcount;
1568 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1569 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1570 extra->type = TRACING_ALLGATHER;
1572 extra->datatype1 = encode_datatype(sendtype, &known);
1573 int dt_size_send = 1;
1575 dt_size_send = sendtype->size();
1576 extra->send_size = sendcount * dt_size_send;
1577 extra->datatype2 = encode_datatype(recvtype, &known);
1578 int dt_size_recv = 1;
1580 dt_size_recv = recvtype->size();
1581 extra->recv_size = recvcount * dt_size_recv;
1583 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1585 simgrid::smpi::Colls::allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1586 retval = MPI_SUCCESS;
1587 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1593 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1594 void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
1600 if (comm == MPI_COMM_NULL) {
1601 retval = MPI_ERR_COMM;
1602 } else if (((sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) || (recvtype == MPI_DATATYPE_NULL)) {
1603 retval = MPI_ERR_TYPE;
1604 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1605 retval = MPI_ERR_COUNT;
1606 } else if (recvcounts == nullptr || displs == nullptr) {
1607 retval = MPI_ERR_ARG;
1610 if(sendbuf == MPI_IN_PLACE) {
1611 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*displs[comm->rank()];
1612 sendcount=recvcounts[comm->rank()];
1615 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1617 int size = comm->size();
1618 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1619 extra->type = TRACING_ALLGATHERV;
1620 extra->num_processes = size;
1622 extra->datatype1 = encode_datatype(sendtype, &known);
1623 int dt_size_send = 1;
1625 dt_size_send = sendtype->size();
1626 extra->send_size = sendcount * dt_size_send;
1627 extra->datatype2 = encode_datatype(recvtype, &known);
1628 int dt_size_recv = 1;
1630 dt_size_recv = recvtype->size();
1631 extra->recvcounts = xbt_new(int, size);
1632 for (i = 0; i < size; i++) // copy data to avoid bad free
1633 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1635 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1637 simgrid::smpi::Colls::allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1638 retval = MPI_SUCCESS;
1639 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1646 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1647 void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1653 if (comm == MPI_COMM_NULL) {
1654 retval = MPI_ERR_COMM;
1655 } else if (((comm->rank() == root) && (!sendtype->is_valid())) ||
1656 ((recvbuf != MPI_IN_PLACE) && (!recvtype->is_valid()))) {
1657 retval = MPI_ERR_TYPE;
1658 } else if ((sendbuf == recvbuf) ||
1659 ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
1660 retval = MPI_ERR_BUFFER;
1663 if (recvbuf == MPI_IN_PLACE) {
1664 recvtype = sendtype;
1665 recvcount = sendcount;
1667 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1668 int root_traced = comm->group()->index(root);
1669 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1670 extra->type = TRACING_SCATTER;
1671 extra->root = root_traced;
1673 extra->datatype1 = encode_datatype(sendtype, &known);
1674 int dt_size_send = 1;
1675 if ((comm->rank() == root) && known == 0)
1676 dt_size_send = sendtype->size();
1677 extra->send_size = sendcount * dt_size_send;
1678 extra->datatype2 = encode_datatype(recvtype, &known);
1679 int dt_size_recv = 1;
1681 dt_size_recv = recvtype->size();
1682 extra->recv_size = recvcount * dt_size_recv;
1683 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1685 simgrid::smpi::Colls::scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1686 retval = MPI_SUCCESS;
1687 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1694 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1695 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1701 if (comm == MPI_COMM_NULL) {
1702 retval = MPI_ERR_COMM;
1703 } else if (sendcounts == nullptr || displs == nullptr) {
1704 retval = MPI_ERR_ARG;
1705 } else if (((comm->rank() == root) && (sendtype == MPI_DATATYPE_NULL)) ||
1706 ((recvbuf != MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1707 retval = MPI_ERR_TYPE;
1709 if (recvbuf == MPI_IN_PLACE) {
1710 recvtype = sendtype;
1711 recvcount = sendcounts[comm->rank()];
1713 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1714 int root_traced = comm->group()->index(root);
1716 int size = comm->size();
1717 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1718 extra->type = TRACING_SCATTERV;
1719 extra->num_processes = size;
1720 extra->root = root_traced;
1722 extra->datatype1 = encode_datatype(sendtype, &known);
1723 int dt_size_send = 1;
1725 dt_size_send = sendtype->size();
1726 if ((comm->rank() == root)) {
1727 extra->sendcounts = xbt_new(int, size);
1728 for (i = 0; i < size; i++) // copy data to avoid bad free
1729 extra->sendcounts[i] = sendcounts[i] * dt_size_send;
1731 extra->datatype2 = encode_datatype(recvtype, &known);
1732 int dt_size_recv = 1;
1734 dt_size_recv = recvtype->size();
1735 extra->recv_size = recvcount * dt_size_recv;
1736 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1738 retval = simgrid::smpi::Colls::scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1740 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1747 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
1753 if (comm == MPI_COMM_NULL) {
1754 retval = MPI_ERR_COMM;
1755 } else if (!datatype->is_valid() || op == MPI_OP_NULL) {
1756 retval = MPI_ERR_ARG;
1758 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1759 int root_traced = comm->group()->index(root);
1760 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1761 extra->type = TRACING_REDUCE;
1763 extra->datatype1 = encode_datatype(datatype, &known);
1764 int dt_size_send = 1;
1766 dt_size_send = datatype->size();
1767 extra->send_size = count * dt_size_send;
1768 extra->root = root_traced;
1770 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1772 simgrid::smpi::Colls::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1774 retval = MPI_SUCCESS;
1775 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1782 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op){
1786 if (!datatype->is_valid() || op == MPI_OP_NULL) {
1787 retval = MPI_ERR_ARG;
1789 op->apply(inbuf, inoutbuf, &count, datatype);
1790 retval = MPI_SUCCESS;
1796 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1802 if (comm == MPI_COMM_NULL) {
1803 retval = MPI_ERR_COMM;
1804 } else if (!datatype->is_valid()) {
1805 retval = MPI_ERR_TYPE;
1806 } else if (op == MPI_OP_NULL) {
1807 retval = MPI_ERR_OP;
1810 char* sendtmpbuf = static_cast<char*>(sendbuf);
1811 if( sendbuf == MPI_IN_PLACE ) {
1812 sendtmpbuf = static_cast<char*>(xbt_malloc(count*datatype->get_extent()));
1813 simgrid::smpi::Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
1815 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1816 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1817 extra->type = TRACING_ALLREDUCE;
1819 extra->datatype1 = encode_datatype(datatype, &known);
1820 int dt_size_send = 1;
1822 dt_size_send = datatype->size();
1823 extra->send_size = count * dt_size_send;
1825 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1827 simgrid::smpi::Colls::allreduce(sendtmpbuf, recvbuf, count, datatype, op, comm);
1829 if( sendbuf == MPI_IN_PLACE )
1830 xbt_free(sendtmpbuf);
1832 retval = MPI_SUCCESS;
1833 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1840 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1846 if (comm == MPI_COMM_NULL) {
1847 retval = MPI_ERR_COMM;
1848 } else if (!datatype->is_valid()) {
1849 retval = MPI_ERR_TYPE;
1850 } else if (op == MPI_OP_NULL) {
1851 retval = MPI_ERR_OP;
1853 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1854 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1855 extra->type = TRACING_SCAN;
1857 extra->datatype1 = encode_datatype(datatype, &known);
1858 int dt_size_send = 1;
1860 dt_size_send = datatype->size();
1861 extra->send_size = count * dt_size_send;
1863 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1865 retval = simgrid::smpi::Colls::scan(sendbuf, recvbuf, count, datatype, op, comm);
1867 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1874 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
1879 if (comm == MPI_COMM_NULL) {
1880 retval = MPI_ERR_COMM;
1881 } else if (!datatype->is_valid()) {
1882 retval = MPI_ERR_TYPE;
1883 } else if (op == MPI_OP_NULL) {
1884 retval = MPI_ERR_OP;
1886 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1887 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1888 extra->type = TRACING_EXSCAN;
1890 extra->datatype1 = encode_datatype(datatype, &known);
1891 int dt_size_send = 1;
1893 dt_size_send = datatype->size();
1894 extra->send_size = count * dt_size_send;
1895 void* sendtmpbuf = sendbuf;
1896 if (sendbuf == MPI_IN_PLACE) {
1897 sendtmpbuf = static_cast<void*>(xbt_malloc(count * datatype->size()));
1898 memcpy(sendtmpbuf, recvbuf, count * datatype->size());
1900 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1902 retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
1904 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1905 if (sendbuf == MPI_IN_PLACE)
1906 xbt_free(sendtmpbuf);
1913 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1918 if (comm == MPI_COMM_NULL) {
1919 retval = MPI_ERR_COMM;
1920 } else if (!datatype->is_valid()) {
1921 retval = MPI_ERR_TYPE;
1922 } else if (op == MPI_OP_NULL) {
1923 retval = MPI_ERR_OP;
1924 } else if (recvcounts == nullptr) {
1925 retval = MPI_ERR_ARG;
1927 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1929 int size = comm->size();
1930 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1931 extra->type = TRACING_REDUCE_SCATTER;
1932 extra->num_processes = size;
1934 extra->datatype1 = encode_datatype(datatype, &known);
1935 int dt_size_send = 1;
1937 dt_size_send = datatype->size();
1938 extra->send_size = 0;
1939 extra->recvcounts = xbt_new(int, size);
1941 for (i = 0; i < size; i++) { // copy data to avoid bad free
1942 extra->recvcounts[i] = recvcounts[i] * dt_size_send;
1943 totalcount += recvcounts[i];
1945 void* sendtmpbuf = sendbuf;
1946 if (sendbuf == MPI_IN_PLACE) {
1947 sendtmpbuf = static_cast<void*>(xbt_malloc(totalcount * datatype->size()));
1948 memcpy(sendtmpbuf, recvbuf, totalcount * datatype->size());
1951 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1953 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1954 retval = MPI_SUCCESS;
1955 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1957 if (sendbuf == MPI_IN_PLACE)
1958 xbt_free(sendtmpbuf);
1965 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
1966 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1971 if (comm == MPI_COMM_NULL) {
1972 retval = MPI_ERR_COMM;
1973 } else if (!datatype->is_valid()) {
1974 retval = MPI_ERR_TYPE;
1975 } else if (op == MPI_OP_NULL) {
1976 retval = MPI_ERR_OP;
1977 } else if (recvcount < 0) {
1978 retval = MPI_ERR_ARG;
1980 int count = comm->size();
1982 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1983 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1984 extra->type = TRACING_REDUCE_SCATTER;
1985 extra->num_processes = count;
1987 extra->datatype1 = encode_datatype(datatype, &known);
1988 int dt_size_send = 1;
1990 dt_size_send = datatype->size();
1991 extra->send_size = 0;
1992 extra->recvcounts = xbt_new(int, count);
1993 for (int i = 0; i < count; i++) // copy data to avoid bad free
1994 extra->recvcounts[i] = recvcount * dt_size_send;
1995 void* sendtmpbuf = sendbuf;
1996 if (sendbuf == MPI_IN_PLACE) {
1997 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * count * datatype->size()));
1998 memcpy(sendtmpbuf, recvbuf, recvcount * count * datatype->size());
2001 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2003 int* recvcounts = static_cast<int*>(xbt_malloc(count * sizeof(int)));
2004 for (int i = 0; i < count; i++)
2005 recvcounts[i] = recvcount;
2006 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
2007 xbt_free(recvcounts);
2008 retval = MPI_SUCCESS;
2010 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2012 if (sendbuf == MPI_IN_PLACE)
2013 xbt_free(sendtmpbuf);
2020 int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
2021 MPI_Datatype recvtype, MPI_Comm comm)
2026 if (comm == MPI_COMM_NULL) {
2027 retval = MPI_ERR_COMM;
2028 } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL) || recvtype == MPI_DATATYPE_NULL) {
2029 retval = MPI_ERR_TYPE;
2031 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2032 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2033 extra->type = TRACING_ALLTOALL;
2035 void* sendtmpbuf = static_cast<char*>(sendbuf);
2036 int sendtmpcount = sendcount;
2037 MPI_Datatype sendtmptype = sendtype;
2038 if (sendbuf == MPI_IN_PLACE) {
2039 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * comm->size() * recvtype->size()));
2040 memcpy(sendtmpbuf, recvbuf, recvcount * comm->size() * recvtype->size());
2041 sendtmpcount = recvcount;
2042 sendtmptype = recvtype;
2046 extra->datatype1 = encode_datatype(sendtmptype, &known);
2048 extra->send_size = sendtmpcount * sendtmptype->size();
2050 extra->send_size = sendtmpcount;
2051 extra->datatype2 = encode_datatype(recvtype, &known);
2053 extra->recv_size = recvcount * recvtype->size();
2055 extra->recv_size = recvcount;
2057 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2059 retval = simgrid::smpi::Colls::alltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
2061 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2063 if (sendbuf == MPI_IN_PLACE)
2064 xbt_free(sendtmpbuf);
2071 int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
2072 int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2078 if (comm == MPI_COMM_NULL) {
2079 retval = MPI_ERR_COMM;
2080 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
2081 retval = MPI_ERR_TYPE;
2082 } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
2083 recvdisps == nullptr) {
2084 retval = MPI_ERR_ARG;
2086 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2088 int size = comm->size();
2089 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2090 extra->type = TRACING_ALLTOALLV;
2091 extra->send_size = 0;
2092 extra->recv_size = 0;
2093 extra->recvcounts = xbt_new(int, size);
2094 extra->sendcounts = xbt_new(int, size);
2096 int dt_size_recv = 1;
2097 extra->datatype2 = encode_datatype(recvtype, &known);
2098 dt_size_recv = recvtype->size();
2100 void* sendtmpbuf = static_cast<char*>(sendbuf);
2101 int* sendtmpcounts = sendcounts;
2102 int* sendtmpdisps = senddisps;
2103 MPI_Datatype sendtmptype = sendtype;
2105 for (i = 0; i < size; i++) { // copy data to avoid bad free
2106 extra->recv_size += recvcounts[i] * dt_size_recv;
2107 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
2108 if (((recvdisps[i] + recvcounts[i]) * dt_size_recv) > maxsize)
2109 maxsize = (recvdisps[i] + recvcounts[i]) * dt_size_recv;
2112 if (sendbuf == MPI_IN_PLACE) {
2113 sendtmpbuf = static_cast<void*>(xbt_malloc(maxsize));
2114 memcpy(sendtmpbuf, recvbuf, maxsize);
2115 sendtmpcounts = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2116 memcpy(sendtmpcounts, recvcounts, size * sizeof(int));
2117 sendtmpdisps = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2118 memcpy(sendtmpdisps, recvdisps, size * sizeof(int));
2119 sendtmptype = recvtype;
2122 extra->datatype1 = encode_datatype(sendtmptype, &known);
2123 int dt_size_send = 1;
2124 dt_size_send = sendtmptype->size();
2126 for (i = 0; i < size; i++) { // copy data to avoid bad free
2127 extra->send_size += sendtmpcounts[i] * dt_size_send;
2128 extra->sendcounts[i] = sendtmpcounts[i] * dt_size_send;
2130 extra->num_processes = size;
2131 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2132 retval = simgrid::smpi::Colls::alltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
2133 recvdisps, recvtype, comm);
2134 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2136 if (sendbuf == MPI_IN_PLACE) {
2137 xbt_free(sendtmpbuf);
2138 xbt_free(sendtmpcounts);
2139 xbt_free(sendtmpdisps);
2148 int PMPI_Get_processor_name(char *name, int *resultlen)
2150 strncpy(name, SIMIX_host_self()->cname(), strlen(SIMIX_host_self()->cname()) < MPI_MAX_PROCESSOR_NAME - 1
2151 ? strlen(SIMIX_host_self()->cname()) + 1
2152 : MPI_MAX_PROCESSOR_NAME - 1);
2153 *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2158 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2160 if (status == nullptr || count == nullptr) {
2162 } else if (!datatype->is_valid()) {
2163 return MPI_ERR_TYPE;
2165 size_t size = datatype->size();
2169 } else if (status->count % size != 0) {
2170 return MPI_UNDEFINED;
2172 *count = simgrid::smpi::Status::get_count(status, datatype);
2178 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2179 if (old_type == MPI_DATATYPE_NULL) {
2180 return MPI_ERR_TYPE;
2181 } else if (count<0){
2182 return MPI_ERR_COUNT;
2184 return simgrid::smpi::Datatype::create_contiguous(count, old_type, 0, new_type);
2188 int PMPI_Type_commit(MPI_Datatype* datatype) {
2189 if (datatype == nullptr || *datatype == MPI_DATATYPE_NULL) {
2190 return MPI_ERR_TYPE;
2192 (*datatype)->commit();
2197 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2198 if (old_type == MPI_DATATYPE_NULL) {
2199 return MPI_ERR_TYPE;
2200 } else if (count<0 || blocklen<0){
2201 return MPI_ERR_COUNT;
2203 return simgrid::smpi::Datatype::create_vector(count, blocklen, stride, old_type, new_type);
2207 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2208 if (old_type == MPI_DATATYPE_NULL) {
2209 return MPI_ERR_TYPE;
2210 } else if (count<0 || blocklen<0){
2211 return MPI_ERR_COUNT;
2213 return simgrid::smpi::Datatype::create_hvector(count, blocklen, stride, old_type, new_type);
2217 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2218 return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2221 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2222 if (old_type == MPI_DATATYPE_NULL) {
2223 return MPI_ERR_TYPE;
2224 } else if (count<0){
2225 return MPI_ERR_COUNT;
2227 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2231 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2232 if (old_type == MPI_DATATYPE_NULL) {
2233 return MPI_ERR_TYPE;
2234 } else if (count<0){
2235 return MPI_ERR_COUNT;
2237 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2241 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type,
2242 MPI_Datatype* new_type)
2244 if (old_type == MPI_DATATYPE_NULL) {
2245 return MPI_ERR_TYPE;
2246 } else if (count<0){
2247 return MPI_ERR_COUNT;
2249 int* blocklens=static_cast<int*>(xbt_malloc(blocklength*count*sizeof(int)));
2250 for (int i = 0; i < count; i++)
2251 blocklens[i]=blocklength;
2252 int retval = simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2253 xbt_free(blocklens);
2258 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
2260 if (old_type == MPI_DATATYPE_NULL) {
2261 return MPI_ERR_TYPE;
2262 } else if (count<0){
2263 return MPI_ERR_COUNT;
2265 return simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2269 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type,
2270 MPI_Datatype* new_type) {
2271 return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2274 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type,
2275 MPI_Datatype* new_type) {
2276 if (old_type == MPI_DATATYPE_NULL) {
2277 return MPI_ERR_TYPE;
2278 } else if (count<0){
2279 return MPI_ERR_COUNT;
2281 int* blocklens=(int*)xbt_malloc(blocklength*count*sizeof(int));
2282 for (int i = 0; i < count; i++)
2283 blocklens[i] = blocklength;
2284 int retval = simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2285 xbt_free(blocklens);
2290 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2292 return MPI_ERR_COUNT;
2294 return simgrid::smpi::Datatype::create_struct(count, blocklens, indices, old_types, new_type);
2298 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types,
2299 MPI_Datatype* new_type) {
2300 return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2303 int PMPI_Error_class(int errorcode, int* errorclass) {
2304 // assume smpi uses only standard mpi error codes
2305 *errorclass=errorcode;
2309 int PMPI_Initialized(int* flag) {
2310 *flag=(smpi_process()!=nullptr && smpi_process()->initialized());
2314 /* The topo part of MPI_COMM_WORLD should always be nullptr. When other topologies will be implemented, not only should we
2315 * check if the topology is nullptr, but we should check if it is the good topology type (so we have to add a
2316 * MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2318 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2319 if (comm_old == MPI_COMM_NULL){
2320 return MPI_ERR_COMM;
2321 } else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
2324 simgrid::smpi::Topo_Cart* topo = new simgrid::smpi::Topo_Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
2325 if(*comm_cart==MPI_COMM_NULL)
2331 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2332 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2333 return MPI_ERR_TOPOLOGY;
2335 if (coords == nullptr) {
2338 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2339 if (topo==nullptr) {
2342 return topo->rank(coords, rank);
2345 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2346 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2347 return MPI_ERR_TOPOLOGY;
2349 if (source == nullptr || dest == nullptr || direction < 0 ) {
2352 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2353 if (topo==nullptr) {
2356 return topo->shift(direction, displ, source, dest);
2359 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2360 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2361 return MPI_ERR_TOPOLOGY;
2363 if (rank < 0 || rank >= comm->size()) {
2364 return MPI_ERR_RANK;
2369 if(coords == nullptr) {
2372 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2373 if (topo==nullptr) {
2376 return topo->coords(rank, maxdims, coords);
2379 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2380 if(comm == nullptr || comm->topo() == nullptr) {
2381 return MPI_ERR_TOPOLOGY;
2383 if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
2386 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2387 if (topo==nullptr) {
2390 return topo->get(maxdims, dims, periods, coords);
2393 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2394 if (comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2395 return MPI_ERR_TOPOLOGY;
2397 if (ndims == nullptr) {
2400 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2401 if (topo==nullptr) {
2404 return topo->dim_get(ndims);
2407 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2408 if(dims == nullptr) {
2411 if (ndims < 1 || nnodes < 1) {
2412 return MPI_ERR_DIMS;
2414 return simgrid::smpi::Topo_Cart::Dims_create(nnodes, ndims, dims);
2417 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2418 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2419 return MPI_ERR_TOPOLOGY;
2421 if (comm_new == nullptr) {
2424 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2425 if (topo==nullptr) {
2428 MPIR_Cart_Topology cart = topo->sub(remain_dims, comm_new);
2429 if(*comm_new==MPI_COMM_NULL)
2436 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2437 if (oldtype == MPI_DATATYPE_NULL) {
2438 return MPI_ERR_TYPE;
2440 int blocks[3] = {1, 1, 1};
2441 MPI_Aint disps[3] = {lb, 0, lb + extent};
2442 MPI_Datatype types[3] = {MPI_LB, oldtype, MPI_UB};
2444 *newtype = new simgrid::smpi::Type_Struct(oldtype->size(), lb, lb + extent, DT_FLAG_DERIVED, 3, blocks, disps, types);
2446 (*newtype)->addflag(~DT_FLAG_COMMITED);
2450 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2453 if (comm == MPI_COMM_NULL) {
2454 retval= MPI_ERR_COMM;
2455 }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
2456 retval= MPI_ERR_OTHER;
2458 *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
2459 retval = MPI_SUCCESS;
2465 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
2468 if (comm == MPI_COMM_NULL) {
2469 retval= MPI_ERR_COMM;
2470 }else if (disp_unit <= 0 || size < 0 ){
2471 retval= MPI_ERR_OTHER;
2473 void* ptr = xbt_malloc(size);
2475 return MPI_ERR_NO_MEM;
2476 *static_cast<void**>(base) = ptr;
2477 *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
2478 retval = MPI_SUCCESS;
2484 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
2487 if (comm == MPI_COMM_NULL) {
2488 retval= MPI_ERR_COMM;
2490 *win = new simgrid::smpi::Win(info, comm);
2491 retval = MPI_SUCCESS;
2497 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
2500 if(win == MPI_WIN_NULL){
2501 retval = MPI_ERR_WIN;
2502 } else if ((base == nullptr && size != 0) || size < 0 ){
2503 retval= MPI_ERR_OTHER;
2505 retval = win->attach(base, size);
2511 int PMPI_Win_detach(MPI_Win win, void *base){
2514 if(win == MPI_WIN_NULL){
2515 retval = MPI_ERR_WIN;
2516 } else if (base == nullptr){
2517 retval= MPI_ERR_OTHER;
2519 retval = win->detach(base);
2526 int PMPI_Win_free( MPI_Win* win){
2529 if (win == nullptr || *win == MPI_WIN_NULL) {
2530 retval = MPI_ERR_WIN;
2539 int PMPI_Win_set_name(MPI_Win win, char * name)
2541 if (win == MPI_WIN_NULL) {
2542 return MPI_ERR_TYPE;
2543 } else if (name == nullptr) {
2546 win->set_name(name);
2551 int PMPI_Win_get_name(MPI_Win win, char * name, int* len)
2553 if (win == MPI_WIN_NULL) {
2555 } else if (name == nullptr) {
2558 win->get_name(name, len);
2563 int PMPI_Win_get_info(MPI_Win win, MPI_Info* info)
2565 if (win == MPI_WIN_NULL) {
2568 *info = win->info();
2573 int PMPI_Win_set_info(MPI_Win win, MPI_Info info)
2575 if (win == MPI_WIN_NULL) {
2576 return MPI_ERR_TYPE;
2578 win->set_info(info);
2583 int PMPI_Win_get_group(MPI_Win win, MPI_Group * group){
2584 if (win == MPI_WIN_NULL) {
2587 win->get_group(group);
2593 int PMPI_Win_fence( int assert, MPI_Win win){
2596 if (win == MPI_WIN_NULL) {
2597 retval = MPI_ERR_WIN;
2599 int rank = smpi_process()->index();
2600 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2601 retval = win->fence(assert);
2602 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2608 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2609 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2612 if (win == MPI_WIN_NULL) {
2613 retval = MPI_ERR_WIN;
2614 } else if (target_rank == MPI_PROC_NULL) {
2615 retval = MPI_SUCCESS;
2616 } else if (target_rank <0){
2617 retval = MPI_ERR_RANK;
2618 } else if (win->dynamic()==0 && target_disp <0){
2619 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2620 retval = MPI_ERR_ARG;
2621 } else if ((origin_count < 0 || target_count < 0) ||
2622 (origin_addr==nullptr && origin_count > 0)){
2623 retval = MPI_ERR_COUNT;
2624 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2625 retval = MPI_ERR_TYPE;
2627 int rank = smpi_process()->index();
2629 win->get_group(&group);
2630 int src_traced = group->index(target_rank);
2631 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2633 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2636 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2642 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2643 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2646 if (win == MPI_WIN_NULL) {
2647 retval = MPI_ERR_WIN;
2648 } else if (target_rank == MPI_PROC_NULL) {
2649 *request = MPI_REQUEST_NULL;
2650 retval = MPI_SUCCESS;
2651 } else if (target_rank <0){
2652 retval = MPI_ERR_RANK;
2653 } else if (win->dynamic()==0 && target_disp <0){
2654 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2655 retval = MPI_ERR_ARG;
2656 } else if ((origin_count < 0 || target_count < 0) ||
2657 (origin_addr==nullptr && origin_count > 0)){
2658 retval = MPI_ERR_COUNT;
2659 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2660 retval = MPI_ERR_TYPE;
2661 } else if(request == nullptr){
2662 retval = MPI_ERR_REQUEST;
2664 int rank = smpi_process()->index();
2666 win->get_group(&group);
2667 int src_traced = group->index(target_rank);
2668 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2670 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2671 target_datatype, request);
2673 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2679 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2680 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2683 if (win == MPI_WIN_NULL) {
2684 retval = MPI_ERR_WIN;
2685 } else if (target_rank == MPI_PROC_NULL) {
2686 retval = MPI_SUCCESS;
2687 } else if (target_rank <0){
2688 retval = MPI_ERR_RANK;
2689 } else if (win->dynamic()==0 && target_disp <0){
2690 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2691 retval = MPI_ERR_ARG;
2692 } else if ((origin_count < 0 || target_count < 0) ||
2693 (origin_addr==nullptr && origin_count > 0)){
2694 retval = MPI_ERR_COUNT;
2695 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2696 retval = MPI_ERR_TYPE;
2698 int rank = smpi_process()->index();
2700 win->get_group(&group);
2701 int dst_traced = group->index(target_rank);
2702 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2703 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2705 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2708 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2714 int PMPI_Rput( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2715 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2718 if (win == MPI_WIN_NULL) {
2719 retval = MPI_ERR_WIN;
2720 } else if (target_rank == MPI_PROC_NULL) {
2721 *request = MPI_REQUEST_NULL;
2722 retval = MPI_SUCCESS;
2723 } else if (target_rank <0){
2724 retval = MPI_ERR_RANK;
2725 } else if (win->dynamic()==0 && target_disp <0){
2726 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2727 retval = MPI_ERR_ARG;
2728 } else if ((origin_count < 0 || target_count < 0) ||
2729 (origin_addr==nullptr && origin_count > 0)){
2730 retval = MPI_ERR_COUNT;
2731 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2732 retval = MPI_ERR_TYPE;
2733 } else if(request == nullptr){
2734 retval = MPI_ERR_REQUEST;
2736 int rank = smpi_process()->index();
2738 win->get_group(&group);
2739 int dst_traced = group->index(target_rank);
2740 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2741 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2743 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2744 target_datatype, request);
2746 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2752 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2753 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2756 if (win == MPI_WIN_NULL) {
2757 retval = MPI_ERR_WIN;
2758 } else if (target_rank == MPI_PROC_NULL) {
2759 retval = MPI_SUCCESS;
2760 } else if (target_rank <0){
2761 retval = MPI_ERR_RANK;
2762 } else if (win->dynamic()==0 && target_disp <0){
2763 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2764 retval = MPI_ERR_ARG;
2765 } else if ((origin_count < 0 || target_count < 0) ||
2766 (origin_addr==nullptr && origin_count > 0)){
2767 retval = MPI_ERR_COUNT;
2768 } else if ((!origin_datatype->is_valid()) ||
2769 (!target_datatype->is_valid())) {
2770 retval = MPI_ERR_TYPE;
2771 } else if (op == MPI_OP_NULL) {
2772 retval = MPI_ERR_OP;
2774 int rank = smpi_process()->index();
2776 win->get_group(&group);
2777 int src_traced = group->index(target_rank);
2778 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2780 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2781 target_datatype, op);
2783 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2789 int PMPI_Raccumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2790 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2793 if (win == MPI_WIN_NULL) {
2794 retval = MPI_ERR_WIN;
2795 } else if (target_rank == MPI_PROC_NULL) {
2796 *request = MPI_REQUEST_NULL;
2797 retval = MPI_SUCCESS;
2798 } else if (target_rank <0){
2799 retval = MPI_ERR_RANK;
2800 } else if (win->dynamic()==0 && target_disp <0){
2801 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2802 retval = MPI_ERR_ARG;
2803 } else if ((origin_count < 0 || target_count < 0) ||
2804 (origin_addr==nullptr && origin_count > 0)){
2805 retval = MPI_ERR_COUNT;
2806 } else if ((!origin_datatype->is_valid()) ||
2807 (!target_datatype->is_valid())) {
2808 retval = MPI_ERR_TYPE;
2809 } else if (op == MPI_OP_NULL) {
2810 retval = MPI_ERR_OP;
2811 } else if(request == nullptr){
2812 retval = MPI_ERR_REQUEST;
2814 int rank = smpi_process()->index();
2816 win->get_group(&group);
2817 int src_traced = group->index(target_rank);
2818 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2820 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2821 target_datatype, op, request);
2823 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2829 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2830 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2831 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2834 if (win == MPI_WIN_NULL) {
2835 retval = MPI_ERR_WIN;
2836 } else if (target_rank == MPI_PROC_NULL) {
2837 retval = MPI_SUCCESS;
2838 } else if (target_rank <0){
2839 retval = MPI_ERR_RANK;
2840 } else if (win->dynamic()==0 && target_disp <0){
2841 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2842 retval = MPI_ERR_ARG;
2843 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2844 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2845 (result_addr==nullptr && result_count > 0)){
2846 retval = MPI_ERR_COUNT;
2847 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2848 (!target_datatype->is_valid())||
2849 (!result_datatype->is_valid())) {
2850 retval = MPI_ERR_TYPE;
2851 } else if (op == MPI_OP_NULL) {
2852 retval = MPI_ERR_OP;
2854 int rank = smpi_process()->index();
2856 win->get_group(&group);
2857 int src_traced = group->index(target_rank);
2858 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2860 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2861 result_count, result_datatype, target_rank, target_disp,
2862 target_count, target_datatype, op);
2864 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2871 int PMPI_Rget_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2872 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2873 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2876 if (win == MPI_WIN_NULL) {
2877 retval = MPI_ERR_WIN;
2878 } else if (target_rank == MPI_PROC_NULL) {
2879 *request = MPI_REQUEST_NULL;
2880 retval = MPI_SUCCESS;
2881 } else if (target_rank <0){
2882 retval = MPI_ERR_RANK;
2883 } else if (win->dynamic()==0 && target_disp <0){
2884 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2885 retval = MPI_ERR_ARG;
2886 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2887 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2888 (result_addr==nullptr && result_count > 0)){
2889 retval = MPI_ERR_COUNT;
2890 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2891 (!target_datatype->is_valid())||
2892 (!result_datatype->is_valid())) {
2893 retval = MPI_ERR_TYPE;
2894 } else if (op == MPI_OP_NULL) {
2895 retval = MPI_ERR_OP;
2896 } else if(request == nullptr){
2897 retval = MPI_ERR_REQUEST;
2899 int rank = smpi_process()->index();
2901 win->get_group(&group);
2902 int src_traced = group->index(target_rank);
2903 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2905 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2906 result_count, result_datatype, target_rank, target_disp,
2907 target_count, target_datatype, op, request);
2909 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2915 int PMPI_Fetch_and_op(void *origin_addr, void *result_addr, MPI_Datatype dtype, int target_rank, MPI_Aint target_disp, MPI_Op op, MPI_Win win){
2916 return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
2919 int PMPI_Compare_and_swap(void *origin_addr, void *compare_addr,
2920 void *result_addr, MPI_Datatype datatype, int target_rank,
2921 MPI_Aint target_disp, MPI_Win win){
2924 if (win == MPI_WIN_NULL) {
2925 retval = MPI_ERR_WIN;
2926 } else if (target_rank == MPI_PROC_NULL) {
2927 retval = MPI_SUCCESS;
2928 } else if (target_rank <0){
2929 retval = MPI_ERR_RANK;
2930 } else if (win->dynamic()==0 && target_disp <0){
2931 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2932 retval = MPI_ERR_ARG;
2933 } else if (origin_addr==nullptr || result_addr==nullptr || compare_addr==nullptr){
2934 retval = MPI_ERR_COUNT;
2935 } else if (!datatype->is_valid()) {
2936 retval = MPI_ERR_TYPE;
2938 int rank = smpi_process()->index();
2940 win->get_group(&group);
2941 int src_traced = group->index(target_rank);
2942 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2944 retval = win->compare_and_swap( origin_addr, compare_addr, result_addr, datatype,
2945 target_rank, target_disp);
2947 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2953 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2956 if (win == MPI_WIN_NULL) {
2957 retval = MPI_ERR_WIN;
2958 } else if (group==MPI_GROUP_NULL){
2959 retval = MPI_ERR_GROUP;
2961 int rank = smpi_process()->index();
2962 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2963 retval = win->post(group,assert);
2964 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2970 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2973 if (win == MPI_WIN_NULL) {
2974 retval = MPI_ERR_WIN;
2975 } else if (group==MPI_GROUP_NULL){
2976 retval = MPI_ERR_GROUP;
2978 int rank = smpi_process()->index();
2979 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2980 retval = win->start(group,assert);
2981 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2987 int PMPI_Win_complete(MPI_Win win){
2990 if (win == MPI_WIN_NULL) {
2991 retval = MPI_ERR_WIN;
2993 int rank = smpi_process()->index();
2994 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2996 retval = win->complete();
2998 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3004 int PMPI_Win_wait(MPI_Win win){
3007 if (win == MPI_WIN_NULL) {
3008 retval = MPI_ERR_WIN;
3010 int rank = smpi_process()->index();
3011 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
3013 retval = win->wait();
3015 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3021 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
3024 if (win == MPI_WIN_NULL) {
3025 retval = MPI_ERR_WIN;
3026 } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
3027 lock_type != MPI_LOCK_SHARED) {
3028 retval = MPI_ERR_LOCKTYPE;
3029 } else if (rank == MPI_PROC_NULL){
3030 retval = MPI_SUCCESS;
3032 int myrank = smpi_process()->index();
3033 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3034 retval = win->lock(lock_type,rank,assert);
3035 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3041 int PMPI_Win_unlock(int rank, MPI_Win win){
3044 if (win == MPI_WIN_NULL) {
3045 retval = MPI_ERR_WIN;
3046 } else if (rank == MPI_PROC_NULL){
3047 retval = MPI_SUCCESS;
3049 int myrank = smpi_process()->index();
3050 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3051 retval = win->unlock(rank);
3052 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3058 int PMPI_Win_lock_all(int assert, MPI_Win win){
3061 if (win == MPI_WIN_NULL) {
3062 retval = MPI_ERR_WIN;
3064 int myrank = smpi_process()->index();
3065 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3066 retval = win->lock_all(assert);
3067 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3073 int PMPI_Win_unlock_all(MPI_Win win){
3076 if (win == MPI_WIN_NULL) {
3077 retval = MPI_ERR_WIN;
3079 int myrank = smpi_process()->index();
3080 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3081 retval = win->unlock_all();
3082 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3088 int PMPI_Win_flush(int rank, MPI_Win win){
3091 if (win == MPI_WIN_NULL) {
3092 retval = MPI_ERR_WIN;
3093 } else if (rank == MPI_PROC_NULL){
3094 retval = MPI_SUCCESS;
3096 int myrank = smpi_process()->index();
3097 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3098 retval = win->flush(rank);
3099 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3105 int PMPI_Win_flush_local(int rank, MPI_Win win){
3108 if (win == MPI_WIN_NULL) {
3109 retval = MPI_ERR_WIN;
3110 } else if (rank == MPI_PROC_NULL){
3111 retval = MPI_SUCCESS;
3113 int myrank = smpi_process()->index();
3114 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3115 retval = win->flush_local(rank);
3116 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3122 int PMPI_Win_flush_all(MPI_Win win){
3125 if (win == MPI_WIN_NULL) {
3126 retval = MPI_ERR_WIN;
3128 int myrank = smpi_process()->index();
3129 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3130 retval = win->flush_all();
3131 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3137 int PMPI_Win_flush_local_all(MPI_Win win){
3140 if (win == MPI_WIN_NULL) {
3141 retval = MPI_ERR_WIN;
3143 int myrank = smpi_process()->index();
3144 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3145 retval = win->flush_local_all();
3146 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3152 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
3153 void *ptr = xbt_malloc(size);
3155 return MPI_ERR_NO_MEM;
3157 *static_cast<void**>(baseptr) = ptr;
3162 int PMPI_Free_mem(void *baseptr){
3167 int PMPI_Type_set_name(MPI_Datatype datatype, char * name)
3169 if (datatype == MPI_DATATYPE_NULL) {
3170 return MPI_ERR_TYPE;
3171 } else if (name == nullptr) {
3174 datatype->set_name(name);
3179 int PMPI_Type_get_name(MPI_Datatype datatype, char * name, int* len)
3181 if (datatype == MPI_DATATYPE_NULL) {
3182 return MPI_ERR_TYPE;
3183 } else if (name == nullptr) {
3186 datatype->get_name(name, len);
3191 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
3192 return static_cast<MPI_Datatype>(simgrid::smpi::F2C::f2c(datatype));
3195 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
3196 return datatype->c2f();
3199 MPI_Group PMPI_Group_f2c(MPI_Fint group){
3200 return simgrid::smpi::Group::f2c(group);
3203 MPI_Fint PMPI_Group_c2f(MPI_Group group){
3204 return group->c2f();
3207 MPI_Request PMPI_Request_f2c(MPI_Fint request){
3208 return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
3211 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
3212 return request->c2f();
3215 MPI_Win PMPI_Win_f2c(MPI_Fint win){
3216 return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
3219 MPI_Fint PMPI_Win_c2f(MPI_Win win){
3223 MPI_Op PMPI_Op_f2c(MPI_Fint op){
3224 return static_cast<MPI_Op>(simgrid::smpi::Op::f2c(op));
3227 MPI_Fint PMPI_Op_c2f(MPI_Op op){
3231 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
3232 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
3235 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
3239 MPI_Info PMPI_Info_f2c(MPI_Fint info){
3240 return static_cast<MPI_Info>(simgrid::smpi::Info::f2c(info));
3243 MPI_Fint PMPI_Info_c2f(MPI_Info info){
3247 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3248 smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr};
3249 smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr};
3250 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
3253 int PMPI_Keyval_free(int* keyval) {
3254 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Comm>(keyval);
3257 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3258 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3259 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3261 else if (comm==MPI_COMM_NULL)
3262 return MPI_ERR_COMM;
3264 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
3267 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3269 static int zero = 0;
3270 static int tag_ub = INT_MAX;
3271 static int last_used_code = MPI_ERR_LASTCODE;
3273 if (comm==MPI_COMM_NULL){
3275 return MPI_ERR_COMM;
3283 *static_cast<int**>(attr_value) = &zero;
3285 case MPI_UNIVERSE_SIZE:
3287 *static_cast<int**>(attr_value) = &smpi_universe_size;
3289 case MPI_LASTUSEDCODE:
3291 *static_cast<int**>(attr_value) = &last_used_code;
3295 *static_cast<int**>(attr_value) = &tag_ub;
3297 case MPI_WTIME_IS_GLOBAL:
3299 *static_cast<int**>(attr_value) = &one;
3302 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
3306 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3307 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3308 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3310 else if (comm==MPI_COMM_NULL)
3311 return MPI_ERR_COMM;
3313 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
3316 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3318 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3321 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3323 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3326 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3328 return PMPI_Attr_delete(comm, comm_keyval);
3331 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
3334 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3337 int PMPI_Comm_free_keyval(int* keyval) {
3338 return PMPI_Keyval_free(keyval);
3341 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3343 if (type==MPI_DATATYPE_NULL)
3344 return MPI_ERR_TYPE;
3346 return type->attr_get<simgrid::smpi::Datatype>(type_keyval, attribute_val, flag);
3349 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3351 if (type==MPI_DATATYPE_NULL)
3352 return MPI_ERR_TYPE;
3354 return type->attr_put<simgrid::smpi::Datatype>(type_keyval, attribute_val);
3357 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3359 if (type==MPI_DATATYPE_NULL)
3360 return MPI_ERR_TYPE;
3362 return type->attr_delete<simgrid::smpi::Datatype>(type_keyval);
3365 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
3368 smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr};
3369 smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr};
3370 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
3373 int PMPI_Type_free_keyval(int* keyval) {
3374 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Datatype>(keyval);
3377 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
3379 static MPI_Aint size;
3380 static int disp_unit;
3381 if (win==MPI_WIN_NULL)
3382 return MPI_ERR_TYPE;
3386 *static_cast<void**>(attribute_val) = win->base();
3391 *static_cast<MPI_Aint**>(attribute_val) = &size;
3394 case MPI_WIN_DISP_UNIT :
3395 disp_unit=win->disp_unit();
3396 *static_cast<int**>(attribute_val) = &disp_unit;
3400 return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
3406 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
3408 if (win==MPI_WIN_NULL)
3409 return MPI_ERR_TYPE;
3411 return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
3414 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
3416 if (win==MPI_WIN_NULL)
3417 return MPI_ERR_TYPE;
3419 return win->attr_delete<simgrid::smpi::Win>(type_keyval);
3422 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
3425 smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
3426 smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
3427 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
3430 int PMPI_Win_free_keyval(int* keyval) {
3431 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
3434 int PMPI_Info_create( MPI_Info *info){
3435 if (info == nullptr)
3437 *info = new simgrid::smpi::Info();
3441 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3442 if (info == nullptr || key == nullptr || value == nullptr)
3444 info->set(key, value);
3448 int PMPI_Info_free( MPI_Info *info){
3449 if (info == nullptr || *info==nullptr)
3451 simgrid::smpi::Info::unref(*info);
3452 *info=MPI_INFO_NULL;
3456 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3458 if (info == nullptr || key == nullptr || valuelen <0)
3460 if (value == nullptr)
3461 return MPI_ERR_INFO_VALUE;
3462 return info->get(key, valuelen, value, flag);
3465 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3466 if (info == nullptr || newinfo==nullptr)
3468 *newinfo = new simgrid::smpi::Info(info);
3472 int PMPI_Info_delete(MPI_Info info, char *key){
3473 if (info == nullptr || key==nullptr)
3475 return info->remove(key);
3478 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3479 if (info == nullptr || nkeys==nullptr)
3481 return info->get_nkeys(nkeys);
3484 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3485 if (info == nullptr || key==nullptr || n<0 || n> MPI_MAX_INFO_KEY)
3487 return info->get_nthkey(n, key);
3490 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3492 if (info == nullptr || key == nullptr || valuelen==nullptr)
3494 return info->get_valuelen(key, valuelen, flag);
3497 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3498 if(incount<0 || outcount < 0 || inbuf==nullptr || outbuf==nullptr)
3500 if(!type->is_valid())
3501 return MPI_ERR_TYPE;
3502 if(comm==MPI_COMM_NULL)
3503 return MPI_ERR_COMM;
3504 return type->unpack(inbuf, incount, position, outbuf,outcount, comm);
3507 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3508 if(incount<0 || outcount < 0|| inbuf==nullptr || outbuf==nullptr)
3510 if(!type->is_valid())
3511 return MPI_ERR_TYPE;
3512 if(comm==MPI_COMM_NULL)
3513 return MPI_ERR_COMM;
3514 return type->pack(inbuf, incount, outbuf,outcount,position, comm);
3517 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3520 if(!datatype->is_valid())
3521 return MPI_ERR_TYPE;
3522 if(comm==MPI_COMM_NULL)
3523 return MPI_ERR_COMM;
3525 *size=incount*datatype->size();