Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into adrien
[simgrid.git] / teshsuite / smpi / mpich3-test / pt2pt / mprobe.c
index 2e97536..e1c55c9 100644 (file)
 #include "mpi.h"
 #include "mpitest.h"
 
-/* This is a temporary #ifdef to control whether we test this functionality.  A
- * configure-test or similar would be better.  Eventually the MPI-3 standard
- * will be released and this can be gated on a MPI_VERSION check */
-#if !defined(USE_STRICT_MPI) && defined(MPICH)
-#define TEST_MPROBE_ROUTINES 1
-#endif
-
 /* assert-like macro that bumps the err count and emits a message */
 #define check(x_)                                                                 \
     do {                                                                          \
         }                                                                         \
     } while (0)
 
+#define LARGE_DIM 512
+#define LARGE_SZ (LARGE_DIM * LARGE_DIM)
+
 int main(int argc, char **argv)
 {
     int errs = 0;
-    int rank, size;
-#ifdef TEST_MPROBE_ROUTINES
     int found, completed;
-    int sendbuf[8], recvbuf[8];
-    int count;
+    int rank, size;
+    int *sendbuf = NULL, *recvbuf = NULL;
+    int count, i;
     MPI_Message msg;
     MPI_Request rreq;
     MPI_Status s1, s2;
-#endif
+    MPI_Datatype vectype;
 
     MPI_Init(&argc, &argv);
 
@@ -49,7 +44,6 @@ int main(int argc, char **argv)
     if (size < 2) {
         printf("this test requires at least 2 processes\n");
         MPI_Abort(MPI_COMM_WORLD, 1);
-        exit(1);
     }
 
     /* all processes besides ranks 0 & 1 aren't used by this test */
@@ -57,7 +51,13 @@ int main(int argc, char **argv)
         goto epilogue;
     }
 
-#ifdef TEST_MPROBE_ROUTINES
+    sendbuf = (int *) malloc(LARGE_SZ * sizeof(int));
+    recvbuf = (int *) malloc(LARGE_SZ * sizeof(int));
+    if (sendbuf == NULL || recvbuf == NULL) {
+        printf("Error in memory allocation\n");
+        MPI_Abort(MPI_COMM_WORLD, 1);
+    }
+
     /* test 0: simple send & mprobe+mrecv */
     if (rank == 0) {
         sendbuf[0] = 0xdeadbeef;
@@ -267,7 +267,7 @@ int main(int argc, char **argv)
         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
         check(rreq != MPI_REQUEST_NULL);
         completed = 0;
-        MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
+        MPI_Test(&rreq, &completed, &s2);       /* single test should always succeed */
         check(completed);
         /* recvbuf should remain unmodified */
         check(recvbuf[0] == 0x01234567);
@@ -341,7 +341,7 @@ int main(int argc, char **argv)
         MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq);
         check(rreq != MPI_REQUEST_NULL);
         completed = 0;
-        MPI_Test(&rreq, &completed, &s2); /* single test should always succeed */
+        MPI_Test(&rreq, &completed, &s2);       /* single test should always succeed */
         check(completed);
         /* recvbuf should remain unmodified */
         check(recvbuf[0] == 0x01234567);
@@ -356,6 +356,221 @@ int main(int argc, char **argv)
         check(count == 0);
     }
 
