Commit Graph

4415 Commits

Author SHA1 Message Date
Aart Bik 9ad62f62b9 [mlir][sparse] remove a few rewriting failures
Rationale:
Make sure preconditions are tested already during verfication.
Currently, the only way a sparse rewriting rule can fail is if
(1) the linalg op does not have sparse annotations, or
(2) a yet to be handled operation is encounted inside the op

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D91748
2020-11-18 17:29:40 -08:00
Diego Caballero c1ba9c43ad [mlir][Affine] Refactor affine fusion code in pass to utilities
Refactoring/clean-up step needed to add support for producer-consumer fusion
with multi-store producer loops and, in general, to implement more general
loop fusion strategies in Affine. It introduces the following changes:
  - AffineLoopFusion pass now uses loop fusion utilities more broadly to compute
    fusion legality (canFuseLoops utility) and perform the fusion transformation
    (fuseLoops utility).
  - Loop fusion utilities have been extended to deal with AffineLoopFusion
    requirements and assumptions while preserving both loop fusion utilities and
    AffineLoopFusion current functionality within a unified implementation.
    'FusionStrategy' has been introduced for this purpose and, in the future, it
    will allow us to have a single loop fusion core implementation that will produce
    different fusion outputs depending on the strategy used.
  - Improve separation of concerns for legality and profitability analysis:
    'isFusionProfitable' no longer filters out illegal scenarios that 'canFuse'
    didn't detect, or the other way around. 'canFuse' now takes loop dependences
    into account to determine the fusion loop depth (producer-consumer fusion only).
  - As a result, maximal fusion now doesn't require any profitability analysis.
  - Slices are now computed only once and reused across the legality, profitability
    and fusion transformation steps (producer-consumer).
  - Refactor some utilities and remove redundant copies of them.

This patch is NFCI and should preserve the existing functionality of both the
AffineLoopFusion pass and the affine fusion utilities.

Reviewed By: andydavis1, bondhugula

Differential Revision: https://reviews.llvm.org/D90798
2020-11-18 13:50:32 -08:00
ergawy adf9f64a02 [MLIR][SPIRV] Rename `spv._reference_of` to `spv.mlir.referenceof`
This commit does the renaming mentioned in the title in order to bring
'spv' dialect closer to the MLIR naming conventions.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D91715
2020-11-18 13:27:29 -05:00
Christian Sigg 8b97e17d16 [mlir] Simplify code generated by ConvertToLLVMPattern::getStridedElementPtr().
Make the interface match the one of ConvertToLLVMPattern::getDataPtr() (to be removed in a separate change).

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D91599
2020-11-18 11:52:09 +01:00
zhanghb97 77133b29b9 [mlir] Get array from the dense elements attribute with buffer protocol.
- Add `mlirElementsAttrGetType` C API.
- Add `def_buffer` binding to PyDenseElementsAttribute.
- Implement the protocol to access the buffer.

Differential Revision: https://reviews.llvm.org/D91021
2020-11-18 15:50:59 +08:00
Tei Jeong 94e4ec6499 Add CalibratedQuantizedType to quant dialect
This type supports a calibrated type with min, max provided.

This will be used for importing calibration values of intermediate tensors (e.g. LSTM) which can't be imported with QuantStats op.

This type was initially suggested in the following RFC: https://llvm.discourse.group/t/rfc-a-proposal-for-implementing-quantization-transformations-in-mlir/655

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D91584
2020-11-17 22:14:54 -08:00
Stella Laurenzo 989b194429 [mlir][Python] Make DenseElementsAttr loading be int size agnostic.
* I had missed the note about "Standard size" in the docs. On Windows, the 'l' types are 32bit.
* This fixes the only failing MLIR-Python test on Windows.

Differential Revision: https://reviews.llvm.org/D91283
2020-11-17 21:50:44 -08:00
daquexian 6bfb4120ea set the alignment of mlir::AttributeStorage to 64 bit explicitly to fix 32 bit platform
On some platform (like WebAssembly), alignof(mlir::AttributeStorage) is 4 instead of 8. As a result, it makes the program crashes since PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable is 3.

So I explicitly set the alignment of mlir::AttributeStoarge to 64 bits, and set PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable according to it.

I also fixed an another related error (alignof(NamedAttribute) -> alignof(DictionaryAttributeStorage)) based on reviewer's comments.

Reviewed By: dblaikie, rriddle

