[vector] Prototype of apply() method on Vector
John Rose
john.r.rose at oracle.com
Thu Jun 13 22:54:31 UTC 2019
I want put a stake in the ground, moving toward these goals,
not getting there immediately, but solving an important
tactical problem.
Right now, the Vector API has too many methods.
I count 128 methods in FloatVector. There are 95
arithmetic methods, and half of those (44) are
seldom-used (but important) transcendentals.
There are several versions of even important
methods such as add, min, abs, etc.
Most of these methods can be folded into a handful
op-driven method of the form Kishor has prototyped.
This will immediately simplify the API, making it less
bulky and more focused and browsable, without loss
of expressiveness or performance.
So, here's what I'm doing:
Vector<E> lanewise(VectorOperators.Unary op);
Vector<E> lanewise(VectorOperators.Unary op, VectorMask<E> o);
Vector<E> lanewise(VectorOperators.Binary op, Vector<E> v);
Vector<E> lanewise(VectorOperators.Binary op, Vector<E> v, VectorMask<E> o);
VectorMask<E> compare(VectorOperators.Comparison op, Vector<E> v);
<F> Vector<F> convert(VectorOperators.Conversion<E,F> conv, int part);
<F> Vector<F> convertShape(VectorOperators.Conversion<E,F> conv, VectorSpecies<F>, int part);
(The meaning of convertShape vs. convert, and the part
number, will be described elsewhere. Briefly, they support
a default mode of shape-invariant programming, with an
overall story for managing partial results from results
which overflow the size of the input shape.)
Example uses:
import static VectorOperators.*;
public final FloatVector min(float s) {
return lanewise(MIN, s);
}
VectorMask<Integer> badMask = iota.compare(GE, indexLimit);
VectorMask<Integer> badMask2 = iota.compare(LT, firstGoodIndex);
In FloatVector etc. there are additional versions of these
operations, with sharpened types and optional broadcasting
of scalars.
FloatVector lanewise(VectorOperators.Unary op);
FloatVector lanewise(VectorOperators.Unary op, VectorMask<Float> m);
FloatVector lanewise(VectorOperators.Binary op, FloatVector v);
FloatVector lanewise(VectorOperators.Binary op, FloatVector v, VectorMask<Float> m);
FloatVector lanewise(VectorOperators.Binary op, float s);
FloatVector lanewise(VectorOperators.Binary op, float s, VectorMask<Float> m);
VectorMask<Float> compare(VectorOperators.Comparison op, float v);
The 8 reductions can also be collapsed into two methods:
public abstract float reduce(VectorOperators.Associative op);
public abstract float reduce(VectorOperators.Associative op, VectorMask<Float> m);
There is a snapshot of the current VectorOperators.java file here:
http://cr.openjdk.java.net/~jrose/vectors/VectorOperators.java
The vector operators are non-semantic tokens. That is, they
"know" their names and kinds, but don't have any way to apply
themselves to scalars. (Nobody needs or wants to do that, yet!)
This keeps them very simple.
It's a good tactical move, for the reasons noted above.
And it unlocks three strategic advantages:
1. It simplifies code generation, since the operator tokens
can hold (secretly) the opcodes used all the way down through
the back end of the JITs.
2. It allows us to add more operations cheaply, by adding more
constants to VectorOperators, or by having "secret" operators
that are published somewhere else. Think unsigned comparisons
or conversions, which are common in vector ISAs but not native
to Java. They can (and do!) have their own operator tokens.
3. It provides a needed foundation for lambda cracking of vector
kernels. If you want to crack a Java lambda, you need a name
for the "+" in "x+y" when you see it in the lambda body. The
vector operator tokens can fill this need.
Comments?
— John
P.S. Here are the 128 methods on FloatVector:
public static FloatVector zero(VectorSpecies<Float> species)
public static FloatVector fromByteArray(VectorSpecies<Float> species, byte[] a, int offset)
public static FloatVector fromByteArray(VectorSpecies<Float> species, byte[] a, int offset, VectorMask<Float> m)
public static FloatVector fromArray(VectorSpecies<Float> species, float[] a, int offset)
public static FloatVector fromArray(VectorSpecies<Float> species, float[] a, int offset, VectorMask<Float> m)
public static FloatVector fromArray(VectorSpecies<Float> species, float[] a, int a_offset, int[] indexMap, int i_offset)
public static FloatVector fromArray(VectorSpecies<Float> species, float[] a, int a_offset, VectorMask<Float> m, int[] indexMap, int i_offset)
public static FloatVector fromByteBuffer(VectorSpecies<Float> species, ByteBuffer bb, int offset)
public static FloatVector fromByteBuffer(VectorSpecies<Float> species, ByteBuffer bb, int offset, VectorMask<Float> m)
public static FloatVector broadcast(VectorSpecies<Float> species, float e)
public static FloatVector scalars(VectorSpecies<Float> species, float... es)
public static final FloatVector single(VectorSpecies<Float> species, float e)
public static FloatVector random(VectorSpecies<Float> species)
public abstract FloatVector add(Vector<Float> v);
public abstract FloatVector add(float s);
public abstract FloatVector add(Vector<Float> v, VectorMask<Float> m);
public abstract FloatVector add(float s, VectorMask<Float> m);
public abstract FloatVector sub(Vector<Float> v);
public abstract FloatVector sub(float s);
public abstract FloatVector sub(Vector<Float> v, VectorMask<Float> m);
public abstract FloatVector sub(float s, VectorMask<Float> m);
public abstract FloatVector mul(Vector<Float> v);
public abstract FloatVector mul(float s);
public abstract FloatVector mul(Vector<Float> v, VectorMask<Float> m);
public abstract FloatVector mul(float s, VectorMask<Float> m);
public abstract FloatVector neg();
public abstract FloatVector neg(VectorMask<Float> m);
public abstract FloatVector abs();
public abstract FloatVector abs(VectorMask<Float> m);
public abstract FloatVector min(Vector<Float> v);
public abstract FloatVector min(Vector<Float> v, VectorMask<Float> m);
public abstract FloatVector min(float s);
public abstract FloatVector max(Vector<Float> v);
public abstract FloatVector max(Vector<Float> v, VectorMask<Float> m);
public abstract FloatVector max(float s);
public abstract VectorMask<Float> equal(Vector<Float> v);
public abstract VectorMask<Float> equal(float s);
public abstract VectorMask<Float> notEqual(Vector<Float> v);
public abstract VectorMask<Float> notEqual(float s);
public abstract VectorMask<Float> lessThan(Vector<Float> v);
public abstract VectorMask<Float> lessThan(float s);
public abstract VectorMask<Float> lessThanEq(Vector<Float> v);
public abstract VectorMask<Float> lessThanEq(float s);
public abstract VectorMask<Float> greaterThan(Vector<Float> v);
public abstract VectorMask<Float> greaterThan(float s);
public abstract VectorMask<Float> greaterThanEq(Vector<Float> v);
public abstract VectorMask<Float> greaterThanEq(float s);
public abstract FloatVector blend(Vector<Float> v, VectorMask<Float> m);
public abstract FloatVector blend(float s, VectorMask<Float> m);
public abstract FloatVector rearrange(Vector<Float> v,
public abstract FloatVector rearrange(VectorShuffle<Float> m);
public abstract FloatVector reshape(VectorSpecies<Float> s);
public abstract FloatVector rotateLanesLeft(int i);
public abstract FloatVector rotateLanesRight(int i);
public abstract FloatVector shiftLanesLeft(int i);
public abstract FloatVector shiftLanesRight(int i);
public abstract FloatVector div(Vector<Float> v);
public abstract FloatVector div(float s);
public abstract FloatVector div(Vector<Float> v, VectorMask<Float> m);
public abstract FloatVector div(float s, VectorMask<Float> m);
public abstract FloatVector sqrt();
public FloatVector sqrt(VectorMask<Float> m)
public FloatVector tan()
public FloatVector tan(VectorMask<Float> m)
public FloatVector tanh()
public FloatVector tanh(VectorMask<Float> m)
public FloatVector sin()
public FloatVector sin(VectorMask<Float> m)
public FloatVector sinh()
public FloatVector sinh(VectorMask<Float> m)
public FloatVector cos()
public FloatVector cos(VectorMask<Float> m)
public FloatVector cosh()
public FloatVector cosh(VectorMask<Float> m)
public FloatVector asin()
public FloatVector asin(VectorMask<Float> m)
public FloatVector acos()
public FloatVector acos(VectorMask<Float> m)
public FloatVector atan()
public FloatVector atan(VectorMask<Float> m)
public FloatVector atan2(Vector<Float> v)
public abstract FloatVector atan2(float s);
public FloatVector atan2(Vector<Float> v, VectorMask<Float> m)
public abstract FloatVector atan2(float s, VectorMask<Float> m);
public FloatVector cbrt()
public FloatVector cbrt(VectorMask<Float> m)
public FloatVector log()
public FloatVector log(VectorMask<Float> m)
public FloatVector log10()
public FloatVector log10(VectorMask<Float> m)
public FloatVector log1p()
public FloatVector log1p(VectorMask<Float> m)
public FloatVector pow(Vector<Float> v)
public abstract FloatVector pow(float s);
public FloatVector pow(Vector<Float> v, VectorMask<Float> m)
public abstract FloatVector pow(float s, VectorMask<Float> m);
public FloatVector exp()
public FloatVector exp(VectorMask<Float> m)
public FloatVector expm1()
public FloatVector expm1(VectorMask<Float> m)
public abstract FloatVector fma(Vector<Float> v1, Vector<Float> v2);
public abstract FloatVector fma(float s1, float s2);
public FloatVector fma(Vector<Float> v1, Vector<Float> v2, VectorMask<Float> m)
public abstract FloatVector fma(float s1, float s2, VectorMask<Float> m);
public FloatVector hypot(Vector<Float> v)
public abstract FloatVector hypot(float s);
public FloatVector hypot(Vector<Float> v, VectorMask<Float> m)
public abstract FloatVector hypot(float s, VectorMask<Float> m);
public abstract void intoByteArray(byte[] a, int ix);
public abstract void intoByteArray(byte[] a, int ix, VectorMask<Float> m);
public abstract void intoByteBuffer(ByteBuffer bb, int ix);
public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Float> m);
public abstract float addLanes();
public abstract float addLanes(VectorMask<Float> m);
public abstract float mulLanes();
public abstract float mulLanes(VectorMask<Float> m);
public abstract float minLanes();
public abstract float minLanes(VectorMask<Float> m);
public abstract float maxLanes();
public abstract float maxLanes(VectorMask<Float> m);
public abstract float lane(int i);
public abstract FloatVector with(int i, float e);
public final float[] toArray()
public abstract void intoArray(float[] a, int offset);
public abstract void intoArray(float[] a, int offset, VectorMask<Float> m);
public abstract void intoArray(float[] a, int a_offset, int[] indexMap, int i_offset);
public abstract void intoArray(float[] a, int a_offset, VectorMask<Float> m, int[] indexMap, int i_offset);
public abstract VectorSpecies<Float> species();
More information about the panama-dev
mailing list