CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
132 lines
5.8 KiB
C++
132 lines
5.8 KiB
C++
//===- SMTExtensionOps.cpp - SMT extension for the Transform dialect ------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Dialect/Transform/SMTExtension/SMTExtensionOps.h"
|
|
#include "mlir/Dialect/SMT/IR/SMTDialect.h"
|
|
#include "mlir/Dialect/SMT/IR/SMTOps.h"
|
|
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
|
|
|
|
using namespace mlir;
|
|
|
|
#define GET_OP_CLASSES
|
|
#include "mlir/Dialect/Transform/SMTExtension/SMTExtensionOps.cpp.inc"
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ConstrainParamsOp
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void transform::smt::ConstrainParamsOp::getEffects(
|
|
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
|
onlyReadsHandle(getParamsMutable(), effects);
|
|
producesHandle(getResults(), effects);
|
|
}
|
|
|
|
DiagnosedSilenceableFailure
|
|
transform::smt::ConstrainParamsOp::apply(transform::TransformRewriter &rewriter,
|
|
transform::TransformResults &results,
|
|
transform::TransformState &state) {
|
|
// TODO: Proper operational semantics are to check the SMT problem in the body
|
|
// with a SMT solver with the arguments of the body constrained to the
|
|
// values passed into the op. Success or failure is then determined by
|
|
// the solver's result.
|
|
// One way to support this is to just promise the TransformOpInterface
|
|
// and allow for users to attach their own implementation, which would,
|
|
// e.g., translate the ops to SMTLIB and hand that over to the user's
|
|
// favourite solver. This requires changes to the dialect's verifier.
|
|
return emitSilenceableFailure(getLoc())
|
|
<< "op does not have interpreted semantics yet";
|
|
}
|
|
|
|
LogicalResult transform::smt::ConstrainParamsOp::verify() {
|
|
auto yieldTerminator =
|
|
dyn_cast<mlir::smt::YieldOp>(getRegion().front().back());
|
|
if (!yieldTerminator)
|
|
return emitOpError() << "expected '"
|
|
<< mlir::smt::YieldOp::getOperationName()
|
|
<< "' as terminator";
|
|
|
|
auto checkTypes = [](size_t idx, Type smtType, StringRef smtDesc,
|
|
Type paramType, StringRef paramDesc,
|
|
auto *atOp) -> InFlightDiagnostic {
|
|
if (!isa<mlir::smt::BoolType, mlir::smt::IntType, mlir::smt::BitVectorType>(
|
|
smtType))
|
|
return atOp->emitOpError() << "the type of " << smtDesc << " #" << idx
|
|
<< " is expected to be either a !smt.bool, a "
|
|
"!smt.int, or a !smt.bv";
|
|
|
|
assert(isa<TransformParamTypeInterface>(paramType) &&
|
|
"ODS specifies params' type should implement param interface");
|
|
if (isa<transform::AnyParamType>(paramType))
|
|
return {}; // No further checks can be done.
|
|
|
|
// NB: This cast must succeed as long as the only implementors of
|
|
// TransformParamTypeInterface are AnyParamType and ParamType.
|
|
Type typeWrappedByParam = cast<ParamType>(paramType).getType();
|
|
|
|
if (isa<mlir::smt::IntType>(smtType)) {
|
|
if (!isa<IntegerType>(typeWrappedByParam))
|
|
return atOp->emitOpError()
|
|
<< "the type of " << smtDesc << " #" << idx
|
|
<< " is !smt.int though the corresponding " << paramDesc
|
|
<< " type (" << paramType << ") is not wrapping an integer type";
|
|
} else if (isa<mlir::smt::BoolType>(smtType)) {
|
|
auto wrappedIntType = dyn_cast<IntegerType>(typeWrappedByParam);
|
|
if (!wrappedIntType || wrappedIntType.getWidth() != 1)
|
|
return atOp->emitOpError()
|
|
<< "the type of " << smtDesc << " #" << idx
|
|
<< " is !smt.bool though the corresponding " << paramDesc
|
|
<< " type (" << paramType << ") is not wrapping i1";
|
|
} else if (auto bvSmtType = dyn_cast<mlir::smt::BitVectorType>(smtType)) {
|
|
auto wrappedIntType = dyn_cast<IntegerType>(typeWrappedByParam);
|
|
if (!wrappedIntType || wrappedIntType.getWidth() != bvSmtType.getWidth())
|
|
return atOp->emitOpError()
|
|
<< "the type of " << smtDesc << " #" << idx << " is " << smtType
|
|
<< " though the corresponding " << paramDesc << " type ("
|
|
<< paramType
|
|
<< ") is not wrapping an integer type of the same bitwidth";
|
|
}
|
|
|
|
return {};
|
|
};
|
|
|
|
if (getOperands().size() != getBody().getNumArguments())
|
|
return emitOpError(
|
|
"must have the same number of block arguments as operands");
|
|
|
|
for (auto [idx, operandType, blockArgType] :
|
|
llvm::enumerate(getOperandTypes(), getBody().getArgumentTypes())) {
|
|
InFlightDiagnostic typeCheckResult =
|
|
checkTypes(idx, blockArgType, "block arg", operandType, "operand",
|
|
/*atOp=*/this);
|
|
if (LogicalResult(typeCheckResult).failed())
|
|
return typeCheckResult;
|
|
}
|
|
|
|
for (auto &op : getBody().getOps()) {
|
|
if (!isa<mlir::smt::SMTDialect>(op.getDialect()))
|
|
return emitOpError(
|
|
"ops contained in region should belong to SMT-dialect");
|
|
}
|
|
|
|
if (yieldTerminator->getNumOperands() != getNumResults())
|
|
return yieldTerminator.emitOpError()
|
|
<< "expected terminator to have as many operands as the parent op "
|
|
"has results";
|
|
|
|
for (auto [idx, termOperandType, resultType] : llvm::enumerate(
|
|
yieldTerminator->getOperands().getType(), getResultTypes())) {
|
|
InFlightDiagnostic typeCheckResult =
|
|
checkTypes(idx, termOperandType, "terminator operand", resultType,
|
|
"result", /*atOp=*/&yieldTerminator);
|
|
if (LogicalResult(typeCheckResult).failed())
|
|
return typeCheckResult;
|
|
}
|
|
|
|
return success();
|
|
}
|