Differential Revision: https://reviews.llvm.org/D91062
2020-11-17 17:51:53 -08:00
MaheshRavishankar b13415b59b [mlir][Linalg] Add dependence type to LinalgDependenceGraphElem.
Differential Revision: https://reviews.llvm.org/D91502
2020-11-17 16:32:57 -08:00
Aart Bik eced4a8e6f [mlir] [sparse] start of sparse tensor compiler support
As discussed in https://llvm.discourse.group/t/mlir-support-for-sparse-tensors/2020
this CL is the start of sparse tensor compiler support in MLIR. Starting with a
"dense" kernel expressed in the Linalg dialect together with per-dimension
sparsity annotations on the tensors, the compiler automatically lowers the
kernel to sparse code using the methods described in Fredrik Kjolstad's thesis.

Many details are still TBD. For example, the sparse "bufferization" is purely
done locally since we don't have a global solution for propagating sparsity
yet. Furthermore, code to input and output the sparse tensors is missing.
Nevertheless, with some hand modifications, the generated MLIR can be
easily converted into runnable code already.

Reviewed By: nicolasvasilache, ftynse

Differential Revision: https://reviews.llvm.org/D90994
2020-11-17 13:10:42 -08:00
Christian Sigg bedaad4495 [mlir] Simplify std.alloc lowering to LLVM.
std.alloc only supports memrefs with identity layout, which means we can simplify the lowering to LLVM and compute strides only from (static and dynamic) sizes.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D91549
2020-11-17 18:55:34 +01:00
ergawy 9793edd5bf [MLIR][SPIRV] Rename `spv._address_of` to `spv.mlir.addressof`
This commit does the renaming mentioned in the title in order to bring
`spv` dialect closer to the MLIR naming conventions.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D91609
2020-11-17 12:12:27 -05:00
Alex Zinenko f3dab16dc7 [mlir] Add a _get_default_loc_context utility to Python bindings
This utility function is helpful for dialect-specific builders that need
to access the context through location, and the location itself may be
either provided as an argument or expected to be recovered from the
implicit location stack.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D91623
2020-11-17 17:55:47 +01:00
Christian Sigg 43ede0e2a7 [mlir] Remove unused ConvertToLLVMPattern::linearizeSubscripts().
Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D91594
2020-11-17 17:25:45 +01:00
Stephan Herhut c4472f8b4c [mlir][std] Canonicalize extract_element(tensor_cast).
Canonicalize extract_element(tensor_cast(v)) to just extract_element(v).

Differential Revision: https://reviews.llvm.org/D91621
2020-11-17 14:41:39 +01:00
Stephan Herhut 3598605c0b [mlir][std] Fold dim(dynamic_tensor_from_elements, %cst)
The shape of the result of a dynamic_tensor_from_elements is defined via its
result type and operands. We already fold dim operations when they reference
one of the statically sized dimensions. Now, also fold dim on the dynamically
sized dimensions by picking the corresponding operand.

Differential Revision: https://reviews.llvm.org/D91616
2020-11-17 14:39:59 +01:00
Stephan Herhut ffac5b8e4c [mlir][linalg] Allow tensor_to_memref in dependence analysis
This enables the use of fusion on buffers in partially lowered
programs.

Differential Revision: https://reviews.llvm.org/D91613
2020-11-17 14:37:47 +01:00
Alex Zinenko c5a6712f8c [mlir] Add basic support for attributes in ODS-generated Python bindings
In ODS, attributes of an operation can be provided as a part of the "arguments"
field, together with operands. Such attributes are accepted by the op builder
and have accessors generated.

Implement similar functionality for ODS-generated op-specific Python bindings:
the `__init__` method now accepts arguments together with operands, in the same
order as in the ODS `arguments` field; the instance properties are introduced
to OpView classes to access the attributes.

This initial implementation accepts and returns instances of the corresponding
attribute class, and not the underlying values since the mapping scheme of the
value types between C++, C and Python is not yet clear. Default-valued
attributes are not supported as that would require Python to be able to parse
C++ literals.

Since attributes in ODS are tightely related to the actual C++ type system,
provide a separate Tablegen file with the mapping between ODS storage type for
attributes (typically, the underlying C++ attribute class), and the
corresponding class name. So far, this might look unnecessary since all names
match exactly, but this is not necessarily the cases for non-standard,
out-of-tree attributes, which may also be placed in non-default namespaces or
Python modules. This also allows out-of-tree users to generate Python bindings
without having to modify the bindings generator itself. Storage type was
preferred over the Tablegen "def" of the attribute class because ODS
essentially encodes attribute _constraints_ rather than classes, e.g. there may
be many Tablegen "def"s in the ODS that correspond to the same attribute type
with additional constraints

The presence of the explicit mapping requires the change in the .td file
structure: instead of just calling the bindings generator directly on the main
ODS file of the dialect, it becomes necessary to create a new file that
includes the main ODS file of the dialect and provides the mapping for
attribute types. Arguably, this approach offers better separability of the
Python bindings in the build system as the main dialect no longer needs to know
that it is being processed by the bindings generator.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D91542
2020-11-17 11:47:37 +01:00
River Riddle 73ca690df8 [mlir][NFC] Remove references to Module.h and Function.h
These includes have been deprecated in favor of BuiltinDialect.h, which contains the definitions of ModuleOp and FuncOp.

Differential Revision: https://reviews.llvm.org/D91572
2020-11-17 00:55:47 -08:00
River Riddle c51e4c4f01 [mlir][IR] Use tablegen for the BuiltinDialect and operations
This has been a long standing TODO, and cleans up a bit of IR/. This will also make it easier to move FuncOp out of IR/ at some point in the future. For now, Module.h and Function.h just forward BuiltinDialect.h. These files will be removed in a followup.

Differential Revision: https://reviews.llvm.org/D91571
2020-11-17 00:53:40 -08:00
Tei Jeong 65d4b5cb18 Add const qualifier to Type's utility functions
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D91491
2020-11-17 03:56:17 +00:00
Rahul Joshi b7382ed3fe [MLIR] Extend Symbol verification to reject public symbol declarations.
- Extend the Symbol interface with `isDeclaration` to identify operations that declare
  a symbol as opposed to define it.
- Extend verification to disallow public declarations as per the discussion in
   https://llvm.discourse.group/t/rfc-symbol-definition-declaration-x-visibility-checks/2140
- Adopt the new interface for `FuncOp` and fix test and code to not have/create public
  function declarations.

Differential Revision: https://reviews.llvm.org/D91456
2020-11-16 16:05:32 -08:00
Lex Augusteijn fbceee2d63 Add an optional argument for pattern rewriter max iteration count (NFC)
Some rewriters take more iterations to converge, add a parameter to overwrite
the built-in maximum iteration count.

Fix PR48073.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D91553
2020-11-16 22:57:14 +00:00
Sean Silva 7c62c6313b [mlir] Add DecomposeCallGraphTypes pass.
This replaces the old type decomposition logic that was previously mixed
into bufferization, and makes it easily accessible.

This also deletes TestFinalizingBufferize, because after we remove the type
decomposition, it doesn't do anything that is not already provided by
func-bufferize.

Differential Revision: https://reviews.llvm.org/D90899
2020-11-16 12:25:35 -08:00
Christian Sigg 04481f26fa [mlir] Require std.alloc() ops to have canonical layout during LLVM lowering.
The current code allows strided layouts, but the number of elements allocated is ambiguous. It could be either the number of elements in the shape (the current implementation), or the amount of elements required to not index out-of-bounds with the given maps (which would require evaluating the layout map).

If we require the canonical layouts, the two will be the same.

Reviewed By: nicolasvasilache, ftynse

Differential Revision: https://reviews.llvm.org/D91523
2020-11-16 17:29:36 +01:00
Hanhan Wang 47fd19f22e [mlir][StandardToSPIRV] Extend support for lowering cmpi to SPIRV.
The logic of vector on boolean was missed. This patch adds the logic and test on
it.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D91403
2020-11-16 06:51:05 -08:00
Nicolas Vasilache 7625742237 [mlir][Linalg] Add support for tileAndDistribute on tensors.
scf.parallel is currently not a good fit for tiling on tensors.
Instead provide a path to parallelism directly through scf.for.
For now, this transformation ignores the distribution scheme and always does a block-cyclic mapping (where block is the tile size).

Differential revision: https://reviews.llvm.org/D90475
2020-11-16 11:12:50 +00:00
Aart Bik 9ddb464d37 [mlir] refactor common idiom into AffineMap method
motivated by a refactoring in the new sparse code (yet to be merged), this avoids some lengthy code dup

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D91465
2020-11-13 19:18:13 -08:00
Sean Silva 703ef17e7a [mlir] Make linalg-bufferize run on FuncOp
That way, it runs in parallel across functions.
2020-11-13 15:43:24 -08:00
Rahul Joshi d843755220 [NFC] Refactor function declaration addition in AsyncToLLVM
- Extract repeated code into helper function/lambdas.

Differential Revision: https://reviews.llvm.org/D91453
2020-11-13 12:53:19 -08:00
Thomas Raoux 6ad31c0f4a [mlir][vector] Support N-D vector in InsertMap/ExtractMap op
Support multi-dimension vector for InsertMap/ExtractMap op and update the
transformations. Currently the relation between IDs and dimension is implicitly
deduced from the types. We can then calculate an AffineMap based on it. In the
future the AffineMap could be part of the operation itself.

