[vector] Prototype of apply() method on Vector

Kharbas, Kishor kishor.kharbas at intel.com
Tue Feb 19 22:02:49 UTC 2019


Thanks Brian for looking at this. Some comments inline,

> -----Original Message-----
> From: Brian Goetz [mailto:brian.goetz at oracle.com]
> Sent: Tuesday, February 19, 2019 12:54 PM
> To: Kharbas, Kishor <kishor.kharbas at intel.com>; panama-
> dev at openjdk.java.net
> Subject: Re: [vector] Prototype of apply() method on Vector
> 
> This is a nice start!  Thanks for plumbing it through for at least one op, and
> verifying the resulting code.  As far as I can see, you add two vectors with
> 
>      v3 = v1.op(BOp.ADD, v2)
> 
> It is encouraging to see that this doesn't affect our ability to inline deep
> enough to generate good code.
> 
> This technique has two main benefits:
> 
>   - Reduces the API surface, by allowing operations like ADD to support all the
> addable types of vectors, rather than having N add methods
>   - Enabling the building of higher-level operations that can deal with the "tail"
> computation.
> 
> The latter is where I see the major value; vectorized APIs won't want to
> expose vectors, they'll want to let users pass in arrays of values and do
> vectorized operations over them.  Because the array size may not be an
> integral multiple of the lane count, there may be a "tail" of values that have
> to be computed "the old fashioned way".  And that's not the really bad part;
> the really bad part is that the main vectorized loop and the "tail" loop will
> spell "add" differently from each other.  And having two ways to say the
> same thing is a bug waiting to happen.
> 

Tail loop written with the current implementation would look something like this,

c[i] = UOp.NEG.apply(BOp.ADD.apply(BOp.MUL.apply(a[i], a[i]), BOp.MUL.apply(b[i], b[i])));

I am afraid this is not very similar to vector operations below, but it is consistent in using the same Operators defined in Vector package (and not Java operations).

We could add new method - 'apply(Vector, Vector)', to vector operators, which would allow vector operations to written as above.

ADD (VectorIntrinsics.VECTOR_OP_ADD) {
    /* new method*/
    <E> Vector<E> apply(Vector<E> opd1, Vector<E> opd2) {
        return opd1.apply(this, opd2);
    }
    ...
}

Now, vector operations can be written as,
UOp.NEG.apply(BOp.ADD.apply(BOp.MUL.apply(av, av), BOp.MUL.apply(bv, bv))).intoArray(c, i); 

Or with a little indentation as,
UOp.NEG.apply(
	BOp.ADD.apply(
		BOp.MUL.apply(av, av), 
		BOp.MUL.apply(bv, bv)))
	).intoArray(c, i);


But I feel this looks a little awkward.

> Rewriting
> 
>              av.mul(av)
>                      .add(bv.mul(bv))
>                      .neg()
>                      .intoArray(c, i);
> 
> to
> 
>              av.apply(BOp.MUL, av)
>                      .apply(BOp.ADD, bv.apply(BOp.MUL, bv))
>                      .apply(UOp.NEG)
>                      .intoArray(c, i);
> 
> is not going to be the user's first choice, but may be tolerable (especially if we
> view this library as a low-level tool for others to build higher-level vectorized
> operations atop.)
> 
> I see this approach as meeting up with the other main API discussion
> direction, which is: positioning the key abstractions (species, vectors) to be
> ready to be values as soon as Valhalla is ready.  This will have some effect on
> the API, such as flattening out class inheritance; I suspect these two
> transformations will interact nontrivially (maybe in a good way, maybe not.)
> 
> Where I would say we are is:
> 
>   - It's really great that we prototyped this, and discovered that this
> transformation of the code is not, in itself, an impediment to efficient
> compilation;
>   - It promises a way out of the "tail loop" problem;
>   - It might be something users can live with;
>   - Let's set it on the shelf for a bit, and let the value-ification of the API play
> out a bit more, and look back at this.
> 
> Does that sound like a good plan?

Yes I like the plan!

Thank you,
Kishor

> 
> On 2/16/2019 7:02 PM, Kharbas, Kishor wrote:
> > Hi Brian, John, Vladimir and others,
> > There has been discussion on this mail thread before (did not find the mail
> thread to reply to it) about having an apply() on vectors.
> >
> > The idea is to reduce the api surface by defining a apply() method
> > which takes the kind of operation to be performed. Here is an attempt
> > to prototype this method,
> > http://cr.openjdk.java.net/~kkharbas/vector-api/webrev-apply.00
> >
> > This prototype does generate optimal vector code just like operation
> specific methods.
> >
> > Please let me know your thoughts.
> >
> > Thanks,
> > Kishor



More information about the panama-dev mailing list