LLVM Discussion Forums

Print in MLIR

I am writing MLIR code for tensor multiplication .But How can I write print operation in MLIR to print multiplication result.

Thanks

The short answer is that it’s not something that MLIR provides out of the box. Personally, I think this is a significant barrier to entry for people, but I haven’t found the time to propose something. There is an example in the toy tutorial that does exactly this, for one type of lowering.

see: https://mlir.llvm.org/docs/Tutorials/Toy/Ch-6/

I have output in memref type.I am not able to print this using toy.print as it takes tensor type.Is there any ways to convert memref to tensor in MLIR or How can I print memref type variable.

Thanks

These things are significantly better handled in C++ than in MLIR.

See https://github.com/llvm/llvm-project/blob/master/mlir/test/mlir-cpu-runner/utils.mlir which links a separately built .so that implements printing.

In a longer term future we just want to use any off-the-shelf library (e.g. numpy).
For now we just have a simple ABI and conventions to allow calling C / C++ from MLIR.

Although not directly applicable to your request, please note that the Vector dialect added some rudimentary built-in support for printing, something we use heavily during debugging and testing, as well as in our integration tests.

Something like

  vector.print %1 : vector<128xf32>

is lowered by unrolling this into a series of simple calls into a very small runtime support library. This approach does not scale very well, but it has the advantage that clients only need to provide a few methods for this runtime support library when targeting a new platform.

The implementation below is used for CPU. Linking these in (either when running JIT or AOT) makes it so much easier to test new features in the vector dialect (or anything that lowers to it).

extern "C" void print_i32(int32_t i) { fprintf(stdout, "%" PRId32, i); }
extern "C" void print_i64(int64_t l) { fprintf(stdout, "%" PRId64, l); }
extern "C" void print_f32(float f)   { fprintf(stdout, "%g", f); }
extern "C" void print_f64(double d)  { fprintf(stdout, "%lg", d); }
extern "C" void print_open()         { fputs("( ", stdout); }
extern "C" void print_close()        { fputs(" )", stdout); }
extern "C" void print_comma()        { fputs(", ", stdout); }
extern "C" void print_newline()      { fputc('\n', stdout); }

Please see examples with print_memref in test/mlir-cpu-runner/.

when I run the code utils.mlir I am getting error like this:
Fail to create MemoryBuffer for: %linalg_test_lib_dir/libmlir_runner_utils%shlibext
JIT session error: Symbols not found: [ _mlir_ciface_print_memref_f32, _mlir_ciface_print_memref_vector_4x4xf32 ]
Error: Failed to materialize symbols: { (main, { _mlir_print_memref_f32, _mlir_print_3d, _mlir_print_memref_vector_4x4xf32, print_0d, print_3d, vector_splat_2d, _mlir_vector_splat_2d, print_memref_f32, _mlir_print_0d, print_memref_vector_4x4xf32, _mlir_print_1d, print_1d }) }

Thank You

From the error message, it looks like you literally typed the option

   -shared-libs=%linalg_test_lib_dir/libmlir_runner_utils%shlibext 

but that is of course not going to work (the %vars are substituted for the right values by the test runner script). You will need to provide the full path. Something like the following, where the fullpathtolib depends on your build setup.

mlir-cpu-runner ....  \
  -shared-libs=**fullpathtolib**/libmlir_runner_utils.so

And then it will work!

Thank You .I want to convert this mlir to llvm and I want to execute this in x86.When I tried this it gave segmentation fault because of the print_memref_f32.This is my MLIR code:

module{
func @main() {
  %f = constant 2.00000e+00 : f32
  %A = alloc() : memref<16xf32>
  %B = memref_cast %A: memref<16xf32> to memref<?xf32>
  linalg.fill(%B, %f) : memref<?xf32>, f32
  %U = memref_cast %B :  memref<?xf32> to memref<*xf32>
  call @print_memref_f32(%U): (memref<*xf32>) -> ()
  dealloc %A : memref<16xf32>
  return
}
func @print_memref_f32(memref<*xf32>)
}

How can I solve this?
Thank You

Please do always mention how exactly you ran it (the entire command) and the output/crash trace you obtained.

1.To lower the code to LLVM dialect: mlir-opt ex.mlir -convert-linalg-to-loops -convert-linalg-to-llvm -convert-std-to-llvm >exllvm.mlir
2. To get LLVMIR : mlir-translate -mlir-to-llvmir ex1.mlir >exllvmir.ll
3.llvm-as exllvmir.ll -o test.bc
4. To run the code : lli test.bc
When I run lli I got error as :
Stack dump:
0. Program arguments: lli test.bc
#0 0x00007f8eba6234ff llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0x9814ff)
#1 0x00007f8eba6217b0 llvm::sys::RunSignalHandlers() (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0x97f7b0)
#2 0x00007f8eba623ac5 (/lib/x86_64-linux-gnu/libLLVM-10.so.1+0x981ac5)
#3 0x00007f8eb9c943c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)
Segmentation fault (core dumped)
Thank You

A few remarks:

  • You don’t need to invoke llvm-as as most LLVM tools accept .ll files as input.
  • instead of lli you could use clang to build your code as a binary I believe.
  • your code depends on the print_memref_f32 function: mlir-cpu-runner examples above are including libmlir_runner_utils.so to get it. This is the reason lli is crashing.

For example clang exllvmir.ll <path_to_build_dir>/lib/libmlir_runner_utils.so -o main followed by LD_LIBRARY_PATH=<path_to_build_dir>/lib ./main is working for me.

Its working for me now .Thank you

When I followed the same method for the following code :
func @main()
{
%c1= constant 0.500:f32
%A = alloc() : memref<1xf32>
%b = exp %c1 : f32
affine.store %b, %A[0] : memref<1xf32>

%U = memref_cast %A: memref<1xf32> to memref<*xf32>
call @print_memref_f32(%U): (memref<*xf32>) -> ()
return
}
func @print_memref_f32(memref<*xf32>)
I lower these code to LLVM dialect using :mlir-opt --lower-affine --convert-scf-to-std -convert-std-to-llvm
then I lowered to LLVM IR using mlir-translate -mlir-to-llvmir

When I run the .ll file using
clang exllvmir.ll <path_to_build_dir>/lib/libmlir_runner_utils.so -o main

I am getting error like this:
/usr/bin/ld: /tmp/n3-b2760a.o: undefined reference to symbol ‘expf@@GLIBC_2.27
/usr/bin/ld: /lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Thank You

ld kind of tell you about the issue: /usr/bin/ld: /lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line

The expf symbols is provided by libm, try adding -lm on the clang invocation?