I’m making use of MLIR bufferization passes as shown below:
// Bufferize
addFilteredPassToPassManager(pm, mlir::createTensorConstantBufferizePass(),
options.enablePass);
addFilteredPassToPassManager(pm, mlir::createStdBufferizePass(),
options.enablePass);
addFilteredPassToPassManager(pm, mlir::createTensorBufferizePass(),
options.enablePass);
addFilteredPassToPassManager(pm, mlir::createLinalgBufferizePass(),
options.enablePass);
addFilteredPassToPassManager(pm, mlir::createConvertLinalgToLoopsPass(),
options.enablePass);
addFilteredPassToPassManager(pm, mlir::createFuncBufferizePass(),
options.enablePass);
addFilteredPassToPassManager(pm, mlir::createFinalizingBufferizePass(),
options.enablePass);
To try to lower some linalg.generic
that contains an unrealized_conversion_cast
. Below are two dummy examples, with and without unrealized_conversion_cast
, the first one fail, while the second work
Example with unrealized_conversion_cast
:
#map0 = affine_map<(d0) -> (d0)>
#map1 = affine_map<(d0) -> (0)>
func @main(%arg0: tensor<2xi64>, %arg1: tensor<2xi8>, %arg2: i64) -> i64 {
%0 = tensor.from_elements %arg2 : tensor<1xi64>
%1 = linalg.generic {indexing_maps = [#map0, #map0, #map1], iterator_types = ["reduction"]} ins(%arg0, %arg1 : tensor<2xi64>, tensor<2xi8>) outs(%0 : tensor<1xi64>) {
^bb0(%arg3: i64, %arg4: i8, %arg5: i64): // no predecessors
%c0_1 = constant 0 : index
%fail = unrealized_conversion_cast %c0_1 : index to i64
linalg.yield %fail : i64
} -> tensor<1xi64>
%c0 = constant 0 : index
%2 = tensor.extract %1[%c0] : tensor<1xi64>
return %2 : i64
}
Failing with /llvm-project/mlir/lib/Dialect/Linalg/Transforms/Loops.cpp:423: llvm::Optional<llvm::SmallVector<mlir::Operation*, 4> > linalgOpToLoopsImpl(mlir::PatternRewriter&, mlir::linalg::LinalgOp) [with LoopTy = mlir::scf::ForOp]: Assertion `linalgOp.hasBufferSemantics() && "expected linalg op with buffer semantics"' failed. Aborted (core dumped)
Example without unrealized_conversion_cast
:
#map0 = affine_map<(d0) -> (d0)>
#map1 = affine_map<(d0) -> (0)>
func @main(%arg0: tensor<2xi64>, %arg1: tensor<2xi8>, %arg2: i64) -> i64 {
%0 = tensor.from_elements %arg2 : tensor<1xi64>
%1 = linalg.generic {indexing_maps = [#map0, #map0, #map1], iterator_types = ["reduction"]} ins(%arg0, %arg1 : tensor<2xi64>, tensor<2xi8>) outs(%0 : tensor<1xi64>) {
^bb0(%arg3: i64, %arg4: i8, %arg5: i64): // no predecessors
linalg.yield %arg3 : i64
} -> tensor<1xi64>
%c0 = constant 0 : index
%2 = tensor.extract %1[%c0] : tensor<1xi64>
return %2 : i64
}
Working fine!
Is there anything specific to unrealized_conversion_cast
that’s making it fail? Other custom operations can be part of linalg.generic
without this issue.