Home | History | Annotate | Line # | Download | only in MPI-Checker
      1 //===-- MPIFunctionClassifier.cpp - classifies MPI functions ----*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 ///
      9 /// \file
     10 /// This file defines functionality to identify and classify MPI functions.
     11 ///
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h"
     15 #include "llvm/ADT/STLExtras.h"
     16 
     17 namespace clang {
     18 namespace ento {
     19 namespace mpi {
     20 
     21 void MPIFunctionClassifier::identifierInit(ASTContext &ASTCtx) {
     22   // Initialize function identifiers.
     23   initPointToPointIdentifiers(ASTCtx);
     24   initCollectiveIdentifiers(ASTCtx);
     25   initAdditionalIdentifiers(ASTCtx);
     26 }
     27 
     28 void MPIFunctionClassifier::initPointToPointIdentifiers(ASTContext &ASTCtx) {
     29   // Copy identifiers into the correct classification containers.
     30   IdentInfo_MPI_Send = &ASTCtx.Idents.get("MPI_Send");
     31   MPIPointToPointTypes.push_back(IdentInfo_MPI_Send);
     32   MPIType.push_back(IdentInfo_MPI_Send);
     33   assert(IdentInfo_MPI_Send);
     34 
     35   IdentInfo_MPI_Isend = &ASTCtx.Idents.get("MPI_Isend");
     36   MPIPointToPointTypes.push_back(IdentInfo_MPI_Isend);
     37   MPINonBlockingTypes.push_back(IdentInfo_MPI_Isend);
     38   MPIType.push_back(IdentInfo_MPI_Isend);
     39   assert(IdentInfo_MPI_Isend);
     40 
     41   IdentInfo_MPI_Ssend = &ASTCtx.Idents.get("MPI_Ssend");
     42   MPIPointToPointTypes.push_back(IdentInfo_MPI_Ssend);
     43   MPIType.push_back(IdentInfo_MPI_Ssend);
     44   assert(IdentInfo_MPI_Ssend);
     45 
     46   IdentInfo_MPI_Issend = &ASTCtx.Idents.get("MPI_Issend");
     47   MPIPointToPointTypes.push_back(IdentInfo_MPI_Issend);
     48   MPINonBlockingTypes.push_back(IdentInfo_MPI_Issend);
     49   MPIType.push_back(IdentInfo_MPI_Issend);
     50   assert(IdentInfo_MPI_Issend);
     51 
     52   IdentInfo_MPI_Bsend = &ASTCtx.Idents.get("MPI_Bsend");
     53   MPIPointToPointTypes.push_back(IdentInfo_MPI_Bsend);
     54   MPIType.push_back(IdentInfo_MPI_Bsend);
     55   assert(IdentInfo_MPI_Bsend);
     56 
     57   IdentInfo_MPI_Ibsend = &ASTCtx.Idents.get("MPI_Ibsend");
     58   MPIPointToPointTypes.push_back(IdentInfo_MPI_Ibsend);
     59   MPINonBlockingTypes.push_back(IdentInfo_MPI_Ibsend);
     60   MPIType.push_back(IdentInfo_MPI_Ibsend);
     61   assert(IdentInfo_MPI_Ibsend);
     62 
     63   IdentInfo_MPI_Rsend = &ASTCtx.Idents.get("MPI_Rsend");
     64   MPIPointToPointTypes.push_back(IdentInfo_MPI_Rsend);
     65   MPIType.push_back(IdentInfo_MPI_Rsend);
     66   assert(IdentInfo_MPI_Rsend);
     67 
     68   IdentInfo_MPI_Irsend = &ASTCtx.Idents.get("MPI_Irsend");
     69   MPIPointToPointTypes.push_back(IdentInfo_MPI_Irsend);
     70   MPIType.push_back(IdentInfo_MPI_Irsend);
     71   assert(IdentInfo_MPI_Irsend);
     72 
     73   IdentInfo_MPI_Recv = &ASTCtx.Idents.get("MPI_Recv");
     74   MPIPointToPointTypes.push_back(IdentInfo_MPI_Recv);
     75   MPIType.push_back(IdentInfo_MPI_Recv);
     76   assert(IdentInfo_MPI_Recv);
     77 
     78   IdentInfo_MPI_Irecv = &ASTCtx.Idents.get("MPI_Irecv");
     79   MPIPointToPointTypes.push_back(IdentInfo_MPI_Irecv);
     80   MPINonBlockingTypes.push_back(IdentInfo_MPI_Irecv);
     81   MPIType.push_back(IdentInfo_MPI_Irecv);
     82   assert(IdentInfo_MPI_Irecv);
     83 }
     84 
     85 void MPIFunctionClassifier::initCollectiveIdentifiers(ASTContext &ASTCtx) {
     86   // Copy identifiers into the correct classification containers.
     87   IdentInfo_MPI_Scatter = &ASTCtx.Idents.get("MPI_Scatter");
     88   MPICollectiveTypes.push_back(IdentInfo_MPI_Scatter);
     89   MPIPointToCollTypes.push_back(IdentInfo_MPI_Scatter);
     90   MPIType.push_back(IdentInfo_MPI_Scatter);
     91   assert(IdentInfo_MPI_Scatter);
     92 
     93   IdentInfo_MPI_Iscatter = &ASTCtx.Idents.get("MPI_Iscatter");
     94   MPICollectiveTypes.push_back(IdentInfo_MPI_Iscatter);
     95   MPIPointToCollTypes.push_back(IdentInfo_MPI_Iscatter);
     96   MPINonBlockingTypes.push_back(IdentInfo_MPI_Iscatter);
     97   MPIType.push_back(IdentInfo_MPI_Iscatter);
     98   assert(IdentInfo_MPI_Iscatter);
     99 
    100   IdentInfo_MPI_Gather = &ASTCtx.Idents.get("MPI_Gather");
    101   MPICollectiveTypes.push_back(IdentInfo_MPI_Gather);
    102   MPICollToPointTypes.push_back(IdentInfo_MPI_Gather);
    103   MPIType.push_back(IdentInfo_MPI_Gather);
    104   assert(IdentInfo_MPI_Gather);
    105 
    106   IdentInfo_MPI_Igather = &ASTCtx.Idents.get("MPI_Igather");
    107   MPICollectiveTypes.push_back(IdentInfo_MPI_Igather);
    108   MPICollToPointTypes.push_back(IdentInfo_MPI_Igather);
    109   MPINonBlockingTypes.push_back(IdentInfo_MPI_Igather);
    110   MPIType.push_back(IdentInfo_MPI_Igather);
    111   assert(IdentInfo_MPI_Igather);
    112 
    113   IdentInfo_MPI_Allgather = &ASTCtx.Idents.get("MPI_Allgather");
    114   MPICollectiveTypes.push_back(IdentInfo_MPI_Allgather);
    115   MPICollToCollTypes.push_back(IdentInfo_MPI_Allgather);
    116   MPIType.push_back(IdentInfo_MPI_Allgather);
    117   assert(IdentInfo_MPI_Allgather);
    118 
    119   IdentInfo_MPI_Iallgather = &ASTCtx.Idents.get("MPI_Iallgather");
    120   MPICollectiveTypes.push_back(IdentInfo_MPI_Iallgather);
    121   MPICollToCollTypes.push_back(IdentInfo_MPI_Iallgather);
    122   MPINonBlockingTypes.push_back(IdentInfo_MPI_Iallgather);
    123   MPIType.push_back(IdentInfo_MPI_Iallgather);
    124   assert(IdentInfo_MPI_Iallgather);
    125 
    126   IdentInfo_MPI_Bcast = &ASTCtx.Idents.get("MPI_Bcast");
    127   MPICollectiveTypes.push_back(IdentInfo_MPI_Bcast);
    128   MPIPointToCollTypes.push_back(IdentInfo_MPI_Bcast);
    129   MPIType.push_back(IdentInfo_MPI_Bcast);
    130   assert(IdentInfo_MPI_Bcast);
    131 
    132   IdentInfo_MPI_Ibcast = &ASTCtx.Idents.get("MPI_Ibcast");
    133   MPICollectiveTypes.push_back(IdentInfo_MPI_Ibcast);
    134   MPIPointToCollTypes.push_back(IdentInfo_MPI_Ibcast);
    135   MPINonBlockingTypes.push_back(IdentInfo_MPI_Ibcast);
    136   MPIType.push_back(IdentInfo_MPI_Ibcast);
    137   assert(IdentInfo_MPI_Ibcast);
    138 
    139   IdentInfo_MPI_Reduce = &ASTCtx.Idents.get("MPI_Reduce");
    140   MPICollectiveTypes.push_back(IdentInfo_MPI_Reduce);
    141   MPICollToPointTypes.push_back(IdentInfo_MPI_Reduce);
    142   MPIType.push_back(IdentInfo_MPI_Reduce);
    143   assert(IdentInfo_MPI_Reduce);
    144 
    145   IdentInfo_MPI_Ireduce = &ASTCtx.Idents.get("MPI_Ireduce");
    146   MPICollectiveTypes.push_back(IdentInfo_MPI_Ireduce);
    147   MPICollToPointTypes.push_back(IdentInfo_MPI_Ireduce);
    148   MPINonBlockingTypes.push_back(IdentInfo_MPI_Ireduce);
    149   MPIType.push_back(IdentInfo_MPI_Ireduce);
    150   assert(IdentInfo_MPI_Ireduce);
    151 
    152   IdentInfo_MPI_Allreduce = &ASTCtx.Idents.get("MPI_Allreduce");
    153   MPICollectiveTypes.push_back(IdentInfo_MPI_Allreduce);
    154   MPICollToCollTypes.push_back(IdentInfo_MPI_Allreduce);
    155   MPIType.push_back(IdentInfo_MPI_Allreduce);
    156   assert(IdentInfo_MPI_Allreduce);
    157 
    158   IdentInfo_MPI_Iallreduce = &ASTCtx.Idents.get("MPI_Iallreduce");
    159   MPICollectiveTypes.push_back(IdentInfo_MPI_Iallreduce);
    160   MPICollToCollTypes.push_back(IdentInfo_MPI_Iallreduce);
    161   MPINonBlockingTypes.push_back(IdentInfo_MPI_Iallreduce);
    162   MPIType.push_back(IdentInfo_MPI_Iallreduce);
    163   assert(IdentInfo_MPI_Iallreduce);
    164 
    165   IdentInfo_MPI_Alltoall = &ASTCtx.Idents.get("MPI_Alltoall");
    166   MPICollectiveTypes.push_back(IdentInfo_MPI_Alltoall);
    167   MPICollToCollTypes.push_back(IdentInfo_MPI_Alltoall);
    168   MPIType.push_back(IdentInfo_MPI_Alltoall);
    169   assert(IdentInfo_MPI_Alltoall);
    170 
    171   IdentInfo_MPI_Ialltoall = &ASTCtx.Idents.get("MPI_Ialltoall");
    172   MPICollectiveTypes.push_back(IdentInfo_MPI_Ialltoall);
    173   MPICollToCollTypes.push_back(IdentInfo_MPI_Ialltoall);
    174   MPINonBlockingTypes.push_back(IdentInfo_MPI_Ialltoall);
    175   MPIType.push_back(IdentInfo_MPI_Ialltoall);
    176   assert(IdentInfo_MPI_Ialltoall);
    177 }
    178 
    179 void MPIFunctionClassifier::initAdditionalIdentifiers(ASTContext &ASTCtx) {
    180   IdentInfo_MPI_Comm_rank = &ASTCtx.Idents.get("MPI_Comm_rank");
    181   MPIType.push_back(IdentInfo_MPI_Comm_rank);
    182   assert(IdentInfo_MPI_Comm_rank);
    183 
    184   IdentInfo_MPI_Comm_size = &ASTCtx.Idents.get("MPI_Comm_size");
    185   MPIType.push_back(IdentInfo_MPI_Comm_size);
    186   assert(IdentInfo_MPI_Comm_size);
    187 
    188   IdentInfo_MPI_Wait = &ASTCtx.Idents.get("MPI_Wait");
    189   MPIType.push_back(IdentInfo_MPI_Wait);
    190   assert(IdentInfo_MPI_Wait);
    191 
    192   IdentInfo_MPI_Waitall = &ASTCtx.Idents.get("MPI_Waitall");
    193   MPIType.push_back(IdentInfo_MPI_Waitall);
    194   assert(IdentInfo_MPI_Waitall);
    195 
    196   IdentInfo_MPI_Barrier = &ASTCtx.Idents.get("MPI_Barrier");
    197   MPICollectiveTypes.push_back(IdentInfo_MPI_Barrier);
    198   MPIType.push_back(IdentInfo_MPI_Barrier);
    199   assert(IdentInfo_MPI_Barrier);
    200 }
    201 
    202 // general identifiers
    203 bool MPIFunctionClassifier::isMPIType(const IdentifierInfo *IdentInfo) const {
    204   return llvm::is_contained(MPIType, IdentInfo);
    205 }
    206 
    207 bool MPIFunctionClassifier::isNonBlockingType(
    208     const IdentifierInfo *IdentInfo) const {
    209   return llvm::is_contained(MPINonBlockingTypes, IdentInfo);
    210 }
    211 
    212 // point-to-point identifiers
    213 bool MPIFunctionClassifier::isPointToPointType(
    214     const IdentifierInfo *IdentInfo) const {
    215   return llvm::is_contained(MPIPointToPointTypes, IdentInfo);
    216 }
    217 
    218 // collective identifiers
    219 bool MPIFunctionClassifier::isCollectiveType(
    220     const IdentifierInfo *IdentInfo) const {
    221   return llvm::is_contained(MPICollectiveTypes, IdentInfo);
    222 }
    223 
    224 bool MPIFunctionClassifier::isCollToColl(
    225     const IdentifierInfo *IdentInfo) const {
    226   return llvm::is_contained(MPICollToCollTypes, IdentInfo);
    227 }
    228 
    229 bool MPIFunctionClassifier::isScatterType(
    230     const IdentifierInfo *IdentInfo) const {
    231   return IdentInfo == IdentInfo_MPI_Scatter ||
    232          IdentInfo == IdentInfo_MPI_Iscatter;
    233 }
    234 
    235 bool MPIFunctionClassifier::isGatherType(
    236     const IdentifierInfo *IdentInfo) const {
    237   return IdentInfo == IdentInfo_MPI_Gather ||
    238          IdentInfo == IdentInfo_MPI_Igather ||
    239          IdentInfo == IdentInfo_MPI_Allgather ||
    240          IdentInfo == IdentInfo_MPI_Iallgather;
    241 }
    242 
    243 bool MPIFunctionClassifier::isAllgatherType(
    244     const IdentifierInfo *IdentInfo) const {
    245   return IdentInfo == IdentInfo_MPI_Allgather ||
    246          IdentInfo == IdentInfo_MPI_Iallgather;
    247 }
    248 
    249 bool MPIFunctionClassifier::isAlltoallType(
    250     const IdentifierInfo *IdentInfo) const {
    251   return IdentInfo == IdentInfo_MPI_Alltoall ||
    252          IdentInfo == IdentInfo_MPI_Ialltoall;
    253 }
    254 
    255 bool MPIFunctionClassifier::isBcastType(const IdentifierInfo *IdentInfo) const {
    256   return IdentInfo == IdentInfo_MPI_Bcast || IdentInfo == IdentInfo_MPI_Ibcast;
    257 }
    258 
    259 bool MPIFunctionClassifier::isReduceType(
    260     const IdentifierInfo *IdentInfo) const {
    261   return IdentInfo == IdentInfo_MPI_Reduce ||
    262          IdentInfo == IdentInfo_MPI_Ireduce ||
    263          IdentInfo == IdentInfo_MPI_Allreduce ||
    264          IdentInfo == IdentInfo_MPI_Iallreduce;
    265 }
    266 
    267 // additional identifiers
    268 bool MPIFunctionClassifier::isMPI_Wait(const IdentifierInfo *IdentInfo) const {
    269   return IdentInfo == IdentInfo_MPI_Wait;
    270 }
    271 
    272 bool MPIFunctionClassifier::isMPI_Waitall(
    273     const IdentifierInfo *IdentInfo) const {
    274   return IdentInfo == IdentInfo_MPI_Waitall;
    275 }
    276 
    277 bool MPIFunctionClassifier::isWaitType(const IdentifierInfo *IdentInfo) const {
    278   return IdentInfo == IdentInfo_MPI_Wait || IdentInfo == IdentInfo_MPI_Waitall;
    279 }
    280 
    281 } // end of namespace: mpi
    282 } // end of namespace: ento
    283 } // end of namespace: clang
    284