Vector API factories
Paul Sandoz
paul.sandoz at oracle.com
Mon Jul 24 19:24:00 UTC 2017
> On 17 Jul 2017, at 17:43, John Rose <john.r.rose at oracle.com> wrote:
>
> On Jul 17, 2017, at 5:20 PM, Paul Sandoz <paul.sandoz at oracle.com <mailto:paul.sandoz at oracle.com>> wrote:
>>
>>
>>> On 17 Jul 2017, at 16:55, Graves, Ian L <ian.l.graves at intel.com> wrote:
>>>
>>> Hi Paul,
>>>
>>> I love it!
>>>
>>> I think you're right that it makes a lot of sense to offload instantiation routines to species and make them semi-concrete by element type. This solves the issue of our element types being too unconstrained. This approach lets us fix the instantiatable-element-types by exposing allowed ones through this semi-concrete species. I think it also makes sense to refactor the vector construction methods to the Species class because instantiation is unique per-species and not per-vector. That's a good play.
>>>
>>
>> Ok. With that and separating FP and bitwise i think we have a reasonable API story.
>
> I have to say that I'm having trouble visualizing this, but it sounds OK.
Here is one such rendition:
http://cr.openjdk.java.net/~psandoz/panama/vector-draft-spec-refactor/webrev/ <http://cr.openjdk.java.net/~psandoz/panama/vector-draft-spec-refactor/webrev/>
(Might be easier just to apply the patch rather than browse it.)
This exposes out IntVector etc as public types, rather than pushing all type specific operations to the species, which is the place for factories. A FloatingPointVector or BitWiseVector is yet to be added. Covariant overrides ensure it’s possible to operate within the sub-type domain.
The generated code for Vector implementations is now relatively compact e.g.:
http://cr.openjdk.java.net/~psandoz/panama/vector-draft-spec-refactor/webrev/test/panama/vector-draft-spec/src/main/java/com/oracle/vector/DoubleVector.java.html <http://cr.openjdk.java.net/~psandoz/panama/vector-draft-spec-refactor/webrev/test/panama/vector-draft-spec/src/main/java/com/oracle/vector/DoubleVector.java.html>
http://cr.openjdk.java.net/~psandoz/panama/vector-draft-spec-refactor/webrev/test/panama/vector-draft-spec/src/main/java/com/oracle/vector/Double256Vector.java.html <http://cr.openjdk.java.net/~psandoz/panama/vector-draft-spec-refactor/webrev/test/panama/vector-draft-spec/src/main/java/com/oracle/vector/Double256Vector.java.html>
It should now be easier to replace the arrays used in the concrete implementations with super longs.
Paul.
> My main concern in the API design is that we allow suitable levels of
> shape abstraction for common use cases. That is, it should be possible
> to code a loop that works across all shapes if you are just arranging
> data. And if you are doing FP stuff, it should be possible to code a
> loop that works across all FP shapes (using a tighter bound on shape).
>
> The point of shape-genericity is it gives us a way to write algorithms
> that can be ported (even dynamically) to different vector sizes,
> depending on late-breaking conditions (even profiling). It also
> gives more portability across ISAs, since shape determines
> vector size, and if you allow generic shapes (subject perhaps
> to lane characteristics) you can write one loop for multiple
> platforms (that includes AVX2 vs. AVX512). Finally, shape
> polymorphism gives a "hook" for doing cleanup and setup
> of loops, if you have special auxiliary shapes for those
> tasks.
>
>>
>>>
>>>
>>>> Also i am wondering about the horizontal reductions now returning a Vector.
>>>> I can see why you did this, we really don’t want the primitive boxes being
>>>> exposed and you can easily reuse the result in further calculations.
>>>>
>>>> This works well for the fixed sized small vectors but what if we have different
>>>> kinds of shape that signify a larger size?
>>>>
>>>> An alternative is to move those reductions into the semi-concrete species. If
>>>> there is a method to construct a new vector with an element at the first
>>>> position then i bet the JIT can optimize to avoid register shuffling.
>>>>
>>>
>>> Reductions are somewhat sensitive to species. I can see how some operations that are more amenable to floating point (div, etc) would be better served to be placed in a more precise location. Right now I think you're right that it makes sense to limit this placement to species and not Vector.
>>>
>>> Would species form the basis of a future templated feature-set of Vector that could be dropped in? Something that could come out of the enhanced generics work in Valhalla?
>>>
>>
>> Yes, i think so. The lack of generics over primitives is steering me to keep Vector in the Vector world and species is the bridge to/from the Vector world.
>>
>> Generics over values/primitives would be beneficial API-wise. Depending on the language features supported it may be possible to declare methods specific to the type parameter(s), so Vector<float> would have FP methods, where as Vector<int> would not (and vice versa for bitwise ops), thereby not requiring specific FP and bitwise interfaces.
>
> Here's a stress test for shape genericity: Can you use the same loop code
> with different plugins for vectors of 2 doubles and vectors of 4 floats?
> If you can say "any FP shape", then you ought to be able to bind the
> same loop (on a machine where 128 bit vectors are native) to handle
> both kinds of vectors in the same algorithm.
>
> Going into the future, if we have genericity over byte/short/int/long, then
> the same effect might show up when programming with a vector stream
> of some lane type <any T>. The platform logic would select the vector
> size, and then the generic instantiation would expand the vector type
> using the size (and type) of the lane and the size of the vector (which
> is the shape-size). So instantiating the same shape on <short> will
> give four times as many lanes as instantiating it on <long>. I think
> this is all reasonable to do in the sort of specialization hooks we
> are looking at.
>
> Meanwhile, the selection of FP methods or not might be gated
> by whether you said <float> or <int>, etc. We have thought about
> allowing conditional methods, gated on various factors. FWIW,
> the specific tactic that appeals to me is declaring additional bounds
> on 'this' for selected methods, so in a Vector<any T,S> maybe there
> is an arctan function with an extra bound of Vector<any T extends
> FloatingPoint<T>>, S>. Or maybe add piecemeal constraints on
> in-scope type variables. There are many ways to pull it off; the big
> question is whether any of them are simple enough to analyze fully.
>
> — John
More information about the panama-dev
mailing list