I have some problems about vector.contract

The vector.contract has an optional kind attribute. The mlir document says that an optional kind attribute may be used to specify the combining function between the intermediate result and accumulator argument of rank K. This attribute can take the values add/mul/min/max for int/fp, and/or/xor for int only. The default is “add”.

  • The results of vector.contract are same when i use add and mul.
  • When i use min/max,whether I use int or fp there is an error here
    I I didn’t find some examples use mul/xor/or in llvm/mlir/test/Integration/Dialect/Vector/CPU/test-contraction.mlir
./vector-contract.mlir:20:136: error: Unknown combining kind: min
  %v3 = vector.contract {indexing_maps = [#map0, #map1, #map2], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<min>} %v0, %v1, %v2 : vector<3x4xf32>, vector<4x3xf32> into vector<3x3xf32>

Here is my code

#map0 = affine_map<(i, j, k) -> (i, k)>
#map1 = affine_map<(i, j, k) -> (k, j)>
#map2 = affine_map<(i, j, k) -> (i, j)> 

func.func @main() -> (i32) {
  %c0 = arith.constant 0 : i32
  %v0 = arith.constant dense<[[1., 2., 3., 4.], 
                              [5., 6., 7., 8.], 
                              [9., 10., 11., 12.]]> : vector<3x4xf32>

  %v1 = arith.constant dense<[[1., 2., 3.], 
                              [4., 5., 6.], 
                              [7., 8., 9.], 
                              [10., 11., 12.]]> : vector<4x3xf32>
  
  %v2 = arith.constant dense<[[0., 0., 0.], 
                              [0., 0., 0.], 
                              [0., 0., 0.]]> : vector<3x3xf32>

  %v3 = vector.contract {indexing_maps = [#map0, #map1, #map2], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<min>} %v0, %v1, %v2 : vector<3x4xf32>, vector<4x3xf32> into vector<3x3xf32>
  vector.print %v3 : vector<3x3xf32>
  return %c0 : i32
}

You can use my code to test.

  • the last problem
    I haven’t been studying MLIR for long, i always meet some problems, i want to learn mlir-opt in depth, not just how to use it and i want to learn about the overall architecture of mlir-opt, so that I can better find problems and I would like some advice on how I should learn mlir-opt.Thanks!

I already know where i made a mistake by viewing source code.when use max or min,the type information should be added.

::llvm::Optional<CombiningKind> symbolizeCombiningKind(::llvm::StringRef str) {
  ::llvm::SmallVector<::llvm::StringRef, 2> symbols;
  str.split(symbols, "|");

  uint32_t val = 0;
  for (auto symbol : symbols) {
    auto bit = llvm::StringSwitch<::llvm::Optional<uint32_t>>(symbol.trim())
      .Case("add", 1)
      .Case("mul", 2)
      .Case("minui", 4)
      .Case("minsi", 8)
      .Case("minf", 16)
      .Case("maxui", 32)
      .Case("maxsi", 64)
      .Case("maxf", 128)
      .Case("and", 256)
      .Case("or", 512)
      .Case("xor", 1024)
      .Default(::llvm::None);
    if (bit) { val |= *bit; } else { return ::llvm::None; }
  }
  return static_cast<CombiningKind>(val);
}

But I still haven’t figured out why the result is the same when I use a different vector.kind,what are the effects of the different kind.

Looks like a bug, contractions other than default mul/add don’t seem to be implemented. cc @nicolasvasilache @ThomasRaoux

Sent incorrect lowering of vector.contract · Issue #58409 · llvm/llvm-project · GitHub for this as well as a stopgap patch that should prevent incorrect lowering by refusing to lower at all.

1 Like