Skip to content

Instantly share code, notes, and snippets.

@goodell
Created March 7, 2012 23:48
Show Gist options
  • Select an option

  • Save goodell/1997360 to your computer and use it in GitHub Desktop.

Select an option

Save goodell/1997360 to your computer and use it in GitHub Desktop.
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