Exemplo n.º 1
0
/**
 * 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;
    }
}
Exemplo n.º 2
0
/**
 * Check if rank arguments of send, recv pair match.
 *
 * @return is matching
 */
bool MPICheckerAST::rankArgsMatch(const MPICall &sendCall,
                                  const MPICall &recvCall,
                                  const MPIRankCase &sendCase,
                                  const MPIRankCase &recvCase) const {
    // match special case
    if (isFirstLastPair(sendCall, recvCall, sendCase, recvCase)) return true;

    // compare ranks
    const auto &rankArgSend = sendCall.arg(MPIPointToPoint::kRank);
    const auto &rankArgRecv = recvCall.arg(MPIPointToPoint::kRank);

    if (rankArgSend.valueSequence().size() !=
            rankArgRecv.valueSequence().size())
        return false;

    // build sequences without last operator(skip first element)
    const llvm::SmallVector<std::string, 4> sendValSeq{
        rankArgSend.valueSequence().begin() + 1,
        rankArgSend.valueSequence().end()},
    recvValSeq{rankArgRecv.valueSequence().begin() + 1,
               rankArgRecv.valueSequence().end()};

    bool containsSubtraction{false};
    for (size_t i = 0; i < sendValSeq.size(); ++i) {
        if (sendValSeq[i] == "-" || recvValSeq[i] == "-") {
            containsSubtraction = true;
            break;
        }
    }

    // check ordered
    if (containsSubtraction && (sendValSeq != recvValSeq)) return false;
    // check permutation
    if (!containsSubtraction &&
            (!cont::isPermutation(sendValSeq, recvValSeq))) {
        return false;
    }
    // last (value|var|function) must be identical
    if (sendValSeq.back() != recvValSeq.back()) return false;
    // last operator must be inverse
    if (!rankArgSend.isLastOperatorInverse(rankArgRecv)) return false;

    return true;
}
Exemplo n.º 3
0
/**
 * 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);
}