Linalg dialect conversion to llvm dialect

I am not able to convert linalg-on-tensor dialect to llvm dialect
The mlir file which I want to convert is :

#map = affine_map<(d0, d1) -> (0, d1)>
#map1 = affine_map<(d0, d1) -> (d0, d1)>
module attributes {torch.debug_module_name = "AnnModel"} {
  ml_program.global private mutable @global_seed(dense<0> : tensor<i64>) : tensor<i64>
  func.func @forward(%arg0: tensor<1x2xf32>) -> tensor<1x2xf32> {
    %0 = tensor.empty() : tensor<1x2xf32>
    %1 = linalg.generic {indexing_maps = [#map, #map, #map1], iterator_types = ["parallel", "parallel"]} ins(%arg0, %arg0 : tensor<1x2xf32>, tensor<1x2xf32>) outs(%0 : tensor<1x2xf32>) {
    ^bb0(%in: f32, %in_0: f32, %out: f32):
      %2 = arith.addf %in, %in_0 : f32
      linalg.yield %2 : f32
    } -> tensor<1x2xf32>
    return %1 : tensor<1x2xf32>
  }
}

using the command

mlir-opt ann_linalg_on_tensors.mlir --convert-linalg-to-llvm

and getting an error:


ann_linalg_on_tensors.mlir:7:10: error: 'linalg.generic' op expects regions to end with 'linalg.yield', found 'llvm.return'
    %1 = linalg.generic {indexing_maps = [#map, #map, #map1], iterator_types = ["parallel", "parallel"]} ins(%arg0, %arg0 : tensor<1x2xf32>, tensor<1x2xf32>) outs(%0 : tensor<1x2xf32>) {
         ^
ann_linalg_on_tensors.mlir:7:10: note: see current operation: 
%1 = "linalg.generic"(%arg0, %arg0, %0) ({
^bb0(%arg1: f32, %arg2: f32, %arg3: f32):
  %2 = "arith.addf"(%arg1, %arg2) {fastmath = #arith.fastmath<none>} : (f32, f32) -> f32
  "llvm.return"(%2) : (f32) -> ()
}) {indexing_maps = [affine_map<(d0, d1) -> (0, d1)>, affine_map<(d0, d1) -> (0, d1)>, affine_map<(d0, d1) -> (d0, d1)>], iterator_types = [#linalg.iterator_type<parallel>, #linalg.iterator_type<parallel>], operand_segment_sizes = array<i32: 2, 1>} : (tensor<1x2xf32>, tensor<1x2xf32>, tensor<1x2xf32>) -> tensor<1x2xf32>
ann_linalg_on_tensors.mlir:7:10: note: in custom textual format, the absence of terminator implies 'linalg.yield'

Please help me out

The conversion from linalg-on-tensors to LLVM is significantly more complex than running one pass. You can look into this test llvm-project/test-tensor-e2e.mlir at main · llvm/llvm-project · GitHub and one of the pass pipelines that may work llvm-project/TestLowerToLLVM.cpp at 0529da5b948cf168f65bec65b0559139f4f5a426 · llvm/llvm-project · GitHub.

1 Like

I suspect the -convert-linalg-to-llvm pass would deserve much more documentation about what it intends to do, see the current one:

Convert the operations from the linalg dialect into the LLVM dialect

@nicolasvasilache or @matthias-springer may be able to help with this?

1 Like

As this is working fine , but if my conversion path will linalg->affine->vector->llvm [reference], what I need to take care? Is there any available pass that will solve the problem?

There is the --convert-linalg-to-affine-loops pass that applies to Linalg operations after bufferization (make sure to run that first). Then there is the --affine-super-vectorize pass that applies to the result. Note, however, that this this flow is not being actively worked on right now.

Instead, it is possible to vectorize directly at the Linalg-on-tensors level, then perform bufferization. This is only exposed via the transform dialect, see llvm-project/transform-op-vectorize.mlir at main · llvm/llvm-project · GitHub for an example. It should be still possible to produce affine loops after vectorization+bufferization if desired, but I haven’t checked.