Created
March 7, 2012 23:48
-
-
Save goodell/1997360 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| commit 62568dc4391e004f7d648faeca1ee543fb5561e4 | |
| Author: Dave Goodell <[email protected]> | |
| Date: Wed Mar 7 16:23:19 2012 -0600 | |
| mprobe: support MPI_PROC_NULL/MPIX_MESSAGE_NO_PROC | |
| This corresponds to the functionality described in MPI Forum ticket #328. | |
| No reviewer. | |
| --- | |
| src/include/mpi.h.in | 1 + | |
| src/mpi/pt2pt/improbe.c | 13 ++-- | |
| src/mpi/pt2pt/imrecv.c | 12 ++-- | |
| src/mpi/pt2pt/mprobe.c | 8 ++- | |
| src/mpi/pt2pt/mrecv.c | 11 +-- | |
| src/mpid/ch3/src/mpid_improbe.c | 1 + | |
| src/mpid/ch3/src/mpid_imrecv.c | 10 +++ | |
| src/mpid/ch3/src/mpid_mprobe.c | 1 + | |
| src/mpid/ch3/src/mpid_mrecv.c | 6 ++ | |
| test/mpi/pt2pt/mprobe.c | 150 ++++++++++++++++++++++++++++++++++++++- | |
| 10 files changed, 197 insertions(+), 16 deletions(-) | |
| diff --git a/src/include/mpi.h.in b/src/include/mpi.h.in | |
| index 5653369..655bd39 100644 | |
| --- a/src/include/mpi.h.in | |
| +++ b/src/include/mpi.h.in | |
| @@ -193,6 +193,7 @@ typedef int MPI_Op; | |
| #define MPI_REQUEST_NULL ((MPI_Request)0x2c000000) | |
| #define MPI_ERRHANDLER_NULL ((MPI_Errhandler)0x14000000) | |
| #define MPIX_MESSAGE_NULL ((MPIX_Message)MPI_REQUEST_NULL) | |
| +#define MPIX_MESSAGE_NO_PROC ((MPIX_Message)0x6c000000) | |
| /* These are only guesses; make sure you change them in mpif.h as well */ | |
| #define MPI_MAX_PROCESSOR_NAME @MPI_MAX_PROCESSOR_NAME@ | |
| diff --git a/src/mpi/pt2pt/improbe.c b/src/mpi/pt2pt/improbe.c | |
| index 63b2f3b..9808960 100644 | |
| --- a/src/mpi/pt2pt/improbe.c | |
| +++ b/src/mpi/pt2pt/improbe.c | |
| @@ -97,12 +97,13 @@ int MPIX_Improbe(int source, int tag, MPI_Comm comm, int *flag, MPIX_Message *me | |
| if (mpi_errno) MPIU_ERR_POP(mpi_errno); | |
| if (*flag) { | |
| - *message = msgp->handle; | |
| - } | |
| - else { | |
| - /* the standard says that if flag is false then message and status are | |
| - * undefined */ | |
| - *message = MPIX_MESSAGE_NULL; | |
| + if (msgp == NULL) { | |
| + MPIU_Assert(source == MPI_PROC_NULL); | |
| + *message = MPIX_MESSAGE_NO_PROC; | |
| + } | |
| + else { | |
| + *message = msgp->handle; | |
| + } | |
| } | |
| /* ... end of body of routine ... */ | |
| diff --git a/src/mpi/pt2pt/imrecv.c b/src/mpi/pt2pt/imrecv.c | |
| index 7839b53..33dad7a 100644 | |
| --- a/src/mpi/pt2pt/imrecv.c | |
| +++ b/src/mpi/pt2pt/imrecv.c | |
| @@ -89,10 +89,14 @@ int MPIX_Imrecv(void *buf, int count, MPI_Datatype datatype, MPIX_Message *messa | |
| MPID_Datatype_committed_ptr(datatype_ptr, mpi_errno); | |
| } | |
| - MPID_Request_valid_ptr(msgp, mpi_errno); | |
| - if (mpi_errno) MPIU_ERR_POP(mpi_errno); | |
| - MPIU_ERR_CHKANDJUMP((msgp->kind != MPID_REQUEST_MPROBE), | |
| - mpi_errno, MPI_ERR_ARG, "**reqnotmsg") | |
| + /* MPIX_MESSAGE_NO_PROC should yield a "proc null" status */ | |
| + if (*message != MPIX_MESSAGE_NO_PROC) { | |
| + MPID_Request_valid_ptr(msgp, mpi_errno); | |
| + if (mpi_errno) MPIU_ERR_POP(mpi_errno); | |
| + MPIU_ERR_CHKANDJUMP((msgp->kind != MPID_REQUEST_MPROBE), | |
| + mpi_errno, MPI_ERR_ARG, "**reqnotmsg") | |
| + | |
| + } | |
| MPIR_ERRTEST_ARGNULL(request, "request", mpi_errno); | |
| /* TODO more checks may be appropriate (counts, in_place, buffer aliasing, etc) */ | |
| diff --git a/src/mpi/pt2pt/mprobe.c b/src/mpi/pt2pt/mprobe.c | |
| index 6fa089d..1362c00 100644 | |
| --- a/src/mpi/pt2pt/mprobe.c | |
| +++ b/src/mpi/pt2pt/mprobe.c | |
| @@ -94,7 +94,13 @@ int MPIX_Mprobe(int source, int tag, MPI_Comm comm, MPIX_Message *message, MPI_S | |
| mpi_errno = MPID_Mprobe(source, tag, comm_ptr, MPID_CONTEXT_INTRA_PT2PT, &msgp, status); | |
| if (mpi_errno) MPIU_ERR_POP(mpi_errno); | |
| - *message = msgp->handle; | |
| + if (msgp == NULL) { | |
| + MPIU_Assert(source == MPI_PROC_NULL); | |
| + *message = MPIX_MESSAGE_NO_PROC; | |
| + } | |
| + else { | |
| + *message = msgp->handle; | |
| + } | |
| /* ... end of body of routine ... */ | |
| diff --git a/src/mpi/pt2pt/mrecv.c b/src/mpi/pt2pt/mrecv.c | |
| index 276dd23..7ab169a 100644 | |
| --- a/src/mpi/pt2pt/mrecv.c | |
| +++ b/src/mpi/pt2pt/mrecv.c | |
| @@ -88,10 +88,13 @@ int MPIX_Mrecv(void *buf, int count, MPI_Datatype datatype, MPIX_Message *messag | |
| MPID_Datatype_committed_ptr(datatype_ptr, mpi_errno); | |
| } | |
| - MPID_Request_valid_ptr(msgp, mpi_errno); | |
| - if (mpi_errno) MPIU_ERR_POP(mpi_errno); | |
| - MPIU_ERR_CHKANDJUMP((msgp->kind != MPID_REQUEST_MPROBE), | |
| - mpi_errno, MPI_ERR_ARG, "**reqnotmsg") | |
| + /* MPIX_MESSAGE_NO_PROC should yield a "proc null" status */ | |
| + if (*message != MPIX_MESSAGE_NO_PROC) { | |
| + MPID_Request_valid_ptr(msgp, mpi_errno); | |
| + if (mpi_errno) MPIU_ERR_POP(mpi_errno); | |
| + MPIU_ERR_CHKANDJUMP((msgp->kind != MPID_REQUEST_MPROBE), | |
| + mpi_errno, MPI_ERR_ARG, "**reqnotmsg") | |
| + } | |
| /* TODO more checks may be appropriate (counts, in_place, buffer aliasing, etc) */ | |
| if (mpi_errno != MPI_SUCCESS) goto fn_fail; | |
| diff --git a/src/mpid/ch3/src/mpid_improbe.c b/src/mpid/ch3/src/mpid_improbe.c | |
| index 11f7514..8b20e72 100644 | |
| --- a/src/mpid/ch3/src/mpid_improbe.c | |
| +++ b/src/mpid/ch3/src/mpid_improbe.c | |
| @@ -26,6 +26,7 @@ int MPID_Improbe(int source, int tag, MPID_Comm *comm, int context_offset, | |
| { | |
| MPIR_Status_set_procnull(status); | |
| *flag = TRUE; | |
| + *message = NULL; /* should be interpreted as MPIX_MESSAGE_NO_PROC */ | |
| goto fn_exit; | |
| } | |
| diff --git a/src/mpid/ch3/src/mpid_imrecv.c b/src/mpid/ch3/src/mpid_imrecv.c | |
| index fc400ef..bf16293 100644 | |
| --- a/src/mpid/ch3/src/mpid_imrecv.c | |
| +++ b/src/mpid/ch3/src/mpid_imrecv.c | |
| @@ -18,6 +18,16 @@ int MPID_Imrecv(void *buf, int count, MPI_Datatype datatype, | |
| MPID_Comm *comm; | |
| MPIDI_VC_t *vc = NULL; | |
| + /* message==NULL is equivalent to MPIX_MESSAGE_NO_PROC being passed at the | |
| + * upper level */ | |
| + if (message == NULL) | |
| + { | |
| + MPIDI_Request_create_null_rreq(rreq, mpi_errno, fn_fail); | |
| + *rreqp = rreq; | |
| + goto fn_exit; | |
| + } | |
| + | |
| + MPIU_Assert(message != NULL); | |
| MPIU_Assert(message->kind == MPID_REQUEST_MPROBE); | |
| /* promote the request object to be a "real" recv request */ | |
| diff --git a/src/mpid/ch3/src/mpid_mprobe.c b/src/mpid/ch3/src/mpid_mprobe.c | |
| index 2ba0fb4..7ab180d 100644 | |
| --- a/src/mpid/ch3/src/mpid_mprobe.c | |
| +++ b/src/mpid/ch3/src/mpid_mprobe.c | |
| @@ -24,6 +24,7 @@ int MPID_Mprobe(int source, int tag, MPID_Comm *comm, int context_offset, | |
| { | |
| MPIR_Status_set_procnull(status); | |
| found = TRUE; | |
| + *message = NULL; /* should be interpreted as MPIX_MESSAGE_NO_PROC */ | |
| goto fn_exit; | |
| } | |
| diff --git a/src/mpid/ch3/src/mpid_mrecv.c b/src/mpid/ch3/src/mpid_mrecv.c | |
| index 6afbd42..d29c1e1 100644 | |
| --- a/src/mpid/ch3/src/mpid_mrecv.c | |
| +++ b/src/mpid/ch3/src/mpid_mrecv.c | |
| @@ -18,6 +18,12 @@ int MPID_Mrecv(void *buf, int count, MPI_Datatype datatype, | |
| int active_flag; /* dummy for MPIR_Request_complete */ | |
| MPID_Request *rreq = NULL; | |
| + if (message == NULL) { | |
| + /* treat as though MPIX_MESSAGE_NO_PROC was passed */ | |
| + MPIR_Status_set_procnull(status); | |
| + goto fn_exit; | |
| + } | |
| + | |
| /* There is no optimized MPID_Mrecv at this time because there is no real | |
| * optimization potential in that case. MPID_Recv exists to prevent | |
| * creating a request unnecessarily for messages that are already present | |
| diff --git a/test/mpi/pt2pt/mprobe.c b/test/mpi/pt2pt/mprobe.c | |
| index 16517e2..b9e60e4 100644 | |
| --- a/test/mpi/pt2pt/mprobe.c | |
| +++ b/test/mpi/pt2pt/mprobe.c | |
| @@ -31,7 +31,7 @@ | |
| int main(int argc, char **argv) | |
| { | |
| int errs = 0; | |
| - int found; | |
| + int found, completed; | |
| int rank, size; | |
| int sendbuf[8], recvbuf[8]; | |
| int count; | |
| @@ -207,6 +207,154 @@ int main(int argc, char **argv) | |
| check(msg == MPIX_MESSAGE_NULL); | |
| } | |
| + /* test 4: mprobe+mrecv with MPI_PROC_NULL */ | |
| + { | |
| + memset(&s1, 0xab, sizeof(MPI_Status)); | |
| + memset(&s2, 0xab, sizeof(MPI_Status)); | |
| + /* the error field should remain unmodified */ | |
| + s1.MPI_ERROR = MPI_ERR_DIMS; | |
| + s2.MPI_ERROR = MPI_ERR_TOPOLOGY; | |
| + | |
| + msg = MPIX_MESSAGE_NULL; | |
| + MPIX_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1); | |
| + check(s1.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s1.MPI_TAG == MPI_ANY_TAG); | |
| + check(s1.MPI_ERROR == MPI_ERR_DIMS); | |
| + check(msg == MPIX_MESSAGE_NO_PROC); | |
| + | |
| + count = -1; | |
| + MPI_Get_count(&s1, MPI_INT, &count); | |
| + check(count == 0); | |
| + | |
| + recvbuf[0] = 0x01234567; | |
| + recvbuf[1] = 0x89abcdef; | |
| + MPIX_Mrecv(recvbuf, count, MPI_INT, &msg, &s2); | |
| + /* recvbuf should remain unmodified */ | |
| + check(recvbuf[0] == 0x01234567); | |
| + check(recvbuf[1] == 0x89abcdef); | |
| + /* should get back "proc null status" */ | |
| + check(s2.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s2.MPI_TAG == MPI_ANY_TAG); | |
| + check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY); | |
| + check(msg == MPIX_MESSAGE_NULL); | |
| + count = -1; | |
| + MPI_Get_count(&s2, MPI_INT, &count); | |
| + check(count == 0); | |
| + } | |
| + | |
| + /* test 5: mprobe+imrecv with MPI_PROC_NULL */ | |
| + { | |
| + memset(&s1, 0xab, sizeof(MPI_Status)); | |
| + memset(&s2, 0xab, sizeof(MPI_Status)); | |
| + /* the error field should remain unmodified */ | |
| + s1.MPI_ERROR = MPI_ERR_DIMS; | |
| + s2.MPI_ERROR = MPI_ERR_TOPOLOGY; | |
| + | |
| + msg = MPIX_MESSAGE_NULL; | |
| + MPIX_Mprobe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &msg, &s1); | |
| + check(s1.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s1.MPI_TAG == MPI_ANY_TAG); | |
| + check(s1.MPI_ERROR == MPI_ERR_DIMS); | |
| + check(msg == MPIX_MESSAGE_NO_PROC); | |
| + count = -1; | |
| + MPI_Get_count(&s1, MPI_INT, &count); | |
| + check(count == 0); | |
| + | |
| + rreq = MPI_REQUEST_NULL; | |
| + recvbuf[0] = 0x01234567; | |
| + recvbuf[1] = 0x89abcdef; | |
| + MPIX_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq); | |
| + check(rreq != MPI_REQUEST_NULL); | |
| + completed = 0; | |
| + MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */ | |
| + check(completed); | |
| + /* recvbuf should remain unmodified */ | |
| + check(recvbuf[0] == 0x01234567); | |
| + check(recvbuf[1] == 0x89abcdef); | |
| + /* should get back "proc null status" */ | |
| + check(s2.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s2.MPI_TAG == MPI_ANY_TAG); | |
| + check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY); | |
| + check(msg == MPIX_MESSAGE_NULL); | |
| + count = -1; | |
| + MPI_Get_count(&s2, MPI_INT, &count); | |
| + check(count == 0); | |
| + } | |
| + | |
| + /* test 6: improbe+mrecv with MPI_PROC_NULL */ | |
| + { | |
| + memset(&s1, 0xab, sizeof(MPI_Status)); | |
| + memset(&s2, 0xab, sizeof(MPI_Status)); | |
| + /* the error field should remain unmodified */ | |
| + s1.MPI_ERROR = MPI_ERR_DIMS; | |
| + s2.MPI_ERROR = MPI_ERR_TOPOLOGY; | |
| + | |
| + msg = MPIX_MESSAGE_NULL; | |
| + found = 0; | |
| + MPIX_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1); | |
| + check(found); | |
| + check(msg == MPIX_MESSAGE_NO_PROC); | |
| + check(s1.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s1.MPI_TAG == MPI_ANY_TAG); | |
| + check(s1.MPI_ERROR == MPI_ERR_DIMS); | |
| + count = -1; | |
| + MPI_Get_count(&s1, MPI_INT, &count); | |
| + check(count == 0); | |
| + | |
| + recvbuf[0] = 0x01234567; | |
| + recvbuf[1] = 0x89abcdef; | |
| + MPIX_Mrecv(recvbuf, count, MPI_INT, &msg, &s2); | |
| + /* recvbuf should remain unmodified */ | |
| + check(recvbuf[0] == 0x01234567); | |
| + check(recvbuf[1] == 0x89abcdef); | |
| + /* should get back "proc null status" */ | |
| + check(s2.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s2.MPI_TAG == MPI_ANY_TAG); | |
| + check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY); | |
| + check(msg == MPIX_MESSAGE_NULL); | |
| + count = -1; | |
| + MPI_Get_count(&s2, MPI_INT, &count); | |
| + check(count == 0); | |
| + } | |
| + | |
| + /* test 7: improbe+imrecv */ | |
| + { | |
| + memset(&s1, 0xab, sizeof(MPI_Status)); | |
| + memset(&s2, 0xab, sizeof(MPI_Status)); | |
| + /* the error field should remain unmodified */ | |
| + s1.MPI_ERROR = MPI_ERR_DIMS; | |
| + s2.MPI_ERROR = MPI_ERR_TOPOLOGY; | |
| + | |
| + msg = MPIX_MESSAGE_NULL; | |
| + MPIX_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1); | |
| + check(found); | |
| + check(msg == MPIX_MESSAGE_NO_PROC); | |
| + check(s1.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s1.MPI_TAG == MPI_ANY_TAG); | |
| + check(s1.MPI_ERROR == MPI_ERR_DIMS); | |
| + count = -1; | |
| + MPI_Get_count(&s1, MPI_INT, &count); | |
| + check(count == 0); | |
| + | |
| + rreq = MPI_REQUEST_NULL; | |
| + MPIX_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq); | |
| + check(rreq != MPI_REQUEST_NULL); | |
| + completed = 0; | |
| + MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */ | |
| + check(completed); | |
| + /* recvbuf should remain unmodified */ | |
| + check(recvbuf[0] == 0x01234567); | |
| + check(recvbuf[1] == 0x89abcdef); | |
| + /* should get back "proc null status" */ | |
| + check(s2.MPI_SOURCE == MPI_PROC_NULL); | |
| + check(s2.MPI_TAG == MPI_ANY_TAG); | |
| + check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY); | |
| + check(msg == MPIX_MESSAGE_NULL); | |
| + count = -1; | |
| + MPI_Get_count(&s2, MPI_INT, &count); | |
| + check(count == 0); | |
| + } | |
| + | |
| /* TODO MPI_ANY_SOURCE and MPI_ANY_TAG should be tested as well */ | |
| /* TODO a full range of message sizes should be tested too */ | |
| /* TODO threaded tests are also needed, but they should go in a separate |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment