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/Engine.hpp"
7 #include "simgrid/s4u/Host.hpp"
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi, "Logging specific to SMPI (pmpi)");
13 //this function need to be here because of the calls to smpi_bench
14 void TRACE_smpi_set_category(const char *category)
16 //need to end bench otherwise categories for execution tasks are wrong
18 TRACE_internal_smpi_set_category (category);
19 //begin bench after changing process's category
23 /* PMPI User level calls */
24 extern "C" { // Obviously, the C MPI interface should use the C linkage
26 int PMPI_Init(int *argc, char ***argv)
28 xbt_assert(simgrid::s4u::Engine::isInitialized(),
29 "Your MPI program was not properly initialized. The easiest is to use smpirun to start it.");
30 // PMPI_Init is called only once per SMPI process
32 MPI_Initialized(&already_init);
33 if(already_init == 0){
34 simgrid::smpi::Process::init(argc, argv);
35 smpi_process()->mark_as_initialized();
36 int rank = smpi_process()->index();
37 TRACE_smpi_init(rank);
38 TRACE_smpi_computing_init(rank);
39 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
40 extra->type = TRACING_INIT;
41 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
42 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
54 int rank = smpi_process()->index();
55 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
56 extra->type = TRACING_FINALIZE;
57 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
59 smpi_process()->finalize();
61 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
62 TRACE_smpi_finalize(smpi_process()->index());
66 int PMPI_Finalized(int* flag)
68 *flag=smpi_process()!=nullptr ? smpi_process()->finalized() : 0;
72 int PMPI_Get_version (int *version,int *subversion){
73 *version = MPI_VERSION;
74 *subversion= MPI_SUBVERSION;
78 int PMPI_Get_library_version (char *version,int *len){
80 snprintf(version, MPI_MAX_LIBRARY_VERSION_STRING, "SMPI Version %d.%d. Copyright The Simgrid Team 2007-2017",
81 SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR);
82 *len = strlen(version) > MPI_MAX_LIBRARY_VERSION_STRING ? MPI_MAX_LIBRARY_VERSION_STRING : strlen(version);
87 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
89 if (provided != nullptr) {
90 *provided = MPI_THREAD_SINGLE;
92 return MPI_Init(argc, argv);
95 int PMPI_Query_thread(int *provided)
97 if (provided == nullptr) {
100 *provided = MPI_THREAD_SINGLE;
105 int PMPI_Is_thread_main(int *flag)
107 if (flag == nullptr) {
110 *flag = smpi_process()->index() == 0;
115 int PMPI_Abort(MPI_Comm comm, int errorcode)
118 // FIXME: should kill all processes in comm instead
119 simcall_process_kill(SIMIX_process_self());
125 return smpi_mpi_wtime();
128 extern double sg_maxmin_precision;
131 return sg_maxmin_precision;
134 int PMPI_Address(void *location, MPI_Aint * address)
136 if (address==nullptr) {
139 *address = reinterpret_cast<MPI_Aint>(location);
144 int PMPI_Get_address(void *location, MPI_Aint * address)
146 return PMPI_Address(location, address);
149 int PMPI_Type_free(MPI_Datatype * datatype)
151 /* Free a predefined datatype is an error according to the standard, and should be checked for */
152 if (*datatype == MPI_DATATYPE_NULL) {
155 simgrid::smpi::Datatype::unref(*datatype);
160 int PMPI_Type_size(MPI_Datatype datatype, int *size)
162 if (datatype == MPI_DATATYPE_NULL) {
164 } else if (size == nullptr) {
167 *size = static_cast<int>(datatype->size());
172 int PMPI_Type_size_x(MPI_Datatype datatype, MPI_Count *size)
174 if (datatype == MPI_DATATYPE_NULL) {
176 } else if (size == nullptr) {
179 *size = static_cast<MPI_Count>(datatype->size());
184 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
186 if (datatype == MPI_DATATYPE_NULL) {
188 } else if (lb == nullptr || extent == nullptr) {
191 return datatype->extent(lb, extent);
195 int PMPI_Type_get_true_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
197 return PMPI_Type_get_extent(datatype, lb, extent);
200 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
202 if (datatype == MPI_DATATYPE_NULL) {
204 } else if (extent == nullptr) {
207 *extent = datatype->get_extent();
212 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
214 if (datatype == MPI_DATATYPE_NULL) {
216 } else if (disp == nullptr) {
219 *disp = datatype->lb();
224 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
226 if (datatype == MPI_DATATYPE_NULL) {
228 } else if (disp == nullptr) {
231 *disp = datatype->ub();
236 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
237 int retval = MPI_SUCCESS;
238 if (datatype == MPI_DATATYPE_NULL) {
241 *newtype = new simgrid::smpi::Datatype(datatype, &retval);
242 //error when duplicating, free the new datatype
243 if(retval!=MPI_SUCCESS){
244 simgrid::smpi::Datatype::unref(*newtype);
245 *newtype = MPI_DATATYPE_NULL;
251 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
253 if (function == nullptr || op == nullptr) {
256 *op = new simgrid::smpi::Op(function, (commute!=0));
261 int PMPI_Op_free(MPI_Op * op)
265 } else if (*op == MPI_OP_NULL) {
274 int PMPI_Op_commutative(MPI_Op op, int* commute){
275 if (op == MPI_OP_NULL) {
277 } else if (commute==nullptr){
280 *commute = op->is_commutative();
285 int PMPI_Group_free(MPI_Group * group)
287 if (group == nullptr) {
290 if(*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_EMPTY)
291 simgrid::smpi::Group::unref(*group);
292 *group = MPI_GROUP_NULL;
297 int PMPI_Group_size(MPI_Group group, int *size)
299 if (group == MPI_GROUP_NULL) {
300 return MPI_ERR_GROUP;
301 } else if (size == nullptr) {
304 *size = group->size();
309 int PMPI_Group_rank(MPI_Group group, int *rank)
311 if (group == MPI_GROUP_NULL) {
312 return MPI_ERR_GROUP;
313 } else if (rank == nullptr) {
316 *rank = group->rank(smpi_process()->index());
321 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2)
323 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
324 return MPI_ERR_GROUP;
326 for (int i = 0; i < n; i++) {
327 if(ranks1[i]==MPI_PROC_NULL){
328 ranks2[i]=MPI_PROC_NULL;
330 int index = group1->index(ranks1[i]);
331 ranks2[i] = group2->rank(index);
338 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
340 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
341 return MPI_ERR_GROUP;
342 } else if (result == nullptr) {
345 *result = group1->compare(group2);
350 int PMPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
353 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
354 return MPI_ERR_GROUP;
355 } else if (newgroup == nullptr) {
358 return group1->group_union(group2, newgroup);
362 int PMPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
365 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
366 return MPI_ERR_GROUP;
367 } else if (newgroup == nullptr) {
370 return group1->intersection(group2,newgroup);
374 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
376 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
377 return MPI_ERR_GROUP;
378 } else if (newgroup == nullptr) {
381 return group1->difference(group2,newgroup);
385 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
387 if (group == MPI_GROUP_NULL) {
388 return MPI_ERR_GROUP;
389 } else if (newgroup == nullptr) {
392 return group->incl(n, ranks, newgroup);
396 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
398 if (group == MPI_GROUP_NULL) {
399 return MPI_ERR_GROUP;
400 } else if (newgroup == nullptr) {
405 if (group != MPI_COMM_WORLD->group()
406 && group != MPI_COMM_SELF->group() && group != MPI_GROUP_EMPTY)
409 } else if (n == group->size()) {
410 *newgroup = MPI_GROUP_EMPTY;
413 return group->excl(n,ranks,newgroup);
418 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
420 if (group == MPI_GROUP_NULL) {
421 return MPI_ERR_GROUP;
422 } else if (newgroup == nullptr) {
426 *newgroup = MPI_GROUP_EMPTY;
429 return group->range_incl(n,ranges,newgroup);
434 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
436 if (group == MPI_GROUP_NULL) {
437 return MPI_ERR_GROUP;
438 } else if (newgroup == nullptr) {
443 if (group != MPI_COMM_WORLD->group() && group != MPI_COMM_SELF->group() &&
444 group != MPI_GROUP_EMPTY)
448 return group->range_excl(n,ranges,newgroup);
453 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
455 if (comm == MPI_COMM_NULL) {
457 } else if (rank == nullptr) {
460 *rank = comm->rank();
465 int PMPI_Comm_size(MPI_Comm comm, int *size)
467 if (comm == MPI_COMM_NULL) {
469 } else if (size == nullptr) {
472 *size = comm->size();
477 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
479 if (comm == MPI_COMM_NULL) {
481 } else if (name == nullptr || len == nullptr) {
484 comm->get_name(name, len);
489 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
491 if (comm == MPI_COMM_NULL) {
493 } else if (group == nullptr) {
496 *group = comm->group();
497 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
503 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
505 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
507 } else if (result == nullptr) {
510 if (comm1 == comm2) { /* Same communicators means same groups */
513 *result = comm1->group()->compare(comm2->group());
514 if (*result == MPI_IDENT) {
515 *result = MPI_CONGRUENT;
522 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
524 if (comm == MPI_COMM_NULL) {
526 } else if (newcomm == nullptr) {
529 return comm->dup(newcomm);
533 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
535 if (comm == MPI_COMM_NULL) {
537 } else if (group == MPI_GROUP_NULL) {
538 return MPI_ERR_GROUP;
539 } else if (newcomm == nullptr) {
541 } else if(group->rank(smpi_process()->index())==MPI_UNDEFINED){
542 *newcomm= MPI_COMM_NULL;
546 *newcomm = new simgrid::smpi::Comm(group, nullptr);
551 int PMPI_Comm_free(MPI_Comm * comm)
553 if (comm == nullptr) {
555 } else if (*comm == MPI_COMM_NULL) {
558 simgrid::smpi::Comm::destroy(*comm);
559 *comm = MPI_COMM_NULL;
564 int PMPI_Comm_disconnect(MPI_Comm * comm)
566 /* TODO: wait until all communication in comm are done */
567 if (comm == nullptr) {
569 } else if (*comm == MPI_COMM_NULL) {
572 simgrid::smpi::Comm::destroy(*comm);
573 *comm = MPI_COMM_NULL;
578 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
583 if (comm_out == nullptr) {
584 retval = MPI_ERR_ARG;
585 } else if (comm == MPI_COMM_NULL) {
586 retval = MPI_ERR_COMM;
588 *comm_out = comm->split(color, key);
589 retval = MPI_SUCCESS;
596 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
601 if (comm_out == nullptr) {
602 retval = MPI_ERR_ARG;
603 } else if (comm == MPI_COMM_NULL) {
604 retval = MPI_ERR_COMM;
606 retval = MPI_Comm_create(comm, group, comm_out);
613 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
618 if (request == nullptr) {
619 retval = MPI_ERR_ARG;
620 } else if (comm == MPI_COMM_NULL) {
621 retval = MPI_ERR_COMM;
622 } else if (!datatype->is_valid()) {
623 retval = MPI_ERR_TYPE;
624 } else if (dst == MPI_PROC_NULL) {
625 retval = MPI_SUCCESS;
627 *request = simgrid::smpi::Request::send_init(buf, count, datatype, dst, tag, comm);
628 retval = MPI_SUCCESS;
631 if (retval != MPI_SUCCESS && request != nullptr)
632 *request = MPI_REQUEST_NULL;
636 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
641 if (request == nullptr) {
642 retval = MPI_ERR_ARG;
643 } else if (comm == MPI_COMM_NULL) {
644 retval = MPI_ERR_COMM;
645 } else if (!datatype->is_valid()) {
646 retval = MPI_ERR_TYPE;
647 } else if (src == MPI_PROC_NULL) {
648 retval = MPI_SUCCESS;
650 *request = simgrid::smpi::Request::recv_init(buf, count, datatype, src, tag, comm);
651 retval = MPI_SUCCESS;
654 if (retval != MPI_SUCCESS && request != nullptr)
655 *request = MPI_REQUEST_NULL;
659 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
664 if (request == nullptr) {
665 retval = MPI_ERR_ARG;
666 } else if (comm == MPI_COMM_NULL) {
667 retval = MPI_ERR_COMM;
668 } else if (!datatype->is_valid()) {
669 retval = MPI_ERR_TYPE;
670 } else if (dst == MPI_PROC_NULL) {
671 retval = MPI_SUCCESS;
673 *request = simgrid::smpi::Request::ssend_init(buf, count, datatype, dst, tag, comm);
674 retval = MPI_SUCCESS;
677 if (retval != MPI_SUCCESS && request != nullptr)
678 *request = MPI_REQUEST_NULL;
682 int PMPI_Start(MPI_Request * request)
687 if (request == nullptr || *request == MPI_REQUEST_NULL) {
688 retval = MPI_ERR_REQUEST;
691 retval = MPI_SUCCESS;
697 int PMPI_Startall(int count, MPI_Request * requests)
701 if (requests == nullptr) {
702 retval = MPI_ERR_ARG;
704 retval = MPI_SUCCESS;
705 for (int i = 0; i < count; i++) {
706 if(requests[i] == MPI_REQUEST_NULL) {
707 retval = MPI_ERR_REQUEST;
710 if(retval != MPI_ERR_REQUEST) {
711 simgrid::smpi::Request::startall(count, requests);
718 int PMPI_Request_free(MPI_Request * request)
723 if (*request == MPI_REQUEST_NULL) {
724 retval = MPI_ERR_ARG;
726 simgrid::smpi::Request::unref(request);
727 retval = MPI_SUCCESS;
733 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
739 if (request == nullptr) {
740 retval = MPI_ERR_ARG;
741 } else if (comm == MPI_COMM_NULL) {
742 retval = MPI_ERR_COMM;
743 } else if (src == MPI_PROC_NULL) {
744 *request = MPI_REQUEST_NULL;
745 retval = MPI_SUCCESS;
746 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
747 retval = MPI_ERR_RANK;
748 } else if ((count < 0) || (buf==nullptr && count > 0)) {
749 retval = MPI_ERR_COUNT;
750 } else if (!datatype->is_valid()) {
751 retval = MPI_ERR_TYPE;
752 } else if(tag<0 && tag != MPI_ANY_TAG){
753 retval = MPI_ERR_TAG;
756 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
757 int src_traced = comm->group()->index(src);
759 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
760 extra->type = TRACING_IRECV;
761 extra->src = src_traced;
764 extra->datatype1 = encode_datatype(datatype, &known);
765 int dt_size_send = 1;
767 dt_size_send = datatype->size();
768 extra->send_size = count*dt_size_send;
769 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
771 *request = simgrid::smpi::Request::irecv(buf, count, datatype, src, tag, comm);
772 retval = MPI_SUCCESS;
774 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
778 if (retval != MPI_SUCCESS && request != nullptr)
779 *request = MPI_REQUEST_NULL;
784 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
789 if (request == nullptr) {
790 retval = MPI_ERR_ARG;
791 } else if (comm == MPI_COMM_NULL) {
792 retval = MPI_ERR_COMM;
793 } else if (dst == MPI_PROC_NULL) {
794 *request = MPI_REQUEST_NULL;
795 retval = MPI_SUCCESS;
796 } else if (dst >= comm->group()->size() || dst <0){
797 retval = MPI_ERR_RANK;
798 } else if ((count < 0) || (buf==nullptr && count > 0)) {
799 retval = MPI_ERR_COUNT;
800 } else if (!datatype->is_valid()) {
801 retval = MPI_ERR_TYPE;
802 } else if(tag<0 && tag != MPI_ANY_TAG){
803 retval = MPI_ERR_TAG;
805 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
806 int dst_traced = comm->group()->index(dst);
807 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
808 extra->type = TRACING_ISEND;
810 extra->dst = dst_traced;
812 extra->datatype1 = encode_datatype(datatype, &known);
813 int dt_size_send = 1;
815 dt_size_send = datatype->size();
816 extra->send_size = count*dt_size_send;
817 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
818 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
820 *request = simgrid::smpi::Request::isend(buf, count, datatype, dst, tag, comm);
821 retval = MPI_SUCCESS;
823 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
827 if (retval != MPI_SUCCESS && request!=nullptr)
828 *request = MPI_REQUEST_NULL;
832 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
837 if (request == nullptr) {
838 retval = MPI_ERR_ARG;
839 } else if (comm == MPI_COMM_NULL) {
840 retval = MPI_ERR_COMM;
841 } else if (dst == MPI_PROC_NULL) {
842 *request = MPI_REQUEST_NULL;
843 retval = MPI_SUCCESS;
844 } else if (dst >= comm->group()->size() || dst <0){
845 retval = MPI_ERR_RANK;
846 } else if ((count < 0)|| (buf==nullptr && count > 0)) {
847 retval = MPI_ERR_COUNT;
848 } else if (!datatype->is_valid()) {
849 retval = MPI_ERR_TYPE;
850 } else if(tag<0 && tag != MPI_ANY_TAG){
851 retval = MPI_ERR_TAG;
853 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
854 int dst_traced = comm->group()->index(dst);
855 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
856 extra->type = TRACING_ISSEND;
858 extra->dst = dst_traced;
860 extra->datatype1 = encode_datatype(datatype, &known);
861 int dt_size_send = 1;
863 dt_size_send = datatype->size();
864 extra->send_size = count*dt_size_send;
865 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
866 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
868 *request = simgrid::smpi::Request::issend(buf, count, datatype, dst, tag, comm);
869 retval = MPI_SUCCESS;
871 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
875 if (retval != MPI_SUCCESS && request!=nullptr)
876 *request = MPI_REQUEST_NULL;
880 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
885 if (comm == MPI_COMM_NULL) {
886 retval = MPI_ERR_COMM;
887 } else if (src == MPI_PROC_NULL) {
888 simgrid::smpi::Status::empty(status);
889 status->MPI_SOURCE = MPI_PROC_NULL;
890 retval = MPI_SUCCESS;
891 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
892 retval = MPI_ERR_RANK;
893 } else if ((count < 0) || (buf==nullptr && count > 0)) {
894 retval = MPI_ERR_COUNT;
895 } else if (!datatype->is_valid()) {
896 retval = MPI_ERR_TYPE;
897 } else if(tag<0 && tag != MPI_ANY_TAG){
898 retval = MPI_ERR_TAG;
900 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
901 int src_traced = comm->group()->index(src);
902 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
903 extra->type = TRACING_RECV;
904 extra->src = src_traced;
907 extra->datatype1 = encode_datatype(datatype, &known);
908 int dt_size_send = 1;
910 dt_size_send = datatype->size();
911 extra->send_size = count * dt_size_send;
912 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
914 simgrid::smpi::Request::recv(buf, count, datatype, src, tag, comm, status);
915 retval = MPI_SUCCESS;
917 // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
918 if (status != MPI_STATUS_IGNORE) {
919 src_traced = comm->group()->index(status->MPI_SOURCE);
920 if (!TRACE_smpi_view_internals()) {
921 TRACE_smpi_recv(rank, src_traced, rank, tag);
924 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
931 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
937 if (comm == MPI_COMM_NULL) {
938 retval = MPI_ERR_COMM;
939 } else if (dst == MPI_PROC_NULL) {
940 retval = MPI_SUCCESS;
941 } else if (dst >= comm->group()->size() || dst <0){
942 retval = MPI_ERR_RANK;
943 } else if ((count < 0) || (buf == nullptr && count > 0)) {
944 retval = MPI_ERR_COUNT;
945 } else if (!datatype->is_valid()) {
946 retval = MPI_ERR_TYPE;
947 } else if(tag < 0 && tag != MPI_ANY_TAG){
948 retval = MPI_ERR_TAG;
950 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
951 int dst_traced = comm->group()->index(dst);
952 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
953 extra->type = TRACING_SEND;
955 extra->dst = dst_traced;
957 extra->datatype1 = encode_datatype(datatype, &known);
958 int dt_size_send = 1;
960 dt_size_send = datatype->size();
962 extra->send_size = count*dt_size_send;
963 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
964 if (!TRACE_smpi_view_internals()) {
965 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
968 simgrid::smpi::Request::send(buf, count, datatype, dst, tag, comm);
969 retval = MPI_SUCCESS;
971 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
978 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
983 if (comm == MPI_COMM_NULL) {
984 retval = MPI_ERR_COMM;
985 } else if (dst == MPI_PROC_NULL) {
986 retval = MPI_SUCCESS;
987 } else if (dst >= comm->group()->size() || dst <0){
988 retval = MPI_ERR_RANK;
989 } else if ((count < 0) || (buf==nullptr && count > 0)) {
990 retval = MPI_ERR_COUNT;
991 } else if (!datatype->is_valid()){
992 retval = MPI_ERR_TYPE;
993 } else if(tag<0 && tag != MPI_ANY_TAG){
994 retval = MPI_ERR_TAG;
996 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
997 int dst_traced = comm->group()->index(dst);
998 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
999 extra->type = TRACING_SSEND;
1001 extra->dst = dst_traced;
1003 extra->datatype1 = encode_datatype(datatype, &known);
1004 int dt_size_send = 1;
1006 dt_size_send = datatype->size();
1008 extra->send_size = count*dt_size_send;
1009 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1010 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
1012 simgrid::smpi::Request::ssend(buf, count, datatype, dst, tag, comm);
1013 retval = MPI_SUCCESS;
1015 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1022 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void *recvbuf,
1023 int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status)
1029 if (comm == MPI_COMM_NULL) {
1030 retval = MPI_ERR_COMM;
1031 } else if (!sendtype->is_valid() || !recvtype->is_valid()) {
1032 retval = MPI_ERR_TYPE;
1033 } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1034 simgrid::smpi::Status::empty(status);
1035 status->MPI_SOURCE = MPI_PROC_NULL;
1036 retval = MPI_SUCCESS;
1037 }else if (dst >= comm->group()->size() || dst <0 ||
1038 (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0))){
1039 retval = MPI_ERR_RANK;
1040 } else if ((sendcount < 0 || recvcount<0) ||
1041 (sendbuf==nullptr && sendcount > 0) || (recvbuf==nullptr && recvcount>0)) {
1042 retval = MPI_ERR_COUNT;
1043 } else if((sendtag<0 && sendtag != MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1044 retval = MPI_ERR_TAG;
1047 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1048 int dst_traced = comm->group()->index(dst);
1049 int src_traced = comm->group()->index(src);
1050 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1051 extra->type = TRACING_SENDRECV;
1052 extra->src = src_traced;
1053 extra->dst = dst_traced;
1055 extra->datatype1 = encode_datatype(sendtype, &known);
1056 int dt_size_send = 1;
1058 dt_size_send = sendtype->size();
1059 extra->send_size = sendcount*dt_size_send;
1060 extra->datatype2 = encode_datatype(recvtype, &known);
1061 int dt_size_recv = 1;
1063 dt_size_recv = recvtype->size();
1064 extra->recv_size = recvcount*dt_size_recv;
1066 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1067 TRACE_smpi_send(rank, rank, dst_traced, sendtag,sendcount*sendtype->size());
1069 simgrid::smpi::Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm,
1071 retval = MPI_SUCCESS;
1073 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1074 TRACE_smpi_recv(rank, src_traced, rank, recvtag);
1081 int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,
1082 MPI_Comm comm, MPI_Status* status)
1085 if (!datatype->is_valid()) {
1086 return MPI_ERR_TYPE;
1087 } else if (count < 0) {
1088 return MPI_ERR_COUNT;
1090 int size = datatype->get_extent() * count;
1091 void* recvbuf = xbt_new0(char, size);
1092 retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
1093 if(retval==MPI_SUCCESS){
1094 simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
1102 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1106 if (request == nullptr || flag == nullptr) {
1107 retval = MPI_ERR_ARG;
1108 } else if (*request == MPI_REQUEST_NULL) {
1110 simgrid::smpi::Status::empty(status);
1111 retval = MPI_SUCCESS;
1113 int rank = ((*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1115 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1116 extra->type = TRACING_TEST;
1117 TRACE_smpi_testing_in(rank, extra);
1119 *flag = simgrid::smpi::Request::test(request,status);
1121 TRACE_smpi_testing_out(rank);
1122 retval = MPI_SUCCESS;
1128 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status)
1133 if (index == nullptr || flag == nullptr) {
1134 retval = MPI_ERR_ARG;
1136 *flag = simgrid::smpi::Request::testany(count, requests, index, status);
1137 retval = MPI_SUCCESS;
1143 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1148 if (flag == nullptr) {
1149 retval = MPI_ERR_ARG;
1151 *flag = simgrid::smpi::Request::testall(count, requests, statuses);
1152 retval = MPI_SUCCESS;
1158 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1162 if (status == nullptr) {
1163 retval = MPI_ERR_ARG;
1164 } else if (comm == MPI_COMM_NULL) {
1165 retval = MPI_ERR_COMM;
1166 } else if (source == MPI_PROC_NULL) {
1167 simgrid::smpi::Status::empty(status);
1168 status->MPI_SOURCE = MPI_PROC_NULL;
1169 retval = MPI_SUCCESS;
1171 simgrid::smpi::Request::probe(source, tag, comm, status);
1172 retval = MPI_SUCCESS;
1178 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1182 if (flag == nullptr) {
1183 retval = MPI_ERR_ARG;
1184 } else if (comm == MPI_COMM_NULL) {
1185 retval = MPI_ERR_COMM;
1186 } else if (source == MPI_PROC_NULL) {
1188 simgrid::smpi::Status::empty(status);
1189 status->MPI_SOURCE = MPI_PROC_NULL;
1190 retval = MPI_SUCCESS;
1192 simgrid::smpi::Request::iprobe(source, tag, comm, flag, status);
1193 retval = MPI_SUCCESS;
1199 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1205 simgrid::smpi::Status::empty(status);
1207 if (request == nullptr) {
1208 retval = MPI_ERR_ARG;
1209 } else if (*request == MPI_REQUEST_NULL) {
1210 retval = MPI_SUCCESS;
1213 int rank = (request!=nullptr && (*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1215 int src_traced = (*request)->src();
1216 int dst_traced = (*request)->dst();
1217 int tag_traced= (*request)->tag();
1218 MPI_Comm comm = (*request)->comm();
1219 int is_wait_for_receive = ((*request)->flags() & RECV);
1220 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1221 extra->type = TRACING_WAIT;
1222 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1224 simgrid::smpi::Request::wait(request, status);
1225 retval = MPI_SUCCESS;
1227 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1228 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1229 if (is_wait_for_receive) {
1230 if(src_traced==MPI_ANY_SOURCE)
1231 src_traced = (status!=MPI_STATUS_IGNORE) ?
1232 comm->group()->rank(status->MPI_SOURCE) :
1234 TRACE_smpi_recv(rank, src_traced, dst_traced, tag_traced);
1242 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1244 if (index == nullptr)
1248 //save requests information for tracing
1256 savedvalstype* savedvals=nullptr;
1258 savedvals = xbt_new0(savedvalstype, count);
1260 for (int i = 0; i < count; i++) {
1261 MPI_Request req = requests[i]; //already received requests are no longer valid
1263 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), req->comm()};
1266 int rank_traced = smpi_process()->index();
1267 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1268 extra->type = TRACING_WAITANY;
1269 extra->send_size=count;
1270 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1272 *index = simgrid::smpi::Request::waitany(count, requests, status);
1274 if(*index!=MPI_UNDEFINED){
1275 int src_traced = savedvals[*index].src;
1276 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1277 int dst_traced = savedvals[*index].dst;
1278 int is_wait_for_receive = savedvals[*index].recv;
1279 if (is_wait_for_receive) {
1280 if(savedvals[*index].src==MPI_ANY_SOURCE)
1281 src_traced = (status != MPI_STATUSES_IGNORE)
1282 ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
1283 : savedvals[*index].src;
1284 TRACE_smpi_recv(rank_traced, src_traced, dst_traced, savedvals[*index].tag);
1286 TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1288 xbt_free(savedvals);
1294 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1297 //save information from requests
1306 savedvalstype* savedvals=xbt_new0(savedvalstype, count);
1308 for (int i = 0; i < count; i++) {
1309 MPI_Request req = requests[i];
1310 if(req!=MPI_REQUEST_NULL){
1311 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), 1, req->comm()};
1313 savedvals[i].valid=0;
1316 int rank_traced = smpi_process()->index();
1317 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1318 extra->type = TRACING_WAITALL;
1319 extra->send_size=count;
1320 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1322 int retval = simgrid::smpi::Request::waitall(count, requests, status);
1324 for (int i = 0; i < count; i++) {
1325 if(savedvals[i].valid){
1326 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1327 int src_traced = savedvals[i].src;
1328 int dst_traced = savedvals[i].dst;
1329 int is_wait_for_receive = savedvals[i].recv;
1330 if (is_wait_for_receive) {
1331 if(src_traced==MPI_ANY_SOURCE)
1332 src_traced = (status!=MPI_STATUSES_IGNORE) ?
1333 savedvals[i].comm->group()->rank(status[i].MPI_SOURCE) : savedvals[i].src;
1334 TRACE_smpi_recv(rank_traced, src_traced, dst_traced,savedvals[i].tag);
1338 TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1339 xbt_free(savedvals);
1345 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount, int *indices, MPI_Status status[])
1350 if (outcount == nullptr) {
1351 retval = MPI_ERR_ARG;
1353 *outcount = simgrid::smpi::Request::waitsome(incount, requests, indices, status);
1354 retval = MPI_SUCCESS;
1360 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[])
1365 if (outcount == nullptr) {
1366 retval = MPI_ERR_ARG;
1368 *outcount = simgrid::smpi::Request::testsome(incount, requests, indices, status);
1369 retval = MPI_SUCCESS;
1376 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1382 if (comm == MPI_COMM_NULL) {
1383 retval = MPI_ERR_COMM;
1384 } else if (!datatype->is_valid()) {
1385 retval = MPI_ERR_ARG;
1387 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1388 int root_traced = comm->group()->index(root);
1390 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1391 extra->type = TRACING_BCAST;
1392 extra->root = root_traced;
1394 extra->datatype1 = encode_datatype(datatype, &known);
1395 int dt_size_send = 1;
1397 dt_size_send = datatype->size();
1398 extra->send_size = count * dt_size_send;
1399 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1400 if (comm->size() > 1)
1401 simgrid::smpi::Colls::bcast(buf, count, datatype, root, comm);
1402 retval = MPI_SUCCESS;
1404 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1410 int PMPI_Barrier(MPI_Comm comm)
1416 if (comm == MPI_COMM_NULL) {
1417 retval = MPI_ERR_COMM;
1419 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1420 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1421 extra->type = TRACING_BARRIER;
1422 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1424 simgrid::smpi::Colls::barrier(comm);
1426 //Barrier can be used to synchronize RMA calls. Finish all requests from comm before.
1427 comm->finish_rma_calls();
1429 retval = MPI_SUCCESS;
1431 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1438 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
1439 int root, MPI_Comm comm)
1445 if (comm == MPI_COMM_NULL) {
1446 retval = MPI_ERR_COMM;
1447 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1448 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1449 retval = MPI_ERR_TYPE;
1450 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) || ((comm->rank() == root) && (recvcount <0))){
1451 retval = MPI_ERR_COUNT;
1454 char* sendtmpbuf = static_cast<char*>(sendbuf);
1455 int sendtmpcount = sendcount;
1456 MPI_Datatype sendtmptype = sendtype;
1457 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1459 sendtmptype=recvtype;
1461 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1462 int root_traced = comm->group()->index(root);
1463 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1464 extra->type = TRACING_GATHER;
1465 extra->root = root_traced;
1467 extra->datatype1 = encode_datatype(sendtmptype, &known);
1468 int dt_size_send = 1;
1470 dt_size_send = sendtmptype->size();
1471 extra->send_size = sendtmpcount * dt_size_send;
1472 extra->datatype2 = encode_datatype(recvtype, &known);
1473 int dt_size_recv = 1;
1474 if ((comm->rank() == root) && known == 0)
1475 dt_size_recv = recvtype->size();
1476 extra->recv_size = recvcount * dt_size_recv;
1478 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1480 simgrid::smpi::Colls::gather(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
1482 retval = MPI_SUCCESS;
1483 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1490 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
1491 MPI_Datatype recvtype, int root, MPI_Comm comm)
1497 if (comm == MPI_COMM_NULL) {
1498 retval = MPI_ERR_COMM;
1499 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1500 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1501 retval = MPI_ERR_TYPE;
1502 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1503 retval = MPI_ERR_COUNT;
1504 } else if (recvcounts == nullptr || displs == nullptr) {
1505 retval = MPI_ERR_ARG;
1507 char* sendtmpbuf = static_cast<char*>(sendbuf);
1508 int sendtmpcount = sendcount;
1509 MPI_Datatype sendtmptype = sendtype;
1510 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1512 sendtmptype=recvtype;
1515 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1516 int root_traced = comm->group()->index(root);
1517 int size = comm->size();
1518 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1519 extra->type = TRACING_GATHERV;
1520 extra->num_processes = size;
1521 extra->root = root_traced;
1523 extra->datatype1 = encode_datatype(sendtmptype, &known);
1524 int dt_size_send = 1;
1526 dt_size_send = sendtype->size();
1527 extra->send_size = sendtmpcount * dt_size_send;
1528 extra->datatype2 = encode_datatype(recvtype, &known);
1529 int dt_size_recv = 1;
1531 dt_size_recv = recvtype->size();
1532 if (comm->rank() == root) {
1533 extra->recvcounts = xbt_new(int, size);
1534 for (int i = 0; i < size; i++) // copy data to avoid bad free
1535 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1537 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1539 retval = simgrid::smpi::Colls::gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
1540 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1547 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1548 void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
1554 if (comm == MPI_COMM_NULL) {
1555 retval = MPI_ERR_COMM;
1556 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1557 (recvtype == MPI_DATATYPE_NULL)){
1558 retval = MPI_ERR_TYPE;
1559 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1561 retval = MPI_ERR_COUNT;
1563 if(sendbuf == MPI_IN_PLACE) {
1564 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*recvcount*comm->rank();
1565 sendcount=recvcount;
1568 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1569 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1570 extra->type = TRACING_ALLGATHER;
1572 extra->datatype1 = encode_datatype(sendtype, &known);
1573 int dt_size_send = 1;
1575 dt_size_send = sendtype->size();
1576 extra->send_size = sendcount * dt_size_send;
1577 extra->datatype2 = encode_datatype(recvtype, &known);
1578 int dt_size_recv = 1;
1580 dt_size_recv = recvtype->size();
1581 extra->recv_size = recvcount * dt_size_recv;
1583 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1585 simgrid::smpi::Colls::allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1586 retval = MPI_SUCCESS;
1587 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1593 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1594 void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
1600 if (comm == MPI_COMM_NULL) {
1601 retval = MPI_ERR_COMM;
1602 } else if (((sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) || (recvtype == MPI_DATATYPE_NULL)) {
1603 retval = MPI_ERR_TYPE;
1604 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1605 retval = MPI_ERR_COUNT;
1606 } else if (recvcounts == nullptr || displs == nullptr) {
1607 retval = MPI_ERR_ARG;
1610 if(sendbuf == MPI_IN_PLACE) {
1611 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*displs[comm->rank()];
1612 sendcount=recvcounts[comm->rank()];
1615 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1617 int size = comm->size();
1618 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1619 extra->type = TRACING_ALLGATHERV;
1620 extra->num_processes = size;
1622 extra->datatype1 = encode_datatype(sendtype, &known);
1623 int dt_size_send = 1;
1625 dt_size_send = sendtype->size();
1626 extra->send_size = sendcount * dt_size_send;
1627 extra->datatype2 = encode_datatype(recvtype, &known);
1628 int dt_size_recv = 1;
1630 dt_size_recv = recvtype->size();
1631 extra->recvcounts = xbt_new(int, size);
1632 for (i = 0; i < size; i++) // copy data to avoid bad free
1633 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1635 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1637 simgrid::smpi::Colls::allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1638 retval = MPI_SUCCESS;
1639 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1646 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1647 void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1653 if (comm == MPI_COMM_NULL) {
1654 retval = MPI_ERR_COMM;
1655 } else if (((comm->rank() == root) && (!sendtype->is_valid())) ||
1656 ((recvbuf != MPI_IN_PLACE) && (!recvtype->is_valid()))) {
1657 retval = MPI_ERR_TYPE;
1658 } else if ((sendbuf == recvbuf) ||
1659 ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
1660 retval = MPI_ERR_BUFFER;
1663 if (recvbuf == MPI_IN_PLACE) {
1664 recvtype = sendtype;
1665 recvcount = sendcount;
1667 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1668 int root_traced = comm->group()->index(root);
1669 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1670 extra->type = TRACING_SCATTER;
1671 extra->root = root_traced;
1673 extra->datatype1 = encode_datatype(sendtype, &known);
1674 int dt_size_send = 1;
1675 if ((comm->rank() == root) && known == 0)
1676 dt_size_send = sendtype->size();
1677 extra->send_size = sendcount * dt_size_send;
1678 extra->datatype2 = encode_datatype(recvtype, &known);
1679 int dt_size_recv = 1;
1681 dt_size_recv = recvtype->size();
1682 extra->recv_size = recvcount * dt_size_recv;
1683 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1685 simgrid::smpi::Colls::scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1686 retval = MPI_SUCCESS;
1687 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1694 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1695 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1701 if (comm == MPI_COMM_NULL) {
1702 retval = MPI_ERR_COMM;
1703 } else if (sendcounts == nullptr || displs == nullptr) {
1704 retval = MPI_ERR_ARG;
1705 } else if (((comm->rank() == root) && (sendtype == MPI_DATATYPE_NULL)) ||
1706 ((recvbuf != MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1707 retval = MPI_ERR_TYPE;
1709 if (recvbuf == MPI_IN_PLACE) {
1710 recvtype = sendtype;
1711 recvcount = sendcounts[comm->rank()];
1713 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1714 int root_traced = comm->group()->index(root);
1715 int size = comm->size();
1716 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1717 extra->type = TRACING_SCATTERV;
1718 extra->num_processes = size;
1719 extra->root = root_traced;
1721 extra->datatype1 = encode_datatype(sendtype, &known);
1722 int dt_size_send = 1;
1724 dt_size_send = sendtype->size();
1725 if (comm->rank() == root) {
1726 extra->sendcounts = xbt_new(int, size);
1727 for (int i = 0; i < size; i++) // copy data to avoid bad free
1728 extra->sendcounts[i] = sendcounts[i] * dt_size_send;
1730 extra->datatype2 = encode_datatype(recvtype, &known);
1731 int dt_size_recv = 1;
1733 dt_size_recv = recvtype->size();
1734 extra->recv_size = recvcount * dt_size_recv;
1735 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1737 retval = simgrid::smpi::Colls::scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1739 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1746 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
1752 if (comm == MPI_COMM_NULL) {
1753 retval = MPI_ERR_COMM;
1754 } else if (!datatype->is_valid() || op == MPI_OP_NULL) {
1755 retval = MPI_ERR_ARG;
1757 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1758 int root_traced = comm->group()->index(root);
1759 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1760 extra->type = TRACING_REDUCE;
1762 extra->datatype1 = encode_datatype(datatype, &known);
1763 int dt_size_send = 1;
1765 dt_size_send = datatype->size();
1766 extra->send_size = count * dt_size_send;
1767 extra->root = root_traced;
1769 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1771 simgrid::smpi::Colls::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1773 retval = MPI_SUCCESS;
1774 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1781 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op){
1785 if (!datatype->is_valid() || op == MPI_OP_NULL) {
1786 retval = MPI_ERR_ARG;
1788 op->apply(inbuf, inoutbuf, &count, datatype);
1789 retval = MPI_SUCCESS;
1795 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1801 if (comm == MPI_COMM_NULL) {
1802 retval = MPI_ERR_COMM;
1803 } else if (!datatype->is_valid()) {
1804 retval = MPI_ERR_TYPE;
1805 } else if (op == MPI_OP_NULL) {
1806 retval = MPI_ERR_OP;
1809 char* sendtmpbuf = static_cast<char*>(sendbuf);
1810 if( sendbuf == MPI_IN_PLACE ) {
1811 sendtmpbuf = static_cast<char*>(xbt_malloc(count*datatype->get_extent()));
1812 simgrid::smpi::Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
1814 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1815 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1816 extra->type = TRACING_ALLREDUCE;
1818 extra->datatype1 = encode_datatype(datatype, &known);
1819 int dt_size_send = 1;
1821 dt_size_send = datatype->size();
1822 extra->send_size = count * dt_size_send;
1824 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1826 simgrid::smpi::Colls::allreduce(sendtmpbuf, recvbuf, count, datatype, op, comm);
1828 if( sendbuf == MPI_IN_PLACE )
1829 xbt_free(sendtmpbuf);
1831 retval = MPI_SUCCESS;
1832 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1839 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1845 if (comm == MPI_COMM_NULL) {
1846 retval = MPI_ERR_COMM;
1847 } else if (!datatype->is_valid()) {
1848 retval = MPI_ERR_TYPE;
1849 } else if (op == MPI_OP_NULL) {
1850 retval = MPI_ERR_OP;
1852 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1853 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1854 extra->type = TRACING_SCAN;
1856 extra->datatype1 = encode_datatype(datatype, &known);
1857 int dt_size_send = 1;
1859 dt_size_send = datatype->size();
1860 extra->send_size = count * dt_size_send;
1862 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1864 retval = simgrid::smpi::Colls::scan(sendbuf, recvbuf, count, datatype, op, comm);
1866 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1873 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
1878 if (comm == MPI_COMM_NULL) {
1879 retval = MPI_ERR_COMM;
1880 } else if (!datatype->is_valid()) {
1881 retval = MPI_ERR_TYPE;
1882 } else if (op == MPI_OP_NULL) {
1883 retval = MPI_ERR_OP;
1885 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1886 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1887 extra->type = TRACING_EXSCAN;
1889 extra->datatype1 = encode_datatype(datatype, &known);
1890 int dt_size_send = 1;
1892 dt_size_send = datatype->size();
1893 extra->send_size = count * dt_size_send;
1894 void* sendtmpbuf = sendbuf;
1895 if (sendbuf == MPI_IN_PLACE) {
1896 sendtmpbuf = static_cast<void*>(xbt_malloc(count * datatype->size()));
1897 memcpy(sendtmpbuf, recvbuf, count * datatype->size());
1899 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1901 retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
1903 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1904 if (sendbuf == MPI_IN_PLACE)
1905 xbt_free(sendtmpbuf);
1912 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1917 if (comm == MPI_COMM_NULL) {
1918 retval = MPI_ERR_COMM;
1919 } else if (!datatype->is_valid()) {
1920 retval = MPI_ERR_TYPE;
1921 } else if (op == MPI_OP_NULL) {
1922 retval = MPI_ERR_OP;
1923 } else if (recvcounts == nullptr) {
1924 retval = MPI_ERR_ARG;
1926 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1928 int size = comm->size();
1929 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1930 extra->type = TRACING_REDUCE_SCATTER;
1931 extra->num_processes = size;
1933 extra->datatype1 = encode_datatype(datatype, &known);
1934 int dt_size_send = 1;
1936 dt_size_send = datatype->size();
1937 extra->send_size = 0;
1938 extra->recvcounts = xbt_new(int, size);
1940 for (i = 0; i < size; i++) { // copy data to avoid bad free
1941 extra->recvcounts[i] = recvcounts[i] * dt_size_send;
1942 totalcount += recvcounts[i];
1944 void* sendtmpbuf = sendbuf;
1945 if (sendbuf == MPI_IN_PLACE) {
1946 sendtmpbuf = static_cast<void*>(xbt_malloc(totalcount * datatype->size()));
1947 memcpy(sendtmpbuf, recvbuf, totalcount * datatype->size());
1950 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1952 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1953 retval = MPI_SUCCESS;
1954 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1956 if (sendbuf == MPI_IN_PLACE)
1957 xbt_free(sendtmpbuf);
1964 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
1965 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1970 if (comm == MPI_COMM_NULL) {
1971 retval = MPI_ERR_COMM;
1972 } else if (!datatype->is_valid()) {
1973 retval = MPI_ERR_TYPE;
1974 } else if (op == MPI_OP_NULL) {
1975 retval = MPI_ERR_OP;
1976 } else if (recvcount < 0) {
1977 retval = MPI_ERR_ARG;
1979 int count = comm->size();
1981 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1982 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1983 extra->type = TRACING_REDUCE_SCATTER;
1984 extra->num_processes = count;
1986 extra->datatype1 = encode_datatype(datatype, &known);
1987 int dt_size_send = 1;
1989 dt_size_send = datatype->size();
1990 extra->send_size = 0;
1991 extra->recvcounts = xbt_new(int, count);
1992 for (int i = 0; i < count; i++) // copy data to avoid bad free
1993 extra->recvcounts[i] = recvcount * dt_size_send;
1994 void* sendtmpbuf = sendbuf;
1995 if (sendbuf == MPI_IN_PLACE) {
1996 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * count * datatype->size()));
1997 memcpy(sendtmpbuf, recvbuf, recvcount * count * datatype->size());
2000 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2002 int* recvcounts = static_cast<int*>(xbt_malloc(count * sizeof(int)));
2003 for (int i = 0; i < count; i++)
2004 recvcounts[i] = recvcount;
2005 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
2006 xbt_free(recvcounts);
2007 retval = MPI_SUCCESS;
2009 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2011 if (sendbuf == MPI_IN_PLACE)
2012 xbt_free(sendtmpbuf);
2019 int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
2020 MPI_Datatype recvtype, MPI_Comm comm)
2025 if (comm == MPI_COMM_NULL) {
2026 retval = MPI_ERR_COMM;
2027 } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL) || recvtype == MPI_DATATYPE_NULL) {
2028 retval = MPI_ERR_TYPE;
2030 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2031 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2032 extra->type = TRACING_ALLTOALL;
2034 void* sendtmpbuf = static_cast<char*>(sendbuf);
2035 int sendtmpcount = sendcount;
2036 MPI_Datatype sendtmptype = sendtype;
2037 if (sendbuf == MPI_IN_PLACE) {
2038 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * comm->size() * recvtype->size()));
2039 memcpy(sendtmpbuf, recvbuf, recvcount * comm->size() * recvtype->size());
2040 sendtmpcount = recvcount;
2041 sendtmptype = recvtype;
2045 extra->datatype1 = encode_datatype(sendtmptype, &known);
2047 extra->send_size = sendtmpcount * sendtmptype->size();
2049 extra->send_size = sendtmpcount;
2050 extra->datatype2 = encode_datatype(recvtype, &known);
2052 extra->recv_size = recvcount * recvtype->size();
2054 extra->recv_size = recvcount;
2056 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2058 retval = simgrid::smpi::Colls::alltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
2060 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2062 if (sendbuf == MPI_IN_PLACE)
2063 xbt_free(sendtmpbuf);
2070 int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
2071 int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2077 if (comm == MPI_COMM_NULL) {
2078 retval = MPI_ERR_COMM;
2079 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
2080 retval = MPI_ERR_TYPE;
2081 } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
2082 recvdisps == nullptr) {
2083 retval = MPI_ERR_ARG;
2085 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2087 int size = comm->size();
2088 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2089 extra->type = TRACING_ALLTOALLV;
2090 extra->send_size = 0;
2091 extra->recv_size = 0;
2092 extra->recvcounts = xbt_new(int, size);
2093 extra->sendcounts = xbt_new(int, size);
2095 int dt_size_recv = 1;
2096 extra->datatype2 = encode_datatype(recvtype, &known);
2097 dt_size_recv = recvtype->size();
2099 void* sendtmpbuf = static_cast<char*>(sendbuf);
2100 int* sendtmpcounts = sendcounts;
2101 int* sendtmpdisps = senddisps;
2102 MPI_Datatype sendtmptype = sendtype;
2104 for (i = 0; i < size; i++) { // copy data to avoid bad free
2105 extra->recv_size += recvcounts[i] * dt_size_recv;
2106 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
2107 if (((recvdisps[i] + recvcounts[i]) * dt_size_recv) > maxsize)
2108 maxsize = (recvdisps[i] + recvcounts[i]) * dt_size_recv;
2111 if (sendbuf == MPI_IN_PLACE) {
2112 sendtmpbuf = static_cast<void*>(xbt_malloc(maxsize));
2113 memcpy(sendtmpbuf, recvbuf, maxsize);
2114 sendtmpcounts = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2115 memcpy(sendtmpcounts, recvcounts, size * sizeof(int));
2116 sendtmpdisps = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2117 memcpy(sendtmpdisps, recvdisps, size * sizeof(int));
2118 sendtmptype = recvtype;
2121 extra->datatype1 = encode_datatype(sendtmptype, &known);
2122 int dt_size_send = 1;
2123 dt_size_send = sendtmptype->size();
2125 for (i = 0; i < size; i++) { // copy data to avoid bad free
2126 extra->send_size += sendtmpcounts[i] * dt_size_send;
2127 extra->sendcounts[i] = sendtmpcounts[i] * dt_size_send;
2129 extra->num_processes = size;
2130 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2131 retval = simgrid::smpi::Colls::alltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
2132 recvdisps, recvtype, comm);
2133 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2135 if (sendbuf == MPI_IN_PLACE) {
2136 xbt_free(sendtmpbuf);
2137 xbt_free(sendtmpcounts);
2138 xbt_free(sendtmpdisps);
2147 int PMPI_Get_processor_name(char *name, int *resultlen)
2149 strncpy(name, SIMIX_host_self()->cname(), strlen(SIMIX_host_self()->cname()) < MPI_MAX_PROCESSOR_NAME - 1
2150 ? strlen(SIMIX_host_self()->cname()) + 1
2151 : MPI_MAX_PROCESSOR_NAME - 1);
2152 *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2157 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2159 if (status == nullptr || count == nullptr) {
2161 } else if (!datatype->is_valid()) {
2162 return MPI_ERR_TYPE;
2164 size_t size = datatype->size();
2168 } else if (status->count % size != 0) {
2169 return MPI_UNDEFINED;
2171 *count = simgrid::smpi::Status::get_count(status, datatype);
2177 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2178 if (old_type == MPI_DATATYPE_NULL) {
2179 return MPI_ERR_TYPE;
2180 } else if (count<0){
2181 return MPI_ERR_COUNT;
2183 return simgrid::smpi::Datatype::create_contiguous(count, old_type, 0, new_type);
2187 int PMPI_Type_commit(MPI_Datatype* datatype) {
2188 if (datatype == nullptr || *datatype == MPI_DATATYPE_NULL) {
2189 return MPI_ERR_TYPE;
2191 (*datatype)->commit();
2196 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2197 if (old_type == MPI_DATATYPE_NULL) {
2198 return MPI_ERR_TYPE;
2199 } else if (count<0 || blocklen<0){
2200 return MPI_ERR_COUNT;
2202 return simgrid::smpi::Datatype::create_vector(count, blocklen, stride, old_type, new_type);
2206 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2207 if (old_type == MPI_DATATYPE_NULL) {
2208 return MPI_ERR_TYPE;
2209 } else if (count<0 || blocklen<0){
2210 return MPI_ERR_COUNT;
2212 return simgrid::smpi::Datatype::create_hvector(count, blocklen, stride, old_type, new_type);
2216 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2217 return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2220 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2221 if (old_type == MPI_DATATYPE_NULL) {
2222 return MPI_ERR_TYPE;
2223 } else if (count<0){
2224 return MPI_ERR_COUNT;
2226 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2230 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2231 if (old_type == MPI_DATATYPE_NULL) {
2232 return MPI_ERR_TYPE;
2233 } else if (count<0){
2234 return MPI_ERR_COUNT;
2236 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2240 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type,
2241 MPI_Datatype* new_type)
2243 if (old_type == MPI_DATATYPE_NULL) {
2244 return MPI_ERR_TYPE;
2245 } else if (count<0){
2246 return MPI_ERR_COUNT;
2248 int* blocklens=static_cast<int*>(xbt_malloc(blocklength*count*sizeof(int)));
2249 for (int i = 0; i < count; i++)
2250 blocklens[i]=blocklength;
2251 int retval = simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2252 xbt_free(blocklens);
2257 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
2259 if (old_type == MPI_DATATYPE_NULL) {
2260 return MPI_ERR_TYPE;
2261 } else if (count<0){
2262 return MPI_ERR_COUNT;
2264 return simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2268 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type,
2269 MPI_Datatype* new_type) {
2270 return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2273 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type,
2274 MPI_Datatype* new_type) {
2275 if (old_type == MPI_DATATYPE_NULL) {
2276 return MPI_ERR_TYPE;
2277 } else if (count<0){
2278 return MPI_ERR_COUNT;
2280 int* blocklens=(int*)xbt_malloc(blocklength*count*sizeof(int));
2281 for (int i = 0; i < count; i++)
2282 blocklens[i] = blocklength;
2283 int retval = simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2284 xbt_free(blocklens);
2289 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2291 return MPI_ERR_COUNT;
2293 return simgrid::smpi::Datatype::create_struct(count, blocklens, indices, old_types, new_type);
2297 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types,
2298 MPI_Datatype* new_type) {
2299 return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2302 int PMPI_Error_class(int errorcode, int* errorclass) {
2303 // assume smpi uses only standard mpi error codes
2304 *errorclass=errorcode;
2308 int PMPI_Initialized(int* flag) {
2309 *flag=(smpi_process()!=nullptr && smpi_process()->initialized());
2313 /* The topo part of MPI_COMM_WORLD should always be nullptr. When other topologies will be implemented, not only should we
2314 * check if the topology is nullptr, but we should check if it is the good topology type (so we have to add a
2315 * MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2317 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2318 if (comm_old == MPI_COMM_NULL){
2319 return MPI_ERR_COMM;
2320 } else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
2323 simgrid::smpi::Topo_Cart* topo = new simgrid::smpi::Topo_Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
2324 if(*comm_cart==MPI_COMM_NULL)
2330 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2331 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2332 return MPI_ERR_TOPOLOGY;
2334 if (coords == nullptr) {
2337 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2338 if (topo==nullptr) {
2341 return topo->rank(coords, rank);
2344 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2345 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2346 return MPI_ERR_TOPOLOGY;
2348 if (source == nullptr || dest == nullptr || direction < 0 ) {
2351 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2352 if (topo==nullptr) {
2355 return topo->shift(direction, displ, source, dest);
2358 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2359 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2360 return MPI_ERR_TOPOLOGY;
2362 if (rank < 0 || rank >= comm->size()) {
2363 return MPI_ERR_RANK;
2368 if(coords == nullptr) {
2371 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2372 if (topo==nullptr) {
2375 return topo->coords(rank, maxdims, coords);
2378 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2379 if(comm == nullptr || comm->topo() == nullptr) {
2380 return MPI_ERR_TOPOLOGY;
2382 if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
2385 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2386 if (topo==nullptr) {
2389 return topo->get(maxdims, dims, periods, coords);
2392 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2393 if (comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2394 return MPI_ERR_TOPOLOGY;
2396 if (ndims == nullptr) {
2399 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2400 if (topo==nullptr) {
2403 return topo->dim_get(ndims);
2406 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2407 if(dims == nullptr) {
2410 if (ndims < 1 || nnodes < 1) {
2411 return MPI_ERR_DIMS;
2413 return simgrid::smpi::Topo_Cart::Dims_create(nnodes, ndims, dims);
2416 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2417 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2418 return MPI_ERR_TOPOLOGY;
2420 if (comm_new == nullptr) {
2423 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2424 if (topo==nullptr) {
2427 MPIR_Cart_Topology cart = topo->sub(remain_dims, comm_new);
2428 if(*comm_new==MPI_COMM_NULL)
2435 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2436 if (oldtype == MPI_DATATYPE_NULL) {
2437 return MPI_ERR_TYPE;
2439 int blocks[3] = {1, 1, 1};
2440 MPI_Aint disps[3] = {lb, 0, lb + extent};
2441 MPI_Datatype types[3] = {MPI_LB, oldtype, MPI_UB};
2443 *newtype = new simgrid::smpi::Type_Struct(oldtype->size(), lb, lb + extent, DT_FLAG_DERIVED, 3, blocks, disps, types);
2445 (*newtype)->addflag(~DT_FLAG_COMMITED);
2449 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2452 if (comm == MPI_COMM_NULL) {
2453 retval= MPI_ERR_COMM;
2454 }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
2455 retval= MPI_ERR_OTHER;
2457 *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
2458 retval = MPI_SUCCESS;
2464 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
2467 if (comm == MPI_COMM_NULL) {
2468 retval= MPI_ERR_COMM;
2469 }else if (disp_unit <= 0 || size < 0 ){
2470 retval= MPI_ERR_OTHER;
2472 void* ptr = xbt_malloc(size);
2474 return MPI_ERR_NO_MEM;
2475 *static_cast<void**>(base) = ptr;
2476 *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
2477 retval = MPI_SUCCESS;
2483 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
2486 if (comm == MPI_COMM_NULL) {
2487 retval= MPI_ERR_COMM;
2489 *win = new simgrid::smpi::Win(info, comm);
2490 retval = MPI_SUCCESS;
2496 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
2499 if(win == MPI_WIN_NULL){
2500 retval = MPI_ERR_WIN;
2501 } else if ((base == nullptr && size != 0) || size < 0 ){
2502 retval= MPI_ERR_OTHER;
2504 retval = win->attach(base, size);
2510 int PMPI_Win_detach(MPI_Win win, void *base){
2513 if(win == MPI_WIN_NULL){
2514 retval = MPI_ERR_WIN;
2515 } else if (base == nullptr){
2516 retval= MPI_ERR_OTHER;
2518 retval = win->detach(base);
2525 int PMPI_Win_free( MPI_Win* win){
2528 if (win == nullptr || *win == MPI_WIN_NULL) {
2529 retval = MPI_ERR_WIN;
2538 int PMPI_Win_set_name(MPI_Win win, char * name)
2540 if (win == MPI_WIN_NULL) {
2541 return MPI_ERR_TYPE;
2542 } else if (name == nullptr) {
2545 win->set_name(name);
2550 int PMPI_Win_get_name(MPI_Win win, char * name, int* len)
2552 if (win == MPI_WIN_NULL) {
2554 } else if (name == nullptr) {
2557 win->get_name(name, len);
2562 int PMPI_Win_get_info(MPI_Win win, MPI_Info* info)
2564 if (win == MPI_WIN_NULL) {
2567 *info = win->info();
2572 int PMPI_Win_set_info(MPI_Win win, MPI_Info info)
2574 if (win == MPI_WIN_NULL) {
2575 return MPI_ERR_TYPE;
2577 win->set_info(info);
2582 int PMPI_Win_get_group(MPI_Win win, MPI_Group * group){
2583 if (win == MPI_WIN_NULL) {
2586 win->get_group(group);
2592 int PMPI_Win_fence( int assert, MPI_Win win){
2595 if (win == MPI_WIN_NULL) {
2596 retval = MPI_ERR_WIN;
2598 int rank = smpi_process()->index();
2599 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2600 retval = win->fence(assert);
2601 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2607 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2608 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2611 if (win == MPI_WIN_NULL) {
2612 retval = MPI_ERR_WIN;
2613 } else if (target_rank == MPI_PROC_NULL) {
2614 retval = MPI_SUCCESS;
2615 } else if (target_rank <0){
2616 retval = MPI_ERR_RANK;
2617 } else if (win->dynamic()==0 && target_disp <0){
2618 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2619 retval = MPI_ERR_ARG;
2620 } else if ((origin_count < 0 || target_count < 0) ||
2621 (origin_addr==nullptr && origin_count > 0)){
2622 retval = MPI_ERR_COUNT;
2623 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2624 retval = MPI_ERR_TYPE;
2626 int rank = smpi_process()->index();
2628 win->get_group(&group);
2629 int src_traced = group->index(target_rank);
2630 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2632 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2635 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2641 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2642 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2645 if (win == MPI_WIN_NULL) {
2646 retval = MPI_ERR_WIN;
2647 } else if (target_rank == MPI_PROC_NULL) {
2648 *request = MPI_REQUEST_NULL;
2649 retval = MPI_SUCCESS;
2650 } else if (target_rank <0){
2651 retval = MPI_ERR_RANK;
2652 } else if (win->dynamic()==0 && target_disp <0){
2653 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2654 retval = MPI_ERR_ARG;
2655 } else if ((origin_count < 0 || target_count < 0) ||
2656 (origin_addr==nullptr && origin_count > 0)){
2657 retval = MPI_ERR_COUNT;
2658 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2659 retval = MPI_ERR_TYPE;
2660 } else if(request == nullptr){
2661 retval = MPI_ERR_REQUEST;
2663 int rank = smpi_process()->index();
2665 win->get_group(&group);
2666 int src_traced = group->index(target_rank);
2667 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2669 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2670 target_datatype, request);
2672 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2678 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2679 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2682 if (win == MPI_WIN_NULL) {
2683 retval = MPI_ERR_WIN;
2684 } else if (target_rank == MPI_PROC_NULL) {
2685 retval = MPI_SUCCESS;
2686 } else if (target_rank <0){
2687 retval = MPI_ERR_RANK;
2688 } else if (win->dynamic()==0 && target_disp <0){
2689 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2690 retval = MPI_ERR_ARG;
2691 } else if ((origin_count < 0 || target_count < 0) ||
2692 (origin_addr==nullptr && origin_count > 0)){
2693 retval = MPI_ERR_COUNT;
2694 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2695 retval = MPI_ERR_TYPE;
2697 int rank = smpi_process()->index();
2699 win->get_group(&group);
2700 int dst_traced = group->index(target_rank);
2701 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2702 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2704 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2707 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2713 int PMPI_Rput( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2714 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
2717 if (win == MPI_WIN_NULL) {
2718 retval = MPI_ERR_WIN;
2719 } else if (target_rank == MPI_PROC_NULL) {
2720 *request = MPI_REQUEST_NULL;
2721 retval = MPI_SUCCESS;
2722 } else if (target_rank <0){
2723 retval = MPI_ERR_RANK;
2724 } else if (win->dynamic()==0 && target_disp <0){
2725 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2726 retval = MPI_ERR_ARG;
2727 } else if ((origin_count < 0 || target_count < 0) ||
2728 (origin_addr==nullptr && origin_count > 0)){
2729 retval = MPI_ERR_COUNT;
2730 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2731 retval = MPI_ERR_TYPE;
2732 } else if(request == nullptr){
2733 retval = MPI_ERR_REQUEST;
2735 int rank = smpi_process()->index();
2737 win->get_group(&group);
2738 int dst_traced = group->index(target_rank);
2739 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2740 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2742 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2743 target_datatype, request);
2745 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2751 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2752 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2755 if (win == MPI_WIN_NULL) {
2756 retval = MPI_ERR_WIN;
2757 } else if (target_rank == MPI_PROC_NULL) {
2758 retval = MPI_SUCCESS;
2759 } else if (target_rank <0){
2760 retval = MPI_ERR_RANK;
2761 } else if (win->dynamic()==0 && target_disp <0){
2762 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2763 retval = MPI_ERR_ARG;
2764 } else if ((origin_count < 0 || target_count < 0) ||
2765 (origin_addr==nullptr && origin_count > 0)){
2766 retval = MPI_ERR_COUNT;
2767 } else if ((!origin_datatype->is_valid()) ||
2768 (!target_datatype->is_valid())) {
2769 retval = MPI_ERR_TYPE;
2770 } else if (op == MPI_OP_NULL) {
2771 retval = MPI_ERR_OP;
2773 int rank = smpi_process()->index();
2775 win->get_group(&group);
2776 int src_traced = group->index(target_rank);
2777 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2779 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2780 target_datatype, op);
2782 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2788 int PMPI_Raccumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2789 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2792 if (win == MPI_WIN_NULL) {
2793 retval = MPI_ERR_WIN;
2794 } else if (target_rank == MPI_PROC_NULL) {
2795 *request = MPI_REQUEST_NULL;
2796 retval = MPI_SUCCESS;
2797 } else if (target_rank <0){
2798 retval = MPI_ERR_RANK;
2799 } else if (win->dynamic()==0 && target_disp <0){
2800 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2801 retval = MPI_ERR_ARG;
2802 } else if ((origin_count < 0 || target_count < 0) ||
2803 (origin_addr==nullptr && origin_count > 0)){
2804 retval = MPI_ERR_COUNT;
2805 } else if ((!origin_datatype->is_valid()) ||
2806 (!target_datatype->is_valid())) {
2807 retval = MPI_ERR_TYPE;
2808 } else if (op == MPI_OP_NULL) {
2809 retval = MPI_ERR_OP;
2810 } else if(request == nullptr){
2811 retval = MPI_ERR_REQUEST;
2813 int rank = smpi_process()->index();
2815 win->get_group(&group);
2816 int src_traced = group->index(target_rank);
2817 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2819 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2820 target_datatype, op, request);
2822 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2828 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2829 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2830 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2833 if (win == MPI_WIN_NULL) {
2834 retval = MPI_ERR_WIN;
2835 } else if (target_rank == MPI_PROC_NULL) {
2836 retval = MPI_SUCCESS;
2837 } else if (target_rank <0){
2838 retval = MPI_ERR_RANK;
2839 } else if (win->dynamic()==0 && target_disp <0){
2840 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2841 retval = MPI_ERR_ARG;
2842 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2843 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2844 (result_addr==nullptr && result_count > 0)){
2845 retval = MPI_ERR_COUNT;
2846 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2847 (!target_datatype->is_valid())||
2848 (!result_datatype->is_valid())) {
2849 retval = MPI_ERR_TYPE;
2850 } else if (op == MPI_OP_NULL) {
2851 retval = MPI_ERR_OP;
2853 int rank = smpi_process()->index();
2855 win->get_group(&group);
2856 int src_traced = group->index(target_rank);
2857 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2859 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2860 result_count, result_datatype, target_rank, target_disp,
2861 target_count, target_datatype, op);
2863 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2870 int PMPI_Rget_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2871 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2872 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
2875 if (win == MPI_WIN_NULL) {
2876 retval = MPI_ERR_WIN;
2877 } else if (target_rank == MPI_PROC_NULL) {
2878 *request = MPI_REQUEST_NULL;
2879 retval = MPI_SUCCESS;
2880 } else if (target_rank <0){
2881 retval = MPI_ERR_RANK;
2882 } else if (win->dynamic()==0 && target_disp <0){
2883 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2884 retval = MPI_ERR_ARG;
2885 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2886 (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
2887 (result_addr==nullptr && result_count > 0)){
2888 retval = MPI_ERR_COUNT;
2889 } else if ((origin_datatype!=MPI_DATATYPE_NULL && !origin_datatype->is_valid()) ||
2890 (!target_datatype->is_valid())||
2891 (!result_datatype->is_valid())) {
2892 retval = MPI_ERR_TYPE;
2893 } else if (op == MPI_OP_NULL) {
2894 retval = MPI_ERR_OP;
2895 } else if(request == nullptr){
2896 retval = MPI_ERR_REQUEST;
2898 int rank = smpi_process()->index();
2900 win->get_group(&group);
2901 int src_traced = group->index(target_rank);
2902 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2904 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2905 result_count, result_datatype, target_rank, target_disp,
2906 target_count, target_datatype, op, request);
2908 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2914 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){
2915 return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
2918 int PMPI_Compare_and_swap(void *origin_addr, void *compare_addr,
2919 void *result_addr, MPI_Datatype datatype, int target_rank,
2920 MPI_Aint target_disp, MPI_Win win){
2923 if (win == MPI_WIN_NULL) {
2924 retval = MPI_ERR_WIN;
2925 } else if (target_rank == MPI_PROC_NULL) {
2926 retval = MPI_SUCCESS;
2927 } else if (target_rank <0){
2928 retval = MPI_ERR_RANK;
2929 } else if (win->dynamic()==0 && target_disp <0){
2930 //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
2931 retval = MPI_ERR_ARG;
2932 } else if (origin_addr==nullptr || result_addr==nullptr || compare_addr==nullptr){
2933 retval = MPI_ERR_COUNT;
2934 } else if (!datatype->is_valid()) {
2935 retval = MPI_ERR_TYPE;
2937 int rank = smpi_process()->index();
2939 win->get_group(&group);
2940 int src_traced = group->index(target_rank);
2941 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2943 retval = win->compare_and_swap( origin_addr, compare_addr, result_addr, datatype,
2944 target_rank, target_disp);
2946 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2952 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2955 if (win == MPI_WIN_NULL) {
2956 retval = MPI_ERR_WIN;
2957 } else if (group==MPI_GROUP_NULL){
2958 retval = MPI_ERR_GROUP;
2960 int rank = smpi_process()->index();
2961 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2962 retval = win->post(group,assert);
2963 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2969 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2972 if (win == MPI_WIN_NULL) {
2973 retval = MPI_ERR_WIN;
2974 } else if (group==MPI_GROUP_NULL){
2975 retval = MPI_ERR_GROUP;
2977 int rank = smpi_process()->index();
2978 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2979 retval = win->start(group,assert);
2980 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2986 int PMPI_Win_complete(MPI_Win win){
2989 if (win == MPI_WIN_NULL) {
2990 retval = MPI_ERR_WIN;
2992 int rank = smpi_process()->index();
2993 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2995 retval = win->complete();
2997 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3003 int PMPI_Win_wait(MPI_Win win){
3006 if (win == MPI_WIN_NULL) {
3007 retval = MPI_ERR_WIN;
3009 int rank = smpi_process()->index();
3010 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
3012 retval = win->wait();
3014 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
3020 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
3023 if (win == MPI_WIN_NULL) {
3024 retval = MPI_ERR_WIN;
3025 } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
3026 lock_type != MPI_LOCK_SHARED) {
3027 retval = MPI_ERR_LOCKTYPE;
3028 } else if (rank == MPI_PROC_NULL){
3029 retval = MPI_SUCCESS;
3031 int myrank = smpi_process()->index();
3032 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3033 retval = win->lock(lock_type,rank,assert);
3034 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3040 int PMPI_Win_unlock(int rank, MPI_Win win){
3043 if (win == MPI_WIN_NULL) {
3044 retval = MPI_ERR_WIN;
3045 } else if (rank == MPI_PROC_NULL){
3046 retval = MPI_SUCCESS;
3048 int myrank = smpi_process()->index();
3049 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3050 retval = win->unlock(rank);
3051 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3057 int PMPI_Win_lock_all(int assert, MPI_Win win){
3060 if (win == MPI_WIN_NULL) {
3061 retval = MPI_ERR_WIN;
3063 int myrank = smpi_process()->index();
3064 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3065 retval = win->lock_all(assert);
3066 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3072 int PMPI_Win_unlock_all(MPI_Win win){
3075 if (win == MPI_WIN_NULL) {
3076 retval = MPI_ERR_WIN;
3078 int myrank = smpi_process()->index();
3079 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3080 retval = win->unlock_all();
3081 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3087 int PMPI_Win_flush(int rank, MPI_Win win){
3090 if (win == MPI_WIN_NULL) {
3091 retval = MPI_ERR_WIN;
3092 } else if (rank == MPI_PROC_NULL){
3093 retval = MPI_SUCCESS;
3095 int myrank = smpi_process()->index();
3096 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3097 retval = win->flush(rank);
3098 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3104 int PMPI_Win_flush_local(int rank, MPI_Win win){
3107 if (win == MPI_WIN_NULL) {
3108 retval = MPI_ERR_WIN;
3109 } else if (rank == MPI_PROC_NULL){
3110 retval = MPI_SUCCESS;
3112 int myrank = smpi_process()->index();
3113 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3114 retval = win->flush_local(rank);
3115 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3121 int PMPI_Win_flush_all(MPI_Win win){
3124 if (win == MPI_WIN_NULL) {
3125 retval = MPI_ERR_WIN;
3127 int myrank = smpi_process()->index();
3128 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3129 retval = win->flush_all();
3130 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3136 int PMPI_Win_flush_local_all(MPI_Win win){
3139 if (win == MPI_WIN_NULL) {
3140 retval = MPI_ERR_WIN;
3142 int myrank = smpi_process()->index();
3143 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
3144 retval = win->flush_local_all();
3145 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
3151 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
3152 void *ptr = xbt_malloc(size);
3154 return MPI_ERR_NO_MEM;
3156 *static_cast<void**>(baseptr) = ptr;
3161 int PMPI_Free_mem(void *baseptr){
3166 int PMPI_Type_set_name(MPI_Datatype datatype, char * name)
3168 if (datatype == MPI_DATATYPE_NULL) {
3169 return MPI_ERR_TYPE;
3170 } else if (name == nullptr) {
3173 datatype->set_name(name);
3178 int PMPI_Type_get_name(MPI_Datatype datatype, char * name, int* len)
3180 if (datatype == MPI_DATATYPE_NULL) {
3181 return MPI_ERR_TYPE;
3182 } else if (name == nullptr) {
3185 datatype->get_name(name, len);
3190 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
3191 return static_cast<MPI_Datatype>(simgrid::smpi::F2C::f2c(datatype));
3194 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
3195 return datatype->c2f();
3198 MPI_Group PMPI_Group_f2c(MPI_Fint group){
3199 return simgrid::smpi::Group::f2c(group);
3202 MPI_Fint PMPI_Group_c2f(MPI_Group group){
3203 return group->c2f();
3206 MPI_Request PMPI_Request_f2c(MPI_Fint request){
3207 return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
3210 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
3211 return request->c2f();
3214 MPI_Win PMPI_Win_f2c(MPI_Fint win){
3215 return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
3218 MPI_Fint PMPI_Win_c2f(MPI_Win win){
3222 MPI_Op PMPI_Op_f2c(MPI_Fint op){
3223 return static_cast<MPI_Op>(simgrid::smpi::Op::f2c(op));
3226 MPI_Fint PMPI_Op_c2f(MPI_Op op){
3230 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
3231 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
3234 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
3238 MPI_Info PMPI_Info_f2c(MPI_Fint info){
3239 return static_cast<MPI_Info>(simgrid::smpi::Info::f2c(info));
3242 MPI_Fint PMPI_Info_c2f(MPI_Info info){
3246 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3247 smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr};
3248 smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr};
3249 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
3252 int PMPI_Keyval_free(int* keyval) {
3253 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Comm>(keyval);
3256 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3257 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3258 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3260 else if (comm==MPI_COMM_NULL)
3261 return MPI_ERR_COMM;
3263 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
3266 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3268 static int zero = 0;
3269 static int tag_ub = INT_MAX;
3270 static int last_used_code = MPI_ERR_LASTCODE;
3272 if (comm==MPI_COMM_NULL){
3274 return MPI_ERR_COMM;
3282 *static_cast<int**>(attr_value) = &zero;
3284 case MPI_UNIVERSE_SIZE:
3286 *static_cast<int**>(attr_value) = &smpi_universe_size;
3288 case MPI_LASTUSEDCODE:
3290 *static_cast<int**>(attr_value) = &last_used_code;
3294 *static_cast<int**>(attr_value) = &tag_ub;
3296 case MPI_WTIME_IS_GLOBAL:
3298 *static_cast<int**>(attr_value) = &one;
3301 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
3305 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3306 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3307 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3309 else if (comm==MPI_COMM_NULL)
3310 return MPI_ERR_COMM;
3312 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
3315 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3317 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3320 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3322 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3325 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3327 return PMPI_Attr_delete(comm, comm_keyval);
3330 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
3333 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3336 int PMPI_Comm_free_keyval(int* keyval) {
3337 return PMPI_Keyval_free(keyval);
3340 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3342 if (type==MPI_DATATYPE_NULL)
3343 return MPI_ERR_TYPE;
3345 return type->attr_get<simgrid::smpi::Datatype>(type_keyval, attribute_val, flag);
3348 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3350 if (type==MPI_DATATYPE_NULL)
3351 return MPI_ERR_TYPE;
3353 return type->attr_put<simgrid::smpi::Datatype>(type_keyval, attribute_val);
3356 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3358 if (type==MPI_DATATYPE_NULL)
3359 return MPI_ERR_TYPE;
3361 return type->attr_delete<simgrid::smpi::Datatype>(type_keyval);
3364 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
3367 smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr};
3368 smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr};
3369 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
3372 int PMPI_Type_free_keyval(int* keyval) {
3373 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Datatype>(keyval);
3376 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
3378 static MPI_Aint size;
3379 static int disp_unit;
3380 if (win==MPI_WIN_NULL)
3381 return MPI_ERR_TYPE;
3385 *static_cast<void**>(attribute_val) = win->base();
3390 *static_cast<MPI_Aint**>(attribute_val) = &size;
3393 case MPI_WIN_DISP_UNIT :
3394 disp_unit=win->disp_unit();
3395 *static_cast<int**>(attribute_val) = &disp_unit;
3399 return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
3405 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
3407 if (win==MPI_WIN_NULL)
3408 return MPI_ERR_TYPE;
3410 return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
3413 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
3415 if (win==MPI_WIN_NULL)
3416 return MPI_ERR_TYPE;
3418 return win->attr_delete<simgrid::smpi::Win>(type_keyval);
3421 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
3424 smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
3425 smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
3426 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
3429 int PMPI_Win_free_keyval(int* keyval) {
3430 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
3433 int PMPI_Info_create( MPI_Info *info){
3434 if (info == nullptr)
3436 *info = new simgrid::smpi::Info();
3440 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3441 if (info == nullptr || key == nullptr || value == nullptr)
3443 info->set(key, value);
3447 int PMPI_Info_free( MPI_Info *info){
3448 if (info == nullptr || *info==nullptr)
3450 simgrid::smpi::Info::unref(*info);
3451 *info=MPI_INFO_NULL;
3455 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3457 if (info == nullptr || key == nullptr || valuelen <0)
3459 if (value == nullptr)
3460 return MPI_ERR_INFO_VALUE;
3461 return info->get(key, valuelen, value, flag);
3464 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3465 if (info == nullptr || newinfo==nullptr)
3467 *newinfo = new simgrid::smpi::Info(info);
3471 int PMPI_Info_delete(MPI_Info info, char *key){
3472 if (info == nullptr || key==nullptr)
3474 return info->remove(key);
3477 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3478 if (info == nullptr || nkeys==nullptr)
3480 return info->get_nkeys(nkeys);
3483 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3484 if (info == nullptr || key==nullptr || n<0 || n> MPI_MAX_INFO_KEY)
3486 return info->get_nthkey(n, key);
3489 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3491 if (info == nullptr || key == nullptr || valuelen==nullptr)
3493 return info->get_valuelen(key, valuelen, flag);
3496 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3497 if(incount<0 || outcount < 0 || inbuf==nullptr || outbuf==nullptr)
3499 if(!type->is_valid())
3500 return MPI_ERR_TYPE;
3501 if(comm==MPI_COMM_NULL)
3502 return MPI_ERR_COMM;
3503 return type->unpack(inbuf, incount, position, outbuf,outcount, comm);
3506 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3507 if(incount<0 || outcount < 0|| inbuf==nullptr || outbuf==nullptr)
3509 if(!type->is_valid())
3510 return MPI_ERR_TYPE;
3511 if(comm==MPI_COMM_NULL)
3512 return MPI_ERR_COMM;
3513 return type->pack(inbuf, incount, outbuf,outcount,position, comm);
3516 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3519 if(!datatype->is_valid())
3520 return MPI_ERR_TYPE;
3521 if(comm==MPI_COMM_NULL)
3522 return MPI_ERR_COMM;
3524 *size=incount*datatype->size();