Skip to content

Commit

Permalink
[mlir][Linalg] Drop symbol_source abstraction which does not pay for …
Browse files Browse the repository at this point in the history
…itself.

Differential Revision: https://reviews.llvm.org/D91956
  • Loading branch information
nicolasvasilache committed Nov 23, 2020
1 parent 61e538b commit 9ac0b31
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 619 deletions.
89 changes: 6 additions & 83 deletions mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
Expand Up @@ -503,28 +503,21 @@ 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 = [{
SmallVector<StringRef, 8> linalgTraitAttrNames() {
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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/Linalg/Passes.td
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions mlir/include/mlir/Dialect/Utils/StructuredOpsUtils.h
Expand Up @@ -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"; }
Expand Down
3 changes: 1 addition & 2 deletions mlir/lib/Dialect/Linalg/EDSC/Builders.cpp
Expand Up @@ -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();
Expand Down

0 comments on commit 9ac0b31

Please sign in to comment.