| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
[mlir] Use OpBuilder::createBlock in op builders and patterns (#82770) When creating a new block in (conversion) rewrite patterns, OpBuilder::createBlock must be used. Otherwise, no notifyBlockInserted notification is sent to the listener. Note: The dialect conversion relies on listener notifications to keep track of IR modifications. Creating blocks without the builder API can lead to memory leaks during rollback. | 2 年前 | |
[mlir][Transforms][NFC] Improve listener layering in dialect conversion (#81236) Context: Conversion patterns provide a ConversionPatternRewriter to modify the IR. ConversionPatternRewriter provides the public API. Most function calls are forwarded/handled by ConversionPatternRewriterImpl. The dialect conversion uses the listener infrastructure to get notified about op/block insertions. In the current design, ConversionPatternRewriter inherits from both PatternRewriter and Listener. The conversion rewriter registers itself as a listener. This is problematic because listener functions such as notifyOperationInserted are now part of the public API and can be called from conversion patterns; that would bring the dialect conversion into an inconsistent state. With this commit, ConversionPatternRewriter no longer inherits from Listener. Instead ConversionPatternRewriterImpl inherits from Listener. This removes the problematic public API and also simplifies the code a bit: block/op insertion notifications were previously forwarded to the ConversionPatternRewriterImpl. This is no longer needed. | 2 年前 | |
[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 | 5 年前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 年前 | ||
| 2 年前 | ||
| 5 年前 |