Home | History | Annotate | Download | only in Analysis
      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