/** * Check if communication between first, last rank. * * @return is matching */ bool MPICheckerAST::isFirstLastPair(const MPICall &sendCall, const MPICall &recvCall, const MPIRankCase &sendCase, const MPIRankCase &recvCase) const { const auto &rankArgSend = sendCall.arg(MPIPointToPoint::kRank); const auto &rankArgRecv = recvCall.arg(MPIPointToPoint::kRank); llvm::SmallVector<std::string, 1> firstRank{"0"}; llvm::SmallVector<std::string, 3> lastRank{"-", MPIProcessCount::encoding, "1"}; // first to last match if (sendCase.isFirstRank() && rankArgSend.valueSequence() == lastRank && recvCase.isLastRank() && rankArgRecv.valueSequence() == firstRank) { return true; } // last to first match else if (sendCase.isLastRank() && rankArgSend.valueSequence() == firstRank && recvCase.isFirstRank() && rankArgRecv.valueSequence() == lastRank) { return true; } else { return false; } }
/** * Check for reachability of calls between two cases. * * @param firstCase * @param secondCase */ void MPICheckerAST::checkReachbilityPair(const MPIRankCase &sendCase, const MPIRankCase &recvCase) const { // find send/recv pairs for (const MPICall &send : sendCase.mpiCalls()) { send.isReachable_ = true; if (send.isMarked_) continue; for (const MPICall &recv : recvCase.mpiCalls()) { recv.isReachable_ = true; if (recv.isMarked_) continue; // check if pair matches if (isSendRecvPair(send, recv, sendCase, recvCase)) { send.isMarked_ = true; recv.isMarked_ = true; break; } // no match and call was blocking else if (funcClassifier_.isBlockingType(recv)) { break; } } // no matching recv found in second case if (funcClassifier_.isBlockingType(send) && !send.isMarked_) { return; } } }
/** * Checks for collective calls in rank case. Triggers bug reporter. * * @param mpiCall */ void MPICheckerAST::checkForCollectiveCalls(const MPIRankCase &rankCase) const { for (const MPICall &call : rankCase.mpiCalls()) { if (funcClassifier_.isCollectiveType(call)) { bugReporter_.reportCollCallInBranch(call.callExpr()); } } }
/** * Matches send with recv operations between two rank cases. * For the first case send operations are tried to be matched * with recv operations from the second case. In case of a match * calls are marked. * * @param rankCase1 * @param rankCase2 */ void MPICheckerAST::checkSendRecvMatches(const MPIRankCase &sendCase, const MPIRankCase &recvCase) const { // find send/recv pairs for (const MPICall &send : sendCase.mpiCalls()) { // skip non sends for case 1 if (!funcClassifier_.isSendType(send) || send.isMarked_) continue; // skip non recvs for case 2 for (const MPICall &recv : recvCase.mpiCalls()) { if (!funcClassifier_.isRecvType(recv) || recv.isMarked_) continue; // check if pair matches if (isSendRecvPair(send, recv, sendCase, recvCase)) { send.isMarked_ = true; recv.isMarked_ = true; break; } } } }
/** * Check if there is a redundant call to the call passed. * * @param callToCheck */ void MPICheckerAST::checkForRedundantCall(const MPICall &callToCheck, const MPIRankCase &rankCase) const { for (const MPICall &comparedCall : rankCase.mpiCalls()) { if (qualifyRedundancyCheck(callToCheck, comparedCall)) { if (callToCheck == comparedCall) { bugReporter_.reportRedundantCall(callToCheck.callExpr(), comparedCall.callExpr()); callToCheck.isMarked_ = true; callToCheck.isMarked_ = true; } } } return; }