[vector] reshape, resize, rebracket, cast

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Mon Dec 3 23:50:16 UTC 2018



>> As you pointed out, `resize`->`reshape` may be questionable, but I'm 
>> in favor of `reshape`. Though Shape is all about vector bit-width now, 
>> it may change in the future (S_Max_BIT is a good example where it may 
>> go).
>>
>> I especially like `reinterpretet(Class<F>)`, but I'm curious whether 
>> there's a better name to communicate there are *both* bit-level 
>> reinterpretation and reshape/resizing happening in case of 
>> `reinterpret(Species<F>)`?
> 
> A vector has two sizes -- number of lanes, and number of bits -- and in 
> different situations, one or the other is the more natural measure. 
> Whenever we are reinterpreting the bits from one element type to 
> another, it is likely that one of these is going to change. So 
> reshape/resize is a natural consequence of _all_ of these ops. >
>> It looks attractive to completely separate element & shape 
>> transformations (reinterpret(Class)/cast(Class) + reshape(Shape)), but 
>> there are some drawbacks.
> 
> Yeah, that was the mail I started to write, but then erased because it 
> ran off the road :)   My goal here is more to (a) put these ops where 
> they belong (Vector, not Species), and (b) refactor the naming so its 
> more obvious what is going on.  I think the ops that have been picked 
> are a sensible set with sensible semantics, but they're just surfaced 
> slightly wrong.
> 
>> The nice thing about operations on Species is their totality: once you 
>> have an instance of Species in your hands, it's possible to convert 
>> (either reinterpret or cast) any Vector instance to it. You lose that 
>> when switching to `cast(Class)`: widening per-element casts can easily 
>> exceed maximum vector size supported (both in hardware & 
>> implementation): e.g, Vector<Byte,S512Bit>.cast(Integer.class) => 
>> Vector<Integer,S2048Bit>.
> 
> OK.  So what you're saying is, while it seems to be attractive to leave 
> off one or the other parameter, we're better off using Species 
> consistently.  Which means that every re-* operation may change the lane 
> size, or bit size, or both.
> 
> So refined proposal:
> 
>      class Vector<E> {
>          Vector<E> reshape(Species<E> sp)
>          <F> Vector<F> reintepret(Species<F> sp)
>          <F> Vector<F> cast(Species<F> sp)
>      }

Looks good. Though it's less clear what `reshape` does, I like the 
similarity between different kinds of vector shape transformations.

FTR I was fine with `reshape(Shape)` as well. My comment was more about 
further steps in that direction.

> Reshape is purely about padding/truncating.  Reinterpret is about 
> bit-reinterpretation, plus padding/truncating.  (In this light, then 
> reshape is just a degenerate case of reinterpret, but probably useful 
> enough to carry its weight anyway.)  Cast is about elementwise 
> conversion, which won't change the lane length, but could change the 
> shape.  In other words, on all these operations, we should expect one, 
> or the other, size to change.

There's also place for element type change without size (either lane- or 
bit-) change. There are no unsigned element types supported yet, but 
once those are introduced, conversions (reinterpret/cast) between 
signed/unsigned vector variants won't involve size change.

Best regards,
Vladimir Ivanov




More information about the panama-dev mailing list