summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/mpichecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/mpichecker.cpp')
-rw-r--r--clang/test/Analysis/mpichecker.cpp342
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);
+}
OpenPOWER on IntegriCloud