I have a simple matrix multiplication written by hand in MLIR in the memref and arith dialects:
module {
func.func @matmul(%M: index, %N: index, %K: index, %A: memref<?x?xf32>, %B: memref<?x?xf32>, %C: memref<?x?xf32>) {
%c0 = arith.constant 0 : index
// Load A[0, 0]
%a = memref.load %A[%c0, %c0] : memref<?x?xf32>
// Load B[0, 0]
%b = memref.load %B[%c0, %c0] : memref<?x?xf32>
// Multiply A[0, 0] and B[0, 0]
%mul = arith.mulf %a, %b : f32
// Store the result in C[0, 0]
memref.store %mul, %C[%c0, %c0] : memref<?x?xf32>
return
}
func.func @main() {
%c2 = arith.constant 2 : index
// Allocate memory for 2x2 matrices A, B, and C
%A = memref.alloc(%c2, %c2) : memref<?x?xf32>
%B = memref.alloc(%c2, %c2) : memref<?x?xf32>
%C = memref.alloc(%c2, %c2) : memref<?x?xf32>
// Initialize matrices A and B
%f1 = arith.constant 1.0 : f32
%f2 = arith.constant 2.0 : f32
%f3 = arith.constant 3.0 : f32
%f4 = arith.constant 4.0 : f32
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
// Initialize matrix A
memref.store %f1, %A[%c0, %c0] : memref<?x?xf32>
memref.store %f2, %A[%c0, %c1] : memref<?x?xf32>
memref.store %f3, %A[%c1, %c0] : memref<?x?xf32>
memref.store %f4, %A[%c1, %c1] : memref<?x?xf32>
// Initialize matrix B
memref.store %f1, %B[%c0, %c0] : memref<?x?xf32>
memref.store %f2, %B[%c0, %c1] : memref<?x?xf32>
memref.store %f3, %B[%c1, %c0] : memref<?x?xf32>
memref.store %f4, %B[%c1, %c1] : memref<?x?xf32>
// Call matmul function
call @matmul(%c2, %c2, %c2, %A, %B, %C) : (index, index, index, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>) -> ()
// Print C[0, 0] using printf
%result = memref.load %C[%c0, %c0] : memref<?x?xf32>
// TODO: print %result
// Free allocated memory
memref.dealloc %A : memref<?x?xf32>
memref.dealloc %B : memref<?x?xf32>
memref.dealloc %C : memref<?x?xf32>
return
}
}
How do I print %result?
I am executing this file by converting it to LLVM and then using Clang to execute the LLVM file.
I can see that there are multiple functions to help with printing here llvm-project/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h at main · llvm/llvm-project · GitHub, but maybe they need the vector dialect, so I tried the following:
%vec = vector.broadcast %result : f32 to vector<1xf32>
vector.print %vec : vector<1xf32>
but I was not able to use --convert-vector-to-llvm to lower it to LLVM.