Differential Revision: https://reviews.llvm.org/D90995
2020-11-13 12:40:17 -08:00
MaheshRavishankar bf3861bf71 [mlir][Linalg] Change LinalgDependenceGraph to use LinalgOp.
Using LinalgOp will reduce the repeated conversion from Operation <->
LinalgOp.

Differential Revision: https://reviews.llvm.org/D91101
2020-11-13 12:34:38 -08:00
Scott Todd c9e9cc3fe7 [MLIR] Allow setting "CodeView" flag in LLVMIR translation on MSVC.
Reviewed By: ftynse, mehdi_amini

Differential Revision: https://reviews.llvm.org/D91365
2020-11-13 17:31:18 +01:00
Eugene Zhulenev c30ab6c2a3 [mlir] Transform scf.parallel to scf.for + async.execute
Depends On D89958

1. Adds `async.group`/`async.awaitall` to group together multiple async tokens/values
2. Rewrite scf.parallel operation into multiple concurrent async.execute operations over non overlapping subranges of the original loop.

Example:

```
   scf.for (%i, %j) = (%lbi, %lbj) to (%ubi, %ubj) step (%si, %sj) {
     "do_some_compute"(%i, %j): () -> ()
   }
```

Converted to:

```
   %c0 = constant 0 : index
   %c1 = constant 1 : index

   // Compute blocks sizes for each induction variable.
   %num_blocks_i = ... : index
   %num_blocks_j = ... : index
   %block_size_i = ... : index
   %block_size_j = ... : index

   // Create an async group to track async execute ops.
   %group = async.create_group

   scf.for %bi = %c0 to %num_blocks_i step %c1 {
     %block_start_i = ... : index
     %block_end_i   = ... : index

     scf.for %bj = %c0 t0 %num_blocks_j step %c1 {
       %block_start_j = ... : index
       %block_end_j   = ... : index

       // Execute the body of original parallel operation for the current
       // block.
       %token = async.execute {
         scf.for %i = %block_start_i to %block_end_i step %si {
           scf.for %j = %block_start_j to %block_end_j step %sj {
             "do_some_compute"(%i, %j): () -> ()
           }
         }
       }

       // Add produced async token to the group.
       async.add_to_group %token, %group
     }
   }

   // Await completion of all async.execute operations.
   async.await_all %group
```
In this example outer loop launches inner block level loops as separate async
execute operations which will be executed concurrently.

At the end it waits for the completiom of all async execute operations.

Reviewed By: ftynse, mehdi_amini

Differential Revision: https://reviews.llvm.org/D89963
2020-11-13 04:02:56 -08:00
Stephan Herhut 4a771108ac [mlir][bufferize] Fix buffer promotion to stack for index types
The index type does not have a bitsize and hence the size of corresponding allocations cannot be computed.  Instead, the promotion pass now has an explicit option to specify the size of index.

Differential Revision: https://reviews.llvm.org/D91360
2020-11-13 09:23:36 +01:00
Stephan Herhut 5da2423bc0 [mlir][gpu] Only transform mapped parallel loops to GPU.
This exposes a hook to configure legality of operations such that only
`scf.parallel` operations that have mapping attributes are marked as
illegal. Consequently, the transformation can now also be applied to
mixed forms.

Differential Revision: https://reviews.llvm.org/D91340
2020-11-13 09:15:17 +01:00
River Riddle 811001380f [mlir][Pass] Remove the verifierPass now that verification is run during normal pass execution
A recent refactoring removed the need to interleave verifier passes and instead opted to verify during the normal execution of passes instead. As such, the old verify pass is no longer necessary and can be removed.

Differential Revision: https://reviews.llvm.org/D91212
2020-11-12 23:45:27 -08:00
River Riddle 48e8129edf [mlir][Asm] Add support for resolving operation locations after parsing has finished
This revision adds support in the parser/printer for "deferrable" aliases, i.e. those that can be resolved after printing has finished. This allows for printing aliases for operation locations after the module instead of before, i.e. this is now supported:

```
"foo.op"() : () -> () loc(#loc)

#loc = loc("some_location")
```

Differential Revision: https://reviews.llvm.org/D91227
2020-11-12 23:34:36 -08:00
River Riddle 7f61396cfa [mlir][Interfaces] Add implicit casts from concrete operation types to the interfaces they implement.
This removes the need to have an explicit `cast<>` given that we always know it `isa` instance of the interface.

