X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/f440f91c0d78d785b2a9cf87c718a54af453cf26..6d12558bf98bb09f8fc8c45527d740bf999f789c:/src/smpi/smpi_base.c diff --git a/src/smpi/smpi_base.c b/src/smpi/smpi_base.c index 73fe79ad64..cb06b33939 100644 --- a/src/smpi/smpi_base.c +++ b/src/smpi/smpi_base.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. +/* Copyright (c) 2007-2013. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -187,7 +187,7 @@ static MPI_Request build_request(void *buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags) { - MPI_Request request; + MPI_Request request = NULL; void *old_buf = NULL; @@ -219,6 +219,7 @@ static MPI_Request build_request(void *buf, int count, request->flags = flags; request->detached = 0; request->detached_sender = NULL; + request->real_src = 0; request->truncated = 0; request->real_size = 0; @@ -284,9 +285,9 @@ static void smpi_mpi_request_free_voidp(void* request) MPI_Request smpi_mpi_send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, PERSISTENT | SEND | PREPARED); + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, PERSISTENT | SEND | PREPARED); request->refcount++; return request; } @@ -294,9 +295,9 @@ MPI_Request smpi_mpi_send_init(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_mpi_ssend_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, PERSISTENT | SSEND | SEND | PREPARED); + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, PERSISTENT | SSEND | SEND | PREPARED); request->refcount++; return request; } @@ -304,9 +305,9 @@ MPI_Request smpi_mpi_ssend_init(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_mpi_recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, - comm, PERSISTENT | RECV | PREPARED); + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, + comm, PERSISTENT | RECV | PREPARED); request->refcount++; return request; } @@ -320,6 +321,7 @@ void smpi_mpi_start(MPI_Request request) if(request->flags & PREPARED)request->flags &= ~PREPARED; if(request->flags & RECV) { print_request("New recv", request); + //FIXME: if receive is posted with a large size, but send is smaller, mailboxes may not match ! if (request->size < sg_cfg_get_int("smpi/async_small_thres")) mailbox = smpi_process_mailbox_small(); else @@ -345,7 +347,7 @@ void smpi_mpi_start(MPI_Request request) #ifdef HAVE_TRACING int rank = smpi_process_index(); if (TRACE_smpi_view_internals()) { - TRACE_smpi_send(rank, rank, receiver); + TRACE_smpi_send(rank, rank, receiver,request->size); } #endif /* if(receiver == MPI_UNDEFINED) {*/ @@ -421,7 +423,6 @@ void smpi_mpi_startall(int count, MPI_Request * requests) void smpi_mpi_request_free(MPI_Request * request) { - if((*request) != MPI_REQUEST_NULL){ (*request)->refcount--; if((*request)->refcount<0) xbt_die("wrong refcount"); @@ -442,20 +443,18 @@ void smpi_mpi_request_free(MPI_Request * request) MPI_Request smpi_isend_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf , count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | SEND | PREPARED); - + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf , count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | ISEND | SEND | PREPARED); return request; } MPI_Request smpi_mpi_isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM?(void*)0:buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | ISEND | SEND); - + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM?(void*)0:buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | ISEND | SEND); smpi_mpi_start(request); return request; } @@ -463,9 +462,9 @@ MPI_Request smpi_mpi_isend(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_mpi_issend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | ISEND | SSEND | SEND); + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | ISEND | SSEND | SEND); smpi_mpi_start(request); return request; } @@ -475,19 +474,18 @@ MPI_Request smpi_mpi_issend(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_irecv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, - comm, NON_PERSISTENT | RECV | PREPARED); + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, + comm, NON_PERSISTENT | RECV | PREPARED); return request; } MPI_Request smpi_mpi_irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, - comm, NON_PERSISTENT | RECV); - + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, + comm, NON_PERSISTENT | RECV); smpi_mpi_start(request); return request; } @@ -495,9 +493,10 @@ MPI_Request smpi_mpi_irecv(void *buf, int count, MPI_Datatype datatype, void smpi_mpi_recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status) { - MPI_Request request; + MPI_Request request = NULL; request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm); smpi_mpi_wait(&request, status); + request = NULL; } @@ -505,23 +504,25 @@ void smpi_mpi_recv(void *buf, int count, MPI_Datatype datatype, int src, void smpi_mpi_send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | SEND); + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | SEND); + smpi_mpi_start(request); smpi_mpi_wait(&request, MPI_STATUS_IGNORE); - + request = NULL; } void smpi_mpi_ssend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | SSEND | SEND); + MPI_Request request = NULL; + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | SSEND | SEND); smpi_mpi_start(request); smpi_mpi_wait(&request, MPI_STATUS_IGNORE); + request = NULL; } void smpi_mpi_sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, @@ -620,7 +621,7 @@ int smpi_mpi_test(MPI_Request * request, MPI_Status * status) { flag = simcall_comm_test((*request)->action); if(flag) { finish_wait(request, status); - request=MPI_REQUEST_NULL; + *request = MPI_REQUEST_NULL; }else{ smpi_empty_status(status); } @@ -677,6 +678,8 @@ int smpi_mpi_testall(int count, MPI_Request requests[], if(requests[i]!= MPI_REQUEST_NULL){ if (smpi_mpi_test(&requests[i], pstat)!=1){ flag=0; + }else{ + requests[i]=MPI_REQUEST_NULL; } }else{ smpi_empty_status(pstat); @@ -752,8 +755,14 @@ void smpi_mpi_wait(MPI_Request * request, MPI_Status * status) if ((*request)->action != NULL) { // this is not a detached send simcall_comm_wait((*request)->action, -1.0); } - finish_wait(request, status); +#ifdef HAVE_MC + if(MC_is_active()) + (*request)->action->comm.dst_data = NULL; // dangling pointer : dst_data is freed with a wait, need to set it to NULL for system state comparison +#endif + + finish_wait(request, status); + *request = MPI_REQUEST_NULL; // FIXME for a detached send, finish_wait is not called: } @@ -882,7 +891,7 @@ int smpi_mpi_testsome(int incount, MPI_Request requests[], int *indices, for(i = 0; i < incount; i++) { if((requests[i] != MPI_REQUEST_NULL)) { if(smpi_mpi_test(&requests[i], pstat)) { - indices[count] = i; + indices[i] = 1; count++; if(status != MPI_STATUSES_IGNORE) { status[i] = *pstat; @@ -1110,8 +1119,10 @@ void smpi_mpi_scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, // FIXME: check for errors smpi_datatype_extent(sendtype, &lb, &sendext); // Local copy from root - smpi_datatype_copy((char *)sendbuf + root * sendcount * sendext, - sendcount, sendtype, recvbuf, recvcount, recvtype); + if(recvbuf!=MPI_IN_PLACE){ + smpi_datatype_copy((char *)sendbuf + root * sendcount * sendext, + sendcount, sendtype, recvbuf, recvcount, recvtype); + } // Send buffers to receivers requests = xbt_new(MPI_Request, size - 1); index = 0; @@ -1149,8 +1160,10 @@ void smpi_mpi_scatterv(void *sendbuf, int *sendcounts, int *displs, // FIXME: check for errors smpi_datatype_extent(sendtype, &lb, &sendext); // Local copy from root - smpi_datatype_copy((char *)sendbuf + displs[root] * sendext, sendcounts[root], + if(recvbuf!=MPI_IN_PLACE){ + smpi_datatype_copy((char *)sendbuf + displs[root] * sendext, sendcounts[root], sendtype, recvbuf, recvcount, recvtype); + } // Send buffers to receivers requests = xbt_new(MPI_Request, size - 1); index = 0; @@ -1179,9 +1192,11 @@ void smpi_mpi_reduce(void *sendbuf, void *recvbuf, int count, MPI_Request *requests; void **tmpbufs; + char* sendtmpbuf = (char*) sendbuf; if( sendbuf == MPI_IN_PLACE ) { - sendtmpbuf = (char *)recvbuf; + sendtmpbuf = (char *)xbt_malloc(count*smpi_datatype_get_extent(datatype)); + smpi_datatype_copy(recvbuf, count, datatype,sendtmpbuf, count, datatype); } rank = smpi_comm_rank(comm); @@ -1234,6 +1249,10 @@ void smpi_mpi_reduce(void *sendbuf, void *recvbuf, int count, } xbt_free(tmpbufs); xbt_free(requests); + + if( sendbuf == MPI_IN_PLACE ) { + xbt_free(sendtmpbuf); + } } } @@ -1247,7 +1266,7 @@ void smpi_mpi_allreduce(void *sendbuf, void *recvbuf, int count, void smpi_mpi_scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) { - int system_tag = 888; + int system_tag = -888; int rank, size, other, index; MPI_Aint lb = 0, dataext = 0; MPI_Request *requests; @@ -1282,14 +1301,94 @@ void smpi_mpi_scan(void *sendbuf, void *recvbuf, int count, } // Wait for completion of all comms. smpi_mpi_startall(size - 1, requests); - for(other = 0; other < size - 1; other++) { - index = smpi_mpi_waitany(size - 1, requests, MPI_STATUS_IGNORE); - if(index == MPI_UNDEFINED) { - break; + + if(smpi_op_is_commute(op)){ + for(other = 0; other < size - 1; other++) { + index = smpi_mpi_waitany(size - 1, requests, MPI_STATUS_IGNORE); + if(index == MPI_UNDEFINED) { + break; + } + if(index < rank) { + // #Request is below rank: it's a irecv + smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype); + } + } + }else{ + //non commutative case, wait in order + for(other = 0; other < size - 1; other++) { + smpi_mpi_wait(&(requests[other]), MPI_STATUS_IGNORE); + if(index < rank) { + smpi_op_apply(op, tmpbufs[other], recvbuf, &count, &datatype); + } + } + } + for(index = 0; index < rank; index++) { + xbt_free(tmpbufs[index]); + } + xbt_free(tmpbufs); + xbt_free(requests); +} + +void smpi_mpi_exscan(void *sendbuf, void *recvbuf, int count, + MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) +{ + int system_tag = -888; + int rank, size, other, index; + MPI_Aint lb = 0, dataext = 0; + MPI_Request *requests; + void **tmpbufs; + int recvbuf_is_empty=1; + rank = smpi_comm_rank(comm); + size = smpi_comm_size(comm); + + // FIXME: check for errors + smpi_datatype_extent(datatype, &lb, &dataext); + + // Send/Recv buffers to/from others; + requests = xbt_new(MPI_Request, size - 1); + tmpbufs = xbt_new(void *, rank); + index = 0; + for(other = 0; other < rank; other++) { + // FIXME: possibly overkill we we have contiguous/noncontiguous data + // mapping... + tmpbufs[index] = xbt_malloc(count * dataext); + requests[index] = + smpi_irecv_init(tmpbufs[index], count, datatype, other, system_tag, + comm); + index++; + } + for(other = rank + 1; other < size; other++) { + requests[index] = + smpi_isend_init(sendbuf, count, datatype, other, system_tag, comm); + index++; + } + // Wait for completion of all comms. + smpi_mpi_startall(size - 1, requests); + if(smpi_op_is_commute(op)){ + for(other = 0; other < size - 1; other++) { + index = smpi_mpi_waitany(size - 1, requests, MPI_STATUS_IGNORE); + if(index == MPI_UNDEFINED) { + break; + } + if(index < rank) { + if(recvbuf_is_empty){ + smpi_datatype_copy(tmpbufs[index], count, datatype, recvbuf, count, datatype); + recvbuf_is_empty=0; + }else + // #Request is below rank: it's a irecv + smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype); + } } - if(index < rank) { - // #Request is below rank: it's a irecv - smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype); + }else{ + //non commutative case, wait in order + for(other = 0; other < size - 1; other++) { + smpi_mpi_wait(&(requests[other]), MPI_STATUS_IGNORE); + if(index < rank) { + if(recvbuf_is_empty){ + smpi_datatype_copy(tmpbufs[other], count, datatype, recvbuf, count, datatype); + recvbuf_is_empty=0; + }else smpi_op_apply(op, tmpbufs[other], recvbuf, &count, &datatype); + } } } for(index = 0; index < rank; index++) {