1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/*
* Copyright (C) by Argonne National Laboratory
* See COPYRIGHT in top-level directory
*/
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "mpitest.h"
/*
* Test handling of truncated messages, including short and rendezvous
*/
static int testShort = 1;
static int ShortLen = 2;
static int testMid = 1;
static int MidLen = 64;
static int testLong = 1;
static int LongLen = 100000;
int checkTruncError(int err, const char *msg);
int checkOk(int err, const char *msg);
int main(int argc, char *argv[])
{
MPI_Status status;
int err, errs = 0, source, dest, rank, size;
int *buf = 0;
MTest_Init(&argc, &argv);
MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
source = 0;
dest = size - 1;
buf = (int *) malloc(LongLen * sizeof(int));
MTEST_VG_MEM_INIT(buf, LongLen * sizeof(int));
if (!buf) {
fprintf(stderr, "Unable to allocate communication buffer of size %d\n", LongLen);
MPI_Abort(MPI_COMM_WORLD, 1);
}
if (testShort) {
if (rank == source) {
err = MPI_Send(buf, ShortLen, MPI_INT, dest, 0, MPI_COMM_WORLD);
errs += checkOk(err, "short");
} else if (rank == dest) {
err = MPI_Recv(buf, ShortLen - 1, MPI_INT, source, 0, MPI_COMM_WORLD, &status);
errs += checkTruncError(err, "short");
}
/* Try a message that is arrives after the receive is posted */
if (rank == source) {
MPI_Sendrecv(MPI_BOTTOM, 0, MPI_INT, dest, 1,
MPI_BOTTOM, 0, MPI_INT, dest, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Send(buf, ShortLen, MPI_INT, dest, 2, MPI_COMM_WORLD);
} else if (rank == dest) {
MPI_Request req;
err = MPI_Irecv(buf, ShortLen - 1, MPI_INT, source, 2, MPI_COMM_WORLD, &req);
errs += checkOk(err, "irecv-short");
MPI_Sendrecv(MPI_BOTTOM, 0, MPI_INT, source, 1,
MPI_BOTTOM, 0, MPI_INT, source, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
err = MPI_Wait(&req, &status);
errs += checkTruncError(err, "irecv-short");
}
}
if (testMid) {
if (rank == source) {
err = MPI_Send(buf, MidLen, MPI_INT, dest, 0, MPI_COMM_WORLD);
errs += checkOk(err, "medium");
} else if (rank == dest) {
err = MPI_Recv(buf, MidLen - 1, MPI_INT, source, 0, MPI_COMM_WORLD, &status);
errs += checkTruncError(err, "medium");
}
}
if (testLong) {
if (rank == source) {
err = MPI_Send(buf, LongLen, MPI_INT, dest, 0, MPI_COMM_WORLD);
errs += checkOk(err, "long");
} else if (rank == dest) {
err = MPI_Recv(buf, LongLen - 1, MPI_INT, source, 0, MPI_COMM_WORLD, &status);
errs += checkTruncError(err, "long");
}
/* Test when the receive buffer is much shorter */
if (rank == source) {
err = MPI_Send(buf, LongLen, MPI_INT, dest, 0, MPI_COMM_WORLD);
errs += checkOk(err, "long");
} else if (rank == dest) {
err = MPI_Recv(buf, ShortLen, MPI_INT, source, 0, MPI_COMM_WORLD, &status);
errs += checkTruncError(err, "long-receive-short");
}
}
MPI_Barrier(MPI_COMM_WORLD);
free(buf);
MTest_Finalize(errs);
return MTestReturnValue(errs);
}
int checkTruncError(int err, const char *msg)
{
char errMsg[MPI_MAX_ERROR_STRING];
int errs = 0, msgLen, errclass;
if (!err) {
errs++;
fprintf(stderr, "MPI_Recv (%s) returned MPI_SUCCESS instead of truncated message\n", msg);
fflush(stderr);
} else {
MPI_Error_class(err, &errclass);
if (errclass != MPI_ERR_TRUNCATE) {
errs++;
MPI_Error_string(err, errMsg, &msgLen);
fprintf(stderr, "MPI_Recv (%s) returned unexpected error message: %s\n", msg, errMsg);
fflush(stderr);
}
}
return errs;
}
int checkOk(int err, const char *msg)
{
char errMsg[MPI_MAX_ERROR_STRING];
int errs = 0, msgLen;
if (err) {
errs++;
MPI_Error_string(err, errMsg, &msgLen);
fprintf(stderr, "MPI_Send(%s) failed with %s\n", msg, errMsg);
fflush(stderr);
}
return errs;
}
|