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-2015",
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);
1515 int size = comm->size();
1516 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1517 extra->type = TRACING_GATHERV;
1518 extra->num_processes = size;
1519 extra->root = root_traced;
1521 extra->datatype1 = encode_datatype(sendtmptype, &known);
1522 int dt_size_send = 1;
1524 dt_size_send = sendtype->size();
1525 extra->send_size = sendtmpcount * dt_size_send;
1526 extra->datatype2 = encode_datatype(recvtype, &known);
1527 int dt_size_recv = 1;
1529 dt_size_recv = recvtype->size();
1530 if ((comm->rank() == root)) {
1531 extra->recvcounts = xbt_new(int, size);
1532 for (i = 0; i < size; i++) // copy data to avoid bad free
1533 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1535 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1537 retval = simgrid::smpi::Colls::gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
1538 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1545 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1546 void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
1552 if (comm == MPI_COMM_NULL) {
1553 retval = MPI_ERR_COMM;
1554 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1555 (recvtype == MPI_DATATYPE_NULL)){
1556 retval = MPI_ERR_TYPE;
1557 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1559 retval = MPI_ERR_COUNT;
1561 if(sendbuf == MPI_IN_PLACE) {
1562 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*recvcount*comm->rank();
1563 sendcount=recvcount;
1566 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1567 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1568 extra->type = TRACING_ALLGATHER;
1570 extra->datatype1 = encode_datatype(sendtype, &known);
1571 int dt_size_send = 1;
1573 dt_size_send = sendtype->size();
1574 extra->send_size = sendcount * dt_size_send;
1575 extra->datatype2 = encode_datatype(recvtype, &known);
1576 int dt_size_recv = 1;
1578 dt_size_recv = recvtype->size();
1579 extra->recv_size = recvcount * dt_size_recv;
1581 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1583 simgrid::smpi::Colls::allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1584 retval = MPI_SUCCESS;
1585 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1591 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1592 void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
1598 if (comm == MPI_COMM_NULL) {
1599 retval = MPI_ERR_COMM;
1600 } else if (((sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) || (recvtype == MPI_DATATYPE_NULL)) {
1601 retval = MPI_ERR_TYPE;
1602 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1603 retval = MPI_ERR_COUNT;
1604 } else if (recvcounts == nullptr || displs == nullptr) {
1605 retval = MPI_ERR_ARG;
1608 if(sendbuf == MPI_IN_PLACE) {
1609 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*displs[comm->rank()];
1610 sendcount=recvcounts[comm->rank()];
1613 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1615 int size = comm->size();
1616 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1617 extra->type = TRACING_ALLGATHERV;
1618 extra->num_processes = size;
1620 extra->datatype1 = encode_datatype(sendtype, &known);
1621 int dt_size_send = 1;
1623 dt_size_send = sendtype->size();
1624 extra->send_size = sendcount * dt_size_send;
1625 extra->datatype2 = encode_datatype(recvtype, &known);
1626 int dt_size_recv = 1;
1628 dt_size_recv = recvtype->size();
1629 extra->recvcounts = xbt_new(int, size);
1630 for (i = 0; i < size; i++) // copy data to avoid bad free
1631 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1633 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1635 simgrid::smpi::Colls::allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1636 retval = MPI_SUCCESS;
1637 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1644 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1645 void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1651 if (comm == MPI_COMM_NULL) {
1652 retval = MPI_ERR_COMM;
1653 } else if (((comm->rank() == root) && (!sendtype->is_valid())) ||
1654 ((recvbuf != MPI_IN_PLACE) && (!recvtype->is_valid()))) {
1655 retval = MPI_ERR_TYPE;
1656 } else if ((sendbuf == recvbuf) ||
1657 ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
1658 retval = MPI_ERR_BUFFER;
1661 if (recvbuf == MPI_IN_PLACE) {
1662 recvtype = sendtype;
1663 recvcount = sendcount;
1665 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1666 int root_traced = comm->group()->index(root);
1667 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1668 extra->type = TRACING_SCATTER;
1669 extra->root = root_traced;
1671 extra->datatype1 = encode_datatype(sendtype, &known);
1672 int dt_size_send = 1;
1673 if ((comm->rank() == root) && known == 0)
1674 dt_size_send = sendtype->size();
1675 extra->send_size = sendcount * dt_size_send;
1676 extra->datatype2 = encode_datatype(recvtype, &known);
1677 int dt_size_recv = 1;
1679 dt_size_recv = recvtype->size();
1680 extra->recv_size = recvcount * dt_size_recv;
1681 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1683 simgrid::smpi::Colls::scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1684 retval = MPI_SUCCESS;
1685 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1692 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1693 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1699 if (comm == MPI_COMM_NULL) {
1700 retval = MPI_ERR_COMM;
1701 } else if (sendcounts == nullptr || displs == nullptr) {
1702 retval = MPI_ERR_ARG;
1703 } else if (((comm->rank() == root) && (sendtype == MPI_DATATYPE_NULL)) ||
1704 ((recvbuf != MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1705 retval = MPI_ERR_TYPE;
1707 if (recvbuf == MPI_IN_PLACE) {
1708 recvtype = sendtype;
1709 recvcount = sendcounts[comm->rank()];
1711 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1712 int root_traced = comm->group()->index(root);
1714 int size = comm->size();
1715 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1716 extra->type = TRACING_SCATTERV;
1717 extra->num_processes = size;
1718 extra->root = root_traced;
1720 extra->datatype1 = encode_datatype(sendtype, &known);
1721 int dt_size_send = 1;
1723 dt_size_send = sendtype->size();
1724 if ((comm->rank() == root)) {
1725 extra->sendcounts = xbt_new(int, size);
1726 for (i = 0; i < size; i++) // copy data to avoid bad free
1727 extra->sendcounts[i] = sendcounts[i] * dt_size_send;
1729 extra->datatype2 = encode_datatype(recvtype, &known);
1730 int dt_size_recv = 1;
1732 dt_size_recv = recvtype->size();
1733 extra->recv_size = recvcount * dt_size_recv;
1734 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1736 retval = simgrid::smpi::Colls::scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1738 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1745 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
1751 if (comm == MPI_COMM_NULL) {
1752 retval = MPI_ERR_COMM;
1753 } else if (!datatype->is_valid() || op == MPI_OP_NULL) {
1754 retval = MPI_ERR_ARG;
1756 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1757 int root_traced = comm->group()->index(root);
1758 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1759 extra->type = TRACING_REDUCE;
1761 extra->datatype1 = encode_datatype(datatype, &known);
1762 int dt_size_send = 1;
1764 dt_size_send = datatype->size();
1765 extra->send_size = count * dt_size_send;
1766 extra->root = root_traced;
1768 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1770 simgrid::smpi::Colls::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1772 retval = MPI_SUCCESS;
1773 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1780 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op){
1784 if (!datatype->is_valid() || op == MPI_OP_NULL) {
1785 retval = MPI_ERR_ARG;
1787 op->apply(inbuf, inoutbuf, &count, datatype);
1788 retval = MPI_SUCCESS;
1794 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1800 if (comm == MPI_COMM_NULL) {
1801 retval = MPI_ERR_COMM;
1802 } else if (!datatype->is_valid()) {
1803 retval = MPI_ERR_TYPE;
1804 } else if (op == MPI_OP_NULL) {
1805 retval = MPI_ERR_OP;
1808 char* sendtmpbuf = static_cast<char*>(sendbuf);
1809 if( sendbuf == MPI_IN_PLACE ) {
1810 sendtmpbuf = static_cast<char*>(xbt_malloc(count*datatype->get_extent()));
1811 simgrid::smpi::Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
1813 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1814 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1815 extra->type = TRACING_ALLREDUCE;
1817 extra->datatype1 = encode_datatype(datatype, &known);
1818 int dt_size_send = 1;
1820 dt_size_send = datatype->size();
1821 extra->send_size = count * dt_size_send;
1823 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1825 simgrid::smpi::Colls::allreduce(sendtmpbuf, recvbuf, count, datatype, op, comm);
1827 if( sendbuf == MPI_IN_PLACE )
1828 xbt_free(sendtmpbuf);
1830 retval = MPI_SUCCESS;
1831 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1838 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1844 if (comm == MPI_COMM_NULL) {
1845 retval = MPI_ERR_COMM;
1846 } else if (!datatype->is_valid()) {
1847 retval = MPI_ERR_TYPE;
1848 } else if (op == MPI_OP_NULL) {
1849 retval = MPI_ERR_OP;
1851 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1852 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1853 extra->type = TRACING_SCAN;
1855 extra->datatype1 = encode_datatype(datatype, &known);
1856 int dt_size_send = 1;
1858 dt_size_send = datatype->size();
1859 extra->send_size = count * dt_size_send;
1861 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1863 retval = simgrid::smpi::Colls::scan(sendbuf, recvbuf, count, datatype, op, comm);
1865 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1872 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
1877 if (comm == MPI_COMM_NULL) {
1878 retval = MPI_ERR_COMM;
1879 } else if (!datatype->is_valid()) {
1880 retval = MPI_ERR_TYPE;
1881 } else if (op == MPI_OP_NULL) {
1882 retval = MPI_ERR_OP;
1884 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1885 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1886 extra->type = TRACING_EXSCAN;
1888 extra->datatype1 = encode_datatype(datatype, &known);
1889 int dt_size_send = 1;
1891 dt_size_send = datatype->size();
1892 extra->send_size = count * dt_size_send;
1893 void* sendtmpbuf = sendbuf;
1894 if (sendbuf == MPI_IN_PLACE) {
1895 sendtmpbuf = static_cast<void*>(xbt_malloc(count * datatype->size()));
1896 memcpy(sendtmpbuf, recvbuf, count * datatype->size());
1898 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1900 retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
1902 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1903 if (sendbuf == MPI_IN_PLACE)
1904 xbt_free(sendtmpbuf);
1911 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1916 if (comm == MPI_COMM_NULL) {
1917 retval = MPI_ERR_COMM;
1918 } else if (!datatype->is_valid()) {
1919 retval = MPI_ERR_TYPE;
1920 } else if (op == MPI_OP_NULL) {
1921 retval = MPI_ERR_OP;
1922 } else if (recvcounts == nullptr) {
1923 retval = MPI_ERR_ARG;
1925 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1927 int size = comm->size();
1928 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1929 extra->type = TRACING_REDUCE_SCATTER;
1930 extra->num_processes = size;
1932 extra->datatype1 = encode_datatype(datatype, &known);
1933 int dt_size_send = 1;
1935 dt_size_send = datatype->size();
1936 extra->send_size = 0;
1937 extra->recvcounts = xbt_new(int, size);
1939 for (i = 0; i < size; i++) { // copy data to avoid bad free
1940 extra->recvcounts[i] = recvcounts[i] * dt_size_send;
1941 totalcount += recvcounts[i];
1943 void* sendtmpbuf = sendbuf;
1944 if (sendbuf == MPI_IN_PLACE) {
1945 sendtmpbuf = static_cast<void*>(xbt_malloc(totalcount * datatype->size()));
1946 memcpy(sendtmpbuf, recvbuf, totalcount * datatype->size());
1949 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1951 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1952 retval = MPI_SUCCESS;
1953 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1955 if (sendbuf == MPI_IN_PLACE)
1956 xbt_free(sendtmpbuf);
1963 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
1964 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1969 if (comm == MPI_COMM_NULL) {
1970 retval = MPI_ERR_COMM;
1971 } else if (!datatype->is_valid()) {
1972 retval = MPI_ERR_TYPE;
1973 } else if (op == MPI_OP_NULL) {
1974 retval = MPI_ERR_OP;
1975 } else if (recvcount < 0) {
1976 retval = MPI_ERR_ARG;
1978 int count = comm->size();
1980 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1981 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1982 extra->type = TRACING_REDUCE_SCATTER;
1983 extra->num_processes = count;
1985 extra->datatype1 = encode_datatype(datatype, &known);
1986 int dt_size_send = 1;
1988 dt_size_send = datatype->size();
1989 extra->send_size = 0;
1990 extra->recvcounts = xbt_new(int, count);
1991 for (int i = 0; i < count; i++) // copy data to avoid bad free
1992 extra->recvcounts[i] = recvcount * dt_size_send;
1993 void* sendtmpbuf = sendbuf;
1994 if (sendbuf == MPI_IN_PLACE) {
1995 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * count * datatype->size()));
1996 memcpy(sendtmpbuf, recvbuf, recvcount * count * datatype->size());
1999 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2001 int* recvcounts = static_cast<int*>(xbt_malloc(count * sizeof(int)));
2002 for (int i = 0; i < count; i++)
2003 recvcounts[i] = recvcount;
2004 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
2005 xbt_free(recvcounts);
2006 retval = MPI_SUCCESS;
2008 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2010 if (sendbuf == MPI_IN_PLACE)
2011 xbt_free(sendtmpbuf);
2018 int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
2019 MPI_Datatype recvtype, MPI_Comm comm)
2024 if (comm == MPI_COMM_NULL) {
2025 retval = MPI_ERR_COMM;
2026 } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL) || recvtype == MPI_DATATYPE_NULL) {
2027 retval = MPI_ERR_TYPE;
2029 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2030 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2031 extra->type = TRACING_ALLTOALL;
2033 void* sendtmpbuf = static_cast<char*>(sendbuf);
2034 int sendtmpcount = sendcount;
2035 MPI_Datatype sendtmptype = sendtype;
2036 if (sendbuf == MPI_IN_PLACE) {
2037 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * comm->size() * recvtype->size()));
2038 memcpy(sendtmpbuf, recvbuf, recvcount * comm->size() * recvtype->size());
2039 sendtmpcount = recvcount;
2040 sendtmptype = recvtype;
2044 extra->datatype1 = encode_datatype(sendtmptype, &known);
2046 extra->send_size = sendtmpcount * sendtmptype->size();
2048 extra->send_size = sendtmpcount;
2049 extra->datatype2 = encode_datatype(recvtype, &known);
2051 extra->recv_size = recvcount * recvtype->size();
2053 extra->recv_size = recvcount;
2055 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2057 retval = simgrid::smpi::Colls::alltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
2059 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2061 if (sendbuf == MPI_IN_PLACE)
2062 xbt_free(sendtmpbuf);
2069 int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
2070 int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2076 if (comm == MPI_COMM_NULL) {
2077 retval = MPI_ERR_COMM;
2078 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
2079 retval = MPI_ERR_TYPE;
2080 } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
2081 recvdisps == nullptr) {
2082 retval = MPI_ERR_ARG;
2084 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2086 int size = comm->size();
2087 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2088 extra->type = TRACING_ALLTOALLV;
2089 extra->send_size = 0;
2090 extra->recv_size = 0;
2091 extra->recvcounts = xbt_new(int, size);
2092 extra->sendcounts = xbt_new(int, size);
2094 int dt_size_recv = 1;
2095 extra->datatype2 = encode_datatype(recvtype, &known);
2096 dt_size_recv = recvtype->size();
2098 void* sendtmpbuf = static_cast<char*>(sendbuf);
2099 int* sendtmpcounts = sendcounts;
2100 int* sendtmpdisps = senddisps;
2101 MPI_Datatype sendtmptype = sendtype;
2103 for (i = 0; i < size; i++) { // copy data to avoid bad free
2104 extra->recv_size += recvcounts[i] * dt_size_recv;
2105 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
2106 if (((recvdisps[i] + recvcounts[i]) * dt_size_recv) > maxsize)
2107 maxsize = (recvdisps[i] + recvcounts[i]) * dt_size_recv;
2110 if (sendbuf == MPI_IN_PLACE) {
2111 sendtmpbuf = static_cast<void*>(xbt_malloc(maxsize));
2112 memcpy(sendtmpbuf, recvbuf, maxsize);
2113 sendtmpcounts = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2114 memcpy(sendtmpcounts, recvcounts, size * sizeof(int));
2115 sendtmpdisps = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2116 memcpy(sendtmpdisps, recvdisps, size * sizeof(int));
2117 sendtmptype = recvtype;
2120 extra->datatype1 = encode_datatype(sendtmptype, &known);
2121 int dt_size_send = 1;
2122 dt_size_send = sendtmptype->size();
2124 for (i = 0; i < size; i++) { // copy data to avoid bad free
2125 extra->send_size += sendtmpcounts[i] * dt_size_send;
2126 extra->sendcounts[i] = sendtmpcounts[i] * dt_size_send;
2128 extra->num_processes = size;
2129 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2130 retval = simgrid::smpi::Colls::alltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
2131 recvdisps, recvtype, comm);
2132 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2134 if (sendbuf == MPI_IN_PLACE) {
2135 xbt_free(sendtmpbuf);
2136 xbt_free(sendtmpcounts);
2137 xbt_free(sendtmpdisps);
2146 int PMPI_Get_processor_name(char *name, int *resultlen)
2148 strncpy(name, SIMIX_host_self()->cname(), strlen(SIMIX_host_self()->cname()) < MPI_MAX_PROCESSOR_NAME - 1
2149 ? strlen(SIMIX_host_self()->cname()) + 1
2150 : MPI_MAX_PROCESSOR_NAME - 1);
2151 *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2156 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2158 if (status == nullptr || count == nullptr) {
2160 } else if (!datatype->is_valid()) {
2161 return MPI_ERR_TYPE;
2163 size_t size = datatype->size();
2167 } else if (status->count % size != 0) {
2168 return MPI_UNDEFINED;
2170 *count = simgrid::smpi::Status::get_count(status, datatype);
2176 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2177 if (old_type == MPI_DATATYPE_NULL) {
2178 return MPI_ERR_TYPE;
2179 } else if (count<0){
2180 return MPI_ERR_COUNT;
2182 return simgrid::smpi::Datatype::create_contiguous(count, old_type, 0, new_type);
2186 int PMPI_Type_commit(MPI_Datatype* datatype) {
2187 if (datatype == nullptr || *datatype == MPI_DATATYPE_NULL) {
2188 return MPI_ERR_TYPE;
2190 (*datatype)->commit();
2195 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2196 if (old_type == MPI_DATATYPE_NULL) {
2197 return MPI_ERR_TYPE;
2198 } else if (count<0 || blocklen<0){
2199 return MPI_ERR_COUNT;
2201 return simgrid::smpi::Datatype::create_vector(count, blocklen, stride, old_type, new_type);
2205 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2206 if (old_type == MPI_DATATYPE_NULL) {
2207 return MPI_ERR_TYPE;
2208 } else if (count<0 || blocklen<0){
2209 return MPI_ERR_COUNT;
2211 return simgrid::smpi::Datatype::create_hvector(count, blocklen, stride, old_type, new_type);
2215 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2216 return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2219 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2220 if (old_type == MPI_DATATYPE_NULL) {
2221 return MPI_ERR_TYPE;
2222 } else if (count<0){
2223 return MPI_ERR_COUNT;
2225 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2229 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2230 if (old_type == MPI_DATATYPE_NULL) {
2231 return MPI_ERR_TYPE;
2232 } else if (count<0){
2233 return MPI_ERR_COUNT;
2235 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2239 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type,
2240 MPI_Datatype* new_type)
2242 if (old_type == MPI_DATATYPE_NULL) {
2243 return MPI_ERR_TYPE;
2244 } else if (count<0){
2245 return MPI_ERR_COUNT;
2247 int* blocklens=static_cast<int*>(xbt_malloc(blocklength*count*sizeof(int)));
2248 for (int i = 0; i < count; i++)
2249 blocklens[i]=blocklength;
2250 int retval = simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2251 xbt_free(blocklens);
2256 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
2258 if (old_type == MPI_DATATYPE_NULL) {
2259 return MPI_ERR_TYPE;
2260 } else if (count<0){
2261 return MPI_ERR_COUNT;
2263 return simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2267 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type,
2268 MPI_Datatype* new_type) {
2269 return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2272 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type,
2273 MPI_Datatype* new_type) {
2274 if (old_type == MPI_DATATYPE_NULL) {
2275 return MPI_ERR_TYPE;
2276 } else if (count<0){
2277 return MPI_ERR_COUNT;
2279 int* blocklens=(int*)xbt_malloc(blocklength*count*sizeof(int));
2280 for (int i = 0; i < count; i++)
2281 blocklens[i] = blocklength;
2282 int retval = simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2283 xbt_free(blocklens);
2288 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2290 return MPI_ERR_COUNT;
2292 return simgrid::smpi::Datatype::create_struct(count, blocklens, indices, old_types, new_type);
2296 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types,
2297 MPI_Datatype* new_type) {
2298 return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2301 int PMPI_Error_class(int errorcode, int* errorclass) {
2302 // assume smpi uses only standard mpi error codes
2303 *errorclass=errorcode;
2307 int PMPI_Initialized(int* flag) {
2308 *flag=(smpi_process()!=nullptr && smpi_process()->initialized());
2312 /* The topo part of MPI_COMM_WORLD should always be nullptr. When other topologies will be implemented, not only should we
2313 * check if the topology is nullptr, but we should check if it is the good topology type (so we have to add a
2314 * MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2316 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2317 if (comm_old == MPI_COMM_NULL){
2318 return MPI_ERR_COMM;
2319 } else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
2322 simgrid::smpi::Topo_Cart* topo = new simgrid::smpi::Topo_Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
2323 if(*comm_cart==MPI_COMM_NULL)
2329 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2330 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2331 return MPI_ERR_TOPOLOGY;
2333 if (coords == nullptr) {
2336 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2337 if (topo==nullptr) {
2340 return topo->rank(coords, rank);
2343 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2344 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2345 return MPI_ERR_TOPOLOGY;
2347 if (source == nullptr || dest == nullptr || direction < 0 ) {
2350 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2351 if (topo==nullptr) {
2354 return topo->shift(direction, displ, source, dest);
2357 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2358 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2359 return MPI_ERR_TOPOLOGY;
2361 if (rank < 0 || rank >= comm->size()) {
2362 return MPI_ERR_RANK;
2367 if(coords == nullptr) {
2370 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2371 if (topo==nullptr) {
2374 return topo->coords(rank, maxdims, coords);
2377 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2378 if(comm == nullptr || comm->topo() == nullptr) {
2379 return MPI_ERR_TOPOLOGY;
2381 if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
2384 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2385 if (topo==nullptr) {
2388 return topo->get(maxdims, dims, periods, coords);
2391 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2392 if (comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2393 return MPI_ERR_TOPOLOGY;
2395 if (ndims == nullptr) {
2398 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2399 if (topo==nullptr) {
2402 return topo->dim_get(ndims);
2405 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2406 if(dims == nullptr) {
2409 if (ndims < 1 || nnodes < 1) {
2410 return MPI_ERR_DIMS;
2412 return simgrid::smpi::Topo_Cart::Dims_create(nnodes, ndims, dims);
2415 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2416 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2417 return MPI_ERR_TOPOLOGY;
2419 if (comm_new == nullptr) {
2422 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2423 if (topo==nullptr) {
2426 MPIR_Cart_Topology cart = topo->sub(remain_dims, comm_new);
2427 if(*comm_new==MPI_COMM_NULL)
2434 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2435 if (oldtype == MPI_DATATYPE_NULL) {
2436 return MPI_ERR_TYPE;
2438 int blocks[3] = {1, 1, 1};
2439 MPI_Aint disps[3] = {lb, 0, lb + extent};
2440 MPI_Datatype types[3] = {MPI_LB, oldtype, MPI_UB};
2442 *newtype = new simgrid::smpi::Type_Struct(oldtype->size(), lb, lb + extent, DT_FLAG_DERIVED, 3, blocks, disps, types);
2444 (*newtype)->addflag(~DT_FLAG_COMMITED);
2448 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2451 if (comm == MPI_COMM_NULL) {
2452 retval= MPI_ERR_COMM;
2453 }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
2454 retval= MPI_ERR_OTHER;
2456 *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
2457 retval = MPI_SUCCESS;
2463 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
2466 if (comm == MPI_COMM_NULL) {
2467 retval= MPI_ERR_COMM;
2468 }else if (disp_unit <= 0 || size < 0 ){
2469 retval= MPI_ERR_OTHER;
2471 void* ptr = xbt_malloc(size);
2473 return MPI_ERR_NO_MEM;
2474 *static_cast<void**>(base) = ptr;
2475 *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
2476 retval = MPI_SUCCESS;
2482 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
2485 if (comm == MPI_COMM_NULL) {
2486 retval= MPI_ERR_COMM;
2488 *win = new simgrid::smpi::Win(info, comm);
2489 retval = MPI_SUCCESS;
2495 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
2498 if(win == MPI_WIN_NULL){
2499 retval = MPI_ERR_WIN;
2500 } else if ((base == nullptr && size != 0) || size < 0 ){
2501 retval= MPI_ERR_OTHER;
2503 retval = win->attach(base, size);
2509 int PMPI_Win_detach(MPI_Win win, void *base){
2512 if(win == MPI_WIN_NULL){
2513 retval = MPI_ERR_WIN;
2514 } else if (base == nullptr){
2515 retval= MPI_ERR_OTHER;
2517 retval = win->detach(base);
2524 int PMPI_Win_free( MPI_Win* win){
2527 if (win == nullptr || *win == MPI_WIN_NULL) {
2528 retval = MPI_ERR_WIN;
2537 int PMPI_Win_set_name(MPI_Win win, char * name)
2539 if (win == MPI_WIN_NULL) {
2540 return MPI_ERR_TYPE;
2541 } else if (name == nullptr) {
2544 win->set_name(name);
2549 int PMPI_Win_get_name(MPI_Win win, char * name, int* len)
2551 if (win == MPI_WIN_NULL) {
2553 } else if (name == nullptr) {
2556 win->get_name(name, len);
2561 int PMPI_Win_get_info(MPI_Win win, MPI_Info* info)
2563 if (win == MPI_WIN_NULL) {
2566 *info = win->info();
2571 int PMPI_Win_set_info(MPI_Win win, MPI_Info info)
2573 if (win == MPI_WIN_NULL) {
2574 return MPI_ERR_TYPE;
2576 win->set_info(info);
2581 int PMPI_Win_get_group(MPI_Win win, MPI_Group * group){
2582 if (win == MPI_WIN_NULL) {
2585 win->get_group(group);
2591 int PMPI_Win_fence( int assert, MPI_Win win){
2594 if (win == MPI_WIN_NULL) {
2595 retval = MPI_ERR_WIN;
2597 int rank = smpi_process()->index();
2598 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2599 retval = win->fence(assert);
2600 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2606 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2607 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2610 if (win == MPI_WIN_NULL) {
2611 retval = MPI_ERR_WIN;
2612 } else if (target_rank == MPI_PROC_NULL) {
2613 retval = MPI_SUCCESS;
2614 } else if (target_rank <0){
2615 retval = MPI_ERR_RANK;
2616 } else if (win->dynamic()==0 && target_disp <0){
2617 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2618 retval = MPI_ERR_ARG;
2619 } else if ((origin_count < 0 || target_count < 0) ||
2620 (origin_addr==nullptr && origin_count > 0)){
2621 retval = MPI_ERR_COUNT;
2622 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2623 retval = MPI_ERR_TYPE;
2625 int rank = smpi_process()->index();
2627 win->get_group(&group);
2628 int src_traced = group->index(target_rank);
2629 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2631 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2634 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2640 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2641 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2644 if (win == MPI_WIN_NULL) {
2645 retval = MPI_ERR_WIN;
2646 } else if (target_rank == MPI_PROC_NULL) {
2647 *request = MPI_REQUEST_NULL;
2648 retval = MPI_SUCCESS;
2649 } else if (target_rank <0){
2650 retval = MPI_ERR_RANK;
2651 } else if (win->dynamic()==0 && target_disp <0){
2652 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2653 retval = MPI_ERR_ARG;
2654 } else if ((origin_count < 0 || target_count < 0) ||
2655 (origin_addr==nullptr && origin_count > 0)){
2656 retval = MPI_ERR_COUNT;
2657 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2658 retval = MPI_ERR_TYPE;
2659 } else if(request == nullptr){
2660 retval = MPI_ERR_REQUEST;
2662 int rank = smpi_process()->index();
2664 win->get_group(&group);
2665 int src_traced = group->index(target_rank);
2666 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2668 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2669 target_datatype, request);
2671 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2677 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2678 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2681 if (win == MPI_WIN_NULL) {
2682 retval = MPI_ERR_WIN;
2683 } else if (target_rank == MPI_PROC_NULL) {
2684 retval = MPI_SUCCESS;
2685 } else if (target_rank <0){
2686 retval = MPI_ERR_RANK;
2687 } else if (win->dynamic()==0 && target_disp <0){
2688 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2689 retval = MPI_ERR_ARG;
2690 } else if ((origin_count < 0 || target_count < 0) ||
2691 (origin_addr==nullptr && origin_count > 0)){
2692 retval = MPI_ERR_COUNT;
2693 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2694 retval = MPI_ERR_TYPE;
2696 int rank = smpi_process()->index();
2698 win->get_group(&group);
2699 int dst_traced = group->index(target_rank);
2700 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2701 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2703 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2706 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2712 int PMPI_Rput( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2713 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2716 if (win == MPI_WIN_NULL) {
2717 retval = MPI_ERR_WIN;
2718 } else if (target_rank == MPI_PROC_NULL) {
2719 *request = MPI_REQUEST_NULL;
2720 retval = MPI_SUCCESS;
2721 } else if (target_rank <0){
2722 retval = MPI_ERR_RANK;
2723 } else if (win->dynamic()==0 && target_disp <0){
2724 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2725 retval = MPI_ERR_ARG;
2726 } else if ((origin_count < 0 || target_count < 0) ||
2727 (origin_addr==nullptr && origin_count > 0)){
2728 retval = MPI_ERR_COUNT;
2729 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2730 retval = MPI_ERR_TYPE;
2731 } else if(request == nullptr){
2732 retval = MPI_ERR_REQUEST;
2734 int rank = smpi_process()->index();
2736 win->get_group(&group);
2737 int dst_traced = group->index(target_rank);
2738 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2739 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2741 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2742 target_datatype, request);
2744 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2750 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2751 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2754 if (win == MPI_WIN_NULL) {
2755 retval = MPI_ERR_WIN;
2756 } else if (target_rank == MPI_PROC_NULL) {
2757 retval = MPI_SUCCESS;
2758 } else if (target_rank <0){
2759 retval = MPI_ERR_RANK;
2760 } else if (win->dynamic()==0 && target_disp <0){
2761 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2762 retval = MPI_ERR_ARG;
2763 } else if ((origin_count < 0 || target_count < 0) ||
2764 (origin_addr==nullptr && origin_count > 0)){
2765 retval = MPI_ERR_COUNT;
2766 } else if ((!origin_datatype->is_valid()) ||
2767 (!target_datatype->is_valid())) {
2768 retval = MPI_ERR_TYPE;
2769 } else if (op == MPI_OP_NULL) {
2770 retval = MPI_ERR_OP;
2772 int rank = smpi_process()->index();
2774 win->get_group(&group);
2775 int src_traced = group->index(target_rank);
2776 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2778 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2779 target_datatype, op);
2781 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2787 int PMPI_Raccumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2788 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2791 if (win == MPI_WIN_NULL) {
2792 retval = MPI_ERR_WIN;
2793 } else if (target_rank == MPI_PROC_NULL) {
2794 *request = MPI_REQUEST_NULL;
2795 retval = MPI_SUCCESS;
2796 } else if (target_rank <0){
2797 retval = MPI_ERR_RANK;
2798 } else if (win->dynamic()==0 && target_disp <0){
2799 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2800 retval = MPI_ERR_ARG;
2801 } else if ((origin_count < 0 || target_count < 0) ||
2802 (origin_addr==nullptr && origin_count > 0)){
2803 retval = MPI_ERR_COUNT;
2804 } else if ((!origin_datatype->is_valid()) ||
2805 (!target_datatype->is_valid())) {
2806 retval = MPI_ERR_TYPE;
2807 } else if (op == MPI_OP_NULL) {
2808 retval = MPI_ERR_OP;
2809 } else if(request == nullptr){
2810 retval = MPI_ERR_REQUEST;
2812 int rank = smpi_process()->index();
2814 win->get_group(&group);
2815 int src_traced = group->index(target_rank);
2816 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2818 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2819 target_datatype, op, request);
2821 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2827 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2828 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2829 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2832 if (win == MPI_WIN_NULL) {
2833 retval = MPI_ERR_WIN;
2834 } else if (target_rank == MPI_PROC_NULL) {
2835 retval = MPI_SUCCESS;
2836 } else if (target_rank <0){
2837 retval = MPI_ERR_RANK;
2838 } else if (win->dynamic()==0 && target_disp <0){
2839 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2840 retval = MPI_ERR_ARG;
2841 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2842 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2843 (result_addr==nullptr && result_count > 0)){
2844 retval = MPI_ERR_COUNT;
2845 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2846 (!target_datatype->is_valid())||
2847 (!result_datatype->is_valid())) {
2848 retval = MPI_ERR_TYPE;
2849 } else if (op == MPI_OP_NULL) {
2850 retval = MPI_ERR_OP;
2852 int rank = smpi_process()->index();
2854 win->get_group(&group);
2855 int src_traced = group->index(target_rank);
2856 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2858 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2859 result_count, result_datatype, target_rank, target_disp,
2860 target_count, target_datatype, op);
2862 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2869 int PMPI_Rget_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2870 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2871 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2874 if (win == MPI_WIN_NULL) {
2875 retval = MPI_ERR_WIN;
2876 } else if (target_rank == MPI_PROC_NULL) {
2877 *request = MPI_REQUEST_NULL;
2878 retval = MPI_SUCCESS;
2879 } else if (target_rank <0){
2880 retval = MPI_ERR_RANK;
2881 } else if (win->dynamic()==0 && target_disp <0){
2882 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2883 retval = MPI_ERR_ARG;
2884 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2885 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2886 (result_addr==nullptr && result_count > 0)){
2887 retval = MPI_ERR_COUNT;
2888 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2889 (!target_datatype->is_valid())||
2890 (!result_datatype->is_valid())) {
2891 retval = MPI_ERR_TYPE;
2892 } else if (op == MPI_OP_NULL) {
2893 retval = MPI_ERR_OP;
2894 } else if(request == nullptr){
2895 retval = MPI_ERR_REQUEST;
2897 int rank = smpi_process()->index();
2899 win->get_group(&group);
2900 int src_traced = group->index(target_rank);
2901 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2903 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2904 result_count, result_datatype, target_rank, target_disp,
2905 target_count, target_datatype, op, request);
2907 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2913 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){
2914 return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
2917 int PMPI_Compare_and_swap(void *origin_addr, void *compare_addr,
2918 void *result_addr, MPI_Datatype datatype, int target_rank,
2919 MPI_Aint target_disp, MPI_Win win){
2922 if (win == MPI_WIN_NULL) {
2923 retval = MPI_ERR_WIN;
2924 } else if (target_rank == MPI_PROC_NULL) {
2925 retval = MPI_SUCCESS;
2926 } else if (target_rank <0){
2927 retval = MPI_ERR_RANK;
2928 } else if (win->dynamic()==0 && target_disp <0){
2929 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2930 retval = MPI_ERR_ARG;
2931 } else if (origin_addr==nullptr || result_addr==nullptr || compare_addr==nullptr){
2932 retval = MPI_ERR_COUNT;
2933 } else if (!datatype->is_valid()) {
2934 retval = MPI_ERR_TYPE;
2936 int rank = smpi_process()->index();
2938 win->get_group(&group);
2939 int src_traced = group->index(target_rank);
2940 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2942 retval = win->compare_and_swap( origin_addr, compare_addr, result_addr, datatype,
2943 target_rank, target_disp);
2945 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2951 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2954 if (win == MPI_WIN_NULL) {
2955 retval = MPI_ERR_WIN;
2956 } else if (group==MPI_GROUP_NULL){
2957 retval = MPI_ERR_GROUP;
2959 int rank = smpi_process()->index();
2960 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2961 retval = win->post(group,assert);
2962 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2968 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2971 if (win == MPI_WIN_NULL) {
2972 retval = MPI_ERR_WIN;
2973 } else if (group==MPI_GROUP_NULL){
2974 retval = MPI_ERR_GROUP;
2976 int rank = smpi_process()->index();
2977 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2978 retval = win->start(group,assert);
2979 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2985 int PMPI_Win_complete(MPI_Win win){
2988 if (win == MPI_WIN_NULL) {
2989 retval = MPI_ERR_WIN;
2991 int rank = smpi_process()->index();
2992 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2994 retval = win->complete();
2996 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3002 int PMPI_Win_wait(MPI_Win win){
3005 if (win == MPI_WIN_NULL) {
3006 retval = MPI_ERR_WIN;
3008 int rank = smpi_process()->index();
3009 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
3011 retval = win->wait();
3013 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3019 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
3022 if (win == MPI_WIN_NULL) {
3023 retval = MPI_ERR_WIN;
3024 } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
3025 lock_type != MPI_LOCK_SHARED) {
3026 retval = MPI_ERR_LOCKTYPE;
3027 } else if (rank == MPI_PROC_NULL){
3028 retval = MPI_SUCCESS;
3030 int myrank = smpi_process()->index();
3031 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3032 retval = win->lock(lock_type,rank,assert);
3033 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3039 int PMPI_Win_unlock(int rank, MPI_Win win){
3042 if (win == MPI_WIN_NULL) {
3043 retval = MPI_ERR_WIN;
3044 } else if (rank == MPI_PROC_NULL){
3045 retval = MPI_SUCCESS;
3047 int myrank = smpi_process()->index();
3048 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3049 retval = win->unlock(rank);
3050 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3056 int PMPI_Win_lock_all(int assert, MPI_Win win){
3059 if (win == MPI_WIN_NULL) {
3060 retval = MPI_ERR_WIN;
3062 int myrank = smpi_process()->index();
3063 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3064 retval = win->lock_all(assert);
3065 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3071 int PMPI_Win_unlock_all(MPI_Win win){
3074 if (win == MPI_WIN_NULL) {
3075 retval = MPI_ERR_WIN;
3077 int myrank = smpi_process()->index();
3078 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3079 retval = win->unlock_all();
3080 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3086 int PMPI_Win_flush(int rank, MPI_Win win){
3089 if (win == MPI_WIN_NULL) {
3090 retval = MPI_ERR_WIN;
3091 } else if (rank == MPI_PROC_NULL){
3092 retval = MPI_SUCCESS;
3094 int myrank = smpi_process()->index();
3095 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3096 retval = win->flush(rank);
3097 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3103 int PMPI_Win_flush_local(int rank, MPI_Win win){
3106 if (win == MPI_WIN_NULL) {
3107 retval = MPI_ERR_WIN;
3108 } else if (rank == MPI_PROC_NULL){
3109 retval = MPI_SUCCESS;
3111 int myrank = smpi_process()->index();
3112 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3113 retval = win->flush_local(rank);
3114 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3120 int PMPI_Win_flush_all(MPI_Win win){
3123 if (win == MPI_WIN_NULL) {
3124 retval = MPI_ERR_WIN;
3126 int myrank = smpi_process()->index();
3127 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3128 retval = win->flush_all();
3129 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3135 int PMPI_Win_flush_local_all(MPI_Win win){
3138 if (win == MPI_WIN_NULL) {
3139 retval = MPI_ERR_WIN;
3141 int myrank = smpi_process()->index();
3142 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3143 retval = win->flush_local_all();
3144 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3150 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
3151 void *ptr = xbt_malloc(size);
3153 return MPI_ERR_NO_MEM;
3155 *static_cast<void**>(baseptr) = ptr;
3160 int PMPI_Free_mem(void *baseptr){
3165 int PMPI_Type_set_name(MPI_Datatype datatype, char * name)
3167 if (datatype == MPI_DATATYPE_NULL) {
3168 return MPI_ERR_TYPE;
3169 } else if (name == nullptr) {
3172 datatype->set_name(name);
3177 int PMPI_Type_get_name(MPI_Datatype datatype, char * name, int* len)
3179 if (datatype == MPI_DATATYPE_NULL) {
3180 return MPI_ERR_TYPE;
3181 } else if (name == nullptr) {
3184 datatype->get_name(name, len);
3189 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
3190 return static_cast<MPI_Datatype>(simgrid::smpi::F2C::f2c(datatype));
3193 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
3194 return datatype->c2f();
3197 MPI_Group PMPI_Group_f2c(MPI_Fint group){
3198 return simgrid::smpi::Group::f2c(group);
3201 MPI_Fint PMPI_Group_c2f(MPI_Group group){
3202 return group->c2f();
3205 MPI_Request PMPI_Request_f2c(MPI_Fint request){
3206 return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
3209 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
3210 return request->c2f();
3213 MPI_Win PMPI_Win_f2c(MPI_Fint win){
3214 return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
3217 MPI_Fint PMPI_Win_c2f(MPI_Win win){
3221 MPI_Op PMPI_Op_f2c(MPI_Fint op){
3222 return static_cast<MPI_Op>(simgrid::smpi::Op::f2c(op));
3225 MPI_Fint PMPI_Op_c2f(MPI_Op op){
3229 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
3230 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
3233 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
3237 MPI_Info PMPI_Info_f2c(MPI_Fint info){
3238 return static_cast<MPI_Info>(simgrid::smpi::Info::f2c(info));
3241 MPI_Fint PMPI_Info_c2f(MPI_Info info){
3245 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3246 smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr};
3247 smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr};
3248 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
3251 int PMPI_Keyval_free(int* keyval) {
3252 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Comm>(keyval);
3255 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3256 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3257 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3259 else if (comm==MPI_COMM_NULL)
3260 return MPI_ERR_COMM;
3262 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
3265 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3267 static int zero = 0;
3268 static int tag_ub = INT_MAX;
3269 static int last_used_code = MPI_ERR_LASTCODE;
3271 if (comm==MPI_COMM_NULL){
3273 return MPI_ERR_COMM;
3281 *static_cast<int**>(attr_value) = &zero;
3283 case MPI_UNIVERSE_SIZE:
3285 *static_cast<int**>(attr_value) = &smpi_universe_size;
3287 case MPI_LASTUSEDCODE:
3289 *static_cast<int**>(attr_value) = &last_used_code;
3293 *static_cast<int**>(attr_value) = &tag_ub;
3295 case MPI_WTIME_IS_GLOBAL:
3297 *static_cast<int**>(attr_value) = &one;
3300 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
3304 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3305 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3306 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3308 else if (comm==MPI_COMM_NULL)
3309 return MPI_ERR_COMM;
3311 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
3314 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3316 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3319 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3321 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3324 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3326 return PMPI_Attr_delete(comm, comm_keyval);
3329 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
3332 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3335 int PMPI_Comm_free_keyval(int* keyval) {
3336 return PMPI_Keyval_free(keyval);
3339 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3341 if (type==MPI_DATATYPE_NULL)
3342 return MPI_ERR_TYPE;
3344 return type->attr_get<simgrid::smpi::Datatype>(type_keyval, attribute_val, flag);
3347 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3349 if (type==MPI_DATATYPE_NULL)
3350 return MPI_ERR_TYPE;
3352 return type->attr_put<simgrid::smpi::Datatype>(type_keyval, attribute_val);
3355 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3357 if (type==MPI_DATATYPE_NULL)
3358 return MPI_ERR_TYPE;
3360 return type->attr_delete<simgrid::smpi::Datatype>(type_keyval);
3363 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
3366 smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr};
3367 smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr};
3368 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
3371 int PMPI_Type_free_keyval(int* keyval) {
3372 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Datatype>(keyval);
3375 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
3377 static MPI_Aint size;
3378 static int disp_unit;
3379 if (win==MPI_WIN_NULL)
3380 return MPI_ERR_TYPE;
3384 *static_cast<void**>(attribute_val) = win->base();
3389 *static_cast<MPI_Aint**>(attribute_val) = &size;
3392 case MPI_WIN_DISP_UNIT :
3393 disp_unit=win->disp_unit();
3394 *static_cast<int**>(attribute_val) = &disp_unit;
3398 return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
3404 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
3406 if (win==MPI_WIN_NULL)
3407 return MPI_ERR_TYPE;
3409 return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
3412 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
3414 if (win==MPI_WIN_NULL)
3415 return MPI_ERR_TYPE;
3417 return win->attr_delete<simgrid::smpi::Win>(type_keyval);
3420 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
3423 smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
3424 smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
3425 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
3428 int PMPI_Win_free_keyval(int* keyval) {
3429 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
3432 int PMPI_Info_create( MPI_Info *info){
3433 if (info == nullptr)
3435 *info = new simgrid::smpi::Info();
3439 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3440 if (info == nullptr || key == nullptr || value == nullptr)
3442 info->set(key, value);
3446 int PMPI_Info_free( MPI_Info *info){
3447 if (info == nullptr || *info==nullptr)
3449 simgrid::smpi::Info::unref(*info);
3450 *info=MPI_INFO_NULL;
3454 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3456 if (info == nullptr || key == nullptr || valuelen <0)
3458 if (value == nullptr)
3459 return MPI_ERR_INFO_VALUE;
3460 return info->get(key, valuelen, value, flag);
3463 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3464 if (info == nullptr || newinfo==nullptr)
3466 *newinfo = new simgrid::smpi::Info(info);
3470 int PMPI_Info_delete(MPI_Info info, char *key){
3471 if (info == nullptr || key==nullptr)
3473 return info->remove(key);
3476 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3477 if (info == nullptr || nkeys==nullptr)
3479 return info->get_nkeys(nkeys);
3482 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3483 if (info == nullptr || key==nullptr || n<0 || n> MPI_MAX_INFO_KEY)
3485 return info->get_nthkey(n, key);
3488 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3490 if (info == nullptr || key == nullptr || valuelen==nullptr)
3492 return info->get_valuelen(key, valuelen, flag);
3495 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3496 if(incount<0 || outcount < 0 || inbuf==nullptr || outbuf==nullptr)
3498 if(!type->is_valid())
3499 return MPI_ERR_TYPE;
3500 if(comm==MPI_COMM_NULL)
3501 return MPI_ERR_COMM;
3502 return type->unpack(inbuf, incount, position, outbuf,outcount, comm);
3505 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3506 if(incount<0 || outcount < 0|| inbuf==nullptr || outbuf==nullptr)
3508 if(!type->is_valid())
3509 return MPI_ERR_TYPE;
3510 if(comm==MPI_COMM_NULL)
3511 return MPI_ERR_COMM;
3512 return type->pack(inbuf, incount, outbuf,outcount,position, comm);
3515 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3518 if(!datatype->is_valid())
3519 return MPI_ERR_TYPE;
3520 if(comm==MPI_COMM_NULL)
3521 return MPI_ERR_COMM;
3523 *size=incount*datatype->size();