Type casting a buffer


#1

If I have a buffer of type int8, and I want to treat it as a buffer of int32, what is the best way to do it? Right now, I do

x32 = tvm.decl_buffer(x8.shape, 'int32', 'name', x8.data,
                      x8.strides, x8.elem_offset, x8.scope,
                      x8.data_alignment, x8.offset_factor)

i.e. create a new buffer with the same parameters as before, but with a different type. This is just for prototyping (the shapes are incorrect, etc.), but I was wondering if there is a better way of doing it.

What I really want is to do x8.vload(0, 'int32x32'), i.e. a load of a vector of i32 from a buffer of type int8.


#2

creating a buffer view is one way to do it.

On the other hand, making most buffers have a single element type will compiler’s life easy. Can you elaborate why do we want the alias int8 buffer as in32 instead of directly declaring it as int32?


#3

I’m trying to generate LLVM intrinsics for HVX instructions. A vector register doesn’t have a type, so in assembly it’s possible to do

  v0 = vadd(v0.b, v1.b)   // treat v0 as vector of bytes
  v1 = vsub(v0.w, v2.w)   // treat v0 as vector of words

Originally HVX was programmed using C intrinsics, and for each of these, there is an LLVM intrinsic. To allow the above assembly in C, all C and LLVM intrinsics are declared as working on vectors of int32 (regardless of what type they actually operate on).

As a consequence, if we have a buffer of int8 and we want to invoke an LLVM vector intrinsic for HVX, we have to use type int32x32.


#4

Maybe one bit stray from the point, I think we could implement it in CodeGen. Like this:

  // LLVM's HVX vector intrinsics don't include the type of the
  // operands, they all operate on vectors of 32 bit integers.
  for (size_t i = 0; i < arg_value.size(); i++) {
    auto intrinsic_arg_type = f->getFunctionType()->getParamType(i);
    if (arg_value[i]->getType() != intrinsic_arg_type) {
      if (intrinsic_arg_type->isVectorTy()) {
        arg_value[i] = builder_->CreateBitCast(arg_value[i], intrinsic_arg_type);
      }
    }
  }

Then we call LLVM intrinsic function and could get the correct assembly.