Convert C vectors->memref and memref -> C vectors

Hello again,

I have a second question today, a very practical one. For I/O, I’d like to:

  • convert plain C vectors (read from stdin) into MLIR memrefs
  • convert MLIR memrefs to C vectors (and output them to, say, stdout).

Is there some (more or less) standard MLIR code able to do this, so that I don’t re-invent the wheel (most certainly with bugs).

Best,
Dumitru

Do you want to convert to C data structure or do you want to do I/O? These things are not necessarily dependent on each other.

For C interop, we have https://github.com/llvm/llvm-project/blob/master/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h that provides a C+±compatible structure for memref descriptor that lets one access individual elements.

We have a printing function for (unranked) memref here https://github.com/llvm/llvm-project/blob/master/mlir/include/mlir/ExecutionEngine/RunnerUtils.h. I’m not aware of any parsing functions though.

1 Like

Hello,

I don’t understand how UnrankedMemRefType in CRunnerUtils.h works.
On the MLIR side, I declare this function : func @handle_memref(%a: memref<*xi32>) -> ()
On the CPP side, I define this one : void handle_memref(UnrankedMemRefType<int> memref) { }
Compilation works fine on both sides. But at linking time, I get an “undefined reference to handle_memref”.

Do you understand why ?

Regards

I do understand how that works, I wrote that code :wink: You need to mangle the function name as described in the documentation. E.g., if you want to declare a function called handle_memref in MLIR, it’s C counterpart must be called _mlir_ciface_handle_memref. You also need to either annotate this function for interface generation, or pass a global flag.

1 Like

The other solution would be, I guess, to directly convert MLIR/LLVMIR code into LLVM bytecode with the C++ calling convention. Is this possible? While looking at mlir-translate I can see no option allowing it.

Dumitru

Do you mean the Itanium C++ mangling? I don’t think it is possible in general, even if we could hard code some cases the generality of the mangling requires to have C++ type level information about every arguments, not only memrefs (and on Windows the mangling is again different).

Hello,

Maybe I misunderstand how the wrapping process works, but when I use the option --convert-std-to-llvm="use-bare-ptr-memref-call-conv=1" the external definition of handle_memref is not lowered to llvm, so I have 'llvm.call' op 'handle_memref' does not reference a valid LLVM function. Is this a bug (if it is, maybe it has been fixed since I updated my local LLVM) or a mistake of me ?

Regards

This is not the right option. This option will make statically-shaped (i.e. constant rank, sizes, strides and offset) convert to a raw data pointer, and ignore all the other memrefs. The option you need is called emit-c-wrappers. Or, alternatively, an llvm.emit_c_interface attribute on individual functions for which the interface should be generated.

1 Like