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());
63 int PMPI_Finalized(int* flag)
65 *flag=smpi_process()!=nullptr ? smpi_process()->finalized() : 0;
69 int PMPI_Get_version (int *version,int *subversion){
70 *version = MPI_VERSION;
71 *subversion= MPI_SUBVERSION;
75 int PMPI_Get_library_version (char *version,int *len){
77 snprintf(version, MPI_MAX_LIBRARY_VERSION_STRING, "SMPI Version %d.%d. Copyright The Simgrid Team 2007-2017",
78 SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR);
79 *len = strlen(version) > MPI_MAX_LIBRARY_VERSION_STRING ? MPI_MAX_LIBRARY_VERSION_STRING : strlen(version);
84 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
86 if (provided != nullptr) {
87 *provided = MPI_THREAD_SINGLE;
89 return MPI_Init(argc, argv);
92 int PMPI_Query_thread(int *provided)
94 if (provided == nullptr) {
97 *provided = MPI_THREAD_SINGLE;
102 int PMPI_Is_thread_main(int *flag)
104 if (flag == nullptr) {
107 *flag = smpi_process()->index() == 0;
112 int PMPI_Abort(MPI_Comm comm, int errorcode)
115 // FIXME: should kill all processes in comm instead
116 simcall_process_kill(SIMIX_process_self());
122 return smpi_mpi_wtime();
125 extern double sg_maxmin_precision;
128 return sg_maxmin_precision;
131 int PMPI_Address(void *location, MPI_Aint * address)
133 if (address==nullptr) {
136 *address = reinterpret_cast<MPI_Aint>(location);
141 int PMPI_Get_address(void *location, MPI_Aint * address)
143 return PMPI_Address(location, address);
146 int PMPI_Type_free(MPI_Datatype * datatype)
148 /* Free a predefined datatype is an error according to the standard, and should be checked for */
149 if (*datatype == MPI_DATATYPE_NULL) {
152 simgrid::smpi::Datatype::unref(*datatype);
157 int PMPI_Type_size(MPI_Datatype datatype, int *size)
159 if (datatype == MPI_DATATYPE_NULL) {
161 } else if (size == nullptr) {
164 *size = static_cast<int>(datatype->size());
169 int PMPI_Type_size_x(MPI_Datatype datatype, MPI_Count *size)
171 if (datatype == MPI_DATATYPE_NULL) {
173 } else if (size == nullptr) {
176 *size = static_cast<MPI_Count>(datatype->size());
181 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
183 if (datatype == MPI_DATATYPE_NULL) {
185 } else if (lb == nullptr || extent == nullptr) {
188 return datatype->extent(lb, extent);
192 int PMPI_Type_get_true_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
194 return PMPI_Type_get_extent(datatype, lb, extent);
197 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
199 if (datatype == MPI_DATATYPE_NULL) {
201 } else if (extent == nullptr) {
204 *extent = datatype->get_extent();
209 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
211 if (datatype == MPI_DATATYPE_NULL) {
213 } else if (disp == nullptr) {
216 *disp = datatype->lb();
221 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
223 if (datatype == MPI_DATATYPE_NULL) {
225 } else if (disp == nullptr) {
228 *disp = datatype->ub();
233 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
234 int retval = MPI_SUCCESS;
235 if (datatype == MPI_DATATYPE_NULL) {
238 *newtype = new simgrid::smpi::Datatype(datatype, &retval);
239 //error when duplicating, free the new datatype
240 if(retval!=MPI_SUCCESS){
241 simgrid::smpi::Datatype::unref(*newtype);
242 *newtype = MPI_DATATYPE_NULL;
248 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
250 if (function == nullptr || op == nullptr) {
253 *op = new simgrid::smpi::Op(function, (commute!=0));
258 int PMPI_Op_free(MPI_Op * op)
262 } else if (*op == MPI_OP_NULL) {
271 int PMPI_Op_commutative(MPI_Op op, int* commute){
272 if (op == MPI_OP_NULL) {
274 } else if (commute==nullptr){
277 *commute = op->is_commutative();
282 int PMPI_Group_free(MPI_Group * group)
284 if (group == nullptr) {
287 if(*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_EMPTY)
288 simgrid::smpi::Group::unref(*group);
289 *group = MPI_GROUP_NULL;
294 int PMPI_Group_size(MPI_Group group, int *size)
296 if (group == MPI_GROUP_NULL) {
297 return MPI_ERR_GROUP;
298 } else if (size == nullptr) {
301 *size = group->size();
306 int PMPI_Group_rank(MPI_Group group, int *rank)
308 if (group == MPI_GROUP_NULL) {
309 return MPI_ERR_GROUP;
310 } else if (rank == nullptr) {
313 *rank = group->rank(smpi_process()->index());
318 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2)
320 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
321 return MPI_ERR_GROUP;
323 for (int i = 0; i < n; i++) {
324 if(ranks1[i]==MPI_PROC_NULL){
325 ranks2[i]=MPI_PROC_NULL;
327 int index = group1->index(ranks1[i]);
328 ranks2[i] = group2->rank(index);
335 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
337 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
338 return MPI_ERR_GROUP;
339 } else if (result == nullptr) {
342 *result = group1->compare(group2);
347 int PMPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
350 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
351 return MPI_ERR_GROUP;
352 } else if (newgroup == nullptr) {
355 return group1->group_union(group2, newgroup);
359 int PMPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
362 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
363 return MPI_ERR_GROUP;
364 } else if (newgroup == nullptr) {
367 return group1->intersection(group2,newgroup);
371 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
373 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
374 return MPI_ERR_GROUP;
375 } else if (newgroup == nullptr) {
378 return group1->difference(group2,newgroup);
382 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
384 if (group == MPI_GROUP_NULL) {
385 return MPI_ERR_GROUP;
386 } else if (newgroup == nullptr) {
389 return group->incl(n, ranks, newgroup);
393 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
395 if (group == MPI_GROUP_NULL) {
396 return MPI_ERR_GROUP;
397 } else if (newgroup == nullptr) {
402 if (group != MPI_COMM_WORLD->group()
403 && group != MPI_COMM_SELF->group() && group != MPI_GROUP_EMPTY)
406 } else if (n == group->size()) {
407 *newgroup = MPI_GROUP_EMPTY;
410 return group->excl(n,ranks,newgroup);
415 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
417 if (group == MPI_GROUP_NULL) {
418 return MPI_ERR_GROUP;
419 } else if (newgroup == nullptr) {
423 *newgroup = MPI_GROUP_EMPTY;
426 return group->range_incl(n,ranges,newgroup);
431 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
433 if (group == MPI_GROUP_NULL) {
434 return MPI_ERR_GROUP;
435 } else if (newgroup == nullptr) {
440 if (group != MPI_COMM_WORLD->group() && group != MPI_COMM_SELF->group() &&
441 group != MPI_GROUP_EMPTY)
445 return group->range_excl(n,ranges,newgroup);
450 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
452 if (comm == MPI_COMM_NULL) {
454 } else if (rank == nullptr) {
457 *rank = comm->rank();
462 int PMPI_Comm_size(MPI_Comm comm, int *size)
464 if (comm == MPI_COMM_NULL) {
466 } else if (size == nullptr) {
469 *size = comm->size();
474 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
476 if (comm == MPI_COMM_NULL) {
478 } else if (name == nullptr || len == nullptr) {
481 comm->get_name(name, len);
486 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
488 if (comm == MPI_COMM_NULL) {
490 } else if (group == nullptr) {
493 *group = comm->group();
494 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
500 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
502 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
504 } else if (result == nullptr) {
507 if (comm1 == comm2) { /* Same communicators means same groups */
510 *result = comm1->group()->compare(comm2->group());
511 if (*result == MPI_IDENT) {
512 *result = MPI_CONGRUENT;
519 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
521 if (comm == MPI_COMM_NULL) {
523 } else if (newcomm == nullptr) {
526 return comm->dup(newcomm);
530 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
532 if (comm == MPI_COMM_NULL) {
534 } else if (group == MPI_GROUP_NULL) {
535 return MPI_ERR_GROUP;
536 } else if (newcomm == nullptr) {
538 } else if(group->rank(smpi_process()->index())==MPI_UNDEFINED){
539 *newcomm= MPI_COMM_NULL;
543 *newcomm = new simgrid::smpi::Comm(group, nullptr);
548 int PMPI_Comm_free(MPI_Comm * comm)
550 if (comm == nullptr) {
552 } else if (*comm == MPI_COMM_NULL) {
555 simgrid::smpi::Comm::destroy(*comm);
556 *comm = MPI_COMM_NULL;
561 int PMPI_Comm_disconnect(MPI_Comm * comm)
563 /* TODO: wait until all communication in comm are done */
564 if (comm == nullptr) {
566 } else if (*comm == MPI_COMM_NULL) {
569 simgrid::smpi::Comm::destroy(*comm);
570 *comm = MPI_COMM_NULL;
575 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
580 if (comm_out == nullptr) {
581 retval = MPI_ERR_ARG;
582 } else if (comm == MPI_COMM_NULL) {
583 retval = MPI_ERR_COMM;
585 *comm_out = comm->split(color, key);
586 retval = MPI_SUCCESS;
593 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
598 if (comm_out == nullptr) {
599 retval = MPI_ERR_ARG;
600 } else if (comm == MPI_COMM_NULL) {
601 retval = MPI_ERR_COMM;
603 retval = MPI_Comm_create(comm, group, comm_out);
610 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
615 if (request == nullptr) {
616 retval = MPI_ERR_ARG;
617 } else if (comm == MPI_COMM_NULL) {
618 retval = MPI_ERR_COMM;
619 } else if (!datatype->is_valid()) {
620 retval = MPI_ERR_TYPE;
621 } else if (dst == MPI_PROC_NULL) {
622 retval = MPI_SUCCESS;
624 *request = simgrid::smpi::Request::send_init(buf, count, datatype, dst, tag, comm);
625 retval = MPI_SUCCESS;
628 if (retval != MPI_SUCCESS && request != nullptr)
629 *request = MPI_REQUEST_NULL;
633 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
638 if (request == nullptr) {
639 retval = MPI_ERR_ARG;
640 } else if (comm == MPI_COMM_NULL) {
641 retval = MPI_ERR_COMM;
642 } else if (!datatype->is_valid()) {
643 retval = MPI_ERR_TYPE;
644 } else if (src == MPI_PROC_NULL) {
645 retval = MPI_SUCCESS;
647 *request = simgrid::smpi::Request::recv_init(buf, count, datatype, src, tag, comm);
648 retval = MPI_SUCCESS;
651 if (retval != MPI_SUCCESS && request != nullptr)
652 *request = MPI_REQUEST_NULL;
656 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
661 if (request == nullptr) {
662 retval = MPI_ERR_ARG;
663 } else if (comm == MPI_COMM_NULL) {
664 retval = MPI_ERR_COMM;
665 } else if (!datatype->is_valid()) {
666 retval = MPI_ERR_TYPE;
667 } else if (dst == MPI_PROC_NULL) {
668 retval = MPI_SUCCESS;
670 *request = simgrid::smpi::Request::ssend_init(buf, count, datatype, dst, tag, comm);
671 retval = MPI_SUCCESS;
674 if (retval != MPI_SUCCESS && request != nullptr)
675 *request = MPI_REQUEST_NULL;
679 int PMPI_Start(MPI_Request * request)
684 if (request == nullptr || *request == MPI_REQUEST_NULL) {
685 retval = MPI_ERR_REQUEST;
688 retval = MPI_SUCCESS;
694 int PMPI_Startall(int count, MPI_Request * requests)
698 if (requests == nullptr) {
699 retval = MPI_ERR_ARG;
701 retval = MPI_SUCCESS;
702 for (int i = 0; i < count; i++) {
703 if(requests[i] == MPI_REQUEST_NULL) {
704 retval = MPI_ERR_REQUEST;
707 if(retval != MPI_ERR_REQUEST) {
708 simgrid::smpi::Request::startall(count, requests);
715 int PMPI_Request_free(MPI_Request * request)
720 if (*request == MPI_REQUEST_NULL) {
721 retval = MPI_ERR_ARG;
723 simgrid::smpi::Request::unref(request);
724 retval = MPI_SUCCESS;
730 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
736 if (request == nullptr) {
737 retval = MPI_ERR_ARG;
738 } else if (comm == MPI_COMM_NULL) {
739 retval = MPI_ERR_COMM;
740 } else if (src == MPI_PROC_NULL) {
741 *request = MPI_REQUEST_NULL;
742 retval = MPI_SUCCESS;
743 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
744 retval = MPI_ERR_RANK;
745 } else if ((count < 0) || (buf==nullptr && count > 0)) {
746 retval = MPI_ERR_COUNT;
747 } else if (!datatype->is_valid()) {
748 retval = MPI_ERR_TYPE;
749 } else if(tag<0 && tag != MPI_ANY_TAG){
750 retval = MPI_ERR_TAG;
753 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
754 int src_traced = comm->group()->index(src);
756 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
757 extra->type = TRACING_IRECV;
758 extra->src = src_traced;
761 extra->datatype1 = encode_datatype(datatype, &known);
762 int dt_size_send = 1;
764 dt_size_send = datatype->size();
765 extra->send_size = count*dt_size_send;
766 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
768 *request = simgrid::smpi::Request::irecv(buf, count, datatype, src, tag, comm);
769 retval = MPI_SUCCESS;
771 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
775 if (retval != MPI_SUCCESS && request != nullptr)
776 *request = MPI_REQUEST_NULL;
781 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
786 if (request == nullptr) {
787 retval = MPI_ERR_ARG;
788 } else if (comm == MPI_COMM_NULL) {
789 retval = MPI_ERR_COMM;
790 } else if (dst == MPI_PROC_NULL) {
791 *request = MPI_REQUEST_NULL;
792 retval = MPI_SUCCESS;
793 } else if (dst >= comm->group()->size() || dst <0){
794 retval = MPI_ERR_RANK;
795 } else if ((count < 0) || (buf==nullptr && count > 0)) {
796 retval = MPI_ERR_COUNT;
797 } else if (!datatype->is_valid()) {
798 retval = MPI_ERR_TYPE;
799 } else if(tag<0 && tag != MPI_ANY_TAG){
800 retval = MPI_ERR_TAG;
802 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
803 int dst_traced = comm->group()->index(dst);
804 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
805 extra->type = TRACING_ISEND;
807 extra->dst = dst_traced;
809 extra->datatype1 = encode_datatype(datatype, &known);
810 int dt_size_send = 1;
812 dt_size_send = datatype->size();
813 extra->send_size = count*dt_size_send;
814 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
815 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
817 *request = simgrid::smpi::Request::isend(buf, count, datatype, dst, tag, comm);
818 retval = MPI_SUCCESS;
820 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
824 if (retval != MPI_SUCCESS && request!=nullptr)
825 *request = MPI_REQUEST_NULL;
829 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
834 if (request == nullptr) {
835 retval = MPI_ERR_ARG;
836 } else if (comm == MPI_COMM_NULL) {
837 retval = MPI_ERR_COMM;
838 } else if (dst == MPI_PROC_NULL) {
839 *request = MPI_REQUEST_NULL;
840 retval = MPI_SUCCESS;
841 } else if (dst >= comm->group()->size() || dst <0){
842 retval = MPI_ERR_RANK;
843 } else if ((count < 0)|| (buf==nullptr && count > 0)) {
844 retval = MPI_ERR_COUNT;
845 } else if (!datatype->is_valid()) {
846 retval = MPI_ERR_TYPE;
847 } else if(tag<0 && tag != MPI_ANY_TAG){
848 retval = MPI_ERR_TAG;
850 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
851 int dst_traced = comm->group()->index(dst);
852 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
853 extra->type = TRACING_ISSEND;
855 extra->dst = dst_traced;
857 extra->datatype1 = encode_datatype(datatype, &known);
858 int dt_size_send = 1;
860 dt_size_send = datatype->size();
861 extra->send_size = count*dt_size_send;
862 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
863 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
865 *request = simgrid::smpi::Request::issend(buf, count, datatype, dst, tag, comm);
866 retval = MPI_SUCCESS;
868 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
872 if (retval != MPI_SUCCESS && request!=nullptr)
873 *request = MPI_REQUEST_NULL;
877 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
882 if (comm == MPI_COMM_NULL) {
883 retval = MPI_ERR_COMM;
884 } else if (src == MPI_PROC_NULL) {
885 simgrid::smpi::Status::empty(status);
886 status->MPI_SOURCE = MPI_PROC_NULL;
887 retval = MPI_SUCCESS;
888 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
889 retval = MPI_ERR_RANK;
890 } else if ((count < 0) || (buf==nullptr && count > 0)) {
891 retval = MPI_ERR_COUNT;
892 } else if (!datatype->is_valid()) {
893 retval = MPI_ERR_TYPE;
894 } else if(tag<0 && tag != MPI_ANY_TAG){
895 retval = MPI_ERR_TAG;
897 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
898 int src_traced = comm->group()->index(src);
899 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
900 extra->type = TRACING_RECV;
901 extra->src = src_traced;
904 extra->datatype1 = encode_datatype(datatype, &known);
905 int dt_size_send = 1;
907 dt_size_send = datatype->size();
908 extra->send_size = count * dt_size_send;
909 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
911 simgrid::smpi::Request::recv(buf, count, datatype, src, tag, comm, status);
912 retval = MPI_SUCCESS;
914 // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
915 if (status != MPI_STATUS_IGNORE) {
916 src_traced = comm->group()->index(status->MPI_SOURCE);
917 if (!TRACE_smpi_view_internals()) {
918 TRACE_smpi_recv(rank, src_traced, rank, tag);
921 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
928 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
934 if (comm == MPI_COMM_NULL) {
935 retval = MPI_ERR_COMM;
936 } else if (dst == MPI_PROC_NULL) {
937 retval = MPI_SUCCESS;
938 } else if (dst >= comm->group()->size() || dst <0){
939 retval = MPI_ERR_RANK;
940 } else if ((count < 0) || (buf == nullptr && count > 0)) {
941 retval = MPI_ERR_COUNT;
942 } else if (!datatype->is_valid()) {
943 retval = MPI_ERR_TYPE;
944 } else if(tag < 0 && tag != MPI_ANY_TAG){
945 retval = MPI_ERR_TAG;
947 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
948 int dst_traced = comm->group()->index(dst);
949 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
950 extra->type = TRACING_SEND;
952 extra->dst = dst_traced;
954 extra->datatype1 = encode_datatype(datatype, &known);
955 int dt_size_send = 1;
957 dt_size_send = datatype->size();
959 extra->send_size = count*dt_size_send;
960 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
961 if (!TRACE_smpi_view_internals()) {
962 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
965 simgrid::smpi::Request::send(buf, count, datatype, dst, tag, comm);
966 retval = MPI_SUCCESS;
968 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
975 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
980 if (comm == MPI_COMM_NULL) {
981 retval = MPI_ERR_COMM;
982 } else if (dst == MPI_PROC_NULL) {
983 retval = MPI_SUCCESS;
984 } else if (dst >= comm->group()->size() || dst <0){
985 retval = MPI_ERR_RANK;
986 } else if ((count < 0) || (buf==nullptr && count > 0)) {
987 retval = MPI_ERR_COUNT;
988 } else if (!datatype->is_valid()){
989 retval = MPI_ERR_TYPE;
990 } else if(tag<0 && tag != MPI_ANY_TAG){
991 retval = MPI_ERR_TAG;
993 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
994 int dst_traced = comm->group()->index(dst);
995 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
996 extra->type = TRACING_SSEND;
998 extra->dst = dst_traced;
1000 extra->datatype1 = encode_datatype(datatype, &known);
1001 int dt_size_send = 1;
1003 dt_size_send = datatype->size();
1005 extra->send_size = count*dt_size_send;
1006 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1007 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
1009 simgrid::smpi::Request::ssend(buf, count, datatype, dst, tag, comm);
1010 retval = MPI_SUCCESS;
1012 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1019 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void *recvbuf,
1020 int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status)
1026 if (comm == MPI_COMM_NULL) {
1027 retval = MPI_ERR_COMM;
1028 } else if (!sendtype->is_valid() || !recvtype->is_valid()) {
1029 retval = MPI_ERR_TYPE;
1030 } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1031 simgrid::smpi::Status::empty(status);
1032 status->MPI_SOURCE = MPI_PROC_NULL;
1033 retval = MPI_SUCCESS;
1034 }else if (dst >= comm->group()->size() || dst <0 ||
1035 (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0))){
1036 retval = MPI_ERR_RANK;
1037 } else if ((sendcount < 0 || recvcount<0) ||
1038 (sendbuf==nullptr && sendcount > 0) || (recvbuf==nullptr && recvcount>0)) {
1039 retval = MPI_ERR_COUNT;
1040 } else if((sendtag<0 && sendtag != MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1041 retval = MPI_ERR_TAG;
1044 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1045 int dst_traced = comm->group()->index(dst);
1046 int src_traced = comm->group()->index(src);
1047 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1048 extra->type = TRACING_SENDRECV;
1049 extra->src = src_traced;
1050 extra->dst = dst_traced;
1052 extra->datatype1 = encode_datatype(sendtype, &known);
1053 int dt_size_send = 1;
1055 dt_size_send = sendtype->size();
1056 extra->send_size = sendcount*dt_size_send;
1057 extra->datatype2 = encode_datatype(recvtype, &known);
1058 int dt_size_recv = 1;
1060 dt_size_recv = recvtype->size();
1061 extra->recv_size = recvcount*dt_size_recv;
1063 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1064 TRACE_smpi_send(rank, rank, dst_traced, sendtag,sendcount*sendtype->size());
1066 simgrid::smpi::Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm,
1068 retval = MPI_SUCCESS;
1070 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1071 TRACE_smpi_recv(rank, src_traced, rank, recvtag);
1078 int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,
1079 MPI_Comm comm, MPI_Status* status)
1082 if (!datatype->is_valid()) {
1083 return MPI_ERR_TYPE;
1084 } else if (count < 0) {
1085 return MPI_ERR_COUNT;
1087 int size = datatype->get_extent() * count;
1088 void* recvbuf = xbt_new0(char, size);
1089 retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
1090 if(retval==MPI_SUCCESS){
1091 simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
1099 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1103 if (request == nullptr || flag == nullptr) {
1104 retval = MPI_ERR_ARG;
1105 } else if (*request == MPI_REQUEST_NULL) {
1107 simgrid::smpi::Status::empty(status);
1108 retval = MPI_SUCCESS;
1110 int rank = ((*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1112 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1113 extra->type = TRACING_TEST;
1114 TRACE_smpi_testing_in(rank, extra);
1116 *flag = simgrid::smpi::Request::test(request,status);
1118 TRACE_smpi_testing_out(rank);
1119 retval = MPI_SUCCESS;
1125 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status)
1130 if (index == nullptr || flag == nullptr) {
1131 retval = MPI_ERR_ARG;
1133 *flag = simgrid::smpi::Request::testany(count, requests, index, status);
1134 retval = MPI_SUCCESS;
1140 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1145 if (flag == nullptr) {
1146 retval = MPI_ERR_ARG;
1148 *flag = simgrid::smpi::Request::testall(count, requests, statuses);
1149 retval = MPI_SUCCESS;
1155 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1159 if (status == nullptr) {
1160 retval = MPI_ERR_ARG;
1161 } else if (comm == MPI_COMM_NULL) {
1162 retval = MPI_ERR_COMM;
1163 } else if (source == MPI_PROC_NULL) {
1164 simgrid::smpi::Status::empty(status);
1165 status->MPI_SOURCE = MPI_PROC_NULL;
1166 retval = MPI_SUCCESS;
1168 simgrid::smpi::Request::probe(source, tag, comm, status);
1169 retval = MPI_SUCCESS;
1175 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1179 if (flag == nullptr) {
1180 retval = MPI_ERR_ARG;
1181 } else if (comm == MPI_COMM_NULL) {
1182 retval = MPI_ERR_COMM;
1183 } else if (source == MPI_PROC_NULL) {
1185 simgrid::smpi::Status::empty(status);
1186 status->MPI_SOURCE = MPI_PROC_NULL;
1187 retval = MPI_SUCCESS;
1189 simgrid::smpi::Request::iprobe(source, tag, comm, flag, status);
1190 retval = MPI_SUCCESS;
1196 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1202 simgrid::smpi::Status::empty(status);
1204 if (request == nullptr) {
1205 retval = MPI_ERR_ARG;
1206 } else if (*request == MPI_REQUEST_NULL) {
1207 retval = MPI_SUCCESS;
1210 int rank = (request!=nullptr && (*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1212 int src_traced = (*request)->src();
1213 int dst_traced = (*request)->dst();
1214 int tag_traced= (*request)->tag();
1215 MPI_Comm comm = (*request)->comm();
1216 int is_wait_for_receive = ((*request)->flags() & RECV);
1217 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1218 extra->type = TRACING_WAIT;
1219 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1221 simgrid::smpi::Request::wait(request, status);
1222 retval = MPI_SUCCESS;
1224 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1225 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1226 if (is_wait_for_receive) {
1227 if(src_traced==MPI_ANY_SOURCE)
1228 src_traced = (status!=MPI_STATUS_IGNORE) ?
1229 comm->group()->rank(status->MPI_SOURCE) :
1231 TRACE_smpi_recv(rank, src_traced, dst_traced, tag_traced);
1239 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1241 if (index == nullptr)
1245 //save requests information for tracing
1253 savedvalstype* savedvals=nullptr;
1255 savedvals = xbt_new0(savedvalstype, count);
1257 for (int i = 0; i < count; i++) {
1258 MPI_Request req = requests[i]; //already received requests are no longer valid
1260 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), req->comm()};
1263 int rank_traced = smpi_process()->index();
1264 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1265 extra->type = TRACING_WAITANY;
1266 extra->send_size=count;
1267 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1269 *index = simgrid::smpi::Request::waitany(count, requests, status);
1271 if(*index!=MPI_UNDEFINED){
1272 int src_traced = savedvals[*index].src;
1273 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1274 int dst_traced = savedvals[*index].dst;
1275 int is_wait_for_receive = savedvals[*index].recv;
1276 if (is_wait_for_receive) {
1277 if(savedvals[*index].src==MPI_ANY_SOURCE)
1278 src_traced = (status != MPI_STATUSES_IGNORE)
1279 ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
1280 : savedvals[*index].src;
1281 TRACE_smpi_recv(rank_traced, src_traced, dst_traced, savedvals[*index].tag);
1283 TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1285 xbt_free(savedvals);
1291 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1294 //save information from requests
1303 savedvalstype* savedvals=xbt_new0(savedvalstype, count);
1305 for (int i = 0; i < count; i++) {
1306 MPI_Request req = requests[i];
1307 if(req!=MPI_REQUEST_NULL){
1308 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), 1, req->comm()};
1310 savedvals[i].valid=0;
1313 int rank_traced = smpi_process()->index();
1314 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1315 extra->type = TRACING_WAITALL;
1316 extra->send_size=count;
1317 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1319 int retval = simgrid::smpi::Request::waitall(count, requests, status);
1321 for (int i = 0; i < count; i++) {
1322 if(savedvals[i].valid){
1323 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1324 int src_traced = savedvals[i].src;
1325 int dst_traced = savedvals[i].dst;
1326 int is_wait_for_receive = savedvals[i].recv;
1327 if (is_wait_for_receive) {
1328 if(src_traced==MPI_ANY_SOURCE)
1329 src_traced = (status!=MPI_STATUSES_IGNORE) ?
1330 savedvals[i].comm->group()->rank(status[i].MPI_SOURCE) : savedvals[i].src;
1331 TRACE_smpi_recv(rank_traced, src_traced, dst_traced,savedvals[i].tag);
1335 TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1336 xbt_free(savedvals);
1342 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount, int *indices, MPI_Status status[])
1347 if (outcount == nullptr) {
1348 retval = MPI_ERR_ARG;
1350 *outcount = simgrid::smpi::Request::waitsome(incount, requests, indices, status);
1351 retval = MPI_SUCCESS;
1357 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[])
1362 if (outcount == nullptr) {
1363 retval = MPI_ERR_ARG;
1365 *outcount = simgrid::smpi::Request::testsome(incount, requests, indices, status);
1366 retval = MPI_SUCCESS;
1373 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1379 if (comm == MPI_COMM_NULL) {
1380 retval = MPI_ERR_COMM;
1381 } else if (!datatype->is_valid()) {
1382 retval = MPI_ERR_ARG;
1384 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1385 int root_traced = comm->group()->index(root);
1387 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1388 extra->type = TRACING_BCAST;
1389 extra->root = root_traced;
1391 extra->datatype1 = encode_datatype(datatype, &known);
1392 int dt_size_send = 1;
1394 dt_size_send = datatype->size();
1395 extra->send_size = count * dt_size_send;
1396 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1397 if (comm->size() > 1)
1398 simgrid::smpi::Colls::bcast(buf, count, datatype, root, comm);
1399 retval = MPI_SUCCESS;
1401 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1407 int PMPI_Barrier(MPI_Comm comm)
1413 if (comm == MPI_COMM_NULL) {
1414 retval = MPI_ERR_COMM;
1416 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1417 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1418 extra->type = TRACING_BARRIER;
1419 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1421 simgrid::smpi::Colls::barrier(comm);
1423 //Barrier can be used to synchronize RMA calls. Finish all requests from comm before.
1424 comm->finish_rma_calls();
1426 retval = MPI_SUCCESS;
1428 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1435 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
1436 int root, MPI_Comm comm)
1442 if (comm == MPI_COMM_NULL) {
1443 retval = MPI_ERR_COMM;
1444 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1445 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1446 retval = MPI_ERR_TYPE;
1447 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) || ((comm->rank() == root) && (recvcount <0))){
1448 retval = MPI_ERR_COUNT;
1451 char* sendtmpbuf = static_cast<char*>(sendbuf);
1452 int sendtmpcount = sendcount;
1453 MPI_Datatype sendtmptype = sendtype;
1454 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1456 sendtmptype=recvtype;
1458 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1459 int root_traced = comm->group()->index(root);
1460 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1461 extra->type = TRACING_GATHER;
1462 extra->root = root_traced;
1464 extra->datatype1 = encode_datatype(sendtmptype, &known);
1465 int dt_size_send = 1;
1467 dt_size_send = sendtmptype->size();
1468 extra->send_size = sendtmpcount * dt_size_send;
1469 extra->datatype2 = encode_datatype(recvtype, &known);
1470 int dt_size_recv = 1;
1471 if ((comm->rank() == root) && known == 0)
1472 dt_size_recv = recvtype->size();
1473 extra->recv_size = recvcount * dt_size_recv;
1475 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1477 simgrid::smpi::Colls::gather(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
1479 retval = MPI_SUCCESS;
1480 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1487 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
1488 MPI_Datatype recvtype, int root, MPI_Comm comm)
1494 if (comm == MPI_COMM_NULL) {
1495 retval = MPI_ERR_COMM;
1496 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1497 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1498 retval = MPI_ERR_TYPE;
1499 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1500 retval = MPI_ERR_COUNT;
1501 } else if (recvcounts == nullptr || displs == nullptr) {
1502 retval = MPI_ERR_ARG;
1504 char* sendtmpbuf = static_cast<char*>(sendbuf);
1505 int sendtmpcount = sendcount;
1506 MPI_Datatype sendtmptype = sendtype;
1507 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1509 sendtmptype=recvtype;
1512 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1513 int root_traced = comm->group()->index(root);
1514 int size = comm->size();
1515 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1516 extra->type = TRACING_GATHERV;
1517 extra->num_processes = size;
1518 extra->root = root_traced;
1520 extra->datatype1 = encode_datatype(sendtmptype, &known);
1521 int dt_size_send = 1;
1523 dt_size_send = sendtype->size();
1524 extra->send_size = sendtmpcount * dt_size_send;
1525 extra->datatype2 = encode_datatype(recvtype, &known);
1526 int dt_size_recv = 1;
1528 dt_size_recv = recvtype->size();
1529 if (comm->rank() == root) {
1530 extra->recvcounts = xbt_new(int, size);
1531 for (int i = 0; i < size; i++) // copy data to avoid bad free
1532 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1534 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1536 retval = simgrid::smpi::Colls::gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
1537 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1544 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1545 void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
1551 if (comm == MPI_COMM_NULL) {
1552 retval = MPI_ERR_COMM;
1553 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1554 (recvtype == MPI_DATATYPE_NULL)){
1555 retval = MPI_ERR_TYPE;
1556 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1558 retval = MPI_ERR_COUNT;
1560 if(sendbuf == MPI_IN_PLACE) {
1561 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*recvcount*comm->rank();
1562 sendcount=recvcount;
1565 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1566 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1567 extra->type = TRACING_ALLGATHER;
1569 extra->datatype1 = encode_datatype(sendtype, &known);
1570 int dt_size_send = 1;
1572 dt_size_send = sendtype->size();
1573 extra->send_size = sendcount * dt_size_send;
1574 extra->datatype2 = encode_datatype(recvtype, &known);
1575 int dt_size_recv = 1;
1577 dt_size_recv = recvtype->size();
1578 extra->recv_size = recvcount * dt_size_recv;
1580 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1582 simgrid::smpi::Colls::allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1583 retval = MPI_SUCCESS;
1584 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1590 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1591 void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
1597 if (comm == MPI_COMM_NULL) {
1598 retval = MPI_ERR_COMM;
1599 } else if (((sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) || (recvtype == MPI_DATATYPE_NULL)) {
1600 retval = MPI_ERR_TYPE;
1601 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1602 retval = MPI_ERR_COUNT;
1603 } else if (recvcounts == nullptr || displs == nullptr) {
1604 retval = MPI_ERR_ARG;
1607 if(sendbuf == MPI_IN_PLACE) {
1608 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*displs[comm->rank()];
1609 sendcount=recvcounts[comm->rank()];
1612 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1614 int size = comm->size();
1615 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1616 extra->type = TRACING_ALLGATHERV;
1617 extra->num_processes = size;
1619 extra->datatype1 = encode_datatype(sendtype, &known);
1620 int dt_size_send = 1;
1622 dt_size_send = sendtype->size();
1623 extra->send_size = sendcount * dt_size_send;
1624 extra->datatype2 = encode_datatype(recvtype, &known);
1625 int dt_size_recv = 1;
1627 dt_size_recv = recvtype->size();
1628 extra->recvcounts = xbt_new(int, size);
1629 for (i = 0; i < size; i++) // copy data to avoid bad free
1630 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1632 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1634 simgrid::smpi::Colls::allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1635 retval = MPI_SUCCESS;
1636 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1643 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1644 void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1650 if (comm == MPI_COMM_NULL) {
1651 retval = MPI_ERR_COMM;
1652 } else if (((comm->rank() == root) && (!sendtype->is_valid())) ||
1653 ((recvbuf != MPI_IN_PLACE) && (!recvtype->is_valid()))) {
1654 retval = MPI_ERR_TYPE;
1655 } else if ((sendbuf == recvbuf) ||
1656 ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
1657 retval = MPI_ERR_BUFFER;
1660 if (recvbuf == MPI_IN_PLACE) {
1661 recvtype = sendtype;
1662 recvcount = sendcount;
1664 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1665 int root_traced = comm->group()->index(root);
1666 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1667 extra->type = TRACING_SCATTER;
1668 extra->root = root_traced;
1670 extra->datatype1 = encode_datatype(sendtype, &known);
1671 int dt_size_send = 1;
1672 if ((comm->rank() == root) && known == 0)
1673 dt_size_send = sendtype->size();
1674 extra->send_size = sendcount * dt_size_send;
1675 extra->datatype2 = encode_datatype(recvtype, &known);
1676 int dt_size_recv = 1;
1678 dt_size_recv = recvtype->size();
1679 extra->recv_size = recvcount * dt_size_recv;
1680 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1682 simgrid::smpi::Colls::scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1683 retval = MPI_SUCCESS;
1684 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1691 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1692 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1698 if (comm == MPI_COMM_NULL) {
1699 retval = MPI_ERR_COMM;
1700 } else if (sendcounts == nullptr || displs == nullptr) {
1701 retval = MPI_ERR_ARG;
1702 } else if (((comm->rank() == root) && (sendtype == MPI_DATATYPE_NULL)) ||
1703 ((recvbuf != MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1704 retval = MPI_ERR_TYPE;
1706 if (recvbuf == MPI_IN_PLACE) {
1707 recvtype = sendtype;
1708 recvcount = sendcounts[comm->rank()];
1710 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1711 int root_traced = comm->group()->index(root);
1712 int size = comm->size();
1713 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1714 extra->type = TRACING_SCATTERV;
1715 extra->num_processes = size;
1716 extra->root = root_traced;
1718 extra->datatype1 = encode_datatype(sendtype, &known);
1719 int dt_size_send = 1;
1721 dt_size_send = sendtype->size();
1722 if (comm->rank() == root) {
1723 extra->sendcounts = xbt_new(int, size);
1724 for (int i = 0; i < size; i++) // copy data to avoid bad free
1725 extra->sendcounts[i] = sendcounts[i] * dt_size_send;
1727 extra->datatype2 = encode_datatype(recvtype, &known);
1728 int dt_size_recv = 1;
1730 dt_size_recv = recvtype->size();
1731 extra->recv_size = recvcount * dt_size_recv;
1732 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1734 retval = simgrid::smpi::Colls::scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1736 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1743 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
1749 if (comm == MPI_COMM_NULL) {
1750 retval = MPI_ERR_COMM;
1751 } else if (!datatype->is_valid() || op == MPI_OP_NULL) {
1752 retval = MPI_ERR_ARG;
1754 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1755 int root_traced = comm->group()->index(root);
1756 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1757 extra->type = TRACING_REDUCE;
1759 extra->datatype1 = encode_datatype(datatype, &known);
1760 int dt_size_send = 1;
1762 dt_size_send = datatype->size();
1763 extra->send_size = count * dt_size_send;
1764 extra->root = root_traced;
1766 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1768 simgrid::smpi::Colls::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1770 retval = MPI_SUCCESS;
1771 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1778 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op){
1782 if (!datatype->is_valid() || op == MPI_OP_NULL) {
1783 retval = MPI_ERR_ARG;
1785 op->apply(inbuf, inoutbuf, &count, datatype);
1786 retval = MPI_SUCCESS;
1792 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1798 if (comm == MPI_COMM_NULL) {
1799 retval = MPI_ERR_COMM;
1800 } else if (!datatype->is_valid()) {
1801 retval = MPI_ERR_TYPE;
1802 } else if (op == MPI_OP_NULL) {
1803 retval = MPI_ERR_OP;
1806 char* sendtmpbuf = static_cast<char*>(sendbuf);
1807 if( sendbuf == MPI_IN_PLACE ) {
1808 sendtmpbuf = static_cast<char*>(xbt_malloc(count*datatype->get_extent()));
1809 simgrid::smpi::Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
1811 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1812 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1813 extra->type = TRACING_ALLREDUCE;
1815 extra->datatype1 = encode_datatype(datatype, &known);
1816 int dt_size_send = 1;
1818 dt_size_send = datatype->size();
1819 extra->send_size = count * dt_size_send;
1821 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1823 simgrid::smpi::Colls::allreduce(sendtmpbuf, recvbuf, count, datatype, op, comm);
1825 if( sendbuf == MPI_IN_PLACE )
1826 xbt_free(sendtmpbuf);
1828 retval = MPI_SUCCESS;
1829 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1836 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1842 if (comm == MPI_COMM_NULL) {
1843 retval = MPI_ERR_COMM;
1844 } else if (!datatype->is_valid()) {
1845 retval = MPI_ERR_TYPE;
1846 } else if (op == MPI_OP_NULL) {
1847 retval = MPI_ERR_OP;
1849 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1850 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1851 extra->type = TRACING_SCAN;
1853 extra->datatype1 = encode_datatype(datatype, &known);
1854 int dt_size_send = 1;
1856 dt_size_send = datatype->size();
1857 extra->send_size = count * dt_size_send;
1859 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1861 retval = simgrid::smpi::Colls::scan(sendbuf, recvbuf, count, datatype, op, comm);
1863 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1870 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
1875 if (comm == MPI_COMM_NULL) {
1876 retval = MPI_ERR_COMM;
1877 } else if (!datatype->is_valid()) {
1878 retval = MPI_ERR_TYPE;
1879 } else if (op == MPI_OP_NULL) {
1880 retval = MPI_ERR_OP;
1882 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1883 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1884 extra->type = TRACING_EXSCAN;
1886 extra->datatype1 = encode_datatype(datatype, &known);
1887 int dt_size_send = 1;
1889 dt_size_send = datatype->size();
1890 extra->send_size = count * dt_size_send;
1891 void* sendtmpbuf = sendbuf;
1892 if (sendbuf == MPI_IN_PLACE) {
1893 sendtmpbuf = static_cast<void*>(xbt_malloc(count * datatype->size()));
1894 memcpy(sendtmpbuf, recvbuf, count * datatype->size());
1896 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1898 retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
1900 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1901 if (sendbuf == MPI_IN_PLACE)
1902 xbt_free(sendtmpbuf);
1909 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1914 if (comm == MPI_COMM_NULL) {
1915 retval = MPI_ERR_COMM;
1916 } else if (!datatype->is_valid()) {
1917 retval = MPI_ERR_TYPE;
1918 } else if (op == MPI_OP_NULL) {
1919 retval = MPI_ERR_OP;
1920 } else if (recvcounts == nullptr) {
1921 retval = MPI_ERR_ARG;
1923 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1925 int size = comm->size();
1926 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1927 extra->type = TRACING_REDUCE_SCATTER;
1928 extra->num_processes = size;
1930 extra->datatype1 = encode_datatype(datatype, &known);
1931 int dt_size_send = 1;
1933 dt_size_send = datatype->size();
1934 extra->send_size = 0;
1935 extra->recvcounts = xbt_new(int, size);
1937 for (i = 0; i < size; i++) { // copy data to avoid bad free
1938 extra->recvcounts[i] = recvcounts[i] * dt_size_send;
1939 totalcount += recvcounts[i];
1941 void* sendtmpbuf = sendbuf;
1942 if (sendbuf == MPI_IN_PLACE) {
1943 sendtmpbuf = static_cast<void*>(xbt_malloc(totalcount * datatype->size()));
1944 memcpy(sendtmpbuf, recvbuf, totalcount * datatype->size());
1947 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1949 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1950 retval = MPI_SUCCESS;
1951 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1953 if (sendbuf == MPI_IN_PLACE)
1954 xbt_free(sendtmpbuf);
1961 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
1962 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1967 if (comm == MPI_COMM_NULL) {
1968 retval = MPI_ERR_COMM;
1969 } else if (!datatype->is_valid()) {
1970 retval = MPI_ERR_TYPE;
1971 } else if (op == MPI_OP_NULL) {
1972 retval = MPI_ERR_OP;
1973 } else if (recvcount < 0) {
1974 retval = MPI_ERR_ARG;
1976 int count = comm->size();
1978 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1979 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1980 extra->type = TRACING_REDUCE_SCATTER;
1981 extra->num_processes = count;
1983 extra->datatype1 = encode_datatype(datatype, &known);
1984 int dt_size_send = 1;
1986 dt_size_send = datatype->size();
1987 extra->send_size = 0;
1988 extra->recvcounts = xbt_new(int, count);
1989 for (int i = 0; i < count; i++) // copy data to avoid bad free
1990 extra->recvcounts[i] = recvcount * dt_size_send;
1991 void* sendtmpbuf = sendbuf;
1992 if (sendbuf == MPI_IN_PLACE) {
1993 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * count * datatype->size()));
1994 memcpy(sendtmpbuf, recvbuf, recvcount * count * datatype->size());
1997 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1999 int* recvcounts = static_cast<int*>(xbt_malloc(count * sizeof(int)));
2000 for (int i = 0; i < count; i++)
2001 recvcounts[i] = recvcount;
2002 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
2003 xbt_free(recvcounts);
2004 retval = MPI_SUCCESS;
2006 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2008 if (sendbuf == MPI_IN_PLACE)
2009 xbt_free(sendtmpbuf);
2016 int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
2017 MPI_Datatype recvtype, MPI_Comm comm)
2022 if (comm == MPI_COMM_NULL) {
2023 retval = MPI_ERR_COMM;
2024 } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL) || recvtype == MPI_DATATYPE_NULL) {
2025 retval = MPI_ERR_TYPE;
2027 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2028 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2029 extra->type = TRACING_ALLTOALL;
2031 void* sendtmpbuf = static_cast<char*>(sendbuf);
2032 int sendtmpcount = sendcount;
2033 MPI_Datatype sendtmptype = sendtype;
2034 if (sendbuf == MPI_IN_PLACE) {
2035 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * comm->size() * recvtype->size()));
2036 memcpy(sendtmpbuf, recvbuf, recvcount * comm->size() * recvtype->size());
2037 sendtmpcount = recvcount;
2038 sendtmptype = recvtype;
2042 extra->datatype1 = encode_datatype(sendtmptype, &known);
2044 extra->send_size = sendtmpcount * sendtmptype->size();
2046 extra->send_size = sendtmpcount;
2047 extra->datatype2 = encode_datatype(recvtype, &known);
2049 extra->recv_size = recvcount * recvtype->size();
2051 extra->recv_size = recvcount;
2053 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2055 retval = simgrid::smpi::Colls::alltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
2057 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2059 if (sendbuf == MPI_IN_PLACE)
2060 xbt_free(sendtmpbuf);
2067 int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
2068 int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2074 if (comm == MPI_COMM_NULL) {
2075 retval = MPI_ERR_COMM;
2076 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
2077 retval = MPI_ERR_TYPE;
2078 } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
2079 recvdisps == nullptr) {
2080 retval = MPI_ERR_ARG;
2082 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2084 int size = comm->size();
2085 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2086 extra->type = TRACING_ALLTOALLV;
2087 extra->send_size = 0;
2088 extra->recv_size = 0;
2089 extra->recvcounts = xbt_new(int, size);
2090 extra->sendcounts = xbt_new(int, size);
2092 int dt_size_recv = 1;
2093 extra->datatype2 = encode_datatype(recvtype, &known);
2094 dt_size_recv = recvtype->size();
2096 void* sendtmpbuf = static_cast<char*>(sendbuf);
2097 int* sendtmpcounts = sendcounts;
2098 int* sendtmpdisps = senddisps;
2099 MPI_Datatype sendtmptype = sendtype;
2101 for (i = 0; i < size; i++) { // copy data to avoid bad free
2102 extra->recv_size += recvcounts[i] * dt_size_recv;
2103 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
2104 if (((recvdisps[i] + recvcounts[i]) * dt_size_recv) > maxsize)
2105 maxsize = (recvdisps[i] + recvcounts[i]) * dt_size_recv;
2108 if (sendbuf == MPI_IN_PLACE) {
2109 sendtmpbuf = static_cast<void*>(xbt_malloc(maxsize));
2110 memcpy(sendtmpbuf, recvbuf, maxsize);
2111 sendtmpcounts = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2112 memcpy(sendtmpcounts, recvcounts, size * sizeof(int));
2113 sendtmpdisps = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2114 memcpy(sendtmpdisps, recvdisps, size * sizeof(int));
2115 sendtmptype = recvtype;
2118 extra->datatype1 = encode_datatype(sendtmptype, &known);
2119 int dt_size_send = 1;
2120 dt_size_send = sendtmptype->size();
2122 for (i = 0; i < size; i++) { // copy data to avoid bad free
2123 extra->send_size += sendtmpcounts[i] * dt_size_send;
2124 extra->sendcounts[i] = sendtmpcounts[i] * dt_size_send;
2126 extra->num_processes = size;
2127 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2128 retval = simgrid::smpi::Colls::alltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
2129 recvdisps, recvtype, comm);
2130 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2132 if (sendbuf == MPI_IN_PLACE) {
2133 xbt_free(sendtmpbuf);
2134 xbt_free(sendtmpcounts);
2135 xbt_free(sendtmpdisps);
2144 int PMPI_Get_processor_name(char *name, int *resultlen)
2146 strncpy(name, SIMIX_host_self()->cname(), strlen(SIMIX_host_self()->cname()) < MPI_MAX_PROCESSOR_NAME - 1
2147 ? strlen(SIMIX_host_self()->cname()) + 1
2148 : MPI_MAX_PROCESSOR_NAME - 1);
2149 *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2154 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2156 if (status == nullptr || count == nullptr) {
2158 } else if (!datatype->is_valid()) {
2159 return MPI_ERR_TYPE;
2161 size_t size = datatype->size();
2165 } else if (status->count % size != 0) {
2166 return MPI_UNDEFINED;
2168 *count = simgrid::smpi::Status::get_count(status, datatype);
2174 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2175 if (old_type == MPI_DATATYPE_NULL) {
2176 return MPI_ERR_TYPE;
2177 } else if (count<0){
2178 return MPI_ERR_COUNT;
2180 return simgrid::smpi::Datatype::create_contiguous(count, old_type, 0, new_type);
2184 int PMPI_Type_commit(MPI_Datatype* datatype) {
2185 if (datatype == nullptr || *datatype == MPI_DATATYPE_NULL) {
2186 return MPI_ERR_TYPE;
2188 (*datatype)->commit();
2193 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2194 if (old_type == MPI_DATATYPE_NULL) {
2195 return MPI_ERR_TYPE;
2196 } else if (count<0 || blocklen<0){
2197 return MPI_ERR_COUNT;
2199 return simgrid::smpi::Datatype::create_vector(count, blocklen, stride, old_type, new_type);
2203 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2204 if (old_type == MPI_DATATYPE_NULL) {
2205 return MPI_ERR_TYPE;
2206 } else if (count<0 || blocklen<0){
2207 return MPI_ERR_COUNT;
2209 return simgrid::smpi::Datatype::create_hvector(count, blocklen, stride, old_type, new_type);
2213 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2214 return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2217 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2218 if (old_type == MPI_DATATYPE_NULL) {
2219 return MPI_ERR_TYPE;
2220 } else if (count<0){
2221 return MPI_ERR_COUNT;
2223 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2227 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2228 if (old_type == MPI_DATATYPE_NULL) {
2229 return MPI_ERR_TYPE;
2230 } else if (count<0){
2231 return MPI_ERR_COUNT;
2233 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2237 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type,
2238 MPI_Datatype* new_type)
2240 if (old_type == MPI_DATATYPE_NULL) {
2241 return MPI_ERR_TYPE;
2242 } else if (count<0){
2243 return MPI_ERR_COUNT;
2245 int* blocklens=static_cast<int*>(xbt_malloc(blocklength*count*sizeof(int)));
2246 for (int i = 0; i < count; i++)
2247 blocklens[i]=blocklength;
2248 int retval = simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2249 xbt_free(blocklens);
2254 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
2256 if (old_type == MPI_DATATYPE_NULL) {
2257 return MPI_ERR_TYPE;
2258 } else if (count<0){
2259 return MPI_ERR_COUNT;
2261 return simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2265 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type,
2266 MPI_Datatype* new_type) {
2267 return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2270 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type,
2271 MPI_Datatype* new_type) {
2272 if (old_type == MPI_DATATYPE_NULL) {
2273 return MPI_ERR_TYPE;
2274 } else if (count<0){
2275 return MPI_ERR_COUNT;
2277 int* blocklens=(int*)xbt_malloc(blocklength*count*sizeof(int));
2278 for (int i = 0; i < count; i++)
2279 blocklens[i] = blocklength;
2280 int retval = simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2281 xbt_free(blocklens);
2286 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2288 return MPI_ERR_COUNT;
2290 return simgrid::smpi::Datatype::create_struct(count, blocklens, indices, old_types, new_type);
2294 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types,
2295 MPI_Datatype* new_type) {
2296 return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2299 int PMPI_Error_class(int errorcode, int* errorclass) {
2300 // assume smpi uses only standard mpi error codes
2301 *errorclass=errorcode;
2305 int PMPI_Initialized(int* flag) {
2306 *flag=(smpi_process()!=nullptr && smpi_process()->initialized());
2310 /* The topo part of MPI_COMM_WORLD should always be nullptr. When other topologies will be implemented, not only should we
2311 * check if the topology is nullptr, but we should check if it is the good topology type (so we have to add a
2312 * MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2314 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2315 if (comm_old == MPI_COMM_NULL){
2316 return MPI_ERR_COMM;
2317 } else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
2320 simgrid::smpi::Topo_Cart* topo = new simgrid::smpi::Topo_Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
2321 if(*comm_cart==MPI_COMM_NULL)
2327 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2328 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2329 return MPI_ERR_TOPOLOGY;
2331 if (coords == nullptr) {
2334 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2335 if (topo==nullptr) {
2338 return topo->rank(coords, rank);
2341 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2342 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2343 return MPI_ERR_TOPOLOGY;
2345 if (source == nullptr || dest == nullptr || direction < 0 ) {
2348 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2349 if (topo==nullptr) {
2352 return topo->shift(direction, displ, source, dest);
2355 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2356 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2357 return MPI_ERR_TOPOLOGY;
2359 if (rank < 0 || rank >= comm->size()) {
2360 return MPI_ERR_RANK;
2365 if(coords == nullptr) {
2368 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2369 if (topo==nullptr) {
2372 return topo->coords(rank, maxdims, coords);
2375 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2376 if(comm == nullptr || comm->topo() == nullptr) {
2377 return MPI_ERR_TOPOLOGY;
2379 if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
2382 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2383 if (topo==nullptr) {
2386 return topo->get(maxdims, dims, periods, coords);
2389 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2390 if (comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2391 return MPI_ERR_TOPOLOGY;
2393 if (ndims == nullptr) {
2396 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2397 if (topo==nullptr) {
2400 return topo->dim_get(ndims);
2403 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2404 if(dims == nullptr) {
2407 if (ndims < 1 || nnodes < 1) {
2408 return MPI_ERR_DIMS;
2410 return simgrid::smpi::Topo_Cart::Dims_create(nnodes, ndims, dims);
2413 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2414 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2415 return MPI_ERR_TOPOLOGY;
2417 if (comm_new == nullptr) {
2420 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2421 if (topo==nullptr) {
2424 MPIR_Cart_Topology cart = topo->sub(remain_dims, comm_new);
2425 if(*comm_new==MPI_COMM_NULL)
2432 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2433 if (oldtype == MPI_DATATYPE_NULL) {
2434 return MPI_ERR_TYPE;
2436 int blocks[3] = {1, 1, 1};
2437 MPI_Aint disps[3] = {lb, 0, lb + extent};
2438 MPI_Datatype types[3] = {MPI_LB, oldtype, MPI_UB};
2440 *newtype = new simgrid::smpi::Type_Struct(oldtype->size(), lb, lb + extent, DT_FLAG_DERIVED, 3, blocks, disps, types);
2442 (*newtype)->addflag(~DT_FLAG_COMMITED);
2446 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2449 if (comm == MPI_COMM_NULL) {
2450 retval= MPI_ERR_COMM;
2451 }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
2452 retval= MPI_ERR_OTHER;
2454 *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
2455 retval = MPI_SUCCESS;
2461 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
2464 if (comm == MPI_COMM_NULL) {
2465 retval= MPI_ERR_COMM;
2466 }else if (disp_unit <= 0 || size < 0 ){
2467 retval= MPI_ERR_OTHER;
2469 void* ptr = xbt_malloc(size);
2471 return MPI_ERR_NO_MEM;
2472 *static_cast<void**>(base) = ptr;
2473 *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
2474 retval = MPI_SUCCESS;
2480 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
2483 if (comm == MPI_COMM_NULL) {
2484 retval= MPI_ERR_COMM;
2486 *win = new simgrid::smpi::Win(info, comm);
2487 retval = MPI_SUCCESS;
2493 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
2496 if(win == MPI_WIN_NULL){
2497 retval = MPI_ERR_WIN;
2498 } else if ((base == nullptr && size != 0) || size < 0 ){
2499 retval= MPI_ERR_OTHER;
2501 retval = win->attach(base, size);
2507 int PMPI_Win_detach(MPI_Win win, void *base){
2510 if(win == MPI_WIN_NULL){
2511 retval = MPI_ERR_WIN;
2512 } else if (base == nullptr){
2513 retval= MPI_ERR_OTHER;
2515 retval = win->detach(base);
2522 int PMPI_Win_free( MPI_Win* win){
2525 if (win == nullptr || *win == MPI_WIN_NULL) {
2526 retval = MPI_ERR_WIN;
2535 int PMPI_Win_set_name(MPI_Win win, char * name)
2537 if (win == MPI_WIN_NULL) {
2538 return MPI_ERR_TYPE;
2539 } else if (name == nullptr) {
2542 win->set_name(name);
2547 int PMPI_Win_get_name(MPI_Win win, char * name, int* len)
2549 if (win == MPI_WIN_NULL) {
2551 } else if (name == nullptr) {
2554 win->get_name(name, len);
2559 int PMPI_Win_get_info(MPI_Win win, MPI_Info* info)
2561 if (win == MPI_WIN_NULL) {
2564 *info = win->info();
2569 int PMPI_Win_set_info(MPI_Win win, MPI_Info info)
2571 if (win == MPI_WIN_NULL) {
2572 return MPI_ERR_TYPE;
2574 win->set_info(info);
2579 int PMPI_Win_get_group(MPI_Win win, MPI_Group * group){
2580 if (win == MPI_WIN_NULL) {
2583 win->get_group(group);
2589 int PMPI_Win_fence( int assert, MPI_Win win){
2592 if (win == MPI_WIN_NULL) {
2593 retval = MPI_ERR_WIN;
2595 int rank = smpi_process()->index();
2596 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2597 retval = win->fence(assert);
2598 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2604 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2605 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2608 if (win == MPI_WIN_NULL) {
2609 retval = MPI_ERR_WIN;
2610 } else if (target_rank == MPI_PROC_NULL) {
2611 retval = MPI_SUCCESS;
2612 } else if (target_rank <0){
2613 retval = MPI_ERR_RANK;
2614 } else if (win->dynamic()==0 && target_disp <0){
2615 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2616 retval = MPI_ERR_ARG;
2617 } else if ((origin_count < 0 || target_count < 0) ||
2618 (origin_addr==nullptr && origin_count > 0)){
2619 retval = MPI_ERR_COUNT;
2620 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2621 retval = MPI_ERR_TYPE;
2623 int rank = smpi_process()->index();
2625 win->get_group(&group);
2626 int src_traced = group->index(target_rank);
2627 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2629 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2632 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2638 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2639 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2642 if (win == MPI_WIN_NULL) {
2643 retval = MPI_ERR_WIN;
2644 } else if (target_rank == MPI_PROC_NULL) {
2645 *request = MPI_REQUEST_NULL;
2646 retval = MPI_SUCCESS;
2647 } else if (target_rank <0){
2648 retval = MPI_ERR_RANK;
2649 } else if (win->dynamic()==0 && target_disp <0){
2650 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2651 retval = MPI_ERR_ARG;
2652 } else if ((origin_count < 0 || target_count < 0) ||
2653 (origin_addr==nullptr && origin_count > 0)){
2654 retval = MPI_ERR_COUNT;
2655 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2656 retval = MPI_ERR_TYPE;
2657 } else if(request == nullptr){
2658 retval = MPI_ERR_REQUEST;
2660 int rank = smpi_process()->index();
2662 win->get_group(&group);
2663 int src_traced = group->index(target_rank);
2664 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2666 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2667 target_datatype, request);
2669 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2675 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2676 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2679 if (win == MPI_WIN_NULL) {
2680 retval = MPI_ERR_WIN;
2681 } else if (target_rank == MPI_PROC_NULL) {
2682 retval = MPI_SUCCESS;
2683 } else if (target_rank <0){
2684 retval = MPI_ERR_RANK;
2685 } else if (win->dynamic()==0 && target_disp <0){
2686 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2687 retval = MPI_ERR_ARG;
2688 } else if ((origin_count < 0 || target_count < 0) ||
2689 (origin_addr==nullptr && origin_count > 0)){
2690 retval = MPI_ERR_COUNT;
2691 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2692 retval = MPI_ERR_TYPE;
2694 int rank = smpi_process()->index();
2696 win->get_group(&group);
2697 int dst_traced = group->index(target_rank);
2698 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2699 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2701 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2704 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2710 int PMPI_Rput( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2711 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2714 if (win == MPI_WIN_NULL) {
2715 retval = MPI_ERR_WIN;
2716 } else if (target_rank == MPI_PROC_NULL) {
2717 *request = MPI_REQUEST_NULL;
2718 retval = MPI_SUCCESS;
2719 } else if (target_rank <0){
2720 retval = MPI_ERR_RANK;
2721 } else if (win->dynamic()==0 && target_disp <0){
2722 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2723 retval = MPI_ERR_ARG;
2724 } else if ((origin_count < 0 || target_count < 0) ||
2725 (origin_addr==nullptr && origin_count > 0)){
2726 retval = MPI_ERR_COUNT;
2727 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2728 retval = MPI_ERR_TYPE;
2729 } else if(request == nullptr){
2730 retval = MPI_ERR_REQUEST;
2732 int rank = smpi_process()->index();
2734 win->get_group(&group);
2735 int dst_traced = group->index(target_rank);
2736 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2737 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2739 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2740 target_datatype, request);
2742 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2748 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2749 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2752 if (win == MPI_WIN_NULL) {
2753 retval = MPI_ERR_WIN;
2754 } else if (target_rank == MPI_PROC_NULL) {
2755 retval = MPI_SUCCESS;
2756 } else if (target_rank <0){
2757 retval = MPI_ERR_RANK;
2758 } else if (win->dynamic()==0 && target_disp <0){
2759 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2760 retval = MPI_ERR_ARG;
2761 } else if ((origin_count < 0 || target_count < 0) ||
2762 (origin_addr==nullptr && origin_count > 0)){
2763 retval = MPI_ERR_COUNT;
2764 } else if ((!origin_datatype->is_valid()) ||
2765 (!target_datatype->is_valid())) {
2766 retval = MPI_ERR_TYPE;
2767 } else if (op == MPI_OP_NULL) {
2768 retval = MPI_ERR_OP;
2770 int rank = smpi_process()->index();
2772 win->get_group(&group);
2773 int src_traced = group->index(target_rank);
2774 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2776 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2777 target_datatype, op);
2779 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2785 int PMPI_Raccumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2786 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2789 if (win == MPI_WIN_NULL) {
2790 retval = MPI_ERR_WIN;
2791 } else if (target_rank == MPI_PROC_NULL) {
2792 *request = MPI_REQUEST_NULL;
2793 retval = MPI_SUCCESS;
2794 } else if (target_rank <0){
2795 retval = MPI_ERR_RANK;
2796 } else if (win->dynamic()==0 && target_disp <0){
2797 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2798 retval = MPI_ERR_ARG;
2799 } else if ((origin_count < 0 || target_count < 0) ||
2800 (origin_addr==nullptr && origin_count > 0)){
2801 retval = MPI_ERR_COUNT;
2802 } else if ((!origin_datatype->is_valid()) ||
2803 (!target_datatype->is_valid())) {
2804 retval = MPI_ERR_TYPE;
2805 } else if (op == MPI_OP_NULL) {
2806 retval = MPI_ERR_OP;
2807 } else if(request == nullptr){
2808 retval = MPI_ERR_REQUEST;
2810 int rank = smpi_process()->index();
2812 win->get_group(&group);
2813 int src_traced = group->index(target_rank);
2814 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2816 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2817 target_datatype, op, request);
2819 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2825 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2826 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2827 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2830 if (win == MPI_WIN_NULL) {
2831 retval = MPI_ERR_WIN;
2832 } else if (target_rank == MPI_PROC_NULL) {
2833 retval = MPI_SUCCESS;
2834 } else if (target_rank <0){
2835 retval = MPI_ERR_RANK;
2836 } else if (win->dynamic()==0 && target_disp <0){
2837 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2838 retval = MPI_ERR_ARG;
2839 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2840 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2841 (result_addr==nullptr && result_count > 0)){
2842 retval = MPI_ERR_COUNT;
2843 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2844 (!target_datatype->is_valid())||
2845 (!result_datatype->is_valid())) {
2846 retval = MPI_ERR_TYPE;
2847 } else if (op == MPI_OP_NULL) {
2848 retval = MPI_ERR_OP;
2850 int rank = smpi_process()->index();
2852 win->get_group(&group);
2853 int src_traced = group->index(target_rank);
2854 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2856 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2857 result_count, result_datatype, target_rank, target_disp,
2858 target_count, target_datatype, op);
2860 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2867 int PMPI_Rget_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2868 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2869 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2872 if (win == MPI_WIN_NULL) {
2873 retval = MPI_ERR_WIN;
2874 } else if (target_rank == MPI_PROC_NULL) {
2875 *request = MPI_REQUEST_NULL;
2876 retval = MPI_SUCCESS;
2877 } else if (target_rank <0){
2878 retval = MPI_ERR_RANK;
2879 } else if (win->dynamic()==0 && target_disp <0){
2880 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2881 retval = MPI_ERR_ARG;
2882 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2883 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2884 (result_addr==nullptr && result_count > 0)){
2885 retval = MPI_ERR_COUNT;
2886 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2887 (!target_datatype->is_valid())||
2888 (!result_datatype->is_valid())) {
2889 retval = MPI_ERR_TYPE;
2890 } else if (op == MPI_OP_NULL) {
2891 retval = MPI_ERR_OP;
2892 } else if(request == nullptr){
2893 retval = MPI_ERR_REQUEST;
2895 int rank = smpi_process()->index();
2897 win->get_group(&group);
2898 int src_traced = group->index(target_rank);
2899 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2901 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2902 result_count, result_datatype, target_rank, target_disp,
2903 target_count, target_datatype, op, request);
2905 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2911 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){
2912 return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
2915 int PMPI_Compare_and_swap(void *origin_addr, void *compare_addr,
2916 void *result_addr, MPI_Datatype datatype, int target_rank,
2917 MPI_Aint target_disp, MPI_Win win){
2920 if (win == MPI_WIN_NULL) {
2921 retval = MPI_ERR_WIN;
2922 } else if (target_rank == MPI_PROC_NULL) {
2923 retval = MPI_SUCCESS;
2924 } else if (target_rank <0){
2925 retval = MPI_ERR_RANK;
2926 } else if (win->dynamic()==0 && target_disp <0){
2927 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2928 retval = MPI_ERR_ARG;
2929 } else if (origin_addr==nullptr || result_addr==nullptr || compare_addr==nullptr){
2930 retval = MPI_ERR_COUNT;
2931 } else if (!datatype->is_valid()) {
2932 retval = MPI_ERR_TYPE;
2934 int rank = smpi_process()->index();
2936 win->get_group(&group);
2937 int src_traced = group->index(target_rank);
2938 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2940 retval = win->compare_and_swap( origin_addr, compare_addr, result_addr, datatype,
2941 target_rank, target_disp);
2943 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2949 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2952 if (win == MPI_WIN_NULL) {
2953 retval = MPI_ERR_WIN;
2954 } else if (group==MPI_GROUP_NULL){
2955 retval = MPI_ERR_GROUP;
2957 int rank = smpi_process()->index();
2958 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2959 retval = win->post(group,assert);
2960 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2966 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2969 if (win == MPI_WIN_NULL) {
2970 retval = MPI_ERR_WIN;
2971 } else if (group==MPI_GROUP_NULL){
2972 retval = MPI_ERR_GROUP;
2974 int rank = smpi_process()->index();
2975 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2976 retval = win->start(group,assert);
2977 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2983 int PMPI_Win_complete(MPI_Win win){
2986 if (win == MPI_WIN_NULL) {
2987 retval = MPI_ERR_WIN;
2989 int rank = smpi_process()->index();
2990 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2992 retval = win->complete();
2994 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3000 int PMPI_Win_wait(MPI_Win win){
3003 if (win == MPI_WIN_NULL) {
3004 retval = MPI_ERR_WIN;
3006 int rank = smpi_process()->index();
3007 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
3009 retval = win->wait();
3011 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3017 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
3020 if (win == MPI_WIN_NULL) {
3021 retval = MPI_ERR_WIN;
3022 } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
3023 lock_type != MPI_LOCK_SHARED) {
3024 retval = MPI_ERR_LOCKTYPE;
3025 } else if (rank == MPI_PROC_NULL){
3026 retval = MPI_SUCCESS;
3028 int myrank = smpi_process()->index();
3029 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3030 retval = win->lock(lock_type,rank,assert);
3031 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3037 int PMPI_Win_unlock(int rank, MPI_Win win){
3040 if (win == MPI_WIN_NULL) {
3041 retval = MPI_ERR_WIN;
3042 } else if (rank == MPI_PROC_NULL){
3043 retval = MPI_SUCCESS;
3045 int myrank = smpi_process()->index();
3046 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3047 retval = win->unlock(rank);
3048 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3054 int PMPI_Win_lock_all(int assert, MPI_Win win){
3057 if (win == MPI_WIN_NULL) {
3058 retval = MPI_ERR_WIN;
3060 int myrank = smpi_process()->index();
3061 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3062 retval = win->lock_all(assert);
3063 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3069 int PMPI_Win_unlock_all(MPI_Win win){
3072 if (win == MPI_WIN_NULL) {
3073 retval = MPI_ERR_WIN;
3075 int myrank = smpi_process()->index();
3076 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3077 retval = win->unlock_all();
3078 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3084 int PMPI_Win_flush(int rank, MPI_Win win){
3087 if (win == MPI_WIN_NULL) {
3088 retval = MPI_ERR_WIN;
3089 } else if (rank == MPI_PROC_NULL){
3090 retval = MPI_SUCCESS;
3092 int myrank = smpi_process()->index();
3093 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3094 retval = win->flush(rank);
3095 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3101 int PMPI_Win_flush_local(int rank, MPI_Win win){
3104 if (win == MPI_WIN_NULL) {
3105 retval = MPI_ERR_WIN;
3106 } else if (rank == MPI_PROC_NULL){
3107 retval = MPI_SUCCESS;
3109 int myrank = smpi_process()->index();
3110 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3111 retval = win->flush_local(rank);
3112 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3118 int PMPI_Win_flush_all(MPI_Win win){
3121 if (win == MPI_WIN_NULL) {
3122 retval = MPI_ERR_WIN;
3124 int myrank = smpi_process()->index();
3125 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3126 retval = win->flush_all();
3127 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3133 int PMPI_Win_flush_local_all(MPI_Win win){
3136 if (win == MPI_WIN_NULL) {
3137 retval = MPI_ERR_WIN;
3139 int myrank = smpi_process()->index();
3140 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3141 retval = win->flush_local_all();
3142 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3148 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
3149 void *ptr = xbt_malloc(size);
3151 return MPI_ERR_NO_MEM;
3153 *static_cast<void**>(baseptr) = ptr;
3158 int PMPI_Free_mem(void *baseptr){
3163 int PMPI_Type_set_name(MPI_Datatype datatype, char * name)
3165 if (datatype == MPI_DATATYPE_NULL) {
3166 return MPI_ERR_TYPE;
3167 } else if (name == nullptr) {
3170 datatype->set_name(name);
3175 int PMPI_Type_get_name(MPI_Datatype datatype, char * name, int* len)
3177 if (datatype == MPI_DATATYPE_NULL) {
3178 return MPI_ERR_TYPE;
3179 } else if (name == nullptr) {
3182 datatype->get_name(name, len);
3187 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
3188 return static_cast<MPI_Datatype>(simgrid::smpi::F2C::f2c(datatype));
3191 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
3192 return datatype->c2f();
3195 MPI_Group PMPI_Group_f2c(MPI_Fint group){
3196 return simgrid::smpi::Group::f2c(group);
3199 MPI_Fint PMPI_Group_c2f(MPI_Group group){
3200 return group->c2f();
3203 MPI_Request PMPI_Request_f2c(MPI_Fint request){
3204 return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
3207 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
3208 return request->c2f();
3211 MPI_Win PMPI_Win_f2c(MPI_Fint win){
3212 return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
3215 MPI_Fint PMPI_Win_c2f(MPI_Win win){
3219 MPI_Op PMPI_Op_f2c(MPI_Fint op){
3220 return static_cast<MPI_Op>(simgrid::smpi::Op::f2c(op));
3223 MPI_Fint PMPI_Op_c2f(MPI_Op op){
3227 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
3228 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
3231 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
3235 MPI_Info PMPI_Info_f2c(MPI_Fint info){
3236 return static_cast<MPI_Info>(simgrid::smpi::Info::f2c(info));
3239 MPI_Fint PMPI_Info_c2f(MPI_Info info){
3243 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3244 smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr};
3245 smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr};
3246 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
3249 int PMPI_Keyval_free(int* keyval) {
3250 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Comm>(keyval);
3253 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3254 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3255 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3257 else if (comm==MPI_COMM_NULL)
3258 return MPI_ERR_COMM;
3260 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
3263 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3265 static int zero = 0;
3266 static int tag_ub = INT_MAX;
3267 static int last_used_code = MPI_ERR_LASTCODE;
3269 if (comm==MPI_COMM_NULL){
3271 return MPI_ERR_COMM;
3279 *static_cast<int**>(attr_value) = &zero;
3281 case MPI_UNIVERSE_SIZE:
3283 *static_cast<int**>(attr_value) = &smpi_universe_size;
3285 case MPI_LASTUSEDCODE:
3287 *static_cast<int**>(attr_value) = &last_used_code;
3291 *static_cast<int**>(attr_value) = &tag_ub;
3293 case MPI_WTIME_IS_GLOBAL:
3295 *static_cast<int**>(attr_value) = &one;
3298 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
3302 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3303 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3304 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3306 else if (comm==MPI_COMM_NULL)
3307 return MPI_ERR_COMM;
3309 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
3312 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3314 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3317 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3319 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3322 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3324 return PMPI_Attr_delete(comm, comm_keyval);
3327 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
3330 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3333 int PMPI_Comm_free_keyval(int* keyval) {
3334 return PMPI_Keyval_free(keyval);
3337 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3339 if (type==MPI_DATATYPE_NULL)
3340 return MPI_ERR_TYPE;
3342 return type->attr_get<simgrid::smpi::Datatype>(type_keyval, attribute_val, flag);
3345 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3347 if (type==MPI_DATATYPE_NULL)
3348 return MPI_ERR_TYPE;
3350 return type->attr_put<simgrid::smpi::Datatype>(type_keyval, attribute_val);
3353 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3355 if (type==MPI_DATATYPE_NULL)
3356 return MPI_ERR_TYPE;
3358 return type->attr_delete<simgrid::smpi::Datatype>(type_keyval);
3361 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
3364 smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr};
3365 smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr};
3366 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
3369 int PMPI_Type_free_keyval(int* keyval) {
3370 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Datatype>(keyval);
3373 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
3375 static MPI_Aint size;
3376 static int disp_unit;
3377 if (win==MPI_WIN_NULL)
3378 return MPI_ERR_TYPE;
3382 *static_cast<void**>(attribute_val) = win->base();
3387 *static_cast<MPI_Aint**>(attribute_val) = &size;
3390 case MPI_WIN_DISP_UNIT :
3391 disp_unit=win->disp_unit();
3392 *static_cast<int**>(attribute_val) = &disp_unit;
3396 return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
3402 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
3404 if (win==MPI_WIN_NULL)
3405 return MPI_ERR_TYPE;
3407 return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
3410 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
3412 if (win==MPI_WIN_NULL)
3413 return MPI_ERR_TYPE;
3415 return win->attr_delete<simgrid::smpi::Win>(type_keyval);
3418 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
3421 smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
3422 smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
3423 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
3426 int PMPI_Win_free_keyval(int* keyval) {
3427 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
3430 int PMPI_Info_create( MPI_Info *info){
3431 if (info == nullptr)
3433 *info = new simgrid::smpi::Info();
3437 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3438 if (info == nullptr || key == nullptr || value == nullptr)
3440 info->set(key, value);
3444 int PMPI_Info_free( MPI_Info *info){
3445 if (info == nullptr || *info==nullptr)
3447 simgrid::smpi::Info::unref(*info);
3448 *info=MPI_INFO_NULL;
3452 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3454 if (info == nullptr || key == nullptr || valuelen <0)
3456 if (value == nullptr)
3457 return MPI_ERR_INFO_VALUE;
3458 return info->get(key, valuelen, value, flag);
3461 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3462 if (info == nullptr || newinfo==nullptr)
3464 *newinfo = new simgrid::smpi::Info(info);
3468 int PMPI_Info_delete(MPI_Info info, char *key){
3469 if (info == nullptr || key==nullptr)
3471 return info->remove(key);
3474 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3475 if (info == nullptr || nkeys==nullptr)
3477 return info->get_nkeys(nkeys);
3480 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3481 if (info == nullptr || key==nullptr || n<0 || n> MPI_MAX_INFO_KEY)
3483 return info->get_nthkey(n, key);
3486 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3488 if (info == nullptr || key == nullptr || valuelen==nullptr)
3490 return info->get_valuelen(key, valuelen, flag);
3493 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3494 if(incount<0 || outcount < 0 || inbuf==nullptr || outbuf==nullptr)
3496 if(!type->is_valid())
3497 return MPI_ERR_TYPE;
3498 if(comm==MPI_COMM_NULL)
3499 return MPI_ERR_COMM;
3500 return type->unpack(inbuf, incount, position, outbuf,outcount, comm);
3503 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3504 if(incount<0 || outcount < 0|| inbuf==nullptr || outbuf==nullptr)
3506 if(!type->is_valid())
3507 return MPI_ERR_TYPE;
3508 if(comm==MPI_COMM_NULL)
3509 return MPI_ERR_COMM;
3510 return type->pack(inbuf, incount, outbuf,outcount,position, comm);
3513 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3516 if(!datatype->is_valid())
3517 return MPI_ERR_TYPE;
3518 if(comm==MPI_COMM_NULL)
3519 return MPI_ERR_COMM;
3521 *size=incount*datatype->size();