Memref type conversion

Hi,
What would be the right way to convert memref of one type to another,

For example, If I want to convert memref of bf16 to f16, would the following be the right code?

%memref = gpu.alloc  () {gpu.alloc_shared} : memref<8xbf16>
%memref_f16 = builtin.unrealized_conversion_cast %memref : memref<8xbf16> to memref<8xf16>

Thank you.

Memref points to memory. You cannot generally just “cast” memory to obtain a different type. In particular, f16 and bf16 have different storage format, and you likely want to preserve their actual values rather than do bit-level reinterpret_cast equivalent. For that, you need to allocate a different memref and copy elements one-by-one with the appropriate cast in the middle.

Hello @ftynse,

Thank you so much.
My specific need is actually doing the reinterpret_cast.
To elaborate,
In my case, I have SPIR-V level function (intrinsic) that works on bf16. Unfortunately, we can’t pass bf16 to SPIR-V (not supported), hence I was planning to pass bf16 reinterpret casted as f16 that would be reinterpreted back to bf16 inside that intrinsic.

The reason, I didn’t want to do actual casting between bf16->f16->bf16 is that I may loose data.
Any suggestion?

Thank you so much again :slight_smile:

Then you can allocate a memref of i8 of the appropriate size and then call memref.view casting it to two different “view” memrefs with different element types.

Thank you so much, @ftynse .
Yep, this might work :slight_smile: