[mlir] run buffer deallocation in transform tutorial (#67978)

Buffer deallocation pipeline previously was incorrect when applied to
functions. It has since been fixed. Make sure it is exercised in the
tutorial to avoid leaking allocations.
This commit is contained in:
Oleksandr "Alex" Zinenko 2023-10-02 16:08:11 +02:00 committed by GitHub
parent c95fcd343d
commit aab795a8dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 0 deletions

View File

@ -497,6 +497,20 @@ bufferization is directly available as a transform operation.
function_boundary_type_conversion = 1 : i32 }
```
One-shot bufferization itself does not produce buffer deallocations, which may
lead to leaks. So we have to run the buffer deallocation pass pipeline to avoid
them. Note that the transform dialect seamlessly runs named passes and pass
pipelines: if desired, one could replace complex `--pass-pipeline expressions`
with operations. Note that we apply the pipeline to functions rather than entire
module to avoid running it on the transform IR that is contained in the module.
```mlir
%f = transform.structured.match ops{["func.func"]} in %arg1
: (!transform.any_op) -> !transform.any_op
transform.apply_registered_pass "buffer-deallocation-pipeline" to %f
: (!transform.any_op) -> !transform.any_op
```
In this particular case, the transformed IR could be directly bufferized. This
is not always the case in general as some operations, in particular
`tensor.empty` may not be bufferizable. Such operations need to be removed

View File

@ -1,6 +1,7 @@
// RUN: mlir-opt %s --test-transform-dialect-interpreter \
// RUN: --test-transform-dialect-erase-schedule \
// RUN: --math-uplift-to-fma \
// RUN: --convert-bufferization-to-memref \
// RUN: --test-lower-to-llvm |\
// RUN: FileCheck %s
@ -307,10 +308,22 @@ module attributes { transform.with_named_sequence } {
// transformation process, so invalidation is not an issue. However, if
// other transformations, such as loop unrolling, are required after
// bufferization, new handles should be produced using the match operations.
//
// One-shot bufferization itself does not produce buffer deallocations,
// which may lead to leaks. So we have to run the buffer deallocation pass
// pipeline to avoid them. Note that the transform dialect seamlessly runs
// named passes and pass pipelines: if desired, one could replace complex
// --pass-pipeline expressions with operations. Note that we apply the
// pipeline to functions rather than entire module to avoid running it
// on the transform IR that is contained in the module.
%arg1 = transform.bufferization.one_shot_bufferize %arg0 {
bufferize_function_boundaries = true,
function_boundary_type_conversion = 1 : i32 }
: (!transform.any_op) -> !transform.any_op
%f = transform.structured.match ops{["func.func"]} in %arg1
: (!transform.any_op) -> !transform.any_op
transform.apply_registered_pass "buffer-deallocation-pipeline" to %f
: (!transform.any_op) -> !transform.any_op
// Apply general canonicalization and CSE to each function after
// bufferization as new simplification opportunities may have appeared.