[vector] RFC: Add scalable shapes for Arm Scalable Vector Extension

Ningsheng Jian (Arm Technology China) Ningsheng.Jian at arm.com
Tue Oct 9 06:56:59 UTC 2018


Hi Vladimir,

Thanks for your comments! 

> >> Overall, I like how it shapes out. There are some aspects I'd like to clarify
> though.
> >>
> >> The name (*ScalableVector) is slightly misleading to me, but I'm fine
> >> with it.  I interpret new shapes as representing vectors of maximally
> >> supported size at runtime without specifying the actual size.
> >>
> >
> > I am happy to change the name if you have some suggestion. The new shapes
> are representing current (SVE) hardware supported (max) vector register size,
> and the actual size is known at runtime.
> 
> Yes, I'd like the names to clearly manifest it's the vector of maximum size
> available at runtime. Maybe *MaxVector, but I'm not too happy with it as well.
> 

OK, but I think Max could not imply the point of one shape to fit multiple sizes. I was thinking about VL (variable length), but finally used current name to align with SVE (Scalable Vector Extension).

> >> New shapes don't interoperate well with existing ones, so unless you
> >> change how vector shapes are checked (==), at runtime scalable and
> >> fixed shape variants shouldn't meet. That leads to the next question:
> >> how do you expect vector shape changing operation working (resize(),
> rebracket(), cast()) with new variants?
> >>
> >
> > Those vector changing operations are in my TODO list. The scalable shapes are
> actually fixed length shape during runtime, so I think it is possible to implement
> those operations. But I am still don't quite understand the motivation and use
> cases of  those vector shape changing APIs. Could you please help to explain a
> bit?
> 
> There are 4 methods which change vector shape: resize/rebracket/reshape and
> cast.
> 
>    (1) Vector.resize() changes only vector length (either shrinking or
> widening) without touching element types:
>    Int64Vector <-> Int128Vector <-> Int256Vector <-> Int512Vector
> 
>    Javadoc for Shape.resize() says [2]:
>      * The lane elements of the input vector are copied without
>      * modification to the resulting vector, but those lane elements, before
>      * copying, may be truncated if the vector length is greater than this
>      * species length, or appended to with default element values if the
>      * vector length is less than this species length.
> 
> 
>    (2) Vector.rebracket() changes only vector element type leaving vector size
> intact
>    Byte256Vector <-> Short256Vector <-> Int256Vector <-> Long256Vector
> 
>    Javadoc says [3]:
>      * The underlying bits of the input vector are copied without
>      * modification to the resulting vector.
> 
> 
>    (3) Vector.reshape generalizes resize() & rebracket() and enables arbitrary
> conversions between vector shapes:
>    Byte64Vector <-> ... <-> Double512Vector
>     * The underlying bits of the input vector are copied to the resulting
>     * vector without modification, but those bits, before copying, may be
>     * truncated if the vector bit size is greater than this species bit
>     * size, or appended to with zero bits if the vector bit size is less
>     * than this species bit size.
> 
> 
>    (4) Vector.cast() allows arbitrary casts between vector shapes
>    Byte64Vector <-> ... <-> Double512Vector
> 
>    Javadoc for Shape.cast() says [4]:
>      * For each input vector lane up to the length of the input vector or
>      * this species, which ever is the minimum, and where {@code N} is the
>      * vector lane index, the element at index {@code N} of primitive type
>      * {@code F} is converted, according to primitive conversion rules
>      * specified by the Java Language Specification, to a value of primitive
>      * type {@code E} and placed into the resulting vector at lane index
>      * {@code N}.  If this species length is greater than the input
>      * vector length then the default primitive value is placed into
>      * subsequent lanes of the resulting vector.
> 
> Right now, resize(), rebracket(), and cast() are intrinsified on x86
> while reshape() is not.
> 
> 
> So, my question boils down to: how vector shape checks are expected to
> work on *ScalableVectors in presence of operations which change vector size.
> 
> For example, IntScalableVector.rebracket() => LongScalableVector which
> is fine, but ISV.resize() => ISV is what I'm concerned about and
> existing checks aren't enough for *ScalableVectors unless you check
> their length at runtime.
> 

Thanks for the detailed explanation. So, which checks do you mean here? Do you mean this [1]? I find that current Java implementations already has some runtime length checks. One thing we need to consider is the ambiguity between existing sizes and scalable size. Current VectorIntrinsics.reinterpret() just tries to get the shape from size (library_call.cpp:get_exact_klass_for_vector_box) instead of getting the real class from input argument, which will lead to ClassCastException. Maybe that can be fixed by adding real klass type to the reinterpret function.

[1] http://hg.openjdk.java.net/panama/dev/file/e8f06cc3fe82/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java#l1513

Thanks,
Ningsheng




More information about the panama-dev mailing list