Differential Revision: https://reviews.llvm.org/D91304
2020-11-12 22:56:08 -08:00
Rahul Joshi 5883c4b470 [MLIR] Fix standard -> LLVM conversion to fail for unsupported memref element type.
- Move isSupportedMemRefType() to ConvertToLLVMPatterns and check if the
  memref element type is supported there.

Differential Revision: https://reviews.llvm.org/D91374
2020-11-12 17:06:05 -08:00
Sean Silva faa66b1b2c [mlir] Bufferize tensor constant ops
We lower them to a std.global_memref (uniqued by constant value) + a
std.get_global_memref to produce the corresponding memref value.
This allows removing Linalg's somewhat hacky lowering of tensor
constants, now that std properly supports this.

Differential Revision: https://reviews.llvm.org/D91306
2020-11-12 14:56:10 -08:00
Sean Silva ad2f9f6745 [mlir] Fix subtensor_insert bufferization.
It was incorrect in the presence of a tensor argument with multiple
uses.

The bufferization of subtensor_insert was writing into a converted
memref operand, but there is no guarantee that the converted memref for
that operand is safe to write into. In this case, the same converted
memref is written to in-place by the subtensor_insert bufferization,
violating the tensor-level semantics.

I left some comments in a TODO about ways forward on this. I will be
working actively on this problem in the coming days.

Differential Revision: https://reviews.llvm.org/D91371
2020-11-12 14:56:09 -08:00
Stella Laurenzo 4726a402a3 [mlir][Python] Fix 'unreferenced local variable' warning on MSVC.
Differential Revision: https://reviews.llvm.org/D91282
2020-11-12 13:34:57 -08:00
Rahul Joshi dea24b422c [NFC] Switch printFunctionLikeOp and parseFunctionLikeOp to only support "inline" visibility.
- Remove the default valued arguments from these functions.
- Besides FuncOp, looks like no other in-tree op is using these functions.

Differential Revision: https://reviews.llvm.org/D91369
2020-11-12 11:29:01 -08:00
Jean-Michel Gorius e47805c995 [mlir] Add plus, star and optional less/greater parsing
The tokens are already handled by the lexer. This revision exposes them
through the parser interface.

This revision also adds missing functions for question mark parsing and
completes the list of valid punctuation tokens in the documentation.

Differential Revision: https://reviews.llvm.org/D90907
2020-11-12 13:28:31 +01:00
MaheshRavishankar 5ca20851e4 [mlir][Linalg] Improve the logic to perform tile and fuse with better dependence tracking.
This change does two main things
1) An operation might have multiple dependences to the same
   producer. Not tracking them correctly can result in incorrect code
   generation with fusion. To rectify this the dependence tracking
   needs to also have the operand number in the consumer.
2) Improve the logic used to find the fused loops making it easier to
   follow. The only constraint for fusion is that linalg ops (on
   buffers) have update semantics for the result. Fusion should be
   such that only one iteration of the fused loop (which is also a
   tiled loop) must touch only one (disjoint) tile of the output. This
   could be relaxed by allowing for recomputation that is the default
   when oeprands are tensors, or can be made legal with promotion of
   the fused view (in future).

Differential Revision: https://reviews.llvm.org/D90579
2020-11-12 00:25:24 -08:00
Aart Bik 0846659648 [mlir][sparse] export sparse tensor runtime support through header file
Exposing the C versions of the methods of the sparse runtime support lib
through header files will enable using the same methods in an MLIR program
as well as a C++ program, which will simplify future benchmarking comparisons
(e.g. comparing MLIR generated code with eigen for Matrix Market sparse matrices).

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D91316
2020-11-11 21:03:39 -08:00
Aart Bik e1dbc25ee2 [mlir][sparse] integrate sparse annotation into generic linalg op
This CL integrates the new sparse annotations (hereto merely added as fully
transparent attributes) more tightly to the generic linalg op in order to add
verification of the annotations' consistency as well as to make make other
passes more aware of their presence (in the long run, rewriting rules must
preserve the integrity of the annotations).

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D91224
2020-11-11 17:26:30 -08:00
David Blaikie 9f310bec34 Add missing override (& fix an else-after-return while I'm here) 2020-11-11 12:29:08 -08:00
Mehdi Amini a62d38a90d Disable implicit nesting on parsing textual pass pipeline
Previous the textual form of the pass pipeline would implicitly nest,
instead we opt for the explicit form here: this has less surprise.

This also avoids asserting in the bindings when passing a pass pipeline
with incorrect nesting.

Differential Revision: https://reviews.llvm.org/D91233
2020-11-11 19:21:51 +00:00