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) || (status == 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_Put( 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){
2646 if (win == MPI_WIN_NULL) {
2647 retval = MPI_ERR_WIN;
2648 } else if (target_rank == MPI_PROC_NULL) {
2649 retval = MPI_SUCCESS;
2650 } else if (target_rank <0){
2651 retval = MPI_ERR_RANK;
2652 } else if (win->dynamic()==0 && target_disp <0){
2653 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2654 retval = MPI_ERR_ARG;
2655 } else if ((origin_count < 0 || target_count < 0) ||
2656 (origin_addr==nullptr && origin_count > 0)){
2657 retval = MPI_ERR_COUNT;
2658 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2659 retval = MPI_ERR_TYPE;
2661 int rank = smpi_process()->index();
2663 win->get_group(&group);
2664 int dst_traced = group->index(target_rank);
2665 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2666 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2668 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2671 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2677 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2678 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2681 if (win == MPI_WIN_NULL) {
2682 retval = MPI_ERR_WIN;
2683 } else if (target_rank == MPI_PROC_NULL) {
2684 retval = MPI_SUCCESS;
2685 } else if (target_rank <0){
2686 retval = MPI_ERR_RANK;
2687 } else if (win->dynamic()==0 && target_disp <0){
2688 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2689 retval = MPI_ERR_ARG;
2690 } else if ((origin_count < 0 || target_count < 0) ||
2691 (origin_addr==nullptr && origin_count > 0)){
2692 retval = MPI_ERR_COUNT;
2693 } else if ((!origin_datatype->is_valid()) ||
2694 (!target_datatype->is_valid())) {
2695 retval = MPI_ERR_TYPE;
2696 } else if (op == MPI_OP_NULL) {
2697 retval = MPI_ERR_OP;
2699 int rank = smpi_process()->index();
2701 win->get_group(&group);
2702 int src_traced = group->index(target_rank);
2703 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2705 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2706 target_datatype, op);
2708 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2714 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2715 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2716 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2719 if (win == MPI_WIN_NULL) {
2720 retval = MPI_ERR_WIN;
2721 } else if (target_rank == MPI_PROC_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 || result_count <0) ||
2729 (origin_addr==nullptr && origin_count > 0) ||
2730 (result_addr==nullptr && result_count > 0)){
2731 retval = MPI_ERR_COUNT;
2732 } else if ((!origin_datatype->is_valid()) ||
2733 (!target_datatype->is_valid())||
2734 (!result_datatype->is_valid())) {
2735 retval = MPI_ERR_TYPE;
2736 } else if (op == MPI_OP_NULL) {
2737 retval = MPI_ERR_OP;
2739 int rank = smpi_process()->index();
2741 win->get_group(&group);
2742 int src_traced = group->index(target_rank);
2743 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2745 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2746 result_count, result_datatype, target_rank, target_disp,
2747 target_count, target_datatype, op);
2749 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2755 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2758 if (win == MPI_WIN_NULL) {
2759 retval = MPI_ERR_WIN;
2760 } else if (group==MPI_GROUP_NULL){
2761 retval = MPI_ERR_GROUP;
2763 int rank = smpi_process()->index();
2764 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2765 retval = win->post(group,assert);
2766 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2772 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2775 if (win == MPI_WIN_NULL) {
2776 retval = MPI_ERR_WIN;
2777 } else if (group==MPI_GROUP_NULL){
2778 retval = MPI_ERR_GROUP;
2780 int rank = smpi_process()->index();
2781 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2782 retval = win->start(group,assert);
2783 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2789 int PMPI_Win_complete(MPI_Win win){
2792 if (win == MPI_WIN_NULL) {
2793 retval = MPI_ERR_WIN;
2795 int rank = smpi_process()->index();
2796 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2798 retval = win->complete();
2800 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2806 int PMPI_Win_wait(MPI_Win win){
2809 if (win == MPI_WIN_NULL) {
2810 retval = MPI_ERR_WIN;
2812 int rank = smpi_process()->index();
2813 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2815 retval = win->wait();
2817 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2823 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
2826 if (win == MPI_WIN_NULL) {
2827 retval = MPI_ERR_WIN;
2828 } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
2829 lock_type != MPI_LOCK_SHARED) {
2830 retval = MPI_ERR_LOCKTYPE;
2831 } else if (rank == MPI_PROC_NULL){
2832 retval = MPI_SUCCESS;
2834 int myrank = smpi_process()->index();
2835 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
2836 retval = win->lock(lock_type,rank,assert);
2837 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
2843 int PMPI_Win_unlock(int rank, MPI_Win win){
2846 if (win == MPI_WIN_NULL) {
2847 retval = MPI_ERR_WIN;
2848 } else if (rank == MPI_PROC_NULL){
2849 retval = MPI_SUCCESS;
2851 int myrank = smpi_process()->index();
2852 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
2853 retval = win->unlock(rank);
2854 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
2860 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
2861 void *ptr = xbt_malloc(size);
2863 return MPI_ERR_NO_MEM;
2865 *static_cast<void**>(baseptr) = ptr;
2870 int PMPI_Free_mem(void *baseptr){
2875 int PMPI_Type_set_name(MPI_Datatype datatype, char * name)
2877 if (datatype == MPI_DATATYPE_NULL) {
2878 return MPI_ERR_TYPE;
2879 } else if (name == nullptr) {
2882 datatype->set_name(name);
2887 int PMPI_Type_get_name(MPI_Datatype datatype, char * name, int* len)
2889 if (datatype == MPI_DATATYPE_NULL) {
2890 return MPI_ERR_TYPE;
2891 } else if (name == nullptr) {
2894 datatype->get_name(name, len);
2899 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
2900 return static_cast<MPI_Datatype>(simgrid::smpi::F2C::f2c(datatype));
2903 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
2904 return datatype->c2f();
2907 MPI_Group PMPI_Group_f2c(MPI_Fint group){
2908 return simgrid::smpi::Group::f2c(group);
2911 MPI_Fint PMPI_Group_c2f(MPI_Group group){
2912 return group->c2f();
2915 MPI_Request PMPI_Request_f2c(MPI_Fint request){
2916 return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
2919 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
2920 return request->c2f();
2923 MPI_Win PMPI_Win_f2c(MPI_Fint win){
2924 return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
2927 MPI_Fint PMPI_Win_c2f(MPI_Win win){
2931 MPI_Op PMPI_Op_f2c(MPI_Fint op){
2932 return static_cast<MPI_Op>(simgrid::smpi::Op::f2c(op));
2935 MPI_Fint PMPI_Op_c2f(MPI_Op op){
2939 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
2940 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
2943 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
2947 MPI_Info PMPI_Info_f2c(MPI_Fint info){
2948 return static_cast<MPI_Info>(simgrid::smpi::Info::f2c(info));
2951 MPI_Fint PMPI_Info_c2f(MPI_Info info){
2955 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
2956 smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr};
2957 smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr};
2958 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
2961 int PMPI_Keyval_free(int* keyval) {
2962 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Comm>(keyval);
2965 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
2966 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
2967 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
2969 else if (comm==MPI_COMM_NULL)
2970 return MPI_ERR_COMM;
2972 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
2975 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
2977 static int zero = 0;
2978 static int tag_ub = 1000000;
2979 static int last_used_code = MPI_ERR_LASTCODE;
2981 if (comm==MPI_COMM_NULL){
2983 return MPI_ERR_COMM;
2991 *static_cast<int**>(attr_value) = &zero;
2993 case MPI_UNIVERSE_SIZE:
2995 *static_cast<int**>(attr_value) = &smpi_universe_size;
2997 case MPI_LASTUSEDCODE:
2999 *static_cast<int**>(attr_value) = &last_used_code;
3003 *static_cast<int**>(attr_value) = &tag_ub;
3005 case MPI_WTIME_IS_GLOBAL:
3007 *static_cast<int**>(attr_value) = &one;
3010 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
3014 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3015 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3016 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3018 else if (comm==MPI_COMM_NULL)
3019 return MPI_ERR_COMM;
3021 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
3024 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3026 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3029 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3031 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3034 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3036 return PMPI_Attr_delete(comm, comm_keyval);
3039 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
3042 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3045 int PMPI_Comm_free_keyval(int* keyval) {
3046 return PMPI_Keyval_free(keyval);
3049 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3051 if (type==MPI_DATATYPE_NULL)
3052 return MPI_ERR_TYPE;
3054 return type->attr_get<simgrid::smpi::Datatype>(type_keyval, attribute_val, flag);
3057 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3059 if (type==MPI_DATATYPE_NULL)
3060 return MPI_ERR_TYPE;
3062 return type->attr_put<simgrid::smpi::Datatype>(type_keyval, attribute_val);
3065 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3067 if (type==MPI_DATATYPE_NULL)
3068 return MPI_ERR_TYPE;
3070 return type->attr_delete<simgrid::smpi::Datatype>(type_keyval);
3073 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
3076 smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr};
3077 smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr};
3078 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
3081 int PMPI_Type_free_keyval(int* keyval) {
3082 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Datatype>(keyval);
3085 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
3087 static MPI_Aint size;
3088 static int disp_unit;
3089 if (win==MPI_WIN_NULL)
3090 return MPI_ERR_TYPE;
3094 *static_cast<void**>(attribute_val) = win->base();
3099 *static_cast<MPI_Aint**>(attribute_val) = &size;
3102 case MPI_WIN_DISP_UNIT :
3103 disp_unit=win->disp_unit();
3104 *static_cast<int**>(attribute_val) = &disp_unit;
3108 return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
3114 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
3116 if (win==MPI_WIN_NULL)
3117 return MPI_ERR_TYPE;
3119 return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
3122 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
3124 if (win==MPI_WIN_NULL)
3125 return MPI_ERR_TYPE;
3127 return win->attr_delete<simgrid::smpi::Win>(type_keyval);
3130 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
3133 smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
3134 smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
3135 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
3138 int PMPI_Win_free_keyval(int* keyval) {
3139 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
3142 int PMPI_Info_create( MPI_Info *info){
3143 if (info == nullptr)
3145 *info = new simgrid::smpi::Info();
3149 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3150 if (info == nullptr || key == nullptr || value == nullptr)
3152 info->set(key, value);
3156 int PMPI_Info_free( MPI_Info *info){
3157 if (info == nullptr || *info==nullptr)
3159 simgrid::smpi::Info::unref(*info);
3160 *info=MPI_INFO_NULL;
3164 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3166 if (info == nullptr || key == nullptr || valuelen <0)
3168 if (value == nullptr)
3169 return MPI_ERR_INFO_VALUE;
3170 return info->get(key, valuelen, value, flag);
3173 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3174 if (info == nullptr || newinfo==nullptr)
3176 *newinfo = new simgrid::smpi::Info(info);
3180 int PMPI_Info_delete(MPI_Info info, char *key){
3181 if (info == nullptr || key==nullptr)
3183 return info->remove(key);
3186 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3187 if (info == nullptr || nkeys==nullptr)
3189 return info->get_nkeys(nkeys);
3192 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3193 if (info == nullptr || key==nullptr || n<0 || n> MPI_MAX_INFO_KEY)
3195 return info->get_nthkey(n, key);
3198 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3200 if (info == nullptr || key == nullptr || valuelen==nullptr)
3202 return info->get_valuelen(key, valuelen, flag);
3205 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3206 if(incount<0 || outcount < 0 || inbuf==nullptr || outbuf==nullptr)
3208 if(!type->is_valid())
3209 return MPI_ERR_TYPE;
3210 if(comm==MPI_COMM_NULL)
3211 return MPI_ERR_COMM;
3212 return type->unpack(inbuf, incount, position, outbuf,outcount, comm);
3215 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3216 if(incount<0 || outcount < 0|| inbuf==nullptr || outbuf==nullptr)
3218 if(!type->is_valid())
3219 return MPI_ERR_TYPE;
3220 if(comm==MPI_COMM_NULL)
3221 return MPI_ERR_COMM;
3222 return type->pack(inbuf, incount, outbuf,outcount,position, comm);
3225 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3228 if(!datatype->is_valid())
3229 return MPI_ERR_TYPE;
3230 if(comm==MPI_COMM_NULL)
3231 return MPI_ERR_COMM;
3233 *size=incount*datatype->size();