MLIR  20.0.0git
LinalgInterfaces.h
Go to the documentation of this file.
1 //===- LinalgInterface.h - Linalg operations interfaces -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the operation interfaces for Linalg operations.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_DIALECT_LINALG_IR_LINALGINTERFACES_H_
14 #define MLIR_DIALECT_LINALG_IR_LINALGINTERFACES_H_
15 
17 #include "mlir/IR/AffineMap.h"
18 #include "mlir/IR/BuiltinTypes.h"
19 #include "mlir/IR/IRMapping.h"
21 #include "mlir/IR/OpDefinition.h"
26 
27 namespace mlir {
28 namespace linalg {
29 class IteratorTypeAttr;
30 class LinalgOp;
31 class GenericOp;
32 
33 namespace detail {
34 /// Implementation of the method that check if given operands
35 /// can be dropped, i.e. the remaining operands can compute the loop
36 /// bounds of the op.
37 bool canOpOperandsBeDroppedImpl(linalg::LinalgOp linalgOp,
38  ArrayRef<OpOperand *> droppedOperands);
39 } // namespace detail
40 
41 /// Positions of a Linalg op loops that correspond to different kinds of a
42 /// contraction dimension.
48 };
49 
50 /// Find at least 2 parallel (m and n) and 1 reduction (k) dimension candidates
51 /// that form a matmul subcomputation within `linalgOp`.
52 /// These dimensions are such that:
53 /// 1. The m dimension is involved in an outer-product along LHS
54 /// (i.e. it is a permutation on RES and LHS and does not appear in RHS).
55 /// 2. The n dimension is involved in an outer-product along RHS
56 /// (i.e. it is a permutation on RES and RHS and does not appear in LHS).
57 /// 3. The k dimension appears as a permutation on LHS and RHS.
58 /// 4. m, n and k appear only once in any given indexing.
59 /// 5. Optional batch dimensions that appear in all operands are captured.
60 /// This allows e.g. detecting that some contraction is embedded within
61 /// `linalgOp` with some orthogonal heuristic.
62 /// When multiple dimension occurrences exist that match `batch`, `m`, `n`, or
63 /// `k`, indices are returned in sorted order.
64 /// Returns a failure if any of `m`, `n` or `k` is empty.
65 FailureOr<ContractionDimensions> inferContractionDims(LinalgOp linalgOp);
66 FailureOr<ContractionDimensions>
68 
69 /// Checks whether `linalgOp` conforms to ContractionOpInterface.
70 // TODO: embed within `isa<ContractionOpInterface>` if possible / natural.
71 bool isaContractionOpInterface(LinalgOp linalgOp);
72 
73 /// Positions of a Linalg op loops that correspond to different kinds of a
74 /// convolution dimension.
84 };
85 
86 /// Find at least 1 parallel (output_image) and reduction (filter_loop)
87 /// dimension candidates that form a convolution subcomputation within
88 /// `linalgOp`. The LHS is assumed to be the convolution input while the
89 /// RHS is assumed as the filter.
90 /// These dimensions are such that:
91 /// 1. Optional batch dimensions that appear in the input and filter.
92 /// 2. The output_image dimension is involved in a cross-correlation along LHS
93 /// (i.e. it is a permutation on RES and LHS and has an associated
94 /// filter_loop in RHS).
95 /// 3. Optional output_channel dimension is involved in an outer-product along
96 /// RHS (i.e. it is a permutation on RES and RHS and does not appear in
97 /// LHS).
98 /// 4. Optional input_channel dimension appears as a permutation on LHS and
99 /// RHS.
100 /// 5. The filter_loop dimension appears as a permutation on the RHS and
101 /// represents the shape of the kernel cross-correlated along a
102 /// corresponding output_image dim.
103 /// 6. The input_channel dimension appears as a permutation on LHS and RHS.
104 /// 7. All dimensions appear only once in any given indexing map.
105 /// This allows e.g. detecting that some convolution is embedded within
106 /// `linalgOp` with some orthogonal heuristic.
107 /// When multiple dimension occurrences exist that match any classification
108 /// indices are returned in sorted order.
109 /// Returns a failure if `output_image` (and implicitly `filter_loop`) is empty.
110 FailureOr<ConvolutionDimensions> inferConvolutionDims(LinalgOp linalgOp);
111 
112 /// Checks whether `linalgOp` conforms to ConvolutionOpInterface.
113 // TODO: embed within `isa<ConvolutionOpInterface>` if possible / natural.
114 bool isaConvolutionOpInterface(LinalgOp linalgOp);
115 
116 /// Checks whether `linalgOp` is semantically equivalent to a `linalg.copyOp`.
117 bool isaCopyOpInterface(LinalgOp linalgOp);
118 
119 /// Checks whether a given `genericOp` is semantically equivalent to a single
120 /// linalgelementwise unary op. e.g. linalg.exp.
121 /// A linalg.generic body could be a series of unary elementwise ops e.g.
122 /// `exp(neg(x))`, such as formed by linalg op fusion. Here we restrict it to
123 /// detecting cases where body is is a single computation op.
124 bool isaElemwiseSingleUnaryOpInterface(GenericOp genericOp);
125 
126 /// Checks whether `genericOp` is semantically equivalent to a single linalg
127 /// elementwise binary op e.g. linalg.sub.
128 bool isaElemwiseSingleBinaryOpInterface(GenericOp genericOp);
129 
130 /// Checks whether `genericOp` is semantically equivalent to a `linalg.fill`.
131 /// Returns the scalar fill value if true.
132 std::optional<Value> isaFillOpInterface(GenericOp genericOp);
133 
134 namespace detail {
135 
136 /// Returns true if the block contains a contraction of the following form:
137 ///
138 /// %0 = <elemwise>(permutation-of(cu(block-argument-0),
139 /// cu(block-argument-1)))
140 /// %1 = <reduce>(permutation-of(cu(%0), cu(block-argument-2)))
141 /// return-like cu(%1)
142 ///
143 /// where <elemwise> and <reduce> are binary operations constituting a
144 /// contraction (in the canonical case, <elemwise> is a multiplication and
145 /// <reduce> is an addition). The name and other properties of these operations
146 /// are checked by `isaPair`. All operands of all operations may be supplied
147 /// through a chain of side effect-free unary operations, such as casts, which
148 /// is denoted as `cu` above.
149 ///
150 /// When the body does not contain a contraction, a more precise description of
151 /// the failed precondition is send to the `errs` stream, if provided.
152 bool isContractionBody(Block &block,
153  function_ref<bool(Operation *, Operation *)> isaPair,
154  llvm::raw_ostream &errs = mlir::thread_safe_nulls());
155 
156 /// Result of matching a Linalg generic against the predicates of it being a
157 /// contraction.
158 enum class MatchContractionResult;
159 
160 /// Checks whether `op` conforms to ContractionOpInterface and populates
161 /// `dimensions` with indexes of the different kinds of dimensions when
162 /// present.
165  ContractionDimensions *dimensions = nullptr);
166 
167 /// Returns the error message corresponding to the contraction checking return
168 /// code.
170 
171 /// Result of matching a Linalg generic against the predicates of it being a
172 /// convolution.
173 enum class MatchConvolutionResult;
174 
175 /// Checks whether `op` conforms to ConvolutionOpInterface and populates
176 /// `dimensions` with indexes of the different kinds of dimensions when
177 /// present.
180  ConvolutionDimensions *dimensions = nullptr);
181 
182 /// Returns the error message corresponding to the convolution checking return
183 /// code.
185 
186 /// Verify that `op` conforms to ContractionOpInterface.
187 LogicalResult verifyContractionInterface(Operation *op);
188 
189 /// Verify that `op` conforms to the ConvolutionOpInterface.
190 LogicalResult verifyConvolutionInterface(Operation *op);
191 
192 /// Verify that `op` conforms to the FillOpInterface.
193 LogicalResult verifyFillInterface(Operation *op);
194 
195 /// Verify that `op` conforms to the invariants of StructuredOpInterface
196 LogicalResult verifyStructuredOpInterface(Operation *op);
197 
198 } // namespace detail
199 } // namespace linalg
200 } // namespace mlir
201 
202 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.h.inc"
203 
204 /// Include the generated interface declarations.
205 #include "mlir/Dialect/Linalg/IR/LinalgInterfaces.h.inc"
206 
207 #endif // MLIR_DIALECT_LINALG_IR_LINALGINTERFACES_H_
Block represents an ordered list of Operations.
Definition: Block.h:31
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
MatchConvolutionResult isConvolutionInterfaceImpl(Operation *op, ConvolutionDimensions *dimensions=nullptr)
Checks whether op conforms to ConvolutionOpInterface and populates dimensions with indexes of the dif...
bool isContractionBody(Block &block, function_ref< bool(Operation *, Operation *)> isaPair, llvm::raw_ostream &errs=mlir::thread_safe_nulls())
Returns true if the block contains a contraction of the following form:
StringRef getMatchConvolutionMessage(MatchConvolutionResult res)
Returns the error message corresponding to the convolution checking return code.
bool canOpOperandsBeDroppedImpl(linalg::LinalgOp linalgOp, ArrayRef< OpOperand * > droppedOperands)
Implementation of the method that check if given operands can be dropped, i.e.
MatchContractionResult isContractionInterfaceImpl(Operation *op, ContractionDimensions *dimensions=nullptr)
Checks whether op conforms to ContractionOpInterface and populates dimensions with indexes of the dif...
LogicalResult verifyContractionInterface(Operation *op)
Verify that op conforms to ContractionOpInterface.
LogicalResult verifyFillInterface(Operation *op)
Verify that op conforms to the FillOpInterface.
StringRef getMatchContractionMessage(MatchContractionResult res)
Returns the error message corresponding to the contraction checking return code.
LogicalResult verifyStructuredOpInterface(Operation *op)
Verify that op conforms to the invariants of StructuredOpInterface.
LogicalResult verifyConvolutionInterface(Operation *op)
Verify that op conforms to the ConvolutionOpInterface.
bool isaElemwiseSingleUnaryOpInterface(GenericOp genericOp)
Checks whether a given genericOp is semantically equivalent to a single linalgelementwise unary op.
bool isaCopyOpInterface(LinalgOp linalgOp)
Checks whether linalgOp is semantically equivalent to a linalg.copyOp.
FailureOr< ConvolutionDimensions > inferConvolutionDims(LinalgOp linalgOp)
Find at least 1 parallel (output_image) and reduction (filter_loop) dimension candidates that form a ...
FailureOr< ContractionDimensions > inferContractionDims(LinalgOp linalgOp)
Find at least 2 parallel (m and n) and 1 reduction (k) dimension candidates that form a matmul subcom...
bool isaConvolutionOpInterface(LinalgOp linalgOp)
Checks whether linalgOp conforms to ConvolutionOpInterface.
bool isaContractionOpInterface(LinalgOp linalgOp)
Checks whether linalgOp conforms to ContractionOpInterface.
std::optional< Value > isaFillOpInterface(GenericOp genericOp)
Checks whether genericOp is semantically equivalent to a linalg.fill.
bool isaElemwiseSingleBinaryOpInterface(GenericOp genericOp)
Checks whether genericOp is semantically equivalent to a single linalg elementwise binary op e....
Include the generated interface declarations.
llvm::raw_ostream & thread_safe_nulls()
Returns a raw output stream that simply discards the output, but in a thread-safe manner.
Positions of a Linalg op loops that correspond to different kinds of a contraction dimension.
SmallVector< unsigned, 2 > batch
SmallVector< unsigned, 2 > m
SmallVector< unsigned, 2 > n
SmallVector< unsigned, 2 > k
Positions of a Linalg op loops that correspond to different kinds of a convolution dimension.
SmallVector< unsigned, 2 > depth
SmallVector< unsigned, 2 > outputImage
SmallVector< unsigned, 2 > outputChannel
SmallVector< int64_t, 2 > dilations
SmallVector< int64_t, 2 > strides
SmallVector< unsigned, 2 > inputChannel
SmallVector< unsigned, 2 > batch
SmallVector< unsigned, 2 > filterLoop