[llvm-branch-commits] [mlir] 9ac0b31 - [mlir][Linalg] Drop symbol_source abstraction which does not pay for itself.
Nicolas Vasilache via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Nov 23 04:52:17 PST 2020
Author: Nicolas Vasilache
Date: 2020-11-23T12:43:02Z
New Revision: 9ac0b314a431405aa6a681124f83138f7544807e
URL: https://github.com/llvm/llvm-project/commit/9ac0b314a431405aa6a681124f83138f7544807e
DIFF: https://github.com/llvm/llvm-project/commit/9ac0b314a431405aa6a681124f83138f7544807e.diff
LOG: [mlir][Linalg] Drop symbol_source abstraction which does not pay for itself.
Differential Revision: https://reviews.llvm.org/D91956
Added:
Modified:
mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
mlir/include/mlir/Dialect/Linalg/Passes.td
mlir/include/mlir/Dialect/Utils/StructuredOpsUtils.h
mlir/lib/Dialect/Linalg/EDSC/Builders.cpp
mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp
mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp
mlir/lib/Dialect/Linalg/Transforms/Loops.cpp
mlir/test/Dialect/Linalg/invalid.mlir
mlir/test/Dialect/Linalg/loops.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td b/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
index aba4f9d61fe0..66f39104d7e7 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
@@ -503,9 +503,7 @@ class GenericOpBase<string mnemonic> : LinalgStructuredBase_Op<mnemonic, [
OptionalAttr<StrAttr>:$doc,
OptionalAttr<StrAttr>:$library_call,
// ArrayAttr of StrArrayAttr:
- OptionalAttr<ArrayAttr>:$sparse,
- Confined<OptionalAttr<I64Attr>, [IntMinValue<0>]>
- :$symbol_source);
+ OptionalAttr<ArrayAttr>:$sparse);
let results = (outs Variadic<AnyRankedTensor>:$result_tensors);
let regions = (region AnyRegion:$region);
let extraClassDeclaration = [{
@@ -513,18 +511,13 @@ class GenericOpBase<string mnemonic> : LinalgStructuredBase_Op<mnemonic, [
return SmallVector<StringRef, 8>{
getDocAttrName(),
getIndexingMapsAttrName(), getLibraryCallAttrName(),
- getIteratorTypesAttrName(), getSymbolSourceAttrName()
+ getIteratorTypesAttrName(),
};
}
std::string getLibraryCallName() {
return library_call().hasValue() ?
library_call()->str() : "op_has_no_registered_library_name";
}
- llvm::Optional<unsigned> getSymbolSource() {
- auto ss = symbol_source();
- return ss.hasValue() ?
- llvm::Optional<unsigned>(ss.getValue()) : llvm::None;
- }
static std::function<void(Block &)> getRegionBuilder() {
return nullptr;
@@ -566,10 +559,6 @@ def GenericOp : GenericOpBase<"generic"> {
parallel, reduction, window
- sparse: an optional list with per-dimension sparsity annotations (either
"D" for dense or "S" for sparse) for each input and output view.
- - symbol_source: index of the operand whose dimensions will be propagated
- as symbols to the indexing maps. When specified the number of symbols
- in each of the indexing maps has to be either 0 or the rank of the
- specified operand.
Example:
Defining a #matmul_trait attribute in MLIR can be done as follows:
@@ -646,50 +635,17 @@ def GenericOp : GenericOpBase<"generic"> {
Tensor values must be legalized by a buffer allocation pass before most
transformations can be applied. Such legalizations move tensor return values
into output buffer operands and updates the region arguments accordingly.
-
- The `symbol_source` attribute allows selecting a particular operand and
- introducing symbols for each operand dimension. Such symbols can then be
- used in the indexing maps.
-
- Example of 1D convolution with symbols:
- ```mlir
- #conv_1d_accesses = [
- affine_map<(m, n)[dimN] -> (m + n - dimN floordiv 2)>, // in
- affine_map<(m, n)[dimN] -> (n)>, // filter
- affine_map<(m, n)[dimN] -> (m)> // out
- ]
-
- #conv_1d_trait = {
- doc = "O(m) += I(m + n - size(n) floordiv 2) * K(n)",
- indexing_maps = #conv_1d_accesses,
- library_call = "linalg_conv_1d",
- iterator_types = ["parallel", "parallel"],
- symbol_source = 1
- }
-
- linalg.generic #conv_1d_trait
- ins(%in, %filter : memref<?xf32>, memref<?xf32>)
- outs(%out : memref<?xf32>) {
- ^bb0(%a: f32, %b: f32, %c: f32) :
- %d = mulf %a, %b : f32
- %e = addf %c, %d : f32
- linalg.yield %e : f32
- }
- ```
- where symbol s0 will be substituted with `dim %filter, %c0` i.e. the first
- and only dimension of the second operand as specified by the symbol_source
- attribute.
}];
let builders = [
OpBuilderDAG<(ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
"ValueRange":$outputBuffers, "ValueRange":$initTensors,
"ArrayRef<AffineMap>":$indexingMaps, "ArrayRef<StringRef>":$iteratorTypes,
- "StringRef":$doc, "StringRef":$libraryCall, "IntegerAttr":$symbolSource,
+ "StringRef":$doc, "StringRef":$libraryCall,
CArg<"function_ref<void(OpBuilder &, Location, ValueRange)>", "nullptr">)>,
OpBuilderDAG<(ins "ValueRange":$inputs, "ValueRange":$outputBuffers,
"ArrayRef<AffineMap>":$indexingMaps, "ArrayRef<StringRef>":$iteratorTypes,
- "StringRef":$doc, "StringRef":$libraryCall, "IntegerAttr":$symbolSource,
+ "StringRef":$doc, "StringRef":$libraryCall,
CArg<"function_ref<void(OpBuilder &, Location, ValueRange)>", "nullptr">)>,
OpBuilderDAG<(ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
"ValueRange":$outputBuffers, "ValueRange":$initTensors,
@@ -819,51 +775,18 @@ def IndexedGenericOp : GenericOpBase<"indexed_generic"> {
Tensor values must be legalized by a buffer allocation pass before most
transformations can be applied. Such legalizations move tensor return values
into output buffer operands and update the region arguments accordingly.
-
- The `symbol_source` attribute allows selecting a particular operand and
- introducing symbols for each operand dimension. Such symbols can then be
- used in the indexing maps.
-
- Example of 1D convolution with symbols:
- ```mlir
- #conv_1d_accesses = [
- affine_map<(m, n)[dimN] -> (m + n - dimN floordiv 2)>, // in
- affine_map<(m, n)[dimN] -> (n)>, // filter
- affine_map<(m, n)[dimN] -> (m)> // out
- ]
-
- #conv_1d_trait = {
- doc = "O(m) += I(m + n - size(n) floordiv 2) * K(n)",
- indexing_maps = #conv_1d_accesses,
- library_call = "linalg_conv_1d",
- iterator_types = ["parallel", "parallel"],
- symbol_source = 1
- }
-
- linalg.generic #conv_1d_trait
- ins(%in, %filter : memref<?xf32>, memref<?xf32>)
- outs(%out : memref<?xf32>) {
- ^bb0(%a: f32, %b: f32, %c: f32) :
- %d = mulf %a, %b : f32
- %e = addf %c, %d : f32
- linalg.yield %e : f32
- }
- ```
- where symbol s0 will be substituted with `dim %filter, %c0` i.e. the first
- and only dimension of the second operand as specified by the symbol_source
- attribute.
}];
let builders = [
OpBuilderDAG<(ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
"ValueRange":$outputBuffers, "ValueRange":$initTensors,
"ArrayRef<AffineMap>":$indexingMaps, "ArrayRef<StringRef>":$iteratorTypes,
- "StringRef":$doc, "StringRef":$libraryCall, "IntegerAttr":$symbolSource,
+ "StringRef":$doc, "StringRef":$libraryCall,
CArg<"function_ref<void(OpBuilder &, Location, ValueRange, ValueRange)>",
"nullptr">)>,
OpBuilderDAG<(ins "ValueRange":$inputs, "ValueRange":$outputBuffers,
"ArrayRef<AffineMap>":$indexingMaps, "ArrayRef<StringRef>":$iteratorTypes,
- "StringRef":$doc, "StringRef":$libraryCall, "IntegerAttr":$symbolSource,
+ "StringRef":$doc, "StringRef":$libraryCall,
CArg<"function_ref<void(OpBuilder &, Location, ValueRange, ValueRange)>",
"nullptr">)>,
OpBuilderDAG<(ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
diff --git a/mlir/include/mlir/Dialect/Linalg/Passes.td b/mlir/include/mlir/Dialect/Linalg/Passes.td
index aabfd44299d5..14f845589a6f 100644
--- a/mlir/include/mlir/Dialect/Linalg/Passes.td
+++ b/mlir/include/mlir/Dialect/Linalg/Passes.td
@@ -64,7 +64,7 @@ def LinalgLowerToLoops : FunctionPass<"convert-linalg-to-loops"> {
def LinalgBufferize : Pass<"linalg-bufferize", "FuncOp"> {
let summary = "Bufferize the linalg dialect";
let constructor = "mlir::createLinalgBufferizePass()";
- let dependentDialects = ["linalg::LinalgDialect"];
+ let dependentDialects = ["linalg::LinalgDialect", "AffineDialect"];
}
def LinalgLowerToParallelLoops
diff --git a/mlir/include/mlir/Dialect/Utils/StructuredOpsUtils.h b/mlir/include/mlir/Dialect/Utils/StructuredOpsUtils.h
index 21c311ed6d18..b257abe0ef30 100644
--- a/mlir/include/mlir/Dialect/Utils/StructuredOpsUtils.h
+++ b/mlir/include/mlir/Dialect/Utils/StructuredOpsUtils.h
@@ -46,10 +46,6 @@ inline bool isColumnMajorMatmul(ArrayAttr indexingMaps) {
return indexingMaps == maps;
}
-/// Attribute name for the IntegerAttr which encodes the index of operand
-/// whose dimensions will be propagated as symbols to the indexing maps
-constexpr StringRef getSymbolSourceAttrName() { return "symbol_source"; }
-
/// Attribute name for the AffineArrayAttr which encodes the relationship
/// between a structured op iterators' and its operands.
constexpr StringRef getIndexingMapsAttrName() { return "indexing_maps"; }
diff --git a/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp b/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp
index 11ac845f0ec7..0ae1efe10b7f 100644
--- a/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp
+++ b/mlir/lib/Dialect/Linalg/EDSC/Builders.cpp
@@ -69,8 +69,7 @@ Operation *mlir::edsc::makeGenericLinalgOp(
builder.getStrArrayAttr(iteratorStrTypes),
StringAttr() /*doc*/,
StringAttr() /*library_call*/,
- ArrayAttr() /*sparse*/,
- IntegerAttr() /*symbol_source*/
+ ArrayAttr() /*sparse*/
/* TODO: other attributes in op */
)
.getOperation();
diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
index 188e00b53940..92668be811f6 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
@@ -60,42 +60,17 @@ SmallVector<Value, 4> mlir::linalg::applyMapToValues(OpBuilder &b, Location loc,
SmallVector<Value, 4> LinalgOp::createFlatListOfOperandDims(OpBuilder &b,
Location loc) {
SmallVector<Value, 4> res;
- SmallVector<unsigned, 4> ranks;
for (Value v : getShapedOperands()) {
ShapedType t = v.getType().template cast<ShapedType>();
- ranks.push_back(t.getRank());
- for (unsigned i = 0; i < t.getRank(); ++i)
+ for (unsigned i = 0, e = t.getRank(); i < e; ++i)
res.push_back(b.create<DimOp>(loc, v, i));
}
-
- // TODO: drop the following once symbol_source is deleted.
- auto attr = getAttrOfType<IntegerAttr>("symbol_source");
- if (!attr)
- return res;
-
- // Find the correct position for inserting values for symbols.
- unsigned numSymb = ranks[attr.getInt()], symbolsPos = 0;
- for (unsigned idx = 0, e = attr.getInt(); idx < e; idx++)
- symbolsPos += ranks[idx];
-
- // Append the end of the value list that corresponds to the
- // values mapping to symbols. Since inside concatenated map symbols
- // are repeated we have to repeat the sizes as well.
-
- // Reserve is mandatory to avoid a potential undefined behavior with
- // pushing back to smallvector from itself.
- res.reserve(res.size() + ranks.size() * numSymb);
- for (unsigned idx = 0, s = ranks.size(); idx < s; ++idx)
- for (unsigned idx2 = 0; idx2 < numSymb; ++idx2)
- res.push_back(res[symbolsPos + idx2]);
return res;
}
SmallVector<Range, 4> LinalgOp::createLoopRanges(OpBuilder &b, Location loc) {
AffineMap map = getLoopsToShapesMap();
unsigned numDims = map.getNumDims(), numRes = map.getNumResults();
- // TODO: drop numSym once symbol_source is deleted.
- unsigned numSym = map.getNumSymbols();
auto viewSizes = createFlatListOfOperandDims(b, loc);
SmallVector<Range, 4> res(numDims);
Value zeroVal = b.create<ConstantIndexOp>(loc, 0);
@@ -107,51 +82,6 @@ SmallVector<Range, 4> LinalgOp::createLoopRanges(OpBuilder &b, Location loc) {
continue;
res[d.getPosition()] = Range{zeroVal, viewSizes[idx], oneVal};
}
-
- // TODO: drop the following once symbol_source is deleted.
- // If the access pattern is of form (m, n)[s] -> (m + n - s floordiv 2),
- // then the bounds are:
- // (s floordiv 2) <= m <= (size(m) + s floordiv 2 - s + 1).
- // where size(n) is applied to the symbol s.
- // This is done statically now.
- if (auto binOp = result.dyn_cast<AffineBinaryOpExpr>()) {
- auto lhs = binOp.getLHS().dyn_cast<AffineBinaryOpExpr>();
- auto rhs = binOp.getRHS().dyn_cast<AffineBinaryOpExpr>();
- if (!lhs || !rhs || binOp.getKind() != AffineExprKind::Add ||
- lhs.getKind() != AffineExprKind::Add ||
- rhs.getKind() != mlir::AffineExprKind::Mul)
- continue;
-
- auto m = lhs.getLHS().dyn_cast<AffineDimExpr>();
- auto n = lhs.getRHS().dyn_cast<AffineDimExpr>();
- auto fDiv = rhs.getLHS().dyn_cast<AffineBinaryOpExpr>();
- auto minusOne = rhs.getRHS().dyn_cast<AffineConstantExpr>();
- if (!m || !n || !fDiv || !minusOne ||
- fDiv.getKind() != AffineExprKind::FloorDiv ||
- !fDiv.getLHS().isa<AffineSymbolExpr>() ||
- !fDiv.getRHS().isa<AffineConstantExpr>())
- continue;
-
- auto s = fDiv.getLHS().dyn_cast<AffineSymbolExpr>();
- if (minusOne.getValue() != -1)
- continue;
-
- int mPos = m.getPosition();
- AffineExpr one = getAffineConstantExpr(1, s.getContext());
- AffineExpr sizeOfM = getAffineSymbolExpr(numSym, s.getContext());
- // Construction of upper bound (size(m) + s floordiv 2 - s + 1).
- AffineExpr upperOffsetExpr = sizeOfM + fDiv + one - s;
- AffineMap fromMap = AffineMap::get(numDims, numSym + 1, fDiv);
- AffineMap toMap = AffineMap::get(numDims, numSym + 1, upperOffsetExpr);
- SmallVector<Value, 8> values(viewSizes.begin(),
- viewSizes.begin() + numDims);
- values.insert(values.end(), viewSizes.begin() + numRes, viewSizes.end());
- values.push_back(viewSizes[mPos]);
- // Construction of the lower bound (s floordiv 2).
- Value from = applyMapToValues(b, loc, fromMap, values).front();
- Value to = applyMapToValues(b, loc, toMap, values).front();
- res[mPos] = Range{from, to, oneVal};
- }
}
return res;
}
@@ -224,14 +154,14 @@ void GenericOp::build(
OpBuilder &builder, OperationState &result, TypeRange resultTensorTypes,
ValueRange inputs, ValueRange outputBuffers, ValueRange initTensors,
ArrayRef<AffineMap> indexingMaps, ArrayRef<StringRef> iteratorTypes,
- StringRef doc, StringRef libraryCall, IntegerAttr symbolSource,
+ StringRef doc, StringRef libraryCall,
function_ref<void(OpBuilder &, Location, ValueRange)> bodyBuild) {
build(builder, result, resultTensorTypes, inputs, outputBuffers, initTensors,
builder.getAffineMapArrayAttr(indexingMaps),
builder.getStrArrayAttr(iteratorTypes),
doc.empty() ? StringAttr() : builder.getStringAttr(doc),
libraryCall.empty() ? StringAttr() : builder.getStringAttr(libraryCall),
- ArrayAttr(), symbolSource);
+ ArrayAttr());
if (!bodyBuild)
return;
@@ -250,10 +180,9 @@ void GenericOp::build(
OpBuilder &builder, OperationState &result, ValueRange inputs,
ValueRange outputBuffers, ArrayRef<AffineMap> indexingMaps,
ArrayRef<StringRef> iteratorTypes, StringRef doc, StringRef libraryCall,
- IntegerAttr symbolSource,
function_ref<void(OpBuilder &, Location, ValueRange)> bodyBuild) {
build(builder, result, TypeRange{}, inputs, outputBuffers, ValueRange{},
- indexingMaps, iteratorTypes, doc, libraryCall, symbolSource, bodyBuild);
+ indexingMaps, iteratorTypes, doc, libraryCall, bodyBuild);
}
void GenericOp::build(
@@ -263,8 +192,7 @@ void GenericOp::build(
function_ref<void(OpBuilder &, Location, ValueRange)> bodyBuild) {
build(builder, result, inputs, outputBuffers, indexingMaps, iteratorTypes,
/*doc=*/"",
- /*libraryCall=*/"",
- /*symbolSource=*/IntegerAttr(), bodyBuild);
+ /*libraryCall=*/"", bodyBuild);
}
void GenericOp::build(
@@ -275,15 +203,13 @@ void GenericOp::build(
build(builder, result, resultTensorTypes, inputs, outputBuffers, initTensors,
indexingMaps, iteratorTypes,
/*doc=*/"",
- /*libraryCall=*/"",
- /*symbolSource=*/IntegerAttr(), bodyBuild);
+ /*libraryCall=*/"", bodyBuild);
}
-
void IndexedGenericOp::build(
OpBuilder &builder, OperationState &result, TypeRange resultTensorTypes,
ValueRange inputs, ValueRange outputBuffers, ValueRange initTensors,
ArrayRef<AffineMap> indexingMaps, ArrayRef<StringRef> iteratorTypes,
- StringRef doc, StringRef libraryCall, IntegerAttr symbolSource,
+ StringRef doc, StringRef libraryCall,
function_ref<void(OpBuilder &, Location, ValueRange, ValueRange)>
bodyBuild) {
build(builder, result, resultTensorTypes, inputs, outputBuffers, initTensors,
@@ -291,7 +217,7 @@ void IndexedGenericOp::build(
builder.getStrArrayAttr(iteratorTypes),
doc.empty() ? StringAttr() : builder.getStringAttr(doc),
libraryCall.empty() ? StringAttr() : builder.getStringAttr(libraryCall),
- ArrayAttr(), symbolSource);
+ ArrayAttr());
if (!bodyBuild)
return;
@@ -313,11 +239,10 @@ void IndexedGenericOp::build(
OpBuilder &builder, OperationState &result, ValueRange inputs,
ValueRange outputBuffers, ArrayRef<AffineMap> indexingMaps,
ArrayRef<StringRef> iteratorTypes, StringRef doc, StringRef libraryCall,
- IntegerAttr symbolSource,
function_ref<void(OpBuilder &, Location, ValueRange, ValueRange)>
bodyBuild) {
build(builder, result, TypeRange{}, inputs, outputBuffers, ValueRange{},
- indexingMaps, iteratorTypes, doc, libraryCall, symbolSource, bodyBuild);
+ indexingMaps, iteratorTypes, doc, libraryCall, bodyBuild);
}
void IndexedGenericOp::build(
@@ -327,9 +252,7 @@ void IndexedGenericOp::build(
function_ref<void(OpBuilder &, Location, ValueRange, ValueRange)>
bodyBuild) {
build(builder, result, inputs, outputBuffers, indexingMaps, iteratorTypes,
- /*doc=*/"",
- /*libraryCall=*/"",
- /*symbolSource=*/IntegerAttr(), bodyBuild);
+ /*doc=*/"", /*libraryCall=*/"", bodyBuild);
}
void IndexedGenericOp::build(
@@ -341,8 +264,7 @@ void IndexedGenericOp::build(
build(builder, result, resultTensorTypes, inputs, outputBuffers, initTensors,
indexingMaps, iteratorTypes,
/*doc=*/"",
- /*libraryCall=*/"",
- /*symbolSource=*/IntegerAttr(), bodyBuild);
+ /*libraryCall=*/"", bodyBuild);
}
template <typename GenericOpType>
@@ -588,16 +510,6 @@ static LogicalResult verifyGenericOp(GenericOpType op) {
if (failed(BlockArgsVerifier<GenericOpType>::verify(op, region.front())))
return failure();
- auto symbolSourceAttr =
- op.template getAttrOfType<IntegerAttr>("symbol_source");
- int64_t expectedNumSymbols = 0;
- if (symbolSourceAttr) {
- unsigned index = symbolSourceAttr.getInt();
- if (index >= op.getNumOperands())
- return op.emitOpError("symbol_source index out of range");
- expectedNumSymbols = op.getShapedType(index).getRank();
- }
-
if (op.indexing_maps().size() != op.getNumInputsAndOutputs())
return op.emitOpError("expected the number of indexing_map (")
<< op.indexing_maps().size()
@@ -612,9 +524,8 @@ static LogicalResult verifyGenericOp(GenericOpType op) {
indexingMaps.push_back(m); // Save reference to map for further checks.
auto view = op.getShapedType(idx);
- if (m.getNumSymbols() != expectedNumSymbols)
- return op.emitOpError("expected the number of symbols in indexing_map #")
- << idx << " to match rank of operand `symbol_source`";
+ if (m.getNumSymbols() != 0)
+ return op.emitOpError("unexpected symbols in indexing_map #") << idx;
if (m.getNumDims() != nLoops)
return op.emitOpError("expected indexing_map #")
@@ -626,14 +537,7 @@ static LogicalResult verifyGenericOp(GenericOpType op) {
<< idx << " results to match view rank: " << view;
}
- // TODO: symbol_source prevents us to just write:
- // if (!op.getShapeToLoopsMap())
- // return op.emitOpError("expected the shape-to-loops map to be non-null");
- //
- // Update when symbol_source is deleted.
- auto concatMap = concatAffineMaps(indexingMaps);
- // TODO: Bound inference for maps with symbols
- if (!concatMap.getNumSymbols() && !inversePermutation(concatMap))
+ if (!op.getShapesToLoopsMap())
return op.emitOpError("expected the shape-to-loops map to be non-null");
if (failed(AnnotationsVerifier<GenericOpType>::verify(op)))
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp b/mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp
index d3d0ff40f124..71d8a5b14705 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp
@@ -120,8 +120,7 @@ static void finalizeBufferAllocation(ConversionPatternRewriter &rewriter,
/*outputBuffers=*/outputs,
/*initTensors=*/llvm::None, genericOp.indexing_maps(),
genericOp.iterator_types(), genericOp.docAttr(),
- genericOp.library_callAttr(), genericOp.sparseAttr(),
- genericOp.symbol_sourceAttr());
+ genericOp.library_callAttr(), genericOp.sparseAttr());
// Create a new block in the region of the new Generic Op.
Block *oldBlock = genericOp.getBody();
@@ -322,7 +321,7 @@ struct LinalgBufferizePass : public LinalgBufferizeBase<LinalgBufferizePass> {
BufferizeTypeConverter typeConverter;
// Mark all Standard operations legal.
- target.addLegalDialect<StandardOpsDialect>();
+ target.addLegalDialect<AffineDialect, StandardOpsDialect>();
target.addIllegalOp<SubTensorOp, SubTensorInsertOp>();
// Mark all Linalg operations illegal as long as they work on tensors.
diff --git a/mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp b/mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp
index 8e1dbf17d3f1..d2a8a307a5ba 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp
@@ -227,8 +227,7 @@ fuseTensorOpsImpl(LinalgOp producer, LinalgOp consumer, unsigned consumerIdx,
consumer.iterator_types(),
/*doc=*/nullptr,
/*library_call=*/nullptr,
- /*sparse=*/nullptr,
- /*symbol_source=*/nullptr)
+ /*sparse=*/nullptr)
.getOperation();
} else {
fusedOp =
@@ -242,8 +241,7 @@ fuseTensorOpsImpl(LinalgOp producer, LinalgOp consumer, unsigned consumerIdx,
consumer.iterator_types(),
/*doc=*/nullptr,
/*library_call=*/nullptr,
- /*sparse=*/nullptr,
- /*symbol_source=*/nullptr)
+ /*sparse=*/nullptr)
.getOperation();
}
@@ -820,8 +818,7 @@ struct FoldConsumerReshapeOpByLinearization
producer.iterator_types(),
/*doc=*/nullptr,
/*library_call=*/nullptr,
- /*sparse=*/nullptr,
- /*symbol_source=*/nullptr);
+ /*sparse=*/nullptr);
auto &fusedRegion = fusedOp.getOperation()->getRegion(0);
rewriter.cloneRegionBefore(producer.getOperation()->getRegion(0),
fusedRegion, fusedRegion.begin());
@@ -904,8 +901,7 @@ struct FoldSplatConstants : public OpRewritePattern<LinalgOpTy> {
linalgOp.iterator_types(),
/*doc=*/nullptr,
/*library_call=*/nullptr,
- /*sparse=*/nullptr,
- /*symbol_source=*/nullptr);
+ /*sparse=*/nullptr);
// Map the block argument corresponding to the replaced argument with the
// scalar constant.
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Loops.cpp b/mlir/lib/Dialect/Linalg/Transforms/Loops.cpp
index c9132e93d13e..3435820aab40 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Loops.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Loops.cpp
@@ -147,15 +147,7 @@ static void emitScalarImplementation(ArrayRef<Value> allIvs,
SmallVector<Value, 4> indexedValues;
indexedValues.reserve(nInputs + nOutputs);
- auto attr = linalgOp.template getAttrOfType<IntegerAttr>("symbol_source");
auto allIvsPlusDims = SmallVector<Value, 4>(allIvs.begin(), allIvs.end());
- if (attr) {
- auto operand = linalgOp.getOperation()->getOperand(attr.getInt());
- auto shapedType = operand.getType().template cast<ShapedType>();
- allIvsPlusDims.reserve(allIvs.size() + shapedType.getRank());
- for (unsigned idx = 0, e = shapedType.getRank(); idx < e; ++idx)
- allIvsPlusDims.push_back(b.create<DimOp>(loc, operand, idx));
- }
// TODO: Avoid the loads if the corresponding argument of the
// region has no uses.
diff --git a/mlir/test/Dialect/Linalg/invalid.mlir b/mlir/test/Dialect/Linalg/invalid.mlir
index 76cd3470a12a..8e98a80e77b1 100644
--- a/mlir/test/Dialect/Linalg/invalid.mlir
+++ b/mlir/test/Dialect/Linalg/invalid.mlir
@@ -63,33 +63,6 @@ func @generic_mismatched_num_returns(%arg0: memref<f32>) {
// -----
-func @generic_symbol_in_map(%arg0: memref<i32>) {
- // expected-error @+1 {{expected the number of symbols in indexing_map #0 to match rank of operand `symbol_source`}}
- linalg.generic {
- indexing_maps = [ affine_map<()[N] -> (0)> ],
- iterator_types = ["parallel"]}
- outs(%arg0 : memref<i32>) {
- ^bb(%i : i32):
- linalg.yield %i : i32
- }
-}
-
-// -----
-
-func @generic_symbol_source_out_of_range(%arg0: memref<i32>) {
- // expected-error @+1 {{symbol_source index out of range}}
- linalg.generic {
- indexing_maps = [ affine_map<()[N] -> (0)> ],
- iterator_types = ["parallel"],
- symbol_source = 1}
- outs(%arg0 : memref<i32>) {
- ^bb(%i : i32):
- linalg.yield %i : i32
- }
-}
-
-// -----
-
func @generic_wrong_dim_in_map(%arg0: memref<1xi32>) {
// expected-error @+1 {{op expected indexing_map #0 to have 1 dim(s) to match the number of loops}}
linalg.generic {
diff --git a/mlir/test/Dialect/Linalg/loops.mlir b/mlir/test/Dialect/Linalg/loops.mlir
index bb2eeeb2e88f..5a9d7330f289 100644
--- a/mlir/test/Dialect/Linalg/loops.mlir
+++ b/mlir/test/Dialect/Linalg/loops.mlir
@@ -14,9 +14,6 @@
// CHECKLOOP-DAG: #[[$stride2Dilation1:.*]] = affine_map<(d0, d1) -> (d0 * 2 + d1)>
// CHECKLOOP-DAG: #[[$stride2Dilation4:.*]] = affine_map<(d0, d1) -> (d0 * 2 + d1 * 4)>
// CHECKLOOP-DAG: #[[$stride3Dilation5:.*]] = affine_map<(d0, d1) -> (d0 * 3 + d1 * 5)>
-// CHECKLOOP-DAG: #[[$convLowerBound:.*]] = affine_map<()[s0] -> (s0 floordiv 2)>
-// CHECKLOOP-DAG: #[[$convUpperBound:.*]] = affine_map<()[s0, s1] -> (s1 + s0 floordiv 2 - s0 + 1)>
-// CHECKLOOP-DAG: #[[$convMap:.*]] = affine_map<(d0, d1)[s0] -> (d0 + d1 - s0 floordiv 2)>
// CHECKLOOP-DAG: #[[$stride1Dilation1Padding1:.*]] = affine_map<(d0, d1) -> (d0 + d1 - 1)>
// CHECKLOOP-DAG: #[[$stride1Dilation1Padding2:.*]] = affine_map<(d0, d1) -> (d0 + d1 - 2)>
@@ -30,9 +27,6 @@
// CHECKPARALLEL-DAG: #[[$stride2Dilation1:.*]] = affine_map<(d0, d1) -> (d0 * 2 + d1)>
// CHECKPARALLEL-DAG: #[[$stride2Dilation4:.*]] = affine_map<(d0, d1) -> (d0 * 2 + d1 * 4)>
// CHECKPARALLEL-DAG: #[[$stride3Dilation5:.*]] = affine_map<(d0, d1) -> (d0 * 3 + d1 * 5)>
-// CHECKPARALLEL-DAG: #[[$convLowerBound:.*]] = affine_map<()[s0] -> (s0 floordiv 2)>
-// CHECKPARALLEL-DAG: #[[$convUpperBound:.*]] = affine_map<()[s0, s1] -> (s1 + s0 floordiv 2 - s0 + 1)>
-// CHECKPARALLEL-DAG: #[[$convMap:.*]] = affine_map<(d0, d1)[s0] -> (d0 + d1 - s0 floordiv 2)>
// CHECKPARALLEL-DAG: #[[$stride1Dilation1Padding1:.*]] = affine_map<(d0, d1) -> (d0 + d1 - 1)>
// CHECKPARALLEL-DAG: #[[$stride1Dilation1Padding2:.*]] = affine_map<(d0, d1) -> (d0 + d1 - 2)>
@@ -1225,373 +1219,6 @@ func @named_batch_matmul(%A: memref<?x?x?xf32>, %B: memref<?x?x?xf32>, %C: memre
// CHECKPARALLEL: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
// CHECKPARALLEL: store %[[res]], %[[mC]][%[[b]], %[[m]], %[[n]]] : memref<?x?x?xf32>
-#conv_1d_accesses = [
- affine_map<(m, n)[s0] -> (m + n - s0 floordiv 2)>, // in
- affine_map<(m, n)[s0] -> (n)>, // filter
- affine_map<(m, n)[s0] -> (m)> // out
-]
-
-#conv_1d_trait = {
- args_in = 2,
- args_out = 1,
- doc = "C(m) += A(m) * B(n)",
- indexing_maps = #conv_1d_accesses,
- library_call = "linalg_conv_1d",
- n_views = [2, 1],
- iterator_types = ["parallel", "parallel"],
- symbol_source = 1
-}
-
-func @conv1d(%in : memref<?xf32>, %filter : memref<?xf32>, %out : memref<?xf32>) -> () {
- linalg.generic #conv_1d_trait
- ins(%in, %filter : memref<?xf32>, memref<?xf32>)
- outs(%out : memref<?xf32>) {
- ^bb0(%a: f32, %b: f32, %c: f32) :
- %d = mulf %a, %b : f32
- %e = addf %c, %d : f32
- linalg.yield %e : f32
- }
- return
-}
-
-// CHECKLOOP-LABEL: @conv1d
-// CHECKLOOP-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?xf32>
-// CHECKLOOP-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?xf32>
-// CHECKLOOP-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?xf32>
-// CHECKLOOP: %[[c0:.*]] = constant 0 : index
-// CHECKLOOP: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?xf32>
-// CHECKLOOP: %[[dim1:.*]] = dim %[[arg1]], %[[c0]] : memref<?xf32>
-// CHECKLOOP: %[[lowerBound:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim1]]]
-// CHECKLOOP: %[[upperBound:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim1]], %[[dim0]]]
-// CHECKLOOP: scf.for %[[b:.*]] = %[[lowerBound]] to %[[upperBound]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[m:.*]] = %{{.*}} to %[[dim1]] step %{{.*}} {
-// CHECKLOOP: %[[dim2:.*]] = dim %[[arg1]], %[[c0]] : memref<?xf32>
-// CHECKLOOP: %[[aff:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim2]]]
-// CHECKLOOP: %[[va:.*]] = load %[[arg0]][%[[aff]]] : memref<?xf32>
-// CHECKLOOP: %[[vb:.*]] = load %[[arg1]][%[[m]]] : memref<?xf32>
-// CHECKLOOP: %[[vc:.*]] = load %[[arg2]][%[[b]]] : memref<?xf32>
-// CHECKLOOP: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKLOOP: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKLOOP: store %[[res]], %[[arg2]][%[[b]]] : memref<?xf32>
-
-// CHECKPARALLEL-LABEL: @conv1d
-// CHECKPARALLEL-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?xf32>
-// CHECKPARALLEL-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?xf32>
-// CHECKPARALLEL-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?xf32>
-// CHECKPARALLEL: %[[c0:.*]] = constant 0 : index
-// CHECKPARALLEL: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?xf32>
-// CHECKPARALLEL: %[[dim1:.*]] = dim %[[arg1]], %[[c0]] : memref<?xf32>
-// CHECKPARALLEL: %[[lowerBound:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim1]]]
-// CHECKPARALLEL: %[[upperBound:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim1]], %[[dim0]]]
-// CHECKPARALLEL: scf.parallel (%[[b:.*]], %[[m:.*]]) = (%[[lowerBound]], %{{.*}}) to (%[[upperBound]], %[[dim1]]) step ({{.*}}) {
-// CHECKPARALLEL: %[[dim2:.*]] = dim %[[arg1]], %[[c0]] : memref<?xf32>
-// CHECKPARALLEL: %[[aff:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim2]]]
-// CHECKPARALLEL: %[[va:.*]] = load %[[arg0]][%[[aff]]] : memref<?xf32>
-// CHECKPARALLEL: %[[vb:.*]] = load %[[arg1]][%[[m]]] : memref<?xf32>
-// CHECKPARALLEL: %[[vc:.*]] = load %[[arg2]][%[[b]]] : memref<?xf32>
-// CHECKPARALLEL: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKPARALLEL: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKPARALLEL: store %[[res]], %[[arg2]][%[[b]]] : memref<?xf32>
-
-#conv_2d_accesses = [
- affine_map<(m, n, m1, n1)[s0, s1] -> (m + m1 - s0 floordiv 2, n + n1 - s1 floordiv 2)>, // in
- affine_map<(m, n, m1, n1)[s0, s1] -> (m1, n1)>, // filter
- affine_map<(m, n, m1, n1)[s0, s1] -> (m, n)> // out
-]
-
-#conv_2d_trait = {
- args_in = 2,
- args_out = 1,
- doc = "C(m,n) += A(m,n) * B(m1,n1)",
- indexing_maps = #conv_2d_accesses,
- library_call = "linalg_conv_2d",
- n_views = [2, 1],
- iterator_types = ["parallel", "parallel", "parallel", "parallel"],
- symbol_source = 1
-}
-
-func @conv2d(%in : memref<?x?xf32>, %filter : memref<?x?xf32>, %out : memref<?x?xf32>) -> () {
- linalg.generic #conv_2d_trait
- ins(%in, %filter : memref<?x?xf32>, memref<?x?xf32>)
- outs(%out : memref<?x?xf32>) {
- ^bb0(%a: f32, %b: f32, %c: f32) :
- %d = mulf %a, %b : f32
- %e = addf %c, %d : f32
- linalg.yield %e : f32
- }
- return
-}
-
-// CHECKLOOP-LABEL: @conv2d
-// CHECKLOOP-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?x?xf32>
-// CHECKLOOP-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?x?xf32>
-// CHECKLOOP-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?x?xf32>
-// CHECKLOOP: %[[c0:.*]] = constant 0 : index
-// CHECKLOOP: %[[c1:.*]] = constant 1 : index
-// CHECKLOOP: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?x?xf32>
-// CHECKLOOP: %[[dim1:.*]] = dim %[[arg0]], %[[c1]] : memref<?x?xf32>
-// CHECKLOOP: %[[dim2:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?xf32>
-// CHECKLOOP: %[[dim3:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?xf32>
-// CHECKLOOP: %[[lowerBound1:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim2]]]
-// CHECKLOOP: %[[upperBound1:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim2]], %[[dim0]]]
-// CHECKLOOP: %[[lowerBound2:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim3]]]
-// CHECKLOOP: %[[upperBound2:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim3]], %[[dim1]]]
-// CHECKLOOP: scf.for %[[i0:.*]] = %[[lowerBound1]] to %[[upperBound1]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i1:.*]] = %[[lowerBound2]] to %[[upperBound2]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i2:.*]] = %{{.*}} to %[[dim2]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i3:.*]] = %{{.*}} to %[[dim3]] step %{{.*}} {
-// CHECKLOOP: %[[dim4:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?xf32>
-// CHECKLOOP: %[[dim5:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?xf32>
-// CHECKLOOP: %[[aff1:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim4]]]
-// CHECKLOOP: %[[aff2:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim5]]]
-// CHECKLOOP: %[[va:.*]] = load %[[arg0]][%[[aff1]], %[[aff2]]] : memref<?x?xf32>
-// CHECKLOOP: %[[vb:.*]] = load %[[arg1]][%[[i2]], %[[i3]]] : memref<?x?xf32>
-// CHECKLOOP: %[[vc:.*]] = load %[[arg2]][%[[i0]], %[[i1]]] : memref<?x?xf32>
-// CHECKLOOP: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKLOOP: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKLOOP: store %[[res]], %[[arg2]][%[[i0]], %[[i1]]] : memref<?x?xf32>
-
-// CHECKPARALLEL-LABEL: @conv2d
-// CHECKPARALLEL-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?x?xf32>
-// CHECKPARALLEL-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?x?xf32>
-// CHECKPARALLEL-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?x?xf32>
-// CHECKPARALLEL: %[[c0:.*]] = constant 0 : index
-// CHECKPARALLEL: %[[c1:.*]] = constant 1 : index
-// CHECKPARALLEL: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[dim1:.*]] = dim %[[arg0]], %[[c1]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[dim2:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[dim3:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[lowerBound1:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim2]]]
-// CHECKPARALLEL: %[[upperBound1:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim2]], %[[dim0]]]
-// CHECKPARALLEL: %[[lowerBound2:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim3]]]
-// CHECKPARALLEL: %[[upperBound2:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim3]], %[[dim1]]]
-// CHECKPARALLEL: scf.parallel (%[[i0:.*]], %[[i1:.*]], %[[i2:.*]], %[[i3:.*]]) = (%[[lowerBound1]], %[[lowerBound2]], %{{.*}}, %{{.*}}) to (%[[upperBound1]], %[[upperBound2]], %[[dim2]], %[[dim3]]) step ({{.*}}) {
-// CHECKPARALLEL: %[[dim4:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[dim5:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[aff1:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim4]]]
-// CHECKPARALLEL: %[[aff2:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim5]]]
-// CHECKPARALLEL: %[[va:.*]] = load %[[arg0]][%[[aff1]], %[[aff2]]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[vb:.*]] = load %[[arg1]][%[[i2]], %[[i3]]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[vc:.*]] = load %[[arg2]][%[[i0]], %[[i1]]] : memref<?x?xf32>
-// CHECKPARALLEL: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKPARALLEL: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKPARALLEL: store %[[res]], %[[arg2]][%[[i0]], %[[i1]]] : memref<?x?xf32>
-
-#conv_3d_accesses = [
- affine_map<(m, n, k, m1, n1, k1)[s0, s1, s2] -> (m + m1 - s0 floordiv 2, n + n1 - s1 floordiv 2, k + k1 - s2 floordiv 2)>, // in
- affine_map<(m, n, k, m1, n1, k1)[s0, s1, s2] -> (m1, n1, k1)>, // filter
- affine_map<(m, n, k, m1, n1, k1)[s0, s1, s2] -> (m, n, k)> // out
-]
-
-#conv_3d_trait = {
- args_in = 2,
- args_out = 1,
- doc = "C(m,n,k) += A(m,n,k) * B(m1,n1,k1)",
- indexing_maps = #conv_3d_accesses,
- library_call = "linalg_conv_3d",
- n_views = [2, 1],
- iterator_types = ["parallel", "parallel", "parallel", "parallel", "parallel", "parallel"],
- symbol_source = 1
-}
-
-func @conv3d(%in : memref<?x?x?xf32>, %filter : memref<?x?x?xf32>, %out : memref<?x?x?xf32>) -> () {
- linalg.generic #conv_3d_trait
- ins(%in, %filter : memref<?x?x?xf32>, memref<?x?x?xf32>)
- outs(%out : memref<?x?x?xf32>) {
- ^bb0(%a: f32, %b: f32, %c: f32) :
- %d = mulf %a, %b : f32
- %e = addf %c, %d : f32
- linalg.yield %e : f32
- }
- return
-}
-
-// CHECKLOOP-LABEL: @conv3d
-// CHECKLOOP-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?x?x?xf32>
-// CHECKLOOP-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?x?x?xf32>
-// CHECKLOOP-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?x?x?xf32>
-// CHECKLOOP: %[[c0:.*]] = constant 0 : index
-// CHECKLOOP: %[[c1:.*]] = constant 1 : index
-// CHECKLOOP: %[[c2:.*]] = constant 2 : index
-// CHECKLOOP: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[dim1:.*]] = dim %[[arg0]], %[[c1]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[dim2:.*]] = dim %[[arg0]], %[[c2]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[dim3:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[dim4:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[dim5:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[lowerBound1:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim3]]]
-// CHECKLOOP: %[[upperBound1:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim3]], %[[dim0]]]
-// CHECKLOOP: %[[lowerBound2:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim4]]]
-// CHECKLOOP: %[[upperBound2:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim4]], %[[dim1]]]
-// CHECKLOOP: %[[lowerBound3:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim5]]]
-// CHECKLOOP: %[[upperBound3:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim5]], %[[dim2]]]
-// CHECKLOOP: scf.for %[[i0:.*]] = %[[lowerBound1]] to %[[upperBound1]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i1:.*]] = %[[lowerBound2]] to %[[upperBound2]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i2:.*]] = %[[lowerBound3]] to %[[upperBound3]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i3:.*]] = %{{.*}} to %[[dim3]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i4:.*]] = %{{.*}} to %[[dim4]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i5:.*]] = %{{.*}} to %[[dim5]] step %{{.*}} {
-// CHECKLOOP: %[[dim6:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[dim7:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[dim8:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[aff1:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim6]]]
-// CHECKLOOP: %[[aff2:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim7]]]
-// CHECKLOOP: %[[aff3:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim8]]]
-// CHECKLOOP: %[[va:.*]] = load %[[arg0]][%[[aff1]], %[[aff2]], %[[aff3]]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[vb:.*]] = load %[[arg1]][%[[i3]], %[[i4]], %[[i5]]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[vc:.*]] = load %[[arg2]][%[[i0]], %[[i1]], %[[i2]]] : memref<?x?x?xf32>
-// CHECKLOOP: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKLOOP: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKLOOP: store %[[res]], %[[arg2]][%[[i0]], %[[i1]], %[[i2]]] : memref<?x?x?xf32>
-
-// CHECKPARALLEL-LABEL: @conv3d
-// CHECKPARALLEL-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?x?x?xf32>
-// CHECKPARALLEL-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?x?x?xf32>
-// CHECKPARALLEL-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?x?x?xf32>
-// CHECKPARALLEL: %[[c0:.*]] = constant 0 : index
-// CHECKPARALLEL: %[[c1:.*]] = constant 1 : index
-// CHECKPARALLEL: %[[c2:.*]] = constant 2 : index
-// CHECKPARALLEL: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[dim1:.*]] = dim %[[arg0]], %[[c1]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[dim2:.*]] = dim %[[arg0]], %[[c2]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[dim3:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[dim4:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[dim5:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[lowerBound1:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim3]]]
-// CHECKPARALLEL: %[[upperBound1:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim3]], %[[dim0]]]
-// CHECKPARALLEL: %[[lowerBound2:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim4]]]
-// CHECKPARALLEL: %[[upperBound2:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim4]], %[[dim1]]]
-// CHECKPARALLEL: %[[lowerBound3:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim5]]]
-// CHECKPARALLEL: %[[upperBound3:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim5]], %[[dim2]]]
-// CHECKPARALLEL: scf.parallel (%[[i0:.*]], %[[i1:.*]], %[[i2:.*]], %[[i3:.*]], %[[i4:.*]], %[[i5:.*]]) = (%[[lowerBound1]], %[[lowerBound2]], %[[lowerBound3]], %{{.*}}, %{{.*}}, %{{.*}}) to (%[[upperBound1]], %[[upperBound2]], %[[upperBound3]], %[[dim3]], %[[dim4]], %[[dim5]]) step ({{.*}}) {
-// CHECKPARALLEL: %[[dim6:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[dim7:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[dim8:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[aff1:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim6]]]
-// CHECKPARALLEL: %[[aff2:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim7]]]
-// CHECKPARALLEL: %[[aff3:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim8]]]
-// CHECKPARALLEL: %[[va:.*]] = load %[[arg0]][%[[aff1]], %[[aff2]], %[[aff3]]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[vb:.*]] = load %[[arg1]][%[[i3]], %[[i4]], %[[i5]]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[vc:.*]] = load %[[arg2]][%[[i0]], %[[i1]], %[[i2]]] : memref<?x?x?xf32>
-// CHECKPARALLEL: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKPARALLEL: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKPARALLEL: store %[[res]], %[[arg2]][%[[i0]], %[[i1]], %[[i2]]] : memref<?x?x?xf32>
-
-#conv_4d_accesses = [
- affine_map<(m, n, k, l, m1, n1, k1, l1)[s0, s1, s2, s3] -> (m + m1 - s0 floordiv 2, n + n1 - s1 floordiv 2, k + k1 - s2 floordiv 2, l + l1 - s3 floordiv 2)>, // in
- affine_map<(m, n, k, l, m1, n1, k1, l1)[s0, s1, s2, s3] -> (m1, n1, k1, l1)>, // filter
- affine_map<(m, n, k, l, m1, n1, k1, l1)[s0, s1, s2, s3] -> (m, n, k, l)> // out
-]
-
-#conv_4d_trait = {
- args_in = 2,
- args_out = 1,
- doc = "C(m,n,k,l) += A(m,n,k,l) * B(m1,n1,k1,l1)",
- indexing_maps = #conv_4d_accesses,
- library_call = "linalg_conv_4d",
- n_views = [2, 1],
- iterator_types = ["parallel", "parallel", "parallel", "parallel", "parallel", "parallel", "parallel", "parallel"],
- symbol_source = 1
-}
-
-func @conv4d(%in : memref<?x?x?x?xf32>, %filter : memref<?x?x?x?xf32>, %out : memref<?x?x?x?xf32>) -> () {
- linalg.generic #conv_4d_trait
- ins(%in, %filter : memref<?x?x?x?xf32>, memref<?x?x?x?xf32>)
- outs(%out : memref<?x?x?x?xf32>) {
- ^bb0(%a: f32, %b: f32, %c: f32) :
- %d = mulf %a, %b : f32
- %e = addf %c, %d : f32
- linalg.yield %e : f32
- }
- return
-}
-
-// CHECKLOOP-LABEL: @conv4d
-// CHECKLOOP-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
-// CHECKLOOP-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
-// CHECKLOOP-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
-// CHECKLOOP: %[[c0:.*]] = constant 0 : index
-// CHECKLOOP: %[[c1:.*]] = constant 1 : index
-// CHECKLOOP: %[[c2:.*]] = constant 2 : index
-// CHECKLOOP: %[[c3:.*]] = constant 3 : index
-// CHECKLOOP: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim1:.*]] = dim %[[arg0]], %[[c1]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim2:.*]] = dim %[[arg0]], %[[c2]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim3:.*]] = dim %[[arg0]], %[[c3]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim4:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim5:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim6:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim7:.*]] = dim %[[arg1]], %[[c3]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[lowerBound1:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim4]]]
-// CHECKLOOP: %[[upperBound1:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim4]], %[[dim0]]]
-// CHECKLOOP: %[[lowerBound2:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim5]]]
-// CHECKLOOP: %[[upperBound2:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim5]], %[[dim1]]]
-// CHECKLOOP: %[[lowerBound3:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim6]]]
-// CHECKLOOP: %[[upperBound3:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim6]], %[[dim2]]]
-// CHECKLOOP: %[[lowerBound4:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim7]]]
-// CHECKLOOP: %[[upperBound4:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim7]], %[[dim3]]]
-// CHECKLOOP: scf.for %[[i0:.*]] = %[[lowerBound1]] to %[[upperBound1]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i1:.*]] = %[[lowerBound2]] to %[[upperBound2]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i2:.*]] = %[[lowerBound3]] to %[[upperBound3]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i3:.*]] = %[[lowerBound4]] to %[[upperBound4]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i4:.*]] = %{{.*}} to %[[dim4]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i5:.*]] = %{{.*}} to %[[dim5]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i6:.*]] = %{{.*}} to %[[dim6]] step %{{.*}} {
-// CHECKLOOP: scf.for %[[i7:.*]] = %{{.*}} to %[[dim7]] step %{{.*}} {
-// CHECKLOOP: %[[dim8:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim9:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim10:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[dim11:.*]] = dim %[[arg1]], %[[c3]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[aff1:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim8]]]
-// CHECKLOOP: %[[aff2:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim9]]]
-// CHECKLOOP: %[[aff3:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim10]]]
-// CHECKLOOP: %[[aff4:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim11]]]
-// CHECKLOOP: %[[va:.*]] = load %[[arg0]][%[[aff1]], %[[aff2]], %[[aff3]], %[[aff4]]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[vb:.*]] = load %[[arg1]][%[[i4]], %[[i5]], %[[i6]], %[[i7]]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[vc:.*]] = load %[[arg2]][%[[i0]], %[[i1]], %[[i2]], %[[i3]]] : memref<?x?x?x?xf32>
-// CHECKLOOP: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKLOOP: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKLOOP: store %[[res]], %[[arg2]][%[[i0]], %[[i1]], %[[i2]], %[[i3]]] : memref<?x?x?x?xf32>
-
-// CHECKPARALLEL-LABEL: @conv4d
-// CHECKPARALLEL-SAME: %[[arg0:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
-// CHECKPARALLEL-SAME: %[[arg1:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
-// CHECKPARALLEL-SAME: %[[arg2:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[c0:.*]] = constant 0 : index
-// CHECKPARALLEL: %[[c1:.*]] = constant 1 : index
-// CHECKPARALLEL: %[[c2:.*]] = constant 2 : index
-// CHECKPARALLEL: %[[c3:.*]] = constant 3 : index
-// CHECKPARALLEL: %[[dim0:.*]] = dim %[[arg0]], %[[c0]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim1:.*]] = dim %[[arg0]], %[[c1]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim2:.*]] = dim %[[arg0]], %[[c2]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim3:.*]] = dim %[[arg0]], %[[c3]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim4:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim5:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim6:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim7:.*]] = dim %[[arg1]], %[[c3]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[lowerBound1:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim4]]]
-// CHECKPARALLEL: %[[upperBound1:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim4]], %[[dim0]]]
-// CHECKPARALLEL: %[[lowerBound2:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim5]]]
-// CHECKPARALLEL: %[[upperBound2:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim5]], %[[dim1]]]
-// CHECKPARALLEL: %[[lowerBound3:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim6]]]
-// CHECKPARALLEL: %[[upperBound3:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim6]], %[[dim2]]]
-// CHECKPARALLEL: %[[lowerBound4:.*]] = affine.apply #[[$convLowerBound]]()[%[[dim7]]]
-// CHECKPARALLEL: %[[upperBound4:.*]] = affine.apply #[[$convUpperBound]]()[%[[dim7]], %[[dim3]]]
-// CHECKPARALLEL: scf.parallel (%[[i0:.*]], %[[i1:.*]], %[[i2:.*]], %[[i3:.*]], %[[i4:.*]], %[[i5:.*]], %[[i6:.*]], %[[i7:.*]]) = (%[[lowerBound1]], %[[lowerBound2]], %[[lowerBound3]], %[[lowerBound4]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) to (%[[upperBound1]], %[[upperBound2]], %[[upperBound3]], %[[upperBound4]], %[[dim4]], %[[dim5]], %[[dim6]], %[[dim7]]) step ({{.*}}) {
-// CHECKPARALLEL: %[[dim8:.*]] = dim %[[arg1]], %[[c0]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim9:.*]] = dim %[[arg1]], %[[c1]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim10:.*]] = dim %[[arg1]], %[[c2]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[dim11:.*]] = dim %[[arg1]], %[[c3]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[aff1:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim8]]]
-// CHECKPARALLEL: %[[aff2:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim9]]]
-// CHECKPARALLEL: %[[aff3:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim10]]]
-// CHECKPARALLEL: %[[aff4:.*]] = affine.apply #[[$convMap]](%{{.*}}, %{{.*}})[%[[dim11]]]
-// CHECKPARALLEL: %[[va:.*]] = load %[[arg0]][%[[aff1]], %[[aff2]], %[[aff3]], %[[aff4]]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[vb:.*]] = load %[[arg1]][%[[i4]], %[[i5]], %[[i6]], %[[i7]]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[vc:.*]] = load %[[arg2]][%[[i0]], %[[i1]], %[[i2]], %[[i3]]] : memref<?x?x?x?xf32>
-// CHECKPARALLEL: %[[inc:.*]] = mulf %[[va]], %[[vb]] : f32
-// CHECKPARALLEL: %[[res:.*]] = addf %[[vc]], %[[inc]] : f32
-// CHECKPARALLEL: store %[[res]], %[[arg2]][%[[i0]], %[[i1]], %[[i2]], %[[i3]]] : memref<?x?x?x?xf32>
func @conv1d_no_symbols(%in : memref<?xf32>, %filter : memref<?xf32>, %out : memref<?xf32>) -> () {
linalg.conv_1d ins(%in, %filter : memref<?xf32>, memref<?xf32>)
More information about the llvm-branch-commits
mailing list