+    /* test 8: simple ssend & mprobe+mrecv */
+    if (rank == 0) {
+        sendbuf[0] = 0xdeadbeef;
+        sendbuf[1] = 0xfeedface;
+        MPI_Ssend(sendbuf, 2, MPI_INT, 1, 5, MPI_COMM_WORLD);
+    }
+    else {
+        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 = MPI_MESSAGE_NULL;
+        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
+        check(s1.MPI_SOURCE == 0);
+        check(s1.MPI_TAG == 5);
+        check(s1.MPI_ERROR == MPI_ERR_DIMS);
+        check(msg != MPI_MESSAGE_NULL);
+
+        count = -1;
+        MPI_Get_count(&s1, MPI_INT, &count);
+        check(count == 2);
+
+        recvbuf[0] = 0x01234567;
+        recvbuf[1] = 0x89abcdef;
+        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
+        check(recvbuf[0] == 0xdeadbeef);
+        check(recvbuf[1] == 0xfeedface);
+        check(s2.MPI_SOURCE == 0);
+        check(s2.MPI_TAG == 5);
+        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
+        check(msg == MPI_MESSAGE_NULL);
+    }
+
+    /* test 9: mprobe+mrecv LARGE */
+    if (rank == 0) {
+        for (i = 0; i < LARGE_SZ; i++)
+            sendbuf[i] = i;
+        MPI_Send(sendbuf, LARGE_SZ, MPI_INT, 1, 5, MPI_COMM_WORLD);
+    }
+    else {
+        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 = MPI_MESSAGE_NULL;
+        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
+        check(s1.MPI_SOURCE == 0);
+        check(s1.MPI_TAG == 5);
+        check(s1.MPI_ERROR == MPI_ERR_DIMS);
+        check(msg != MPI_MESSAGE_NULL);
+
+        count = -1;
+        MPI_Get_count(&s1, MPI_INT, &count);
+        check(count == LARGE_SZ);
+
+        memset(recvbuf, 0xFF, LARGE_SZ * sizeof(int));
+        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
+        for (i = 0; i < LARGE_SZ; i++)
+            check(recvbuf[i] == i);
+        check(s2.MPI_SOURCE == 0);
+        check(s2.MPI_TAG == 5);
+        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
+        check(msg == MPI_MESSAGE_NULL);
+    }
+
+    /* test 10: mprobe+mrecv noncontiguous datatype */
+    MPI_Type_vector(2, 1, 4, MPI_INT, &vectype);
+    MPI_Type_commit(&vectype);
+    if (rank == 0) {
+        memset(sendbuf, 0, 8 * sizeof(int));
+        sendbuf[0] = 0xdeadbeef;
+        sendbuf[4] = 0xfeedface;
+        MPI_Send(sendbuf, 1, vectype, 1, 5, MPI_COMM_WORLD);
+    }
+    else {
+        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 = MPI_MESSAGE_NULL;
+        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
+        check(s1.MPI_SOURCE == 0);
+        check(s1.MPI_TAG == 5);
+        check(s1.MPI_ERROR == MPI_ERR_DIMS);
+        check(msg != MPI_MESSAGE_NULL);
+
+        count = -1;
+        MPI_Get_count(&s1, vectype, &count);
+        check(count == 1);
+
+        memset(recvbuf, 0, 8 * sizeof(int));
+        MPI_Mrecv(recvbuf, 1, vectype, &msg, &s2);
+        check(recvbuf[0] == 0xdeadbeef);
+        for (i = 1; i < 4; i++)
+            check(recvbuf[i] == 0);
+        check(recvbuf[4] = 0xfeedface);
+        for (i = 5; i < 8; i++)
+            check(recvbuf[i] == 0);
+        check(s2.MPI_SOURCE == 0);
+        check(s2.MPI_TAG == 5);
+        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
+        check(msg == MPI_MESSAGE_NULL);
+    }
+    MPI_Type_free(&vectype);
+
+    /* test 11: mprobe+mrecv noncontiguous datatype LARGE */
+    MPI_Type_vector(LARGE_DIM, LARGE_DIM - 1, LARGE_DIM, MPI_INT, &vectype);
+    MPI_Type_commit(&vectype);
+    if (rank == 0) {
+        for (i = 0; i < LARGE_SZ; i++)
+            sendbuf[i] = i;
+        MPI_Send(sendbuf, 1, vectype, 1, 5, MPI_COMM_WORLD);
+    }
+    else {
+        int idx = 0;
+
+        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 = MPI_MESSAGE_NULL;
+        MPI_Mprobe(0, 5, MPI_COMM_WORLD, &msg, &s1);
+        check(s1.MPI_SOURCE == 0);
+        check(s1.MPI_TAG == 5);
+        check(s1.MPI_ERROR == MPI_ERR_DIMS);
+        check(msg != MPI_MESSAGE_NULL);
+
+        count = -1;
+        MPI_Get_count(&s1, vectype, &count);
+        check(count == 1);
+
+        memset(recvbuf, 0, LARGE_SZ * sizeof(int));
+        MPI_Mrecv(recvbuf, 1, vectype, &msg, &s2);
+        for (i = 0; i < LARGE_DIM; i++) {
+            int j;
+            for (j = 0; j < LARGE_DIM - 1; j++) {
+                check(recvbuf[idx] == idx);
+                ++idx;
+            }
+            check(recvbuf[idx++] == 0);
+        }
+        check(s2.MPI_SOURCE == 0);
+        check(s2.MPI_TAG == 5);
+        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
+        check(msg == MPI_MESSAGE_NULL);
+    }
+    MPI_Type_free(&vectype);
+
+    /* test 12: order test */
+    if (rank == 0) {
+        MPI_Request lrequest[2];
+        sendbuf[0] = 0xdeadbeef;
+        sendbuf[1] = 0xfeedface;
+        sendbuf[2] = 0xdeadbeef;
+        sendbuf[3] = 0xfeedface;
+        sendbuf[4] = 0xdeadbeef;
+        sendbuf[5] = 0xfeedface;
+        MPI_Isend(&sendbuf[0], 4, MPI_INT, 1, 6, MPI_COMM_WORLD, &lrequest[0]);
+        MPI_Isend(&sendbuf[4], 2, MPI_INT, 1, 6, MPI_COMM_WORLD, &lrequest[1]);
+        MPI_Waitall(2, &lrequest[0], MPI_STATUSES_IGNORE);
+    }
+    else {
+        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 = MPI_MESSAGE_NULL;
+        MPI_Mprobe(0, 6, MPI_COMM_WORLD, &msg, &s1);
+        check(s1.MPI_SOURCE == 0);
+        check(s1.MPI_TAG == 6);
+        check(s1.MPI_ERROR == MPI_ERR_DIMS);
+        check(msg != MPI_MESSAGE_NULL);
+
+        count = -1;
+        MPI_Get_count(&s1, MPI_INT, &count);
+        check(count == 4);
+
+        recvbuf[0] = 0x01234567;
+        recvbuf[1] = 0x89abcdef;
+        MPI_Recv(recvbuf, 2, MPI_INT, 0, 6, MPI_COMM_WORLD, &s2);
+        check(s2.MPI_SOURCE == 0);
+        check(s2.MPI_TAG == 6);
+        check(recvbuf[0] == 0xdeadbeef);
+        check(recvbuf[1] == 0xfeedface);
+
+        recvbuf[0] = 0x01234567;
+        recvbuf[1] = 0x89abcdef;
+        recvbuf[2] = 0x01234567;
+        recvbuf[3] = 0x89abcdef;
+        s2.MPI_ERROR = MPI_ERR_TOPOLOGY;
+
+        MPI_Mrecv(recvbuf, count, MPI_INT, &msg, &s2);
+        check(recvbuf[0] == 0xdeadbeef);
+        check(recvbuf[1] == 0xfeedface);
+        check(recvbuf[2] == 0xdeadbeef);
+        check(recvbuf[3] == 0xfeedface);
+        check(s2.MPI_SOURCE == 0);
+        check(s2.MPI_TAG == 6);
+        check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY);
+        check(msg == MPI_MESSAGE_NULL);
+    }
+
+    free(sendbuf);
+    free(recvbuf);
+
     /* 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
@@ -378,9 +593,7 @@ int main(int argc, char **argv)
         check(msg == MPI_MESSAGE_NULL);
     }
 
-#endif /* TEST_MPROBE_ROUTINES */
-
-epilogue:
+  epilogue:
     MPI_Reduce((rank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
     if (rank == 0) {
         if (errs) {
@@ -395,4 +608,3 @@ epilogue:
 
     return 0;
 }
-