forked from OSchip/llvm-project
[mlir][EDSC] Refactor dependencies involving EDSCs.
Summary: This diff removes the dependency of LinalgOps and VectorOps on EDSCs. Reviewers: jpienaar, ftynse Reviewed By: ftynse Subscribers: merge_guards_bot, mgorny, mehdi_amini, rriddle, burmako, shauheen, antiagainst, csigg, arpith-jacob, mgester, lucyrfox, herhut, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D72481
This commit is contained in:
parent
441410be47
commit
89b395fe79
|
@ -24,6 +24,64 @@ namespace mlir {
|
|||
class BlockArgument;
|
||||
|
||||
namespace edsc {
|
||||
|
||||
/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations.
|
||||
/// More specifically it is meant to be used as a temporary object for
|
||||
/// representing any nested MLIR construct that is "related to" an mlir::Value
|
||||
/// (for now an induction variable).
|
||||
class LoopRangeBuilder : public NestedBuilder {
|
||||
public:
|
||||
/// Constructs a new loop.for and captures the associated induction
|
||||
/// variable. A ValueHandle pointer is passed as the first argument and is the
|
||||
/// *only* way to capture the loop induction variable.
|
||||
LoopRangeBuilder(ValueHandle *iv, ValueHandle range);
|
||||
LoopRangeBuilder(ValueHandle *iv, Value range);
|
||||
LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range);
|
||||
|
||||
LoopRangeBuilder(const LoopRangeBuilder &) = delete;
|
||||
LoopRangeBuilder(LoopRangeBuilder &&) = default;
|
||||
|
||||
LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete;
|
||||
LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default;
|
||||
|
||||
/// The only purpose of this operator is to serve as a sequence point so that
|
||||
/// the evaluation of `fun` (which build IR snippets in a scoped fashion) is
|
||||
/// scoped within a LoopRangeBuilder.
|
||||
ValueHandle operator()(std::function<void(void)> fun = nullptr);
|
||||
};
|
||||
|
||||
/// Helper class to sugar building loop.for loop nests from ranges.
|
||||
/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges
|
||||
/// directly. In the current implementation it produces loop.for operations.
|
||||
class LoopNestRangeBuilder {
|
||||
public:
|
||||
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<edsc::ValueHandle> ranges);
|
||||
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<Value> ranges);
|
||||
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<SubViewOp::Range> ranges);
|
||||
edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
|
||||
|
||||
private:
|
||||
SmallVector<LoopRangeBuilder, 4> loops;
|
||||
};
|
||||
|
||||
/// Helper template class for building loop.for and affine.loop nests from
|
||||
/// ranges.
|
||||
template <typename LoopTy> class GenericLoopNestRangeBuilder {
|
||||
public:
|
||||
GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<Value> ranges);
|
||||
void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
|
||||
|
||||
private:
|
||||
typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
|
||||
AffineLoopNestBuilder,
|
||||
LoopNestRangeBuilder>::type BuilderType;
|
||||
std::unique_ptr<BuilderType> builder;
|
||||
};
|
||||
|
||||
enum class IterType { Parallel, Reduction };
|
||||
|
||||
inline StringRef toString(IterType t) {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
|
||||
#include "mlir/Dialect/LoopOps/LoopOps.h"
|
||||
#include "mlir/Dialect/StandardOps/Ops.h"
|
||||
#include "mlir/EDSC/Helpers.h"
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
|
||||
|
@ -21,67 +20,6 @@ class AffineExpr;
|
|||
class AffineMap;
|
||||
class OperationFolder;
|
||||
|
||||
namespace edsc {
|
||||
|
||||
/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations.
|
||||
/// More specifically it is meant to be used as a temporary object for
|
||||
/// representing any nested MLIR construct that is "related to" an mlir::Value
|
||||
/// (for now an induction variable).
|
||||
class LoopRangeBuilder : public NestedBuilder {
|
||||
public:
|
||||
/// Constructs a new loop.for and captures the associated induction
|
||||
/// variable. A ValueHandle pointer is passed as the first argument and is the
|
||||
/// *only* way to capture the loop induction variable.
|
||||
LoopRangeBuilder(ValueHandle *iv, ValueHandle range);
|
||||
LoopRangeBuilder(ValueHandle *iv, Value range);
|
||||
LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range);
|
||||
|
||||
LoopRangeBuilder(const LoopRangeBuilder &) = delete;
|
||||
LoopRangeBuilder(LoopRangeBuilder &&) = default;
|
||||
|
||||
LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete;
|
||||
LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default;
|
||||
|
||||
/// The only purpose of this operator is to serve as a sequence point so that
|
||||
/// the evaluation of `fun` (which build IR snippets in a scoped fashion) is
|
||||
/// scoped within a LoopRangeBuilder.
|
||||
ValueHandle operator()(std::function<void(void)> fun = nullptr);
|
||||
};
|
||||
|
||||
/// Helper class to sugar building loop.for loop nests from ranges.
|
||||
/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges
|
||||
/// directly. In the current implementation it produces loop.for operations.
|
||||
class LoopNestRangeBuilder {
|
||||
public:
|
||||
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<edsc::ValueHandle> ranges);
|
||||
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<Value> ranges);
|
||||
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<SubViewOp::Range> ranges);
|
||||
edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
|
||||
|
||||
private:
|
||||
SmallVector<LoopRangeBuilder, 4> loops;
|
||||
};
|
||||
|
||||
/// Helper template class for building loop.for and affine.loop nests from
|
||||
/// ranges.
|
||||
template <typename LoopTy> class GenericLoopNestRangeBuilder {
|
||||
public:
|
||||
GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<Value> ranges);
|
||||
void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
|
||||
|
||||
private:
|
||||
typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
|
||||
AffineLoopNestBuilder,
|
||||
LoopNestRangeBuilder>::type BuilderType;
|
||||
std::unique_ptr<BuilderType> builder;
|
||||
};
|
||||
|
||||
} // namespace edsc
|
||||
|
||||
namespace linalg {
|
||||
class LinalgDependenceGraph;
|
||||
|
||||
|
@ -117,12 +55,13 @@ Optional<FusionInfo> fuseProducerOf(OpBuilder &b, LinalgOp consumer,
|
|||
/// the inverse, concatenated loopToOperandRangeMaps to this list allows the
|
||||
/// derivation of loop ranges for any linalgOp.
|
||||
template <typename ConcreteOp>
|
||||
SmallVector<Value, 8> getViewSizes(ConcreteOp linalgOp) {
|
||||
SmallVector<Value, 8> getViewSizes(OpBuilder &builder, ConcreteOp linalgOp) {
|
||||
auto loc = linalgOp.getLoc();
|
||||
SmallVector<Value, 8> res;
|
||||
for (auto v : linalgOp.getInputsAndOutputBuffers()) {
|
||||
MemRefType t = v.getType().template cast<MemRefType>();
|
||||
for (unsigned i = 0; i < t.getRank(); ++i)
|
||||
res.push_back(edsc::intrinsics::dim(v, i));
|
||||
res.push_back(builder.create<DimOp>(loc, v, i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ add_llvm_library(MLIRLinalgToLLVM
|
|||
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/LinalgToLLVM
|
||||
)
|
||||
set(LIBS
|
||||
MLIRLinalg
|
||||
MLIRLinalgOps
|
||||
MLIRLLVMIR
|
||||
MLIRTransforms
|
||||
LLVMCore
|
||||
|
|
|
@ -2,7 +2,7 @@ set(LIBS
|
|||
MLIRAffineOps
|
||||
MLIRGPU
|
||||
MLIRIR
|
||||
MLIRLinalg
|
||||
MLIRLinalgOps
|
||||
MLIRPass
|
||||
MLIRStandardOps
|
||||
MLIRSupport
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
set(LIBS
|
||||
|
||||
MLIRLinalgOps
|
||||
MLIRStandardOps
|
||||
)
|
||||
|
||||
|
||||
add_llvm_library(MLIRLinalgAnalysis
|
||||
DependenceAnalysis.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
add_dependencies(MLIRLinalgAnalysis ${LIBS})
|
||||
target_link_libraries(MLIRLinalgAnalysis ${LIBS})
|
|
@ -1,31 +1,5 @@
|
|||
add_llvm_library(MLIRLinalg
|
||||
LinalgRegistration.cpp
|
||||
Analysis/DependenceAnalysis.cpp
|
||||
EDSC/Builders.cpp
|
||||
IR/LinalgOps.cpp
|
||||
IR/LinalgTypes.cpp
|
||||
Transforms/Fusion.cpp
|
||||
Transforms/LinalgTransforms.cpp
|
||||
Transforms/LinalgToLoops.cpp
|
||||
Transforms/Promotion.cpp
|
||||
Transforms/Tiling.cpp
|
||||
Utils/Utils.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
add_dependencies(MLIRLinalg
|
||||
|
||||
MLIRAffineOps
|
||||
MLIRAnalysis
|
||||
MLIREDSC
|
||||
MLIRLinalgOpsIncGen
|
||||
MLIRLinalgStructuredOpsIncGen
|
||||
MLIRLinalgTransformPatternsIncGen
|
||||
MLIRStandardOps
|
||||
MLIRStandardToLLVM
|
||||
MLIRVectorOps
|
||||
)
|
||||
add_subdirectory(Analysis)
|
||||
add_subdirectory(EDSC)
|
||||
add_subdirectory(IR)
|
||||
add_subdirectory(Transforms)
|
||||
add_subdirectory(Utils)
|
||||
|
|
|
@ -19,6 +19,96 @@ using namespace mlir;
|
|||
using namespace mlir::edsc;
|
||||
using namespace mlir::edsc::intrinsics;
|
||||
using namespace mlir::edsc::ops;
|
||||
using namespace mlir::linalg;
|
||||
using namespace mlir::loop;
|
||||
|
||||
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
|
||||
ValueHandle range) {
|
||||
assert(range.getType() && "expected !linalg.range type");
|
||||
assert(range.getValue().getDefiningOp() &&
|
||||
"need operations to extract range parts");
|
||||
auto rangeOp = cast<RangeOp>(range.getValue().getDefiningOp());
|
||||
auto lb = rangeOp.min();
|
||||
auto ub = rangeOp.max();
|
||||
auto step = rangeOp.step();
|
||||
auto forOp = OperationHandle::createOp<ForOp>(lb, ub, step);
|
||||
*iv = ValueHandle(forOp.getInductionVar());
|
||||
auto *body = forOp.getBody();
|
||||
enter(body, /*prev=*/1);
|
||||
}
|
||||
|
||||
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
|
||||
SubViewOp::Range range) {
|
||||
auto forOp =
|
||||
OperationHandle::createOp<ForOp>(range.offset, range.size, range.stride);
|
||||
*iv = ValueHandle(forOp.getInductionVar());
|
||||
auto *body = forOp.getBody();
|
||||
enter(body, /*prev=*/1);
|
||||
}
|
||||
|
||||
ValueHandle mlir::edsc::LoopRangeBuilder::
|
||||
operator()(std::function<void(void)> fun) {
|
||||
if (fun)
|
||||
fun();
|
||||
exit();
|
||||
return ValueHandle::null();
|
||||
}
|
||||
|
||||
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
|
||||
ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> ranges) {
|
||||
loops.reserve(ranges.size());
|
||||
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
|
||||
loops.emplace_back(ivs[i], ranges[i]);
|
||||
}
|
||||
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
|
||||
}
|
||||
|
||||
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
|
||||
ArrayRef<ValueHandle *> ivs, ArrayRef<ValueHandle> ranges) {
|
||||
loops.reserve(ranges.size());
|
||||
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
|
||||
loops.emplace_back(ivs[i], ranges[i]);
|
||||
}
|
||||
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
|
||||
}
|
||||
|
||||
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
|
||||
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges)
|
||||
: LoopNestRangeBuilder(
|
||||
ivs, SmallVector<ValueHandle, 4>(ranges.begin(), ranges.end())) {}
|
||||
|
||||
ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::
|
||||
operator()(std::function<void(void)> fun) {
|
||||
if (fun)
|
||||
fun();
|
||||
for (auto &lit : reverse(loops)) {
|
||||
lit({});
|
||||
}
|
||||
return ValueHandle::null();
|
||||
}
|
||||
|
||||
template <>
|
||||
GenericLoopNestRangeBuilder<loop::ForOp>::GenericLoopNestRangeBuilder(
|
||||
ArrayRef<edsc::ValueHandle *> ivs, ArrayRef<Value> ranges) {
|
||||
builder = std::make_unique<LoopNestRangeBuilder>(ivs, ranges);
|
||||
}
|
||||
|
||||
template <>
|
||||
GenericLoopNestRangeBuilder<AffineForOp>::GenericLoopNestRangeBuilder(
|
||||
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges) {
|
||||
SmallVector<ValueHandle, 4> lbs;
|
||||
SmallVector<ValueHandle, 4> ubs;
|
||||
SmallVector<int64_t, 4> steps;
|
||||
for (Value range : ranges) {
|
||||
assert(range.getType() && "expected linalg.range type");
|
||||
assert(range.getDefiningOp() && "need operations to extract range parts");
|
||||
RangeOp rangeOp = cast<RangeOp>(range.getDefiningOp());
|
||||
lbs.emplace_back(ValueHandle(rangeOp.min()));
|
||||
ubs.emplace_back(ValueHandle(rangeOp.max()));
|
||||
steps.emplace_back(ValueHandle(rangeOp.step()));
|
||||
}
|
||||
builder = std::make_unique<AffineLoopNestBuilder>(ivs, lbs, ubs, steps);
|
||||
}
|
||||
|
||||
static void getMaxDimIndex(ArrayRef<StructuredIndexed> structuredIndices,
|
||||
unsigned &pos) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
set(LIBS
|
||||
|
||||
MLIREDSC
|
||||
MLIRIR
|
||||
MLIRLinalgOps
|
||||
MLIRLoopOps
|
||||
MLIRStandardOps
|
||||
)
|
||||
|
||||
add_llvm_library(MLIRLinalgEDSC
|
||||
Builders.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
add_dependencies(MLIRLinalgEDSC ${LIBS})
|
||||
target_link_libraries(MLIRLinalgEDSC ${LIBS})
|
|
@ -0,0 +1,23 @@
|
|||
set(LIBS
|
||||
|
||||
MLIRIR
|
||||
)
|
||||
|
||||
add_llvm_library(MLIRLinalgOps
|
||||
LinalgOps.cpp
|
||||
LinalgTypes.cpp
|
||||
LinalgRegistration.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
add_dependencies(MLIRLinalgOps
|
||||
|
||||
${LIBS}
|
||||
MLIRLinalgOpsIncGen
|
||||
MLIRLinalgStructuredOpsIncGen
|
||||
)
|
||||
target_link_libraries(MLIRLinalgOps ${LIBS})
|
|
@ -12,9 +12,6 @@
|
|||
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
|
||||
#include "mlir/Dialect/Linalg/Utils/Utils.h"
|
||||
#include "mlir/Dialect/LoopOps/LoopOps.h"
|
||||
#include "mlir/EDSC/Helpers.h"
|
||||
#include "mlir/IR/AffineExpr.h"
|
||||
#include "mlir/IR/AffineMap.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
|
@ -26,15 +23,12 @@
|
|||
#include "mlir/Support/Functional.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Support/STLExtras.h"
|
||||
#include "mlir/Transforms/FoldUtils.h"
|
||||
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace mlir;
|
||||
using namespace mlir::edsc;
|
||||
using namespace mlir::edsc::intrinsics;
|
||||
using namespace mlir::linalg;
|
||||
|
||||
///////////////////// Operations defined with Tablegen /////////////////////////
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
set(LIBS
|
||||
|
||||
MLIRAffineOps
|
||||
MLIRAnalysis
|
||||
MLIREDSC
|
||||
MLIRIR
|
||||
MLIRLinalgAnalysis
|
||||
MLIRLinalgEDSC
|
||||
MLIRLinalgOps
|
||||
MLIRLoopOps
|
||||
MLIRPass
|
||||
MLIRStandardOps
|
||||
MLIRStandardToLLVM
|
||||
MLIRTransformUtils
|
||||
MLIRVectorOps
|
||||
)
|
||||
|
||||
add_llvm_library(MLIRLinalgTransforms
|
||||
Fusion.cpp
|
||||
LinalgTransforms.cpp
|
||||
LinalgToLoops.cpp
|
||||
Promotion.cpp
|
||||
Tiling.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
add_dependencies(MLIRLinalgTransforms
|
||||
|
||||
${LIBS}
|
||||
MLIRLinalgTransformPatternsIncGen
|
||||
)
|
||||
target_link_libraries(MLIRLinalgTransforms ${LIBS})
|
|
@ -1,4 +1,4 @@
|
|||
//===- LowerToLoops.cpp - conversion from Linalg library ops to loops------===//
|
||||
//===- LinalgToLoops.cpp - conversion from Linalg library ops to loops-----===//
|
||||
//
|
||||
// Part of the MLIR Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "mlir/Dialect/Linalg/EDSC/Builders.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
|
||||
#include "mlir/Dialect/Linalg/Passes.h"
|
||||
|
@ -438,7 +439,7 @@ LogicalResult LinalgOpToLoopsImpl<LoopTy, IndexedValueTy, ConcreteOpTy>::doit(
|
|||
SmallVector<ValueHandle *, 4> allPIvs =
|
||||
makeHandlePointers(MutableArrayRef<IndexHandle>(allIvs));
|
||||
auto loopRanges = emitLoopRanges(scope.getBuilder(), scope.getLocation(),
|
||||
invertedMap, getViewSizes(linalgOp));
|
||||
invertedMap, getViewSizes(b, linalgOp));
|
||||
assert(loopRanges.size() == allIvs.size());
|
||||
|
||||
GenericLoopNestRangeBuilder<LoopTy>(allPIvs, loopRanges)([&] {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "mlir/Dialect/Linalg/EDSC/Builders.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
|
||||
#include "mlir/Dialect/Linalg/Passes.h"
|
||||
|
@ -333,7 +334,7 @@ mlir::linalg::tileLinalgOp(OpBuilder &b, LinalgOp op, ArrayRef<Value> tileSizes,
|
|||
b.setInsertionPoint(op);
|
||||
ScopedContext scope(b, op.getLoc());
|
||||
// 2. Build the tiled loop ranges.
|
||||
auto viewSizes = getViewSizes(op);
|
||||
auto viewSizes = getViewSizes(b, op);
|
||||
// The flattened loopToOperandRangesMaps is expected to be an invertible
|
||||
// permutation map (asserted in the inverse calculation).
|
||||
auto viewSizesToLoopsMap =
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
set(LIBS
|
||||
|
||||
MLIREDSC
|
||||
MLIRIR
|
||||
MLIRLinalgOps
|
||||
MLIRLoopOps
|
||||
MLIRPass
|
||||
MLIRStandardOps
|
||||
MLIRTransformUtils
|
||||
)
|
||||
|
||||
add_llvm_library(MLIRLinalgUtils
|
||||
|
||||
Utils.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
add_dependencies(MLIRLinalgUtils ${LIBS})
|
||||
target_link_libraries(MLIRLinalgUtils ${LIBS})
|
|
@ -13,7 +13,6 @@
|
|||
#include "mlir/Dialect/Linalg/Utils/Utils.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
|
||||
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
|
||||
#include "mlir/Dialect/Linalg/Passes.h"
|
||||
#include "mlir/Dialect/Linalg/Utils/Intrinsics.h"
|
||||
#include "mlir/Dialect/LoopOps/LoopOps.h"
|
||||
#include "mlir/Dialect/StandardOps/Ops.h"
|
||||
|
@ -32,102 +31,6 @@ using namespace mlir::linalg;
|
|||
using namespace mlir::linalg::intrinsics;
|
||||
using namespace mlir::loop;
|
||||
|
||||
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
|
||||
ValueHandle range) {
|
||||
assert(range.getType() && "expected !linalg.range type");
|
||||
assert(range.getValue().getDefiningOp() &&
|
||||
"need operations to extract range parts");
|
||||
auto rangeOp = cast<RangeOp>(range.getValue().getDefiningOp());
|
||||
auto lb = rangeOp.min();
|
||||
auto ub = rangeOp.max();
|
||||
auto step = rangeOp.step();
|
||||
auto forOp = OperationHandle::createOp<ForOp>(lb, ub, step);
|
||||
*iv = ValueHandle(forOp.getInductionVar());
|
||||
auto *body = forOp.getBody();
|
||||
enter(body, /*prev=*/1);
|
||||
}
|
||||
|
||||
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
|
||||
SubViewOp::Range range) {
|
||||
auto forOp =
|
||||
OperationHandle::createOp<ForOp>(range.offset, range.size, range.stride);
|
||||
*iv = ValueHandle(forOp.getInductionVar());
|
||||
auto *body = forOp.getBody();
|
||||
enter(body, /*prev=*/1);
|
||||
}
|
||||
|
||||
ValueHandle
|
||||
mlir::edsc::LoopRangeBuilder::operator()(std::function<void(void)> fun) {
|
||||
if (fun)
|
||||
fun();
|
||||
exit();
|
||||
return ValueHandle::null();
|
||||
}
|
||||
|
||||
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
|
||||
ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> ranges) {
|
||||
loops.reserve(ranges.size());
|
||||
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
|
||||
loops.emplace_back(ivs[i], ranges[i]);
|
||||
}
|
||||
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
|
||||
}
|
||||
|
||||
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
|
||||
ArrayRef<ValueHandle *> ivs, ArrayRef<ValueHandle> ranges) {
|
||||
loops.reserve(ranges.size());
|
||||
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
|
||||
loops.emplace_back(ivs[i], ranges[i]);
|
||||
}
|
||||
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
|
||||
}
|
||||
|
||||
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
|
||||
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges)
|
||||
: LoopNestRangeBuilder(
|
||||
ivs, SmallVector<ValueHandle, 4>(ranges.begin(), ranges.end())) {}
|
||||
|
||||
ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::operator()(
|
||||
std::function<void(void)> fun) {
|
||||
if (fun)
|
||||
fun();
|
||||
for (auto &lit : reverse(loops)) {
|
||||
lit({});
|
||||
}
|
||||
return ValueHandle::null();
|
||||
}
|
||||
|
||||
namespace mlir {
|
||||
namespace edsc {
|
||||
|
||||
template <>
|
||||
GenericLoopNestRangeBuilder<
|
||||
loop::ForOp>::GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
|
||||
ArrayRef<Value> ranges) {
|
||||
builder = std::make_unique<LoopNestRangeBuilder>(ivs, ranges);
|
||||
}
|
||||
|
||||
template <>
|
||||
GenericLoopNestRangeBuilder<
|
||||
AffineForOp>::GenericLoopNestRangeBuilder(ArrayRef<ValueHandle *> ivs,
|
||||
ArrayRef<Value> ranges) {
|
||||
SmallVector<ValueHandle, 4> lbs;
|
||||
SmallVector<ValueHandle, 4> ubs;
|
||||
SmallVector<int64_t, 4> steps;
|
||||
for (Value range : ranges) {
|
||||
assert(range.getType() && "expected linalg.range type");
|
||||
assert(range.getDefiningOp() && "need operations to extract range parts");
|
||||
RangeOp rangeOp = cast<RangeOp>(range.getDefiningOp());
|
||||
lbs.emplace_back(ValueHandle(rangeOp.min()));
|
||||
ubs.emplace_back(ValueHandle(rangeOp.max()));
|
||||
steps.emplace_back(ValueHandle(rangeOp.step()));
|
||||
}
|
||||
builder = std::make_unique<AffineLoopNestBuilder>(ivs, lbs, ubs, steps);
|
||||
}
|
||||
|
||||
} // namespace edsc
|
||||
} // namespace mlir
|
||||
|
||||
static Value emitOrFoldComposedAffineApply(OpBuilder &b, Location loc,
|
||||
AffineMap map,
|
||||
ArrayRef<Value> operandsRef,
|
||||
|
|
|
@ -12,11 +12,10 @@
|
|||
|
||||
#include <type_traits>
|
||||
|
||||
#include "mlir/Dialect/AffineOps/AffineOps.h"
|
||||
#include "mlir/Dialect/VectorOps/Utils.h"
|
||||
#include "mlir/Dialect/VectorOps/VectorOps.h"
|
||||
#include "mlir/Dialect/VectorOps/VectorTransforms.h"
|
||||
#include "mlir/EDSC/Builders.h"
|
||||
#include "mlir/EDSC/Helpers.h"
|
||||
#include "mlir/IR/AffineExpr.h"
|
||||
#include "mlir/IR/AffineMap.h"
|
||||
#include "mlir/IR/Attributes.h"
|
||||
|
|
|
@ -9,7 +9,8 @@ target_link_libraries(mlir-edsc-builder-api-test
|
|||
MLIRAffineOps
|
||||
MLIREDSC
|
||||
MLIRIR
|
||||
MLIRLinalg
|
||||
MLIRLinalgEDSC
|
||||
MLIRLinalgOps
|
||||
MLIRLoopOps
|
||||
MLIRStandardOps
|
||||
MLIRTransforms
|
||||
|
@ -21,7 +22,7 @@ target_include_directories(mlir-edsc-builder-api-test PRIVATE ..)
|
|||
|
||||
whole_archive_link(mlir-edsc-builder-api-test
|
||||
MLIRAffineOps
|
||||
MLIRLinalg
|
||||
MLIRLinalgOps
|
||||
MLIRLoopOps
|
||||
MLIRStandardOps
|
||||
MLIRTransforms
|
||||
|
|
|
@ -29,6 +29,9 @@ target_link_libraries(MLIRTestTransforms
|
|||
MLIRAnalysis
|
||||
MLIREDSC
|
||||
MLIRGPU
|
||||
MLIRLinalgOps
|
||||
MLIRLinalgTransforms
|
||||
MLIRLinalgUtils
|
||||
MLIRLoopOps
|
||||
MLIRPass
|
||||
MLIRTestDialect
|
||||
|
|
|
@ -29,7 +29,7 @@ set(LIBS
|
|||
MLIRGPUtoNVVMTransforms
|
||||
MLIRGPUtoROCDLTransforms
|
||||
MLIRGPUtoSPIRVTransforms
|
||||
MLIRLinalg
|
||||
MLIRLinalgOps
|
||||
MLIRLLVMIR
|
||||
MLIRLoopOps
|
||||
MLIRNVVMIR
|
||||
|
|
Loading…
Reference in New Issue