/** * Check if two calls are a send/recv pair. * * @param sendCall * @param recvCall * * @return if they are send/recv pair */ bool MPICheckerAST::isSendRecvPair(const MPICall &sendCall, const MPICall &recvCall) const { if (!funcClassifier_.isSendType(sendCall)) return false; if (!funcClassifier_.isRecvType(recvCall)) return false; if (!areDatatypesEqual(sendCall, recvCall)) return false; // compare count, tag for (const size_t idx : {MPIPointToPoint::kCount, MPIPointToPoint::kTag}) { if (!sendCall.arguments()[idx].isEqual(recvCall.arguments()[idx])) { return false; } } // compare ranks const auto &rankArgSend = sendCall.arguments()[MPIPointToPoint::kRank]; const auto &rankArgRecv = recvCall.arguments()[MPIPointToPoint::kRank]; if (rankArgSend.typeSequence().size() != rankArgRecv.typeSequence().size()) return false; // build sequences without last operator(skip first element) std::vector<ArgumentVisitor::ComponentType> seq1, seq2; std::vector<std::string> val1, val2; bool containsSubtraction{false}; for (size_t i = 1; i < rankArgSend.typeSequence().size(); ++i) { seq1.push_back(rankArgSend.typeSequence()[i]); val1.push_back(rankArgSend.valueSequence()[i]); seq2.push_back(rankArgRecv.typeSequence()[i]); val2.push_back(rankArgRecv.valueSequence()[i]); if (rankArgSend.valueSequence()[i] == "-") containsSubtraction = true; if (rankArgRecv.valueSequence()[i] == "-") containsSubtraction = true; } if (containsSubtraction) { // check ordered if (seq1 != seq2 || val1 != val2) return false; } else { // check permutation if ((!cont::isPermutation(seq1, seq2)) || (!cont::isPermutation(val1, val2))) { return false; } } // last (value|var|function) must be identical if (val1.back() != val2.back()) return false; // last operator must be inverse if (!rankArgSend.isLastOperatorInverse(rankArgRecv)) return false; return true; }
/** * Checks if two (point to point) calls are a send/recv pair. * * @param sendCall * @param recvCall * * @return if they are send/recv pair */ bool MPICheckerAST::isSendRecvPair(const MPICall &sendCall, const MPICall &recvCall, const MPIRankCase &sendCase, const MPIRankCase &recvCase) const { if (!funcClassifier_.isSendType(sendCall)) return false; if (!funcClassifier_.isRecvType(recvCall)) return false; if (!areDatatypesEqual(sendCall, recvCall)) return false; // compare count, tag for (const size_t idx : { MPIPointToPoint::kCount, MPIPointToPoint::kTag }) { if (sendCall.arg(idx) != recvCall.arg(idx)) { return false; } } return rankArgsMatch(sendCall, recvCall, sendCase, recvCase); }