1 /* Copyright (c) 2007-2017. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include <simgrid/s4u/host.hpp>
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi, "Logging specific to SMPI (pmpi)");
12 //this function need to be here because of the calls to smpi_bench
13 void TRACE_smpi_set_category(const char *category)
15 //need to end bench otherwise categories for execution tasks are wrong
17 TRACE_internal_smpi_set_category (category);
18 //begin bench after changing process's category
22 /* PMPI User level calls */
23 extern "C" { // Obviously, the C MPI interface should use the C linkage
25 int PMPI_Init(int *argc, char ***argv)
27 // PMPI_Init is call only one time by only by SMPI process
29 MPI_Initialized(&already_init);
30 if(already_init == 0){
31 simgrid::smpi::Process::init(argc, argv);
32 smpi_process()->mark_as_initialized();
33 int rank = smpi_process()->index();
34 TRACE_smpi_init(rank);
35 TRACE_smpi_computing_init(rank);
36 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
37 extra->type = TRACING_INIT;
38 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
39 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
51 int rank = smpi_process()->index();
52 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
53 extra->type = TRACING_FINALIZE;
54 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
56 smpi_process()->finalize();
58 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
59 TRACE_smpi_finalize(smpi_process()->index());
60 smpi_process()->destroy();
64 int PMPI_Finalized(int* flag)
66 *flag=smpi_process()!=nullptr ? smpi_process()->finalized() : 0;
70 int PMPI_Get_version (int *version,int *subversion){
71 *version = MPI_VERSION;
72 *subversion= MPI_SUBVERSION;
76 int PMPI_Get_library_version (char *version,int *len){
78 snprintf(version,MPI_MAX_LIBRARY_VERSION_STRING,"SMPI Version %d.%d. Copyright The Simgrid Team 2007-2015",
79 SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR);
80 *len = strlen(version) > MPI_MAX_LIBRARY_VERSION_STRING ? MPI_MAX_LIBRARY_VERSION_STRING : strlen(version);
85 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
87 if (provided != nullptr) {
88 *provided = MPI_THREAD_SINGLE;
90 return MPI_Init(argc, argv);
93 int PMPI_Query_thread(int *provided)
95 if (provided == nullptr) {
98 *provided = MPI_THREAD_SINGLE;
103 int PMPI_Is_thread_main(int *flag)
105 if (flag == nullptr) {
108 *flag = smpi_process()->index() == 0;
113 int PMPI_Abort(MPI_Comm comm, int errorcode)
116 smpi_process()->destroy();
117 // FIXME: should kill all processes in comm instead
118 simcall_process_kill(SIMIX_process_self());
124 return smpi_mpi_wtime();
127 extern double sg_maxmin_precision;
130 return sg_maxmin_precision;
133 int PMPI_Address(void *location, MPI_Aint * address)
135 if (address==nullptr) {
138 *address = reinterpret_cast<MPI_Aint>(location);
143 int PMPI_Get_address(void *location, MPI_Aint * address)
145 return PMPI_Address(location, address);
148 int PMPI_Type_free(MPI_Datatype * datatype)
150 /* Free a predefined datatype is an error according to the standard, and should be checked for */
151 if (*datatype == MPI_DATATYPE_NULL) {
154 simgrid::smpi::Datatype::unref(*datatype);
159 int PMPI_Type_size(MPI_Datatype datatype, int *size)
161 if (datatype == MPI_DATATYPE_NULL) {
163 } else if (size == nullptr) {
166 *size = static_cast<int>(datatype->size());
171 int PMPI_Type_size_x(MPI_Datatype datatype, MPI_Count *size)
173 if (datatype == MPI_DATATYPE_NULL) {
175 } else if (size == nullptr) {
178 *size = static_cast<MPI_Count>(datatype->size());
183 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
185 if (datatype == MPI_DATATYPE_NULL) {
187 } else if (lb == nullptr || extent == nullptr) {
190 return datatype->extent(lb, extent);
194 int PMPI_Type_get_true_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
196 return PMPI_Type_get_extent(datatype, lb, extent);
199 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
201 if (datatype == MPI_DATATYPE_NULL) {
203 } else if (extent == nullptr) {
206 *extent = datatype->get_extent();
211 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
213 if (datatype == MPI_DATATYPE_NULL) {
215 } else if (disp == nullptr) {
218 *disp = datatype->lb();
223 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
225 if (datatype == MPI_DATATYPE_NULL) {
227 } else if (disp == nullptr) {
230 *disp = datatype->ub();
235 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
236 int retval = MPI_SUCCESS;
237 if (datatype == MPI_DATATYPE_NULL) {
240 *newtype = new simgrid::smpi::Datatype(datatype, &retval);
241 //error when duplicating, free the new datatype
242 if(retval!=MPI_SUCCESS){
243 simgrid::smpi::Datatype::unref(*newtype);
244 *newtype = MPI_DATATYPE_NULL;
250 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
252 if (function == nullptr || op == nullptr) {
255 *op = new simgrid::smpi::Op(function, (commute!=0));
260 int PMPI_Op_free(MPI_Op * op)
264 } else if (*op == MPI_OP_NULL) {
273 int PMPI_Group_free(MPI_Group * group)
275 if (group == nullptr) {
278 if(*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_EMPTY)
279 simgrid::smpi::Group::unref(*group);
280 *group = MPI_GROUP_NULL;
285 int PMPI_Group_size(MPI_Group group, int *size)
287 if (group == MPI_GROUP_NULL) {
288 return MPI_ERR_GROUP;
289 } else if (size == nullptr) {
292 *size = group->size();
297 int PMPI_Group_rank(MPI_Group group, int *rank)
299 if (group == MPI_GROUP_NULL) {
300 return MPI_ERR_GROUP;
301 } else if (rank == nullptr) {
304 *rank = group->rank(smpi_process()->index());
309 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2)
311 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
312 return MPI_ERR_GROUP;
314 for (int i = 0; i < n; i++) {
315 if(ranks1[i]==MPI_PROC_NULL){
316 ranks2[i]=MPI_PROC_NULL;
318 int index = group1->index(ranks1[i]);
319 ranks2[i] = group2->rank(index);
326 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
328 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
329 return MPI_ERR_GROUP;
330 } else if (result == nullptr) {
333 *result = group1->compare(group2);
338 int PMPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
341 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
342 return MPI_ERR_GROUP;
343 } else if (newgroup == nullptr) {
346 return group1->group_union(group2, newgroup);
350 int PMPI_Group_intersection(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->intersection(group2,newgroup);
362 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
364 if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
365 return MPI_ERR_GROUP;
366 } else if (newgroup == nullptr) {
369 return group1->difference(group2,newgroup);
373 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
375 if (group == MPI_GROUP_NULL) {
376 return MPI_ERR_GROUP;
377 } else if (newgroup == nullptr) {
380 return group->incl(n, ranks, newgroup);
384 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
386 if (group == MPI_GROUP_NULL) {
387 return MPI_ERR_GROUP;
388 } else if (newgroup == nullptr) {
393 if (group != MPI_COMM_WORLD->group()
394 && group != MPI_COMM_SELF->group() && group != MPI_GROUP_EMPTY)
397 } else if (n == group->size()) {
398 *newgroup = MPI_GROUP_EMPTY;
401 return group->excl(n,ranks,newgroup);
406 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
408 if (group == MPI_GROUP_NULL) {
409 return MPI_ERR_GROUP;
410 } else if (newgroup == nullptr) {
414 *newgroup = MPI_GROUP_EMPTY;
417 return group->range_incl(n,ranges,newgroup);
422 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup)
424 if (group == MPI_GROUP_NULL) {
425 return MPI_ERR_GROUP;
426 } else if (newgroup == nullptr) {
431 if (group != MPI_COMM_WORLD->group() && group != MPI_COMM_SELF->group() &&
432 group != MPI_GROUP_EMPTY)
436 return group->range_excl(n,ranges,newgroup);
441 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
443 if (comm == MPI_COMM_NULL) {
445 } else if (rank == nullptr) {
448 *rank = comm->rank();
453 int PMPI_Comm_size(MPI_Comm comm, int *size)
455 if (comm == MPI_COMM_NULL) {
457 } else if (size == nullptr) {
460 *size = comm->size();
465 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
467 if (comm == MPI_COMM_NULL) {
469 } else if (name == nullptr || len == nullptr) {
472 comm->get_name(name, len);
477 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
479 if (comm == MPI_COMM_NULL) {
481 } else if (group == nullptr) {
484 *group = comm->group();
485 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
491 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
493 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
495 } else if (result == nullptr) {
498 if (comm1 == comm2) { /* Same communicators means same groups */
501 *result = comm1->group()->compare(comm2->group());
502 if (*result == MPI_IDENT) {
503 *result = MPI_CONGRUENT;
510 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
512 if (comm == MPI_COMM_NULL) {
514 } else if (newcomm == nullptr) {
517 return comm->dup(newcomm);
521 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
523 if (comm == MPI_COMM_NULL) {
525 } else if (group == MPI_GROUP_NULL) {
526 return MPI_ERR_GROUP;
527 } else if (newcomm == nullptr) {
529 } else if(group->rank(smpi_process()->index())==MPI_UNDEFINED){
530 *newcomm= MPI_COMM_NULL;
534 *newcomm = new simgrid::smpi::Comm(group, nullptr);
539 int PMPI_Comm_free(MPI_Comm * comm)
541 if (comm == nullptr) {
543 } else if (*comm == MPI_COMM_NULL) {
546 simgrid::smpi::Comm::destroy(*comm);
547 *comm = MPI_COMM_NULL;
552 int PMPI_Comm_disconnect(MPI_Comm * comm)
554 /* TODO: wait until all communication in comm are done */
555 if (comm == nullptr) {
557 } else if (*comm == MPI_COMM_NULL) {
560 simgrid::smpi::Comm::destroy(*comm);
561 *comm = MPI_COMM_NULL;
566 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
571 if (comm_out == nullptr) {
572 retval = MPI_ERR_ARG;
573 } else if (comm == MPI_COMM_NULL) {
574 retval = MPI_ERR_COMM;
576 *comm_out = comm->split(color, key);
577 retval = MPI_SUCCESS;
584 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
589 if (comm_out == nullptr) {
590 retval = MPI_ERR_ARG;
591 } else if (comm == MPI_COMM_NULL) {
592 retval = MPI_ERR_COMM;
594 retval = MPI_Comm_create(comm, group, comm_out);
601 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
606 if (request == nullptr) {
607 retval = MPI_ERR_ARG;
608 } else if (comm == MPI_COMM_NULL) {
609 retval = MPI_ERR_COMM;
610 } else if (!datatype->is_valid()) {
611 retval = MPI_ERR_TYPE;
612 } else if (dst == MPI_PROC_NULL) {
613 retval = MPI_SUCCESS;
615 *request = simgrid::smpi::Request::send_init(buf, count, datatype, dst, tag, comm);
616 retval = MPI_SUCCESS;
619 if (retval != MPI_SUCCESS && request != nullptr)
620 *request = MPI_REQUEST_NULL;
624 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
629 if (request == nullptr) {
630 retval = MPI_ERR_ARG;
631 } else if (comm == MPI_COMM_NULL) {
632 retval = MPI_ERR_COMM;
633 } else if (!datatype->is_valid()) {
634 retval = MPI_ERR_TYPE;
635 } else if (src == MPI_PROC_NULL) {
636 retval = MPI_SUCCESS;
638 *request = simgrid::smpi::Request::recv_init(buf, count, datatype, src, tag, comm);
639 retval = MPI_SUCCESS;
642 if (retval != MPI_SUCCESS && request != nullptr)
643 *request = MPI_REQUEST_NULL;
647 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
652 if (request == nullptr) {
653 retval = MPI_ERR_ARG;
654 } else if (comm == MPI_COMM_NULL) {
655 retval = MPI_ERR_COMM;
656 } else if (!datatype->is_valid()) {
657 retval = MPI_ERR_TYPE;
658 } else if (dst == MPI_PROC_NULL) {
659 retval = MPI_SUCCESS;
661 *request = simgrid::smpi::Request::ssend_init(buf, count, datatype, dst, tag, comm);
662 retval = MPI_SUCCESS;
665 if (retval != MPI_SUCCESS && request != nullptr)
666 *request = MPI_REQUEST_NULL;
670 int PMPI_Start(MPI_Request * request)
675 if (request == nullptr || *request == MPI_REQUEST_NULL) {
676 retval = MPI_ERR_REQUEST;
679 retval = MPI_SUCCESS;
685 int PMPI_Startall(int count, MPI_Request * requests)
689 if (requests == nullptr) {
690 retval = MPI_ERR_ARG;
692 retval = MPI_SUCCESS;
693 for (int i = 0; i < count; i++) {
694 if(requests[i] == MPI_REQUEST_NULL) {
695 retval = MPI_ERR_REQUEST;
698 if(retval != MPI_ERR_REQUEST) {
699 simgrid::smpi::Request::startall(count, requests);
706 int PMPI_Request_free(MPI_Request * request)
711 if (*request == MPI_REQUEST_NULL) {
712 retval = MPI_ERR_ARG;
714 simgrid::smpi::Request::unref(request);
715 retval = MPI_SUCCESS;
721 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
727 if (request == nullptr) {
728 retval = MPI_ERR_ARG;
729 } else if (comm == MPI_COMM_NULL) {
730 retval = MPI_ERR_COMM;
731 } else if (src == MPI_PROC_NULL) {
732 *request = MPI_REQUEST_NULL;
733 retval = MPI_SUCCESS;
734 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
735 retval = MPI_ERR_RANK;
736 } else if ((count < 0) || (buf==nullptr && count > 0)) {
737 retval = MPI_ERR_COUNT;
738 } else if (!datatype->is_valid()) {
739 retval = MPI_ERR_TYPE;
740 } else if(tag<0 && tag != MPI_ANY_TAG){
741 retval = MPI_ERR_TAG;
744 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
745 int src_traced = comm->group()->index(src);
747 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
748 extra->type = TRACING_IRECV;
749 extra->src = src_traced;
752 extra->datatype1 = encode_datatype(datatype, &known);
753 int dt_size_send = 1;
755 dt_size_send = datatype->size();
756 extra->send_size = count*dt_size_send;
757 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
759 *request = simgrid::smpi::Request::irecv(buf, count, datatype, src, tag, comm);
760 retval = MPI_SUCCESS;
762 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
766 if (retval != MPI_SUCCESS && request != nullptr)
767 *request = MPI_REQUEST_NULL;
772 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
777 if (request == nullptr) {
778 retval = MPI_ERR_ARG;
779 } else if (comm == MPI_COMM_NULL) {
780 retval = MPI_ERR_COMM;
781 } else if (dst == MPI_PROC_NULL) {
782 *request = MPI_REQUEST_NULL;
783 retval = MPI_SUCCESS;
784 } else if (dst >= comm->group()->size() || dst <0){
785 retval = MPI_ERR_RANK;
786 } else if ((count < 0) || (buf==nullptr && count > 0)) {
787 retval = MPI_ERR_COUNT;
788 } else if (!datatype->is_valid()) {
789 retval = MPI_ERR_TYPE;
790 } else if(tag<0 && tag != MPI_ANY_TAG){
791 retval = MPI_ERR_TAG;
793 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
794 int dst_traced = comm->group()->index(dst);
795 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
796 extra->type = TRACING_ISEND;
798 extra->dst = dst_traced;
800 extra->datatype1 = encode_datatype(datatype, &known);
801 int dt_size_send = 1;
803 dt_size_send = datatype->size();
804 extra->send_size = count*dt_size_send;
805 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
806 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
808 *request = simgrid::smpi::Request::isend(buf, count, datatype, dst, tag, comm);
809 retval = MPI_SUCCESS;
811 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
815 if (retval != MPI_SUCCESS && request!=nullptr)
816 *request = MPI_REQUEST_NULL;
820 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
825 if (request == nullptr) {
826 retval = MPI_ERR_ARG;
827 } else if (comm == MPI_COMM_NULL) {
828 retval = MPI_ERR_COMM;
829 } else if (dst == MPI_PROC_NULL) {
830 *request = MPI_REQUEST_NULL;
831 retval = MPI_SUCCESS;
832 } else if (dst >= comm->group()->size() || dst <0){
833 retval = MPI_ERR_RANK;
834 } else if ((count < 0)|| (buf==nullptr && count > 0)) {
835 retval = MPI_ERR_COUNT;
836 } else if (!datatype->is_valid()) {
837 retval = MPI_ERR_TYPE;
838 } else if(tag<0 && tag != MPI_ANY_TAG){
839 retval = MPI_ERR_TAG;
841 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
842 int dst_traced = comm->group()->index(dst);
843 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
844 extra->type = TRACING_ISSEND;
846 extra->dst = dst_traced;
848 extra->datatype1 = encode_datatype(datatype, &known);
849 int dt_size_send = 1;
851 dt_size_send = datatype->size();
852 extra->send_size = count*dt_size_send;
853 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
854 TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
856 *request = simgrid::smpi::Request::issend(buf, count, datatype, dst, tag, comm);
857 retval = MPI_SUCCESS;
859 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
863 if (retval != MPI_SUCCESS && request!=nullptr)
864 *request = MPI_REQUEST_NULL;
868 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
873 if (comm == MPI_COMM_NULL) {
874 retval = MPI_ERR_COMM;
875 } else if (src == MPI_PROC_NULL) {
876 simgrid::smpi::Status::empty(status);
877 status->MPI_SOURCE = MPI_PROC_NULL;
878 retval = MPI_SUCCESS;
879 } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
880 retval = MPI_ERR_RANK;
881 } else if ((count < 0) || (buf==nullptr && count > 0)) {
882 retval = MPI_ERR_COUNT;
883 } else if (!datatype->is_valid()) {
884 retval = MPI_ERR_TYPE;
885 } else if(tag<0 && tag != MPI_ANY_TAG){
886 retval = MPI_ERR_TAG;
888 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
889 int src_traced = comm->group()->index(src);
890 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
891 extra->type = TRACING_RECV;
892 extra->src = src_traced;
895 extra->datatype1 = encode_datatype(datatype, &known);
896 int dt_size_send = 1;
898 dt_size_send = datatype->size();
899 extra->send_size = count * dt_size_send;
900 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
902 simgrid::smpi::Request::recv(buf, count, datatype, src, tag, comm, status);
903 retval = MPI_SUCCESS;
905 // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
906 if (status != MPI_STATUS_IGNORE) {
907 src_traced = comm->group()->index(status->MPI_SOURCE);
908 if (!TRACE_smpi_view_internals()) {
909 TRACE_smpi_recv(rank, src_traced, rank, tag);
912 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
919 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
925 if (comm == MPI_COMM_NULL) {
926 retval = MPI_ERR_COMM;
927 } else if (dst == MPI_PROC_NULL) {
928 retval = MPI_SUCCESS;
929 } else if (dst >= comm->group()->size() || dst <0){
930 retval = MPI_ERR_RANK;
931 } else if ((count < 0) || (buf == nullptr && count > 0)) {
932 retval = MPI_ERR_COUNT;
933 } else if (!datatype->is_valid()) {
934 retval = MPI_ERR_TYPE;
935 } else if(tag < 0 && tag != MPI_ANY_TAG){
936 retval = MPI_ERR_TAG;
938 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
939 int dst_traced = comm->group()->index(dst);
940 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
941 extra->type = TRACING_SEND;
943 extra->dst = dst_traced;
945 extra->datatype1 = encode_datatype(datatype, &known);
946 int dt_size_send = 1;
948 dt_size_send = datatype->size();
950 extra->send_size = count*dt_size_send;
951 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
952 if (!TRACE_smpi_view_internals()) {
953 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
956 simgrid::smpi::Request::send(buf, count, datatype, dst, tag, comm);
957 retval = MPI_SUCCESS;
959 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
966 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
971 if (comm == MPI_COMM_NULL) {
972 retval = MPI_ERR_COMM;
973 } else if (dst == MPI_PROC_NULL) {
974 retval = MPI_SUCCESS;
975 } else if (dst >= comm->group()->size() || dst <0){
976 retval = MPI_ERR_RANK;
977 } else if ((count < 0) || (buf==nullptr && count > 0)) {
978 retval = MPI_ERR_COUNT;
979 } else if (!datatype->is_valid()){
980 retval = MPI_ERR_TYPE;
981 } else if(tag<0 && tag != MPI_ANY_TAG){
982 retval = MPI_ERR_TAG;
984 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
985 int dst_traced = comm->group()->index(dst);
986 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
987 extra->type = TRACING_SSEND;
989 extra->dst = dst_traced;
991 extra->datatype1 = encode_datatype(datatype, &known);
992 int dt_size_send = 1;
994 dt_size_send = datatype->size();
996 extra->send_size = count*dt_size_send;
997 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
998 TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
1000 simgrid::smpi::Request::ssend(buf, count, datatype, dst, tag, comm);
1001 retval = MPI_SUCCESS;
1003 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1010 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void *recvbuf,
1011 int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status)
1017 if (comm == MPI_COMM_NULL) {
1018 retval = MPI_ERR_COMM;
1019 } else if (!sendtype->is_valid() || !recvtype->is_valid()) {
1020 retval = MPI_ERR_TYPE;
1021 } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1022 simgrid::smpi::Status::empty(status);
1023 status->MPI_SOURCE = MPI_PROC_NULL;
1024 retval = MPI_SUCCESS;
1025 }else if (dst >= comm->group()->size() || dst <0 ||
1026 (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0))){
1027 retval = MPI_ERR_RANK;
1028 } else if ((sendcount < 0 || recvcount<0) ||
1029 (sendbuf==nullptr && sendcount > 0) || (recvbuf==nullptr && recvcount>0)) {
1030 retval = MPI_ERR_COUNT;
1031 } else if((sendtag<0 && sendtag != MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1032 retval = MPI_ERR_TAG;
1035 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1036 int dst_traced = comm->group()->index(dst);
1037 int src_traced = comm->group()->index(src);
1038 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1039 extra->type = TRACING_SENDRECV;
1040 extra->src = src_traced;
1041 extra->dst = dst_traced;
1043 extra->datatype1 = encode_datatype(sendtype, &known);
1044 int dt_size_send = 1;
1046 dt_size_send = sendtype->size();
1047 extra->send_size = sendcount*dt_size_send;
1048 extra->datatype2 = encode_datatype(recvtype, &known);
1049 int dt_size_recv = 1;
1051 dt_size_recv = recvtype->size();
1052 extra->recv_size = recvcount*dt_size_recv;
1054 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1055 TRACE_smpi_send(rank, rank, dst_traced, sendtag,sendcount*sendtype->size());
1057 simgrid::smpi::Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm,
1059 retval = MPI_SUCCESS;
1061 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1062 TRACE_smpi_recv(rank, src_traced, rank, recvtag);
1069 int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,
1070 MPI_Comm comm, MPI_Status* status)
1073 if (!datatype->is_valid()) {
1074 return MPI_ERR_TYPE;
1075 } else if (count < 0) {
1076 return MPI_ERR_COUNT;
1078 int size = datatype->get_extent() * count;
1079 void* recvbuf = xbt_new0(char, size);
1080 retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
1081 if(retval==MPI_SUCCESS){
1082 simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
1090 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1094 if (request == nullptr || flag == nullptr) {
1095 retval = MPI_ERR_ARG;
1096 } else if (*request == MPI_REQUEST_NULL) {
1098 simgrid::smpi::Status::empty(status);
1099 retval = MPI_SUCCESS;
1101 int rank = ((*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1103 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1104 extra->type = TRACING_TEST;
1105 TRACE_smpi_testing_in(rank, extra);
1107 *flag = simgrid::smpi::Request::test(request,status);
1109 TRACE_smpi_testing_out(rank);
1110 retval = MPI_SUCCESS;
1116 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status)
1121 if (index == nullptr || flag == nullptr) {
1122 retval = MPI_ERR_ARG;
1124 *flag = simgrid::smpi::Request::testany(count, requests, index, status);
1125 retval = MPI_SUCCESS;
1131 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1136 if (flag == nullptr) {
1137 retval = MPI_ERR_ARG;
1139 *flag = simgrid::smpi::Request::testall(count, requests, statuses);
1140 retval = MPI_SUCCESS;
1146 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1150 if (status == nullptr) {
1151 retval = MPI_ERR_ARG;
1152 } else if (comm == MPI_COMM_NULL) {
1153 retval = MPI_ERR_COMM;
1154 } else if (source == MPI_PROC_NULL) {
1155 simgrid::smpi::Status::empty(status);
1156 status->MPI_SOURCE = MPI_PROC_NULL;
1157 retval = MPI_SUCCESS;
1159 simgrid::smpi::Request::probe(source, tag, comm, status);
1160 retval = MPI_SUCCESS;
1166 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1170 if ((flag == nullptr) || (status == nullptr)) {
1171 retval = MPI_ERR_ARG;
1172 } else if (comm == MPI_COMM_NULL) {
1173 retval = MPI_ERR_COMM;
1174 } else if (source == MPI_PROC_NULL) {
1176 simgrid::smpi::Status::empty(status);
1177 status->MPI_SOURCE = MPI_PROC_NULL;
1178 retval = MPI_SUCCESS;
1180 simgrid::smpi::Request::iprobe(source, tag, comm, flag, status);
1181 retval = MPI_SUCCESS;
1187 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1193 simgrid::smpi::Status::empty(status);
1195 if (request == nullptr) {
1196 retval = MPI_ERR_ARG;
1197 } else if (*request == MPI_REQUEST_NULL) {
1198 retval = MPI_SUCCESS;
1201 int rank = (request!=nullptr && (*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
1203 int src_traced = (*request)->src();
1204 int dst_traced = (*request)->dst();
1205 int tag_traced= (*request)->tag();
1206 MPI_Comm comm = (*request)->comm();
1207 int is_wait_for_receive = ((*request)->flags() & RECV);
1208 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1209 extra->type = TRACING_WAIT;
1210 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1212 simgrid::smpi::Request::wait(request, status);
1213 retval = MPI_SUCCESS;
1215 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1216 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1217 if (is_wait_for_receive) {
1218 if(src_traced==MPI_ANY_SOURCE)
1219 src_traced = (status!=MPI_STATUS_IGNORE) ?
1220 comm->group()->rank(status->MPI_SOURCE) :
1222 TRACE_smpi_recv(rank, src_traced, dst_traced, tag_traced);
1230 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1232 if (index == nullptr)
1236 //save requests information for tracing
1244 savedvalstype* savedvals=nullptr;
1246 savedvals = xbt_new0(savedvalstype, count);
1248 for (int i = 0; i < count; i++) {
1249 MPI_Request req = requests[i]; //already received requests are no longer valid
1251 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), req->comm()};
1254 int rank_traced = smpi_process()->index();
1255 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1256 extra->type = TRACING_WAITANY;
1257 extra->send_size=count;
1258 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1260 *index = simgrid::smpi::Request::waitany(count, requests, status);
1262 if(*index!=MPI_UNDEFINED){
1263 int src_traced = savedvals[*index].src;
1264 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1265 int dst_traced = savedvals[*index].dst;
1266 int is_wait_for_receive = savedvals[*index].recv;
1267 if (is_wait_for_receive) {
1268 if(savedvals[*index].src==MPI_ANY_SOURCE)
1269 src_traced = (status != MPI_STATUSES_IGNORE)
1270 ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
1271 : savedvals[*index].src;
1272 TRACE_smpi_recv(rank_traced, src_traced, dst_traced, savedvals[*index].tag);
1274 TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1276 xbt_free(savedvals);
1282 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1285 //save information from requests
1294 savedvalstype* savedvals=xbt_new0(savedvalstype, count);
1296 for (int i = 0; i < count; i++) {
1297 MPI_Request req = requests[i];
1298 if(req!=MPI_REQUEST_NULL){
1299 savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), 1, req->comm()};
1301 savedvals[i].valid=0;
1304 int rank_traced = smpi_process()->index();
1305 instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1306 extra->type = TRACING_WAITALL;
1307 extra->send_size=count;
1308 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1310 int retval = simgrid::smpi::Request::waitall(count, requests, status);
1312 for (int i = 0; i < count; i++) {
1313 if(savedvals[i].valid){
1314 //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1315 int src_traced = savedvals[i].src;
1316 int dst_traced = savedvals[i].dst;
1317 int is_wait_for_receive = savedvals[i].recv;
1318 if (is_wait_for_receive) {
1319 if(src_traced==MPI_ANY_SOURCE)
1320 src_traced = (status!=MPI_STATUSES_IGNORE) ?
1321 savedvals[i].comm->group()->rank(status[i].MPI_SOURCE) : savedvals[i].src;
1322 TRACE_smpi_recv(rank_traced, src_traced, dst_traced,savedvals[i].tag);
1326 TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1327 xbt_free(savedvals);
1333 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount, int *indices, MPI_Status status[])
1338 if (outcount == nullptr) {
1339 retval = MPI_ERR_ARG;
1341 *outcount = simgrid::smpi::Request::waitsome(incount, requests, indices, status);
1342 retval = MPI_SUCCESS;
1348 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[])
1353 if (outcount == nullptr) {
1354 retval = MPI_ERR_ARG;
1356 *outcount = simgrid::smpi::Request::testsome(incount, requests, indices, status);
1357 retval = MPI_SUCCESS;
1364 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1370 if (comm == MPI_COMM_NULL) {
1371 retval = MPI_ERR_COMM;
1372 } else if (!datatype->is_valid()) {
1373 retval = MPI_ERR_ARG;
1375 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1376 int root_traced = comm->group()->index(root);
1378 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1379 extra->type = TRACING_BCAST;
1380 extra->root = root_traced;
1382 extra->datatype1 = encode_datatype(datatype, &known);
1383 int dt_size_send = 1;
1385 dt_size_send = datatype->size();
1386 extra->send_size = count * dt_size_send;
1387 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1388 if (comm->size() > 1)
1389 simgrid::smpi::Colls::bcast(buf, count, datatype, root, comm);
1390 retval = MPI_SUCCESS;
1392 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1398 int PMPI_Barrier(MPI_Comm comm)
1404 if (comm == MPI_COMM_NULL) {
1405 retval = MPI_ERR_COMM;
1407 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1408 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1409 extra->type = TRACING_BARRIER;
1410 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1412 simgrid::smpi::Colls::barrier(comm);
1414 //Barrier can be used to synchronize RMA calls. Finish all requests from comm before.
1415 comm->finish_rma_calls();
1417 retval = MPI_SUCCESS;
1419 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1426 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
1427 int root, MPI_Comm comm)
1433 if (comm == MPI_COMM_NULL) {
1434 retval = MPI_ERR_COMM;
1435 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1436 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1437 retval = MPI_ERR_TYPE;
1438 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) || ((comm->rank() == root) && (recvcount <0))){
1439 retval = MPI_ERR_COUNT;
1442 char* sendtmpbuf = static_cast<char*>(sendbuf);
1443 int sendtmpcount = sendcount;
1444 MPI_Datatype sendtmptype = sendtype;
1445 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1447 sendtmptype=recvtype;
1449 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1450 int root_traced = comm->group()->index(root);
1451 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1452 extra->type = TRACING_GATHER;
1453 extra->root = root_traced;
1455 extra->datatype1 = encode_datatype(sendtmptype, &known);
1456 int dt_size_send = 1;
1458 dt_size_send = sendtmptype->size();
1459 extra->send_size = sendtmpcount * dt_size_send;
1460 extra->datatype2 = encode_datatype(recvtype, &known);
1461 int dt_size_recv = 1;
1462 if ((comm->rank() == root) && known == 0)
1463 dt_size_recv = recvtype->size();
1464 extra->recv_size = recvcount * dt_size_recv;
1466 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1468 simgrid::smpi::Colls::gather(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
1470 retval = MPI_SUCCESS;
1471 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1478 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
1479 MPI_Datatype recvtype, int root, MPI_Comm comm)
1485 if (comm == MPI_COMM_NULL) {
1486 retval = MPI_ERR_COMM;
1487 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1488 ((comm->rank() == root) && (recvtype == MPI_DATATYPE_NULL))){
1489 retval = MPI_ERR_TYPE;
1490 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1491 retval = MPI_ERR_COUNT;
1492 } else if (recvcounts == nullptr || displs == nullptr) {
1493 retval = MPI_ERR_ARG;
1495 char* sendtmpbuf = static_cast<char*>(sendbuf);
1496 int sendtmpcount = sendcount;
1497 MPI_Datatype sendtmptype = sendtype;
1498 if( (comm->rank() == root) && (sendbuf == MPI_IN_PLACE )) {
1500 sendtmptype=recvtype;
1503 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1504 int root_traced = comm->group()->index(root);
1506 int size = comm->size();
1507 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1508 extra->type = TRACING_GATHERV;
1509 extra->num_processes = size;
1510 extra->root = root_traced;
1512 extra->datatype1 = encode_datatype(sendtmptype, &known);
1513 int dt_size_send = 1;
1515 dt_size_send = sendtype->size();
1516 extra->send_size = sendtmpcount * dt_size_send;
1517 extra->datatype2 = encode_datatype(recvtype, &known);
1518 int dt_size_recv = 1;
1520 dt_size_recv = recvtype->size();
1521 if ((comm->rank() == root)) {
1522 extra->recvcounts = xbt_new(int, size);
1523 for (i = 0; i < size; i++) // copy data to avoid bad free
1524 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1526 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1528 retval = simgrid::smpi::Colls::gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
1529 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1536 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1537 void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
1543 if (comm == MPI_COMM_NULL) {
1544 retval = MPI_ERR_COMM;
1545 } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1546 (recvtype == MPI_DATATYPE_NULL)){
1547 retval = MPI_ERR_TYPE;
1548 } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1550 retval = MPI_ERR_COUNT;
1552 if(sendbuf == MPI_IN_PLACE) {
1553 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*recvcount*comm->rank();
1554 sendcount=recvcount;
1557 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1558 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1559 extra->type = TRACING_ALLGATHER;
1561 extra->datatype1 = encode_datatype(sendtype, &known);
1562 int dt_size_send = 1;
1564 dt_size_send = sendtype->size();
1565 extra->send_size = sendcount * dt_size_send;
1566 extra->datatype2 = encode_datatype(recvtype, &known);
1567 int dt_size_recv = 1;
1569 dt_size_recv = recvtype->size();
1570 extra->recv_size = recvcount * dt_size_recv;
1572 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1574 simgrid::smpi::Colls::allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
1575 retval = MPI_SUCCESS;
1576 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1582 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1583 void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
1589 if (comm == MPI_COMM_NULL) {
1590 retval = MPI_ERR_COMM;
1591 } else if (((sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) || (recvtype == MPI_DATATYPE_NULL)) {
1592 retval = MPI_ERR_TYPE;
1593 } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1594 retval = MPI_ERR_COUNT;
1595 } else if (recvcounts == nullptr || displs == nullptr) {
1596 retval = MPI_ERR_ARG;
1599 if(sendbuf == MPI_IN_PLACE) {
1600 sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*displs[comm->rank()];
1601 sendcount=recvcounts[comm->rank()];
1604 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1606 int size = comm->size();
1607 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1608 extra->type = TRACING_ALLGATHERV;
1609 extra->num_processes = size;
1611 extra->datatype1 = encode_datatype(sendtype, &known);
1612 int dt_size_send = 1;
1614 dt_size_send = sendtype->size();
1615 extra->send_size = sendcount * dt_size_send;
1616 extra->datatype2 = encode_datatype(recvtype, &known);
1617 int dt_size_recv = 1;
1619 dt_size_recv = recvtype->size();
1620 extra->recvcounts = xbt_new(int, size);
1621 for (i = 0; i < size; i++) // copy data to avoid bad free
1622 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
1624 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1626 simgrid::smpi::Colls::allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
1627 retval = MPI_SUCCESS;
1628 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1635 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1636 void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1642 if (comm == MPI_COMM_NULL) {
1643 retval = MPI_ERR_COMM;
1644 } else if (((comm->rank() == root) && (!sendtype->is_valid())) ||
1645 ((recvbuf != MPI_IN_PLACE) && (!recvtype->is_valid()))) {
1646 retval = MPI_ERR_TYPE;
1647 } else if ((sendbuf == recvbuf) ||
1648 ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
1649 retval = MPI_ERR_BUFFER;
1652 if (recvbuf == MPI_IN_PLACE) {
1653 recvtype = sendtype;
1654 recvcount = sendcount;
1656 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1657 int root_traced = comm->group()->index(root);
1658 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1659 extra->type = TRACING_SCATTER;
1660 extra->root = root_traced;
1662 extra->datatype1 = encode_datatype(sendtype, &known);
1663 int dt_size_send = 1;
1664 if ((comm->rank() == root) && known == 0)
1665 dt_size_send = sendtype->size();
1666 extra->send_size = sendcount * dt_size_send;
1667 extra->datatype2 = encode_datatype(recvtype, &known);
1668 int dt_size_recv = 1;
1670 dt_size_recv = recvtype->size();
1671 extra->recv_size = recvcount * dt_size_recv;
1672 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1674 simgrid::smpi::Colls::scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
1675 retval = MPI_SUCCESS;
1676 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1683 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1684 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
1690 if (comm == MPI_COMM_NULL) {
1691 retval = MPI_ERR_COMM;
1692 } else if (sendcounts == nullptr || displs == nullptr) {
1693 retval = MPI_ERR_ARG;
1694 } else if (((comm->rank() == root) && (sendtype == MPI_DATATYPE_NULL)) ||
1695 ((recvbuf != MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1696 retval = MPI_ERR_TYPE;
1698 if (recvbuf == MPI_IN_PLACE) {
1699 recvtype = sendtype;
1700 recvcount = sendcounts[comm->rank()];
1702 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1703 int root_traced = comm->group()->index(root);
1705 int size = comm->size();
1706 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1707 extra->type = TRACING_SCATTERV;
1708 extra->num_processes = size;
1709 extra->root = root_traced;
1711 extra->datatype1 = encode_datatype(sendtype, &known);
1712 int dt_size_send = 1;
1714 dt_size_send = sendtype->size();
1715 if ((comm->rank() == root)) {
1716 extra->sendcounts = xbt_new(int, size);
1717 for (i = 0; i < size; i++) // copy data to avoid bad free
1718 extra->sendcounts[i] = sendcounts[i] * dt_size_send;
1720 extra->datatype2 = encode_datatype(recvtype, &known);
1721 int dt_size_recv = 1;
1723 dt_size_recv = recvtype->size();
1724 extra->recv_size = recvcount * dt_size_recv;
1725 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1727 retval = simgrid::smpi::Colls::scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
1729 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1736 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
1742 if (comm == MPI_COMM_NULL) {
1743 retval = MPI_ERR_COMM;
1744 } else if (!datatype->is_valid() || op == MPI_OP_NULL) {
1745 retval = MPI_ERR_ARG;
1747 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1748 int root_traced = comm->group()->index(root);
1749 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1750 extra->type = TRACING_REDUCE;
1752 extra->datatype1 = encode_datatype(datatype, &known);
1753 int dt_size_send = 1;
1755 dt_size_send = datatype->size();
1756 extra->send_size = count * dt_size_send;
1757 extra->root = root_traced;
1759 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1761 simgrid::smpi::Colls::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
1763 retval = MPI_SUCCESS;
1764 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1771 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op){
1775 if (!datatype->is_valid() || op == MPI_OP_NULL) {
1776 retval = MPI_ERR_ARG;
1778 op->apply(inbuf, inoutbuf, &count, datatype);
1779 retval = MPI_SUCCESS;
1785 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1791 if (comm == MPI_COMM_NULL) {
1792 retval = MPI_ERR_COMM;
1793 } else if (!datatype->is_valid()) {
1794 retval = MPI_ERR_TYPE;
1795 } else if (op == MPI_OP_NULL) {
1796 retval = MPI_ERR_OP;
1799 char* sendtmpbuf = static_cast<char*>(sendbuf);
1800 if( sendbuf == MPI_IN_PLACE ) {
1801 sendtmpbuf = static_cast<char*>(xbt_malloc(count*datatype->get_extent()));
1802 simgrid::smpi::Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
1804 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1805 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1806 extra->type = TRACING_ALLREDUCE;
1808 extra->datatype1 = encode_datatype(datatype, &known);
1809 int dt_size_send = 1;
1811 dt_size_send = datatype->size();
1812 extra->send_size = count * dt_size_send;
1814 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1816 simgrid::smpi::Colls::allreduce(sendtmpbuf, recvbuf, count, datatype, op, comm);
1818 if( sendbuf == MPI_IN_PLACE )
1819 xbt_free(sendtmpbuf);
1821 retval = MPI_SUCCESS;
1822 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1829 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1835 if (comm == MPI_COMM_NULL) {
1836 retval = MPI_ERR_COMM;
1837 } else if (!datatype->is_valid()) {
1838 retval = MPI_ERR_TYPE;
1839 } else if (op == MPI_OP_NULL) {
1840 retval = MPI_ERR_OP;
1842 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1843 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1844 extra->type = TRACING_SCAN;
1846 extra->datatype1 = encode_datatype(datatype, &known);
1847 int dt_size_send = 1;
1849 dt_size_send = datatype->size();
1850 extra->send_size = count * dt_size_send;
1852 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1854 retval = simgrid::smpi::Colls::scan(sendbuf, recvbuf, count, datatype, op, comm);
1856 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1863 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
1868 if (comm == MPI_COMM_NULL) {
1869 retval = MPI_ERR_COMM;
1870 } else if (!datatype->is_valid()) {
1871 retval = MPI_ERR_TYPE;
1872 } else if (op == MPI_OP_NULL) {
1873 retval = MPI_ERR_OP;
1875 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1876 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1877 extra->type = TRACING_EXSCAN;
1879 extra->datatype1 = encode_datatype(datatype, &known);
1880 int dt_size_send = 1;
1882 dt_size_send = datatype->size();
1883 extra->send_size = count * dt_size_send;
1884 void* sendtmpbuf = sendbuf;
1885 if (sendbuf == MPI_IN_PLACE) {
1886 sendtmpbuf = static_cast<void*>(xbt_malloc(count * datatype->size()));
1887 memcpy(sendtmpbuf, recvbuf, count * datatype->size());
1889 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1891 retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
1893 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1894 if (sendbuf == MPI_IN_PLACE)
1895 xbt_free(sendtmpbuf);
1902 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1907 if (comm == MPI_COMM_NULL) {
1908 retval = MPI_ERR_COMM;
1909 } else if (!datatype->is_valid()) {
1910 retval = MPI_ERR_TYPE;
1911 } else if (op == MPI_OP_NULL) {
1912 retval = MPI_ERR_OP;
1913 } else if (recvcounts == nullptr) {
1914 retval = MPI_ERR_ARG;
1916 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1918 int size = comm->size();
1919 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1920 extra->type = TRACING_REDUCE_SCATTER;
1921 extra->num_processes = size;
1923 extra->datatype1 = encode_datatype(datatype, &known);
1924 int dt_size_send = 1;
1926 dt_size_send = datatype->size();
1927 extra->send_size = 0;
1928 extra->recvcounts = xbt_new(int, size);
1930 for (i = 0; i < size; i++) { // copy data to avoid bad free
1931 extra->recvcounts[i] = recvcounts[i] * dt_size_send;
1932 totalcount += recvcounts[i];
1934 void* sendtmpbuf = sendbuf;
1935 if (sendbuf == MPI_IN_PLACE) {
1936 sendtmpbuf = static_cast<void*>(xbt_malloc(totalcount * datatype->size()));
1937 memcpy(sendtmpbuf, recvbuf, totalcount * datatype->size());
1940 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1942 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1943 retval = MPI_SUCCESS;
1944 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1946 if (sendbuf == MPI_IN_PLACE)
1947 xbt_free(sendtmpbuf);
1954 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
1955 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
1960 if (comm == MPI_COMM_NULL) {
1961 retval = MPI_ERR_COMM;
1962 } else if (!datatype->is_valid()) {
1963 retval = MPI_ERR_TYPE;
1964 } else if (op == MPI_OP_NULL) {
1965 retval = MPI_ERR_OP;
1966 } else if (recvcount < 0) {
1967 retval = MPI_ERR_ARG;
1969 int count = comm->size();
1971 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
1972 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
1973 extra->type = TRACING_REDUCE_SCATTER;
1974 extra->num_processes = count;
1976 extra->datatype1 = encode_datatype(datatype, &known);
1977 int dt_size_send = 1;
1979 dt_size_send = datatype->size();
1980 extra->send_size = 0;
1981 extra->recvcounts = xbt_new(int, count);
1982 for (int i = 0; i < count; i++) // copy data to avoid bad free
1983 extra->recvcounts[i] = recvcount * dt_size_send;
1984 void* sendtmpbuf = sendbuf;
1985 if (sendbuf == MPI_IN_PLACE) {
1986 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * count * datatype->size()));
1987 memcpy(sendtmpbuf, recvbuf, recvcount * count * datatype->size());
1990 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1992 int* recvcounts = static_cast<int*>(xbt_malloc(count * sizeof(int)));
1993 for (int i = 0; i < count; i++)
1994 recvcounts[i] = recvcount;
1995 simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
1996 xbt_free(recvcounts);
1997 retval = MPI_SUCCESS;
1999 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2001 if (sendbuf == MPI_IN_PLACE)
2002 xbt_free(sendtmpbuf);
2009 int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
2010 MPI_Datatype recvtype, MPI_Comm comm)
2015 if (comm == MPI_COMM_NULL) {
2016 retval = MPI_ERR_COMM;
2017 } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL) || recvtype == MPI_DATATYPE_NULL) {
2018 retval = MPI_ERR_TYPE;
2020 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2021 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2022 extra->type = TRACING_ALLTOALL;
2024 void* sendtmpbuf = static_cast<char*>(sendbuf);
2025 int sendtmpcount = sendcount;
2026 MPI_Datatype sendtmptype = sendtype;
2027 if (sendbuf == MPI_IN_PLACE) {
2028 sendtmpbuf = static_cast<void*>(xbt_malloc(recvcount * comm->size() * recvtype->size()));
2029 memcpy(sendtmpbuf, recvbuf, recvcount * comm->size() * recvtype->size());
2030 sendtmpcount = recvcount;
2031 sendtmptype = recvtype;
2035 extra->datatype1 = encode_datatype(sendtmptype, &known);
2037 extra->send_size = sendtmpcount * sendtmptype->size();
2039 extra->send_size = sendtmpcount;
2040 extra->datatype2 = encode_datatype(recvtype, &known);
2042 extra->recv_size = recvcount * recvtype->size();
2044 extra->recv_size = recvcount;
2046 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2048 retval = simgrid::smpi::Colls::alltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
2050 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2052 if (sendbuf == MPI_IN_PLACE)
2053 xbt_free(sendtmpbuf);
2060 int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
2061 int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2067 if (comm == MPI_COMM_NULL) {
2068 retval = MPI_ERR_COMM;
2069 } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
2070 retval = MPI_ERR_TYPE;
2071 } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
2072 recvdisps == nullptr) {
2073 retval = MPI_ERR_ARG;
2075 int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
2077 int size = comm->size();
2078 instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
2079 extra->type = TRACING_ALLTOALLV;
2080 extra->send_size = 0;
2081 extra->recv_size = 0;
2082 extra->recvcounts = xbt_new(int, size);
2083 extra->sendcounts = xbt_new(int, size);
2085 int dt_size_recv = 1;
2086 extra->datatype2 = encode_datatype(recvtype, &known);
2087 dt_size_recv = recvtype->size();
2089 void* sendtmpbuf = static_cast<char*>(sendbuf);
2090 int* sendtmpcounts = sendcounts;
2091 int* sendtmpdisps = senddisps;
2092 MPI_Datatype sendtmptype = sendtype;
2094 for (i = 0; i < size; i++) { // copy data to avoid bad free
2095 extra->recv_size += recvcounts[i] * dt_size_recv;
2096 extra->recvcounts[i] = recvcounts[i] * dt_size_recv;
2097 if (((recvdisps[i] + recvcounts[i]) * dt_size_recv) > maxsize)
2098 maxsize = (recvdisps[i] + recvcounts[i]) * dt_size_recv;
2101 if (sendbuf == MPI_IN_PLACE) {
2102 sendtmpbuf = static_cast<void*>(xbt_malloc(maxsize));
2103 memcpy(sendtmpbuf, recvbuf, maxsize);
2104 sendtmpcounts = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2105 memcpy(sendtmpcounts, recvcounts, size * sizeof(int));
2106 sendtmpdisps = static_cast<int*>(xbt_malloc(size * sizeof(int)));
2107 memcpy(sendtmpdisps, recvdisps, size * sizeof(int));
2108 sendtmptype = recvtype;
2111 extra->datatype1 = encode_datatype(sendtmptype, &known);
2112 int dt_size_send = 1;
2113 dt_size_send = sendtmptype->size();
2115 for (i = 0; i < size; i++) { // copy data to avoid bad free
2116 extra->send_size += sendtmpcounts[i] * dt_size_send;
2117 extra->sendcounts[i] = sendtmpcounts[i] * dt_size_send;
2119 extra->num_processes = size;
2120 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
2121 retval = simgrid::smpi::Colls::alltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
2122 recvdisps, recvtype, comm);
2123 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2125 if (sendbuf == MPI_IN_PLACE) {
2126 xbt_free(sendtmpbuf);
2127 xbt_free(sendtmpcounts);
2128 xbt_free(sendtmpdisps);
2137 int PMPI_Get_processor_name(char *name, int *resultlen)
2139 strncpy(name, SIMIX_host_self()->cname(), strlen(SIMIX_host_self()->cname()) < MPI_MAX_PROCESSOR_NAME - 1
2140 ? strlen(SIMIX_host_self()->cname()) + 1
2141 : MPI_MAX_PROCESSOR_NAME - 1);
2142 *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2147 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2149 if (status == nullptr || count == nullptr) {
2151 } else if (!datatype->is_valid()) {
2152 return MPI_ERR_TYPE;
2154 size_t size = datatype->size();
2158 } else if (status->count % size != 0) {
2159 return MPI_UNDEFINED;
2161 *count = simgrid::smpi::Status::get_count(status, datatype);
2167 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2168 if (old_type == MPI_DATATYPE_NULL) {
2169 return MPI_ERR_TYPE;
2170 } else if (count<0){
2171 return MPI_ERR_COUNT;
2173 return simgrid::smpi::Datatype::create_contiguous(count, old_type, 0, new_type);
2177 int PMPI_Type_commit(MPI_Datatype* datatype) {
2178 if (datatype == nullptr || *datatype == MPI_DATATYPE_NULL) {
2179 return MPI_ERR_TYPE;
2181 (*datatype)->commit();
2186 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2187 if (old_type == MPI_DATATYPE_NULL) {
2188 return MPI_ERR_TYPE;
2189 } else if (count<0 || blocklen<0){
2190 return MPI_ERR_COUNT;
2192 return simgrid::smpi::Datatype::create_vector(count, blocklen, stride, old_type, new_type);
2196 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint 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_hvector(count, blocklen, stride, old_type, new_type);
2206 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2207 return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2210 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2211 if (old_type == MPI_DATATYPE_NULL) {
2212 return MPI_ERR_TYPE;
2213 } else if (count<0){
2214 return MPI_ERR_COUNT;
2216 return simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2220 int PMPI_Type_create_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_block(int count, int blocklength, int* indices, MPI_Datatype old_type,
2231 MPI_Datatype* new_type)
2233 if (old_type == MPI_DATATYPE_NULL) {
2234 return MPI_ERR_TYPE;
2235 } else if (count<0){
2236 return MPI_ERR_COUNT;
2238 int* blocklens=static_cast<int*>(xbt_malloc(blocklength*count*sizeof(int)));
2239 for (int i = 0; i < count; i++)
2240 blocklens[i]=blocklength;
2241 int retval = simgrid::smpi::Datatype::create_indexed(count, blocklens, indices, old_type, new_type);
2242 xbt_free(blocklens);
2247 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
2249 if (old_type == MPI_DATATYPE_NULL) {
2250 return MPI_ERR_TYPE;
2251 } else if (count<0){
2252 return MPI_ERR_COUNT;
2254 return simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2258 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type,
2259 MPI_Datatype* new_type) {
2260 return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2263 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type,
2264 MPI_Datatype* new_type) {
2265 if (old_type == MPI_DATATYPE_NULL) {
2266 return MPI_ERR_TYPE;
2267 } else if (count<0){
2268 return MPI_ERR_COUNT;
2270 int* blocklens=(int*)xbt_malloc(blocklength*count*sizeof(int));
2271 for (int i = 0; i < count; i++)
2272 blocklens[i] = blocklength;
2273 int retval = simgrid::smpi::Datatype::create_hindexed(count, blocklens, indices, old_type, new_type);
2274 xbt_free(blocklens);
2279 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2281 return MPI_ERR_COUNT;
2283 return simgrid::smpi::Datatype::create_struct(count, blocklens, indices, old_types, new_type);
2287 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types,
2288 MPI_Datatype* new_type) {
2289 return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2292 int PMPI_Error_class(int errorcode, int* errorclass) {
2293 // assume smpi uses only standard mpi error codes
2294 *errorclass=errorcode;
2298 int PMPI_Initialized(int* flag) {
2299 *flag=(smpi_process()!=nullptr && smpi_process()->initialized());
2303 /* The topo part of MPI_COMM_WORLD should always be nullptr. When other topologies will be implemented, not only should we
2304 * check if the topology is nullptr, but we should check if it is the good topology type (so we have to add a
2305 * MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2307 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2308 if (comm_old == MPI_COMM_NULL){
2309 return MPI_ERR_COMM;
2310 } else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
2313 simgrid::smpi::Topo_Cart* topo = new simgrid::smpi::Topo_Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
2314 if(*comm_cart==MPI_COMM_NULL)
2320 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2321 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2322 return MPI_ERR_TOPOLOGY;
2324 if (coords == nullptr) {
2327 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2328 if (topo==nullptr) {
2331 return topo->rank(coords, rank);
2334 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2335 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2336 return MPI_ERR_TOPOLOGY;
2338 if (source == nullptr || dest == nullptr || direction < 0 ) {
2341 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2342 if (topo==nullptr) {
2345 return topo->shift(direction, displ, source, dest);
2348 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2349 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2350 return MPI_ERR_TOPOLOGY;
2352 if (rank < 0 || rank >= comm->size()) {
2353 return MPI_ERR_RANK;
2358 if(coords == nullptr) {
2361 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2362 if (topo==nullptr) {
2365 return topo->coords(rank, maxdims, coords);
2368 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2369 if(comm == nullptr || comm->topo() == nullptr) {
2370 return MPI_ERR_TOPOLOGY;
2372 if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
2375 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2376 if (topo==nullptr) {
2379 return topo->get(maxdims, dims, periods, coords);
2382 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2383 if (comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2384 return MPI_ERR_TOPOLOGY;
2386 if (ndims == nullptr) {
2389 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2390 if (topo==nullptr) {
2393 return topo->dim_get(ndims);
2396 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2397 if(dims == nullptr) {
2400 if (ndims < 1 || nnodes < 1) {
2401 return MPI_ERR_DIMS;
2403 return simgrid::smpi::Topo_Cart::Dims_create(nnodes, ndims, dims);
2406 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2407 if(comm == MPI_COMM_NULL || comm->topo() == nullptr) {
2408 return MPI_ERR_TOPOLOGY;
2410 if (comm_new == nullptr) {
2413 MPIR_Cart_Topology topo = static_cast<MPIR_Cart_Topology>(comm->topo());
2414 if (topo==nullptr) {
2417 MPIR_Cart_Topology cart = topo->sub(remain_dims, comm_new);
2418 if(*comm_new==MPI_COMM_NULL)
2425 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2426 if (oldtype == MPI_DATATYPE_NULL) {
2427 return MPI_ERR_TYPE;
2429 int blocks[3] = {1, 1, 1};
2430 MPI_Aint disps[3] = {lb, 0, lb + extent};
2431 MPI_Datatype types[3] = {MPI_LB, oldtype, MPI_UB};
2433 *newtype = new simgrid::smpi::Type_Struct(oldtype->size(), lb, lb + extent, DT_FLAG_DERIVED, 3, blocks, disps, types);
2435 (*newtype)->addflag(~DT_FLAG_COMMITED);
2439 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2442 if (comm == MPI_COMM_NULL) {
2443 retval= MPI_ERR_COMM;
2444 }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
2445 retval= MPI_ERR_OTHER;
2447 *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
2448 retval = MPI_SUCCESS;
2454 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
2457 if (comm == MPI_COMM_NULL) {
2458 retval= MPI_ERR_COMM;
2459 }else if (disp_unit <= 0 || size < 0 ){
2460 retval= MPI_ERR_OTHER;
2462 void* ptr = xbt_malloc(size);
2464 return MPI_ERR_NO_MEM;
2465 *static_cast<void**>(base) = ptr;
2466 *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
2467 retval = MPI_SUCCESS;
2473 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
2476 if (comm == MPI_COMM_NULL) {
2477 retval= MPI_ERR_COMM;
2479 *win = new simgrid::smpi::Win(info, comm);
2480 retval = MPI_SUCCESS;
2486 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
2489 if(win == MPI_WIN_NULL){
2490 retval = MPI_ERR_WIN;
2491 } else if ((base == nullptr && size != 0) || size < 0 ){
2492 retval= MPI_ERR_OTHER;
2494 retval = win->attach(base, size);
2500 int PMPI_Win_detach(MPI_Win win, void *base){
2503 if(win == MPI_WIN_NULL){
2504 retval = MPI_ERR_WIN;
2505 } else if (base == nullptr){
2506 retval= MPI_ERR_OTHER;
2508 retval = win->detach(base);
2515 int PMPI_Win_free( MPI_Win* win){
2518 if (win == nullptr || *win == MPI_WIN_NULL) {
2519 retval = MPI_ERR_WIN;
2528 int PMPI_Win_set_name(MPI_Win win, char * name)
2530 if (win == MPI_WIN_NULL) {
2531 return MPI_ERR_TYPE;
2532 } else if (name == nullptr) {
2535 win->set_name(name);
2540 int PMPI_Win_get_name(MPI_Win win, char * name, int* len)
2542 if (win == MPI_WIN_NULL) {
2544 } else if (name == nullptr) {
2547 win->get_name(name, len);
2552 int PMPI_Win_get_info(MPI_Win win, MPI_Info* info)
2554 if (win == MPI_WIN_NULL) {
2557 *info = win->info();
2562 int PMPI_Win_set_info(MPI_Win win, MPI_Info info)
2564 if (win == MPI_WIN_NULL) {
2565 return MPI_ERR_TYPE;
2567 win->set_info(info);
2572 int PMPI_Win_get_group(MPI_Win win, MPI_Group * group){
2573 if (win == MPI_WIN_NULL) {
2576 win->get_group(group);
2582 int PMPI_Win_fence( int assert, MPI_Win win){
2585 if (win == MPI_WIN_NULL) {
2586 retval = MPI_ERR_WIN;
2588 int rank = smpi_process()->index();
2589 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2590 retval = win->fence(assert);
2591 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2597 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2598 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2601 if (win == MPI_WIN_NULL) {
2602 retval = MPI_ERR_WIN;
2603 } else if (target_rank == MPI_PROC_NULL) {
2604 retval = MPI_SUCCESS;
2605 } else if (target_rank <0){
2606 retval = MPI_ERR_RANK;
2607 } else if (target_disp <0){
2608 retval = MPI_ERR_ARG;
2609 } else if ((origin_count < 0 || target_count < 0) ||
2610 (origin_addr==nullptr && origin_count > 0)){
2611 retval = MPI_ERR_COUNT;
2612 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2613 retval = MPI_ERR_TYPE;
2615 int rank = smpi_process()->index();
2617 win->get_group(&group);
2618 int src_traced = group->index(target_rank);
2619 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2621 retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2624 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2630 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2631 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2634 if (win == MPI_WIN_NULL) {
2635 retval = MPI_ERR_WIN;
2636 } else if (target_rank == MPI_PROC_NULL) {
2637 retval = MPI_SUCCESS;
2638 } else if (target_rank <0){
2639 retval = MPI_ERR_RANK;
2640 } else if (target_disp <0){
2641 retval = MPI_ERR_ARG;
2642 } else if ((origin_count < 0 || target_count < 0) ||
2643 (origin_addr==nullptr && origin_count > 0)){
2644 retval = MPI_ERR_COUNT;
2645 } else if ((!origin_datatype->is_valid()) || (!target_datatype->is_valid())) {
2646 retval = MPI_ERR_TYPE;
2648 int rank = smpi_process()->index();
2650 win->get_group(&group);
2651 int dst_traced = group->index(target_rank);
2652 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
2653 TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
2655 retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2658 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2664 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2665 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2668 if (win == MPI_WIN_NULL) {
2669 retval = MPI_ERR_WIN;
2670 } else if (target_rank == MPI_PROC_NULL) {
2671 retval = MPI_SUCCESS;
2672 } else if (target_rank <0){
2673 retval = MPI_ERR_RANK;
2674 } else if (target_disp <0){
2675 retval = MPI_ERR_ARG;
2676 } else if ((origin_count < 0 || target_count < 0) ||
2677 (origin_addr==nullptr && origin_count > 0)){
2678 retval = MPI_ERR_COUNT;
2679 } else if ((!origin_datatype->is_valid()) ||
2680 (!target_datatype->is_valid())) {
2681 retval = MPI_ERR_TYPE;
2682 } else if (op == MPI_OP_NULL) {
2683 retval = MPI_ERR_OP;
2685 int rank = smpi_process()->index();
2687 win->get_group(&group);
2688 int src_traced = group->index(target_rank);
2689 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2691 retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
2692 target_datatype, op);
2694 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2700 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
2701 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
2702 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2705 if (win == MPI_WIN_NULL) {
2706 retval = MPI_ERR_WIN;
2707 } else if (target_rank == MPI_PROC_NULL) {
2708 retval = MPI_SUCCESS;
2709 } else if (target_rank <0){
2710 retval = MPI_ERR_RANK;
2711 } else if (target_disp <0){
2712 retval = MPI_ERR_ARG;
2713 } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
2714 (origin_addr==nullptr && origin_count > 0) ||
2715 (result_addr==nullptr && result_count > 0)){
2716 retval = MPI_ERR_COUNT;
2717 } else if ((!origin_datatype->is_valid()) ||
2718 (!target_datatype->is_valid())||
2719 (!result_datatype->is_valid())) {
2720 retval = MPI_ERR_TYPE;
2721 } else if (op == MPI_OP_NULL) {
2722 retval = MPI_ERR_OP;
2724 int rank = smpi_process()->index();
2726 win->get_group(&group);
2727 int src_traced = group->index(target_rank);
2728 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
2730 retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
2731 result_count, result_datatype, target_rank, target_disp,
2732 target_count, target_datatype, op);
2734 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2740 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2743 if (win == MPI_WIN_NULL) {
2744 retval = MPI_ERR_WIN;
2745 } else if (group==MPI_GROUP_NULL){
2746 retval = MPI_ERR_GROUP;
2748 int rank = smpi_process()->index();
2749 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2750 retval = win->post(group,assert);
2751 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2757 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2760 if (win == MPI_WIN_NULL) {
2761 retval = MPI_ERR_WIN;
2762 } else if (group==MPI_GROUP_NULL){
2763 retval = MPI_ERR_GROUP;
2765 int rank = smpi_process()->index();
2766 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2767 retval = win->start(group,assert);
2768 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2774 int PMPI_Win_complete(MPI_Win win){
2777 if (win == MPI_WIN_NULL) {
2778 retval = MPI_ERR_WIN;
2780 int rank = smpi_process()->index();
2781 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2783 retval = win->complete();
2785 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2791 int PMPI_Win_wait(MPI_Win win){
2794 if (win == MPI_WIN_NULL) {
2795 retval = MPI_ERR_WIN;
2797 int rank = smpi_process()->index();
2798 TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
2800 retval = win->wait();
2802 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2808 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
2811 if (win == MPI_WIN_NULL) {
2812 retval = MPI_ERR_WIN;
2813 } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
2814 lock_type != MPI_LOCK_SHARED) {
2815 retval = MPI_ERR_LOCKTYPE;
2816 } else if (rank == MPI_PROC_NULL){
2817 retval = MPI_SUCCESS;
2819 int myrank = smpi_process()->index();
2820 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
2821 retval = win->lock(lock_type,rank,assert);
2822 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
2828 int PMPI_Win_unlock(int rank, MPI_Win win){
2831 if (win == MPI_WIN_NULL) {
2832 retval = MPI_ERR_WIN;
2833 } else if (rank == MPI_PROC_NULL){
2834 retval = MPI_SUCCESS;
2836 int myrank = smpi_process()->index();
2837 TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
2838 retval = win->unlock(rank);
2839 TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
2845 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
2846 void *ptr = xbt_malloc(size);
2848 return MPI_ERR_NO_MEM;
2850 *static_cast<void**>(baseptr) = ptr;
2855 int PMPI_Free_mem(void *baseptr){
2860 int PMPI_Type_set_name(MPI_Datatype datatype, char * name)
2862 if (datatype == MPI_DATATYPE_NULL) {
2863 return MPI_ERR_TYPE;
2864 } else if (name == nullptr) {
2867 datatype->set_name(name);
2872 int PMPI_Type_get_name(MPI_Datatype datatype, char * name, int* len)
2874 if (datatype == MPI_DATATYPE_NULL) {
2875 return MPI_ERR_TYPE;
2876 } else if (name == nullptr) {
2879 datatype->get_name(name, len);
2884 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
2885 return static_cast<MPI_Datatype>(simgrid::smpi::F2C::f2c(datatype));
2888 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
2889 return datatype->c2f();
2892 MPI_Group PMPI_Group_f2c(MPI_Fint group){
2893 return simgrid::smpi::Group::f2c(group);
2896 MPI_Fint PMPI_Group_c2f(MPI_Group group){
2897 return group->c2f();
2900 MPI_Request PMPI_Request_f2c(MPI_Fint request){
2901 return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
2904 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
2905 return request->c2f();
2908 MPI_Win PMPI_Win_f2c(MPI_Fint win){
2909 return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
2912 MPI_Fint PMPI_Win_c2f(MPI_Win win){
2916 MPI_Op PMPI_Op_f2c(MPI_Fint op){
2917 return static_cast<MPI_Op>(simgrid::smpi::Op::f2c(op));
2920 MPI_Fint PMPI_Op_c2f(MPI_Op op){
2924 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
2925 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
2928 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
2932 MPI_Info PMPI_Info_f2c(MPI_Fint info){
2933 return static_cast<MPI_Info>(simgrid::smpi::Info::f2c(info));
2936 MPI_Fint PMPI_Info_c2f(MPI_Info info){
2940 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
2941 smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr};
2942 smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr};
2943 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
2946 int PMPI_Keyval_free(int* keyval) {
2947 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Comm>(keyval);
2950 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
2951 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
2952 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
2954 else if (comm==MPI_COMM_NULL)
2955 return MPI_ERR_COMM;
2957 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
2960 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
2962 static int zero = 0;
2963 static int tag_ub = 1000000;
2964 static int last_used_code = MPI_ERR_LASTCODE;
2966 if (comm==MPI_COMM_NULL){
2968 return MPI_ERR_COMM;
2976 *static_cast<int**>(attr_value) = &zero;
2978 case MPI_UNIVERSE_SIZE:
2980 *static_cast<int**>(attr_value) = &smpi_universe_size;
2982 case MPI_LASTUSEDCODE:
2984 *static_cast<int**>(attr_value) = &last_used_code;
2988 *static_cast<int**>(attr_value) = &tag_ub;
2990 case MPI_WTIME_IS_GLOBAL:
2992 *static_cast<int**>(attr_value) = &one;
2995 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
2999 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3000 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3001 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3003 else if (comm==MPI_COMM_NULL)
3004 return MPI_ERR_COMM;
3006 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
3009 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3011 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3014 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3016 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3019 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3021 return PMPI_Attr_delete(comm, comm_keyval);
3024 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
3027 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3030 int PMPI_Comm_free_keyval(int* keyval) {
3031 return PMPI_Keyval_free(keyval);
3034 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3036 if (type==MPI_DATATYPE_NULL)
3037 return MPI_ERR_TYPE;
3039 return type->attr_get<simgrid::smpi::Datatype>(type_keyval, attribute_val, flag);
3042 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3044 if (type==MPI_DATATYPE_NULL)
3045 return MPI_ERR_TYPE;
3047 return type->attr_put<simgrid::smpi::Datatype>(type_keyval, attribute_val);
3050 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3052 if (type==MPI_DATATYPE_NULL)
3053 return MPI_ERR_TYPE;
3055 return type->attr_delete<simgrid::smpi::Datatype>(type_keyval);
3058 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
3061 smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr};
3062 smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr};
3063 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
3066 int PMPI_Type_free_keyval(int* keyval) {
3067 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Datatype>(keyval);
3070 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
3072 static MPI_Aint size;
3073 static int disp_unit;
3074 if (win==MPI_WIN_NULL)
3075 return MPI_ERR_TYPE;
3079 *static_cast<void**>(attribute_val) = win->base();
3084 *static_cast<MPI_Aint**>(attribute_val) = &size;
3087 case MPI_WIN_DISP_UNIT :
3088 disp_unit=win->disp_unit();
3089 *static_cast<int**>(attribute_val) = &disp_unit;
3093 return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
3099 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
3101 if (win==MPI_WIN_NULL)
3102 return MPI_ERR_TYPE;
3104 return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
3107 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
3109 if (win==MPI_WIN_NULL)
3110 return MPI_ERR_TYPE;
3112 return win->attr_delete<simgrid::smpi::Win>(type_keyval);
3115 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
3118 smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
3119 smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
3120 return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
3123 int PMPI_Win_free_keyval(int* keyval) {
3124 return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
3127 int PMPI_Info_create( MPI_Info *info){
3128 if (info == nullptr)
3130 *info = new simgrid::smpi::Info();
3134 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3135 if (info == nullptr || key == nullptr || value == nullptr)
3137 info->set(key, value);
3141 int PMPI_Info_free( MPI_Info *info){
3142 if (info == nullptr || *info==nullptr)
3144 simgrid::smpi::Info::unref(*info);
3145 *info=MPI_INFO_NULL;
3149 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3151 if (info == nullptr || key == nullptr || valuelen <0)
3153 if (value == nullptr)
3154 return MPI_ERR_INFO_VALUE;
3155 return info->get(key, valuelen, value, flag);
3158 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3159 if (info == nullptr || newinfo==nullptr)
3161 *newinfo = new simgrid::smpi::Info(info);
3165 int PMPI_Info_delete(MPI_Info info, char *key){
3166 if (info == nullptr || key==nullptr)
3168 return info->remove(key);
3171 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3172 if (info == nullptr || nkeys==nullptr)
3174 return info->get_nkeys(nkeys);
3177 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3178 if (info == nullptr || key==nullptr || n<0 || n> MPI_MAX_INFO_KEY)
3180 return info->get_nthkey(n, key);
3183 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3185 if (info == nullptr || key == nullptr || valuelen==nullptr)
3187 return info->get_valuelen(key, valuelen, flag);
3190 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3191 if(incount<0 || outcount < 0 || inbuf==nullptr || outbuf==nullptr)
3193 if(!type->is_valid())
3194 return MPI_ERR_TYPE;
3195 if(comm==MPI_COMM_NULL)
3196 return MPI_ERR_COMM;
3197 return type->unpack(inbuf, incount, position, outbuf,outcount, comm);
3200 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3201 if(incount<0 || outcount < 0|| inbuf==nullptr || outbuf==nullptr)
3203 if(!type->is_valid())
3204 return MPI_ERR_TYPE;
3205 if(comm==MPI_COMM_NULL)
3206 return MPI_ERR_COMM;
3207 return type->pack(inbuf, incount, outbuf,outcount,position, comm);
3210 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3213 if(!datatype->is_valid())
3214 return MPI_ERR_TYPE;
3215 if(comm==MPI_COMM_NULL)
3216 return MPI_ERR_COMM;
3218 *size=incount*datatype->size();