Esempio n. 1
0
/**
 * Select apprioriate function to match the buffer type against
 * the specified mpi datatype.
 *
 * @param typeVisitor contains information about the buffer
 * @param mpiCall call whose arguments are observed
 * @param mpiDatatypeString
 * @param idxPair bufferIdx, mpiDatatypeIdx
 */
void MPICheckerAST::selectTypeMatcher(
    const mpi::TypeVisitor &typeVisitor, const MPICall &mpiCall,
    const StringRef mpiDatatypeString,
    const std::pair<size_t, size_t> &idxPair) const {
    const clang::BuiltinType *builtinType = typeVisitor.builtinType();
    bool isTypeMatching{true};

    // check for exact width types (e.g. int16_t, uint32_t)
    if (typeVisitor.isTypedefType()) {
        isTypeMatching = matchExactWidthType(typeVisitor, mpiDatatypeString);
    }
    // check for complex-floating types (e.g. float _Complex)
    else if (typeVisitor.isComplexType()) {
        isTypeMatching = matchComplexType(typeVisitor, mpiDatatypeString);
    }
    // check for basic builtin types (e.g. int, char)
    else if (!builtinType) {
        return;  // if no builtin type cancel checking
    } else if (builtinType->isBooleanType()) {
        isTypeMatching = matchBoolType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isAnyCharacterType()) {
        isTypeMatching = matchCharType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isSignedInteger()) {
        isTypeMatching = matchSignedType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isUnsignedIntegerType()) {
        isTypeMatching = matchUnsignedType(typeVisitor, mpiDatatypeString);
    } else if (builtinType->isFloatingType()) {
        isTypeMatching = matchFloatType(typeVisitor, mpiDatatypeString);
    }

    if (!isTypeMatching)
        bugReporter_.reportTypeMismatch(mpiCall.callExpr(), idxPair,
                                        typeVisitor.qualType_,
                                        mpiDatatypeString);
}
Esempio n. 2
0
/**
 * Returns index pairs for each buffer, datatype pair.
 *
 * @param mpiCall
 *
 * @return index pairs
 */
MPICheckerAST::IndexPairs MPICheckerAST::bufferDataTypeIndices(
    const MPICall &mpiCall) const {
    IndexPairs indexPairs;

    if (funcClassifier_.isPointToPointType(mpiCall)) {
        indexPairs.push_back(
        {MPIPointToPoint::kBuf, MPIPointToPoint::kDatatype});
    } else if (funcClassifier_.isCollectiveType(mpiCall)) {
        if (funcClassifier_.isReduceType(mpiCall)) {
            // only check buffer type if not inplace
            if (util::sourceRangeAsStringRef(
                        mpiCall.callExpr()->getArg(0)->getSourceRange(),
                        analysisManager_) != "MPI_IN_PLACE") {
                indexPairs.push_back({0, 3});
            }
            indexPairs.push_back({1, 3});
        } else if (funcClassifier_.isScatterType(mpiCall) ||
                   funcClassifier_.isGatherType(mpiCall) ||
                   funcClassifier_.isAlltoallType(mpiCall)) {
            indexPairs.push_back({0, 2});
            indexPairs.push_back({3, 5});
        } else if (funcClassifier_.isBcastType(mpiCall)) {
            indexPairs.push_back({0, 2});
        }
    }
    return indexPairs;
}
Esempio n. 3
0
/**
 * Checks if mpi-datatypes for 2 different point to point calls are equal.
 *
 * @param sendCall
 * @param recvCall
 *
 * @return equality
 */
bool MPICheckerAST::areDatatypesEqual(const MPICall &sendCall,
                                      const MPICall &recvCall) const {
    // compare mpi datatype
    llvm::StringRef sendDataType =
        util::sourceRangeAsStringRef(sendCall.callExpr()
                                     ->getArg(MPIPointToPoint::kDatatype)
                                     ->getSourceRange(),
                                     analysisManager_);

    llvm::StringRef recvDataType =
        util::sourceRangeAsStringRef(recvCall.callExpr()
                                     ->getArg(MPIPointToPoint::kDatatype)
                                     ->getSourceRange(),
                                     analysisManager_);

    return sendDataType == recvDataType;
}
Esempio n. 4
0
/**
 * Check if invalid argument types are used in a mpi call.
 * This check looks at indices where only integer values are valid.
 * (count, rank, tag) Any non integer type usage is reported.
 *
 * @param mpiCall to check the arguments for
 */
void MPICheckerAST::checkForInvalidArgs(const MPICall &mpiCall) const {
    std::vector<size_t> indicesToCheck = integerIndices(mpiCall);
    if (!indicesToCheck.size()) return;

    // iterate indices which should not have integer arguments
    for (const size_t idx : indicesToCheck) {
        // check for invalid variable types
        const auto &arg = mpiCall.arguments()[idx];
        const auto &vars = arg.vars();
        for (const auto &var : vars) {
            const mpi::TypeVisitor typeVisitor{var->getType()};
            if (!typeVisitor.builtinType() ||
                !typeVisitor.builtinType()->isIntegerType()) {
                bugReporter_.reportInvalidArgumentType(
                    mpiCall.callExpr(), idx, var->getSourceRange(), "Variable");
            }
        }

        // check for float literals
        if (arg.floatingLiterals().size()) {
            bugReporter_.reportInvalidArgumentType(
                mpiCall.callExpr(), idx,
                arg.floatingLiterals().front()->getSourceRange(), "Literal");
        }

        // check for invalid return types from functions
        const auto &functions = arg.functions();
        for (const auto &function : functions) {
            const mpi::TypeVisitor typeVisitor{function->getReturnType()};
            if (!typeVisitor.builtinType() ||
                !typeVisitor.builtinType()->isIntegerType()) {
                bugReporter_.reportInvalidArgumentType(
                    mpiCall.callExpr(), idx, function->getSourceRange(),
                    "Return value");
            }
        }
    }
}
Esempio n. 5
0
/**
 * 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;
}