diff options
Diffstat (limited to 'clang/test/Analysis/mpichecker.cpp')
-rw-r--r-- | clang/test/Analysis/mpichecker.cpp | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/clang/test/Analysis/mpichecker.cpp b/clang/test/Analysis/mpichecker.cpp new file mode 100644 index 00000000000..b7a1e00e00b --- /dev/null +++ b/clang/test/Analysis/mpichecker.cpp @@ -0,0 +1,342 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -verify %s + +#include "MPIMock.h" + +void matchedWait1() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank >= 0) { + MPI_Request sendReq1, recvReq1; + MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1); + MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1); + + MPI_Wait(&sendReq1, MPI_STATUS_IGNORE); + MPI_Wait(&recvReq1, MPI_STATUS_IGNORE); + } +} // no error + +void matchedWait2() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank >= 0) { + MPI_Request sendReq1, recvReq1; + MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1); + MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1); + MPI_Wait(&sendReq1, MPI_STATUS_IGNORE); + MPI_Wait(&recvReq1, MPI_STATUS_IGNORE); + } +} // no error + +void matchedWait3() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank >= 0) { + MPI_Request sendReq1, recvReq1; + MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1); + MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1); + + if (rank > 1000) { + MPI_Wait(&sendReq1, MPI_STATUS_IGNORE); + MPI_Wait(&recvReq1, MPI_STATUS_IGNORE); + } else { + MPI_Wait(&sendReq1, MPI_STATUS_IGNORE); + MPI_Wait(&recvReq1, MPI_STATUS_IGNORE); + } + } +} // no error + +void missingWait1() { // Check missing wait for dead region. + double buf = 0; + MPI_Request sendReq1; + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &sendReq1); +} // expected-warning{{Request 'sendReq1' has no matching wait.}} + +void missingWait2() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { + } else { + MPI_Request sendReq1, recvReq1; + + MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1); + MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1); // expected-warning{{Request 'sendReq1' has no matching wait.}} + MPI_Wait(&recvReq1, MPI_STATUS_IGNORE); + } +} + +void doubleNonblocking() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 1) { + } else { + MPI_Request sendReq1; + + MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1); + MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &sendReq1); // expected-warning{{Double nonblocking on request 'sendReq1'.}} + MPI_Wait(&sendReq1, MPI_STATUS_IGNORE); + } +} + +void doubleNonblocking2() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Request req; + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req); // expected-warning{{Double nonblocking on request 'req'.}} + MPI_Wait(&req, MPI_STATUS_IGNORE); +} + +void doubleNonblocking3() { + typedef struct { MPI_Request req; } ReqStruct; + + ReqStruct rs; + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &rs.req); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &rs.req); // expected-warning{{Double nonblocking on request 'rs.req'.}} + MPI_Wait(&rs.req, MPI_STATUS_IGNORE); +} + +void doubleNonblocking4() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Request req; + for (int i = 0; i < 2; ++i) { + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req); // expected-warning{{Double nonblocking on request 'req'.}} + } + MPI_Wait(&req, MPI_STATUS_IGNORE); +} + +void tripleNonblocking() { + double buf = 0; + MPI_Request sendReq; + MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); + MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // expected-warning{{Double nonblocking on request 'sendReq'.}} + MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // expected-warning{{Double nonblocking on request 'sendReq'.}} + MPI_Wait(&sendReq, MPI_STATUS_IGNORE); +} + +void missingNonBlocking() { + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Request sendReq1[10][10][10]; + MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // expected-warning{{Request 'sendReq1[1][7][9]' has no matching nonblocking call.}} +} + +void missingNonBlocking2() { + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + typedef struct { MPI_Request req[2][2]; } ReqStruct; + ReqStruct rs; + MPI_Request *r = &rs.req[0][1]; + MPI_Wait(r, MPI_STATUS_IGNORE); // expected-warning{{Request 'rs.req[0][1]' has no matching nonblocking call.}} +} + +void missingNonBlocking3() { + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Request sendReq; + MPI_Wait(&sendReq, MPI_STATUS_IGNORE); // expected-warning{{Request 'sendReq' has no matching nonblocking call.}} +} + +void missingNonBlockingMultiple() { + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Request sendReq[4]; + for (int i = 0; i < 4; ++i) { + MPI_Wait(&sendReq[i], MPI_STATUS_IGNORE); // expected-warning-re 1+{{Request {{.*}} has no matching nonblocking call.}} + } +} + +void missingNonBlockingWaitall() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Request req[4]; + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req[0]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req[1]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req[3]); + + MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning{{Request 'req[2]' has no matching nonblocking call.}} +} + +void missingNonBlockingWaitall2() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Request req[4]; + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req[0]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req[3]); + + MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 2{{Request '{{(.*)[[1-2]](.*)}}' has no matching nonblocking call.}} +} + +void missingNonBlockingWaitall3() { + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Request req[4]; + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req[0]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req[2]); + + MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 2{{Request '{{(.*)[[1,3]](.*)}}' has no matching nonblocking call.}} +} + +void missingNonBlockingWaitall4() { + int rank = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Request req[4]; + MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 4{{Request '{{(.*)[[0-3]](.*)}}' has no matching nonblocking call.}} +} + +void noDoubleRequestUsage() { + typedef struct { + MPI_Request req; + MPI_Request req2; + } ReqStruct; + + ReqStruct rs; + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req2); + MPI_Wait(&rs.req, MPI_STATUS_IGNORE); + MPI_Wait(&rs.req2, MPI_STATUS_IGNORE); +} // no error + +void noDoubleRequestUsage2() { + typedef struct { + MPI_Request req[2]; + MPI_Request req2; + } ReqStruct; + + ReqStruct rs; + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req[0]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req[1]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req2); + MPI_Wait(&rs.req[0], MPI_STATUS_IGNORE); + MPI_Wait(&rs.req[1], MPI_STATUS_IGNORE); + MPI_Wait(&rs.req2, MPI_STATUS_IGNORE); +} // no error + +void nestedRequest() { + typedef struct { + MPI_Request req[2]; + MPI_Request req2; + } ReqStruct; + + ReqStruct rs; + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req[0]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req[1]); + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &rs.req2); + MPI_Waitall(2, rs.req, MPI_STATUSES_IGNORE); + MPI_Wait(&rs.req2, MPI_STATUS_IGNORE); +} // no error + +void singleRequestInWaitall() { + MPI_Request r; + int rank = 0; + double buf = 0; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &r); + MPI_Waitall(1, &r, MPI_STATUSES_IGNORE); +} // no error + +void multiRequestUsage() { + double buf = 0; + MPI_Request req; + + MPI_Isend(&buf, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &req); + MPI_Wait(&req, MPI_STATUS_IGNORE); + + MPI_Irecv(&buf, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &req); + MPI_Wait(&req, MPI_STATUS_IGNORE); +} // no error + +void multiRequestUsage2() { + double buf = 0; + MPI_Request req; + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req); + MPI_Wait(&req, MPI_STATUS_IGNORE); + + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req); + MPI_Wait(&req, MPI_STATUS_IGNORE); +} // no error + +// wrapper function +void callNonblocking(MPI_Request *req) { + double buf = 0; + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + req); +} + +// wrapper function +void callWait(MPI_Request *req) { + MPI_Wait(req, MPI_STATUS_IGNORE); +} + +// Call nonblocking, wait wrapper functions. +void callWrapperFunctions() { + MPI_Request req; + callNonblocking(&req); + callWait(&req); +} // no error + +void externFunctions1() { + double buf = 0; + MPI_Request req; + MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, + &req); + void callWaitExtern(MPI_Request *req); + callWaitExtern(&req); +} // expected-warning{{Request 'req' has no matching wait.}} + +void externFunctions2() { + MPI_Request req; + void callNonblockingExtern(MPI_Request *req); + callNonblockingExtern(&req); +} |