int MPIX_Imrecv_x(void *buf, MPI_Count count, MPI_Datatype datatype, MPI_Message *message, MPI_Request *request) { int rc = MPI_SUCCESS; if (likely (count <= bigmpi_int_max )) { rc = MPI_Imrecv(buf, (int)count, datatype, message, request); } else { MPI_Datatype newtype; BigMPI_Type_contiguous(0,count, datatype, &newtype); MPI_Type_commit(&newtype); rc = MPI_Imrecv(buf, 1, newtype, message, request); MPI_Type_free(&newtype); } return rc; }
JNIEXPORT jlong JNICALL Java_mpi_Message_imRecv( JNIEnv *env, jobject jthis, jlong jMessage, jobject buf, jint count, jlong jType) { MPI_Message message = (MPI_Message)jMessage; MPI_Datatype type = (MPI_Datatype)jType; void *ptr = ompi_java_getDirectBufferAddress(env, buf); MPI_Request request; int rc = MPI_Imrecv(ptr, count, type, &message, &request); ompi_java_exceptionCheck(env, rc); (*env)->SetLongField(env, jthis, ompi_java.MessageHandle, (jlong)message); return (jlong)request; }
void ompi_imrecv_f(char *buf, MPI_Fint *count, MPI_Fint *datatype, MPI_Fint *message, MPI_Fint *request, MPI_Fint *ierr) { int c_ierr; MPI_Datatype c_type = MPI_Type_f2c(*datatype); MPI_Request c_req; MPI_Message c_message; c_message = MPI_Message_f2c(*message); c_ierr = OMPI_INT_2_FINT(MPI_Imrecv(OMPI_F2C_BOTTOM(buf), OMPI_FINT_2_INT(*count), c_type, &c_message, &c_req)); if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr); if (MPI_SUCCESS == c_ierr) { *request = MPI_Request_c2f(c_req); /* message is an INOUT, and may be updated by the recv */ *message = MPI_Message_c2f(c_message); } }
int main(int argc, char **argv) { int errs = 0; int found, completed; int rank, size; int *sendbuf = NULL, *recvbuf = NULL; int count, i; MPI_Message msg; MPI_Request rreq; MPI_Status s1, s2; MPI_Datatype vectype; MTest_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size < 2) { printf("this test requires at least 2 processes\n"); MPI_Abort(MPI_COMM_WORLD, 1); } /* all processes besides ranks 0 & 1 aren't used by this test */ if (rank >= 2) { goto epilogue; } 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; sendbuf[1] = 0xfeedface; MPI_Send(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 1: simple send & mprobe+imrecv */ if (rank == 0) { sendbuf[0] = 0xdeadbeef; sendbuf[1] = 0xfeedface; MPI_Send(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); rreq = MPI_REQUEST_NULL; recvbuf[0] = 0x01234567; recvbuf[1] = 0x89abcdef; MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq); check(rreq != MPI_REQUEST_NULL); MPI_Wait(&rreq, &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 2: simple send & improbe+mrecv */ if (rank == 0) { sendbuf[0] = 0xdeadbeef; sendbuf[1] = 0xfeedface; MPI_Send(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; do { check(msg == MPI_MESSAGE_NULL); MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1); } while (!found); check(msg != MPI_MESSAGE_NULL); check(s1.MPI_SOURCE == 0); check(s1.MPI_TAG == 5); check(s1.MPI_ERROR == MPI_ERR_DIMS); 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 3: simple send & improbe+imrecv */ if (rank == 0) { sendbuf[0] = 0xdeadbeef; sendbuf[1] = 0xfeedface; MPI_Send(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; do { check(msg == MPI_MESSAGE_NULL); MPI_Improbe(0, 5, MPI_COMM_WORLD, &found, &msg, &s1); } while (!found); check(msg != MPI_MESSAGE_NULL); check(s1.MPI_SOURCE == 0); check(s1.MPI_TAG == 5); check(s1.MPI_ERROR == MPI_ERR_DIMS); count = -1; MPI_Get_count(&s1, MPI_INT, &count); check(count == 2); rreq = MPI_REQUEST_NULL; MPI_Imrecv(recvbuf, count, MPI_INT, &msg, &rreq); check(rreq != MPI_REQUEST_NULL); MPI_Wait(&rreq, &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 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 = MPI_MESSAGE_NULL; MPI_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 == MPI_MESSAGE_NO_PROC); count = -1; MPI_Get_count(&s1, MPI_INT, &count); check(count == 0); recvbuf[0] = 0x01234567; recvbuf[1] = 0x89abcdef; MPI_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 == MPI_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 = MPI_MESSAGE_NULL; MPI_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 == MPI_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; 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 */ 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 == MPI_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 = MPI_MESSAGE_NULL; found = 0; MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1); check(found); check(msg == MPI_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; MPI_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 == MPI_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 = MPI_MESSAGE_NULL; MPI_Improbe(MPI_PROC_NULL, 5, MPI_COMM_WORLD, &found, &msg, &s1); check(found); check(msg == MPI_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; 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 */ 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 == MPI_MESSAGE_NULL); count = -1; MPI_Get_count(&s2, MPI_INT, &count); 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); } /* test 13: simple send & mprobe+mrecv with zero count */ if (rank == 0) { MPI_Send(sendbuf, 0, MPI_INT, 1, 13, 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, 13, MPI_COMM_WORLD, &msg, &s1); check(s1.MPI_SOURCE == 0); check(s1.MPI_TAG == 13); check(s1.MPI_ERROR == MPI_ERR_DIMS); check(msg != MPI_MESSAGE_NULL); count = -1; MPI_Get_count(&s1, MPI_INT, &count); check(count == 0); recvbuf[0] = 0x01234567; recvbuf[1] = 0x89abcdef; MPI_Mrecv(recvbuf, 0, MPI_INT, &msg, &s2); /* recvbuf should remain unmodified */ check(recvbuf[0] == 0x01234567); check(recvbuf[1] == 0x89abcdef); check(s2.MPI_SOURCE == 0); check(s2.MPI_TAG == 13); check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY); check(msg == MPI_MESSAGE_NULL); count = -1; MPI_Get_count(&s2, MPI_INT, &count); check(count == 0); } /* test 14: simple send & mprobe+mrecv with zero-size datatype */ if (rank == 0) { MPI_Send(sendbuf, 0, MPI_BYTE, 1, 14, MPI_COMM_WORLD); } else { MPI_Datatype zero_dtype; MPI_Type_contiguous(0, MPI_INT, &zero_dtype); MPI_Type_commit(&zero_dtype); 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, 14, MPI_COMM_WORLD, &msg, &s1); check(s1.MPI_SOURCE == 0); check(s1.MPI_TAG == 14); check(s1.MPI_ERROR == MPI_ERR_DIMS); check(msg != MPI_MESSAGE_NULL); count = -1; MPI_Get_count(&s1, zero_dtype, &count); check(count == 0); recvbuf[0] = 0x01234567; recvbuf[1] = 0x89abcdef; MPI_Mrecv(recvbuf, 1, zero_dtype, &msg, &s2); /* recvbuf should remain unmodified */ check(recvbuf[0] == 0x01234567); check(recvbuf[1] == 0x89abcdef); check(s2.MPI_SOURCE == 0); check(s2.MPI_TAG == 14); check(s2.MPI_ERROR == MPI_ERR_TOPOLOGY); check(msg == MPI_MESSAGE_NULL); count = -1; MPI_Get_count(&s2, zero_dtype, &count); check(count == 0); MPI_Type_free(&zero_dtype); } 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 * program */ /* simple test to ensure that c2f/f2c routines are present (initially missed * in MPICH impl) */ { MPI_Fint f_handle = 0xdeadbeef; f_handle = MPI_Message_c2f(MPI_MESSAGE_NULL); msg = MPI_Message_f2c(f_handle); check(f_handle != 0xdeadbeef); check(msg == MPI_MESSAGE_NULL); /* PMPI_ versions should also exists */ f_handle = 0xdeadbeef; f_handle = PMPI_Message_c2f(MPI_MESSAGE_NULL); msg = PMPI_Message_f2c(f_handle); check(f_handle != 0xdeadbeef); check(msg == MPI_MESSAGE_NULL); } epilogue: MTest_Finalize(errs); return MTestReturnValue(errs); }