• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -verify %s
2  
3  #include "MPIMock.h"
4  
5  void matchedWait1() {
6    int rank = 0;
7    double buf = 0;
8    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
9    if (rank >= 0) {
10      MPI_Request sendReq1, recvReq1;
11      MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
12      MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1);
13  
14      MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
15      MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
16    }
17  } // no error
18  
19  void matchedWait2() {
20    int rank = 0;
21    double buf = 0;
22    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
23    if (rank >= 0) {
24      MPI_Request sendReq1, recvReq1;
25      MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
26      MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1);
27      MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
28      MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
29    }
30  } // no error
31  
32  void matchedWait3() {
33    int rank = 0;
34    double buf = 0;
35    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
36    if (rank >= 0) {
37      MPI_Request sendReq1, recvReq1;
38      MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
39      MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1);
40  
41      if (rank > 1000) {
42        MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
43        MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
44      } else {
45        MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
46        MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
47      }
48    }
49  } // no error
50  
51  void missingWait1() { // Check missing wait for dead region.
52    double buf = 0;
53    MPI_Request sendReq1;
54    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &sendReq1);
55  } // expected-warning{{Request 'sendReq1' has no matching wait.}}
56  
57  void missingWait2() {
58    int rank = 0;
59    double buf = 0;
60    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
61    if (rank == 0) {
62    } else {
63      MPI_Request sendReq1, recvReq1;
64  
65      MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
66      MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &recvReq1); // expected-warning{{Request 'sendReq1' has no matching wait.}}
67      MPI_Wait(&recvReq1, MPI_STATUS_IGNORE);
68    }
69  }
70  
71  void doubleNonblocking() {
72    int rank = 0;
73    double buf = 0;
74    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
75    if (rank == 1) {
76    } else {
77      MPI_Request sendReq1;
78  
79      MPI_Isend(&buf, 1, MPI_DOUBLE, rank + 1, 0, MPI_COMM_WORLD, &sendReq1);
80      MPI_Irecv(&buf, 1, MPI_DOUBLE, rank - 1, 0, MPI_COMM_WORLD, &sendReq1); // expected-warning{{Double nonblocking on request 'sendReq1'.}}
81      MPI_Wait(&sendReq1, MPI_STATUS_IGNORE);
82    }
83  }
84  
85  void doubleNonblocking2() {
86    int rank = 0;
87    double buf = 0;
88    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
89  
90    MPI_Request req;
91    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req);
92    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req); // expected-warning{{Double nonblocking on request 'req'.}}
93    MPI_Wait(&req, MPI_STATUS_IGNORE);
94  }
95  
96  void doubleNonblocking3() {
97    typedef struct { MPI_Request req; } ReqStruct;
98  
99    ReqStruct rs;
100    int rank = 0;
101    double buf = 0;
102    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
103  
104    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &rs.req);
105    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'.}}
106    MPI_Wait(&rs.req, MPI_STATUS_IGNORE);
107  }
108  
109  void doubleNonblocking4() {
110    int rank = 0;
111    double buf = 0;
112    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
113  
114    MPI_Request req;
115    for (int i = 0; i < 2; ++i) {
116      MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req); // expected-warning{{Double nonblocking on request 'req'.}}
117    }
118    MPI_Wait(&req, MPI_STATUS_IGNORE);
119  }
120  
121  void tripleNonblocking() {
122    double buf = 0;
123    MPI_Request sendReq;
124    MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
125    MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // expected-warning{{Double nonblocking on request 'sendReq'.}}
126    MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // expected-warning{{Double nonblocking on request 'sendReq'.}}
127    MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
128  }
129  
130  void missingNonBlocking() {
131    int rank = 0;
132    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
133    MPI_Request sendReq1[10][10][10];
134    MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // expected-warning{{Request 'sendReq1[1][7][9]' has no matching nonblocking call.}}
135  }
136  
137  void missingNonBlocking2() {
138    int rank = 0;
139    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
140    typedef struct { MPI_Request req[2][2]; } ReqStruct;
141    ReqStruct rs;
142    MPI_Request *r = &rs.req[0][1];
143    MPI_Wait(r, MPI_STATUS_IGNORE); // expected-warning{{Request 'rs.req[0][1]' has no matching nonblocking call.}}
144  }
145  
146  void missingNonBlocking3() {
147    int rank = 0;
148    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
149    MPI_Request sendReq;
150    MPI_Wait(&sendReq, MPI_STATUS_IGNORE); // expected-warning{{Request 'sendReq' has no matching nonblocking call.}}
151  }
152  
153  void missingNonBlockingMultiple() {
154    int rank = 0;
155    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
156    MPI_Request sendReq[4];
157    for (int i = 0; i < 4; ++i) {
158      MPI_Wait(&sendReq[i], MPI_STATUS_IGNORE); // expected-warning-re 1+{{Request {{.*}} has no matching nonblocking call.}}
159    }
160  }
161  
162  void missingNonBlockingWaitall() {
163    int rank = 0;
164    double buf = 0;
165    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
166    MPI_Request req[4];
167  
168    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
169        &req[0]);
170    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
171        &req[1]);
172    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
173        &req[3]);
174  
175    MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning{{Request 'req[2]' has no matching nonblocking call.}}
176  }
177  
178  void missingNonBlockingWaitall2() {
179    int rank = 0;
180    double buf = 0;
181    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
182    MPI_Request req[4];
183  
184    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
185        &req[0]);
186    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
187        &req[3]);
188  
189    MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 2{{Request '{{(.*)[[1-2]](.*)}}' has no matching nonblocking call.}}
190  }
191  
192  void missingNonBlockingWaitall3() {
193    int rank = 0;
194    double buf = 0;
195    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
196    MPI_Request req[4];
197  
198    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
199        &req[0]);
200    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
201        &req[2]);
202  
203    MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 2{{Request '{{(.*)[[1,3]](.*)}}' has no matching nonblocking call.}}
204  }
205  
206  void missingNonBlockingWaitall4() {
207    int rank = 0;
208    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
209    MPI_Request req[4];
210    MPI_Waitall(4, req, MPI_STATUSES_IGNORE); // expected-warning-re 4{{Request '{{(.*)[[0-3]](.*)}}' has no matching nonblocking call.}}
211  }
212  
213  void noDoubleRequestUsage() {
214    typedef struct {
215      MPI_Request req;
216      MPI_Request req2;
217    } ReqStruct;
218  
219    ReqStruct rs;
220    int rank = 0;
221    double buf = 0;
222    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
223  
224    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
225                &rs.req);
226    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
227                &rs.req2);
228    MPI_Wait(&rs.req, MPI_STATUS_IGNORE);
229    MPI_Wait(&rs.req2, MPI_STATUS_IGNORE);
230  } // no error
231  
232  void noDoubleRequestUsage2() {
233    typedef struct {
234      MPI_Request req[2];
235      MPI_Request req2;
236    } ReqStruct;
237  
238    ReqStruct rs;
239    int rank = 0;
240    double buf = 0;
241    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
242  
243    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
244                &rs.req[0]);
245    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
246                &rs.req[1]);
247    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
248                &rs.req2);
249    MPI_Wait(&rs.req[0], MPI_STATUS_IGNORE);
250    MPI_Wait(&rs.req[1], MPI_STATUS_IGNORE);
251    MPI_Wait(&rs.req2, MPI_STATUS_IGNORE);
252  } // no error
253  
254  void nestedRequest() {
255    typedef struct {
256      MPI_Request req[2];
257      MPI_Request req2;
258    } ReqStruct;
259  
260    ReqStruct rs;
261    int rank = 0;
262    double buf = 0;
263    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
264  
265    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
266                &rs.req[0]);
267    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
268                &rs.req[1]);
269    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
270                &rs.req2);
271    MPI_Waitall(2, rs.req, MPI_STATUSES_IGNORE);
272    MPI_Wait(&rs.req2, MPI_STATUS_IGNORE);
273  } // no error
274  
275  void singleRequestInWaitall() {
276    MPI_Request r;
277    int rank = 0;
278    double buf = 0;
279    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
280  
281    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
282                &r);
283    MPI_Waitall(1, &r, MPI_STATUSES_IGNORE);
284  } // no error
285  
286  void multiRequestUsage() {
287    double buf = 0;
288    MPI_Request req;
289  
290    MPI_Isend(&buf, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &req);
291    MPI_Wait(&req, MPI_STATUS_IGNORE);
292  
293    MPI_Irecv(&buf, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &req);
294    MPI_Wait(&req, MPI_STATUS_IGNORE);
295  } // no error
296  
297  void multiRequestUsage2() {
298    double buf = 0;
299    MPI_Request req;
300  
301    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
302                &req);
303    MPI_Wait(&req, MPI_STATUS_IGNORE);
304  
305    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
306                &req);
307    MPI_Wait(&req, MPI_STATUS_IGNORE);
308  } // no error
309  
310  // wrapper function
311  void callNonblocking(MPI_Request *req) {
312    double buf = 0;
313    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
314               req);
315  }
316  
317  // wrapper function
318  void callWait(MPI_Request *req) {
319    MPI_Wait(req, MPI_STATUS_IGNORE);
320  }
321  
322  // Call nonblocking, wait wrapper functions.
323  void callWrapperFunctions() {
324    MPI_Request req;
325    callNonblocking(&req);
326    callWait(&req);
327  } // no error
328  
329  void externFunctions1() {
330    double buf = 0;
331    MPI_Request req;
332    MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD,
333                &req);
334    void callWaitExtern(MPI_Request *req);
335    callWaitExtern(&req);
336  } // expected-warning{{Request 'req' has no matching wait.}}
337  
338  void externFunctions2() {
339    MPI_Request req;
340    void callNonblockingExtern(MPI_Request *req);
341    callNonblockingExtern(&req);
342  }
343