< prev index next >
src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java
Print this page
rev 54658 : refactored mask and shuffle creation methods, moved classes to top-level
*** 28,38 ****
--- 28,42 ----
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Stable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+ import java.util.Objects;
+ import java.util.function.Function;
import java.util.function.IntUnaryOperator;
+ import java.util.function.UnaryOperator;
+
import jdk.incubator.vector.*;
/**
* A {@code Vector} is designed for use in computations that can be transformed
* by a runtime compiler, on supported hardware, to Single Instruction Multiple
*** 47,57 ****
* {@code byte}, {@code short}, {@code int}, {@code long}, {@code float}, or
* {@code double}). The type variable {@code E} corresponds to the boxed
* element type, specifically the class that wraps a value of {@code e} in an
* object (such the {@code Integer} class that wraps a value of {@code int}}.
* A Vector has a {@link #shape() shape} {@code S}, extending type
! * {@link Shape}, that governs the total {@link #bitSize() size} in bits
* of the sequence of values.
* <p>
* The number of values in the sequence is referred to as the Vector
* {@link #length() length}. The length also corresponds to the number of
* Vector lanes. The lane element at lane index {@code N} (from {@code 0},
--- 51,61 ----
* {@code byte}, {@code short}, {@code int}, {@code long}, {@code float}, or
* {@code double}). The type variable {@code E} corresponds to the boxed
* element type, specifically the class that wraps a value of {@code e} in an
* object (such the {@code Integer} class that wraps a value of {@code int}}.
* A Vector has a {@link #shape() shape} {@code S}, extending type
! * {@link VectorShape}, that governs the total {@link #bitSize() size} in bits
* of the sequence of values.
* <p>
* The number of values in the sequence is referred to as the Vector
* {@link #length() length}. The length also corresponds to the number of
* Vector lanes. The lane element at lane index {@code N} (from {@code 0},
*** 72,89 ****
* of element types, {@link ByteVector}, {@link ShortVector},
* {@link IntVector} {@link LongVector}, {@link FloatVector}, and
* {@link DoubleVector}.
* <p>
* Vector values, instances of Vector, are created from a special kind of
! * factory called a {@link Species}. A Species has an
* element type and shape and creates Vector values of the same element type
* and shape.
! * A species can be {@link Species#of(Class, Shape)} obtained} given an element
* type and shape, or a preferred species can be
! * {@link Species#ofPreferred(Class)} obtained} given just an element type where the most
* optimal shape is selected for the current platform. It is recommended that
! * Species instances be held in {@code static final} fields for optimal creation
* and usage of Vector values by the runtime compiler.
* <p>
* Vector operations can be grouped into various categories and their behaviour
* generally specified as follows:
* <ul>
--- 76,93 ----
* of element types, {@link ByteVector}, {@link ShortVector},
* {@link IntVector} {@link LongVector}, {@link FloatVector}, and
* {@link DoubleVector}.
* <p>
* Vector values, instances of Vector, are created from a special kind of
! * factory called a {@link VectorSpecies}. A VectorSpecies has an
* element type and shape and creates Vector values of the same element type
* and shape.
! * A species can be {@link VectorSpecies#of(Class, VectorShape)} obtained} given an element
* type and shape, or a preferred species can be
! * {@link VectorSpecies#ofPreferred(Class)} obtained} given just an element type where the most
* optimal shape is selected for the current platform. It is recommended that
! * VectorSpecies instances be held in {@code static final} fields for optimal creation
* and usage of Vector values by the runtime compiler.
* <p>
* Vector operations can be grouped into various categories and their behaviour
* generally specified as follows:
* <ul>
*** 175,185 ****
* EVector<S> b = ...;
* boolean[] ar = new boolean[a.length()];
* for (int i = 0; i < a.length(); i++) {
* ar[i] = scalar_binary_test_op(a.get(i), b.get(i));
* }
! * Mask<E> r = a.species().maskFromArray(ar, 0);
* }</pre>
*
* Unless otherwise specified the two input vectors and result mask will have
* the same element type and shape.
*
--- 179,189 ----
* EVector<S> b = ...;
* boolean[] ar = new boolean[a.length()];
* for (int i = 0; i < a.length(); i++) {
* ar[i] = scalar_binary_test_op(a.get(i), b.get(i));
* }
! * VectorMask<E> r = a.species().maskFromArray(ar, 0);
* }</pre>
*
* Unless otherwise specified the two input vectors and result mask will have
* the same element type and shape.
*
*** 189,200 ****
* the scalar operation is applied to elements taken from input vectors at the
* same lane, and if appropriate applied to the result vector at the same lane.
* A further category of operation is a cross-lane vector operation where lane
* access is defined by the arguments to the operation. Cross-lane operations
* generally rearrange lane elements, for example by permutation (commonly
! * controlled by a {@link Shuffle}) or by blending (commonly controlled by a
! * {@link Mask}). Such an operation explicitly specifies how it rearranges lane
* elements.
* </ul>
*
* If a vector operation is represented as an instance method then first input
* vector corresponds to {@code this} vector and subsequent input vectors are
--- 193,204 ----
* the scalar operation is applied to elements taken from input vectors at the
* same lane, and if appropriate applied to the result vector at the same lane.
* A further category of operation is a cross-lane vector operation where lane
* access is defined by the arguments to the operation. Cross-lane operations
* generally rearrange lane elements, for example by permutation (commonly
! * controlled by a {@link VectorShuffle}) or by blending (commonly controlled by a
! * {@link VectorMask}). Such an operation explicitly specifies how it rearranges lane
* elements.
* </ul>
*
* If a vector operation is represented as an instance method then first input
* vector corresponds to {@code this} vector and subsequent input vectors are
*** 205,215 ****
* the operation explicitly specifies how it processes the lane elements of
* input vectors, and where appropriate expresses the behaviour using
* pseudocode.
*
* <p>
! * Many vector operations provide an additional {@link Mask mask} accepting
* variant.
* The mask controls which lanes are selected for application of the scalar
* operation. Masks are a key component for the support of control flow in
* vector computations.
* <p>
--- 209,219 ----
* the operation explicitly specifies how it processes the lane elements of
* input vectors, and where appropriate expresses the behaviour using
* pseudocode.
*
* <p>
! * Many vector operations provide an additional {@link VectorMask mask} accepting
* variant.
* The mask controls which lanes are selected for application of the scalar
* operation. Masks are a key component for the support of control flow in
* vector computations.
* <p>
*** 238,248 ****
* For convenience many vector operations, of arity greater than one, provide
* an additional scalar accepting variant. This variant accepts compatible
* scalar values instead of vectors for the second and subsequent input vectors,
* if any.
* Unless otherwise specified the scalar variant behaves as if each scalar value
! * is transformed to a vector using the vector Species
* {@code broadcast} operation, and
* then the vector accepting vector operation is applied using the transformed
* values.
*
* <p>
--- 242,252 ----
* For convenience many vector operations, of arity greater than one, provide
* an additional scalar accepting variant. This variant accepts compatible
* scalar values instead of vectors for the second and subsequent input vectors,
* if any.
* Unless otherwise specified the scalar variant behaves as if each scalar value
! * is transformed to a vector using the vector species
* {@code broadcast} operation, and
* then the vector accepting vector operation is applied using the transformed
* values.
*
* <p>
*** 260,270 ****
/**
* Returns the species of this vector.
*
* @return the species of this vector
*/
! public abstract Species<E> species();
/**
* Returns the primitive element type of this vector.
*
* @return the primitive element type of this vector
--- 264,274 ----
/**
* Returns the species of this vector.
*
* @return the species of this vector
*/
! public abstract VectorSpecies<E> species();
/**
* Returns the primitive element type of this vector.
*
* @return the primitive element type of this vector
*** 281,291 ****
/**
* Returns the shape of this vector.
*
* @return the shape of this vector
*/
! public Shape shape() { return species().shape(); }
/**
* Returns the number of vector lanes (the length).
*
* @return the number of vector lanes
--- 285,295 ----
/**
* Returns the shape of this vector.
*
* @return the shape of this vector
*/
! public VectorShape shape() { return species().shape(); }
/**
* Returns the number of vector lanes (the length).
*
* @return the number of vector lanes
*** 321,331 ****
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of adding this vector to the given vector
*/
! public abstract Vector<E> add(Vector<E> v, Mask<E> m);
/**
* Subtracts an input vector from this vector.
* <p>
* This is a vector binary operation where the primitive subtraction
--- 325,335 ----
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of adding this vector to the given vector
*/
! public abstract Vector<E> add(Vector<E> v, VectorMask<E> m);
/**
* Subtracts an input vector from this vector.
* <p>
* This is a vector binary operation where the primitive subtraction
*** 345,355 ****
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of subtracting the input vector from this vector
*/
! public abstract Vector<E> sub(Vector<E> v, Mask<E> m);
/**
* Multiplies this vector with an input vector.
* <p>
* This is a vector binary operation where the primitive multiplication
--- 349,359 ----
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of subtracting the input vector from this vector
*/
! public abstract Vector<E> sub(Vector<E> v, VectorMask<E> m);
/**
* Multiplies this vector with an input vector.
* <p>
* This is a vector binary operation where the primitive multiplication
*** 369,379 ****
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of multiplying this vector with the input vector
*/
! public abstract Vector<E> mul(Vector<E> v, Mask<E> m);
/**
* Negates this vector.
* <p>
* This is a vector unary operation where the primitive negation operation
--- 373,383 ----
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of multiplying this vector with the input vector
*/
! public abstract Vector<E> mul(Vector<E> v, VectorMask<E> m);
/**
* Negates this vector.
* <p>
* This is a vector unary operation where the primitive negation operation
*** 390,400 ****
* ({@code -})is applied to lane elements.
*
* @param m the mask controlling lane selection
* @return the negation this vector
*/
! public abstract Vector<E> neg(Mask<E> m);
// Maths from java.math
/**
* Returns the modulus of this vector.
--- 394,404 ----
* ({@code -})is applied to lane elements.
*
* @param m the mask controlling lane selection
* @return the negation this vector
*/
! public abstract Vector<E> neg(VectorMask<E> m);
// Maths from java.math
/**
* Returns the modulus of this vector.
*** 414,424 ****
* {@code (a) -> (a < 0) ? -a : a} is applied to lane elements.
*
* @param m the mask controlling lane selection
* @return the modulus this vector
*/
! public abstract Vector<E> abs(Mask<E> m);
/**
* Returns the minimum of this vector and an input vector.
* <p>
* This is a vector binary operation where the operation
--- 418,428 ----
* {@code (a) -> (a < 0) ? -a : a} is applied to lane elements.
*
* @param m the mask controlling lane selection
* @return the modulus this vector
*/
! public abstract Vector<E> abs(VectorMask<E> m);
/**
* Returns the minimum of this vector and an input vector.
* <p>
* This is a vector binary operation where the operation
*** 438,448 ****
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the minimum of this vector and the input vector
*/
! public abstract Vector<E> min(Vector<E> v, Mask<E> m);
/**
* Returns the maximum of this vector and an input vector.
* <p>
* This is a vector binary operation where the operation
--- 442,452 ----
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the minimum of this vector and the input vector
*/
! public abstract Vector<E> min(Vector<E> v, VectorMask<E> m);
/**
* Returns the maximum of this vector and an input vector.
* <p>
* This is a vector binary operation where the operation
*** 462,472 ****
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the maximum of this vector and the input vector
*/
! public abstract Vector<E> max(Vector<E> v, Mask<E> m);
// Comparisons
/**
* Tests if this vector is equal to an input vector.
--- 466,476 ----
*
* @param v the input vector
* @param m the mask controlling lane selection
* @return the maximum of this vector and the input vector
*/
! public abstract Vector<E> max(Vector<E> v, VectorMask<E> m);
// Comparisons
/**
* Tests if this vector is equal to an input vector.
*** 476,486 ****
*
* @param v the input vector
* @return the result mask of testing if this vector is equal to the input
* vector
*/
! public abstract Mask<E> equal(Vector<E> v);
/**
* Tests if this vector is not equal to an input vector.
* <p>
* This is a vector binary test operation where the primitive not equals
--- 480,490 ----
*
* @param v the input vector
* @return the result mask of testing if this vector is equal to the input
* vector
*/
! public abstract VectorMask<E> equal(Vector<E> v);
/**
* Tests if this vector is not equal to an input vector.
* <p>
* This is a vector binary test operation where the primitive not equals
*** 488,498 ****
*
* @param v the input vector
* @return the result mask of testing if this vector is not equal to the
* input vector
*/
! public abstract Mask<E> notEqual(Vector<E> v);
/**
* Tests if this vector is less than an input vector.
* <p>
* This is a vector binary test operation where the primitive less than
--- 492,502 ----
*
* @param v the input vector
* @return the result mask of testing if this vector is not equal to the
* input vector
*/
! public abstract VectorMask<E> notEqual(Vector<E> v);
/**
* Tests if this vector is less than an input vector.
* <p>
* This is a vector binary test operation where the primitive less than
*** 500,510 ****
*
* @param v the input vector
* @return the mask result of testing if this vector is less than the input
* vector
*/
! public abstract Mask<E> lessThan(Vector<E> v);
/**
* Tests if this vector is less or equal to an input vector.
* <p>
* This is a vector binary test operation where the primitive less than
--- 504,514 ----
*
* @param v the input vector
* @return the mask result of testing if this vector is less than the input
* vector
*/
! public abstract VectorMask<E> lessThan(Vector<E> v);
/**
* Tests if this vector is less or equal to an input vector.
* <p>
* This is a vector binary test operation where the primitive less than
*** 512,522 ****
*
* @param v the input vector
* @return the mask result of testing if this vector is less than or equal
* to the input vector
*/
! public abstract Mask<E> lessThanEq(Vector<E> v);
/**
* Tests if this vector is greater than an input vector.
* <p>
* This is a vector binary test operation where the primitive greater than
--- 516,526 ----
*
* @param v the input vector
* @return the mask result of testing if this vector is less than or equal
* to the input vector
*/
! public abstract VectorMask<E> lessThanEq(Vector<E> v);
/**
* Tests if this vector is greater than an input vector.
* <p>
* This is a vector binary test operation where the primitive greater than
*** 524,534 ****
*
* @param v the input vector
* @return the mask result of testing if this vector is greater than the
* input vector
*/
! public abstract Mask<E> greaterThan(Vector<E> v);
/**
* Tests if this vector is greater than or equal to an input vector.
* <p>
* This is a vector binary test operation where the primitive greater than
--- 528,538 ----
*
* @param v the input vector
* @return the mask result of testing if this vector is greater than the
* input vector
*/
! public abstract VectorMask<E> greaterThan(Vector<E> v);
/**
* Tests if this vector is greater than or equal to an input vector.
* <p>
* This is a vector binary test operation where the primitive greater than
*** 536,546 ****
*
* @param v the input vector
* @return the mask result of testing if this vector is greater than or
* equal to the given vector
*/
! public abstract Mask<E> greaterThanEq(Vector<E> v);
// Elemental shifting
/**
* Rotates left the lane elements of this vector by the given number of
--- 540,550 ----
*
* @param v the input vector
* @return the mask result of testing if this vector is greater than or
* equal to the given vector
*/
! public abstract VectorMask<E> greaterThanEq(Vector<E> v);
// Elemental shifting
/**
* Rotates left the lane elements of this vector by the given number of
*** 617,627 ****
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of blending the lane elements of this vector with
* those of an input vector
*/
! public abstract Vector<E> blend(Vector<E> v, Mask<E> m);
/**
* Rearranges the lane elements of this vector and those of an input vector,
* selecting lane indexes controlled by shuffles and a mask.
* <p>
--- 621,631 ----
* @param v the input vector
* @param m the mask controlling lane selection
* @return the result of blending the lane elements of this vector with
* those of an input vector
*/
! public abstract Vector<E> blend(Vector<E> v, VectorMask<E> m);
/**
* Rearranges the lane elements of this vector and those of an input vector,
* selecting lane indexes controlled by shuffles and a mask.
* <p>
*** 642,652 ****
* those of an input vector
*/
@ForceInline
// rearrange
public abstract Vector<E> rearrange(Vector<E> v,
! Shuffle<E> s, Mask<E> m);
/**
* Rearranges the lane elements of this vector selecting lane indexes
* controlled by a shuffle.
* <p>
--- 646,656 ----
* those of an input vector
*/
@ForceInline
// rearrange
public abstract Vector<E> rearrange(Vector<E> v,
! VectorShuffle<E> s, VectorMask<E> m);
/**
* Rearranges the lane elements of this vector selecting lane indexes
* controlled by a shuffle.
* <p>
*** 658,668 ****
*
* @param s the shuffle controlling lane index selection
* @return the rearrangement of the lane elements of this vector
*/
// rearrange
! public abstract Vector<E> rearrange(Shuffle<E> s);
// Conversions
/**
--- 662,672 ----
*
* @param s the shuffle controlling lane index selection
* @return the rearrangement of the lane elements of this vector
*/
// rearrange
! public abstract Vector<E> rearrange(VectorShuffle<E> s);
// Conversions
/**
*** 681,691 ****
* return this.species().shuffleFromValues(sa);
* }</pre>
*
* @return a shuffle representation of this vector
*/
! public abstract Shuffle<E> toShuffle();
// Bitwise preserving
/**
* Transforms this vector to a vector of the given species of element type {@code F}.
--- 685,695 ----
* return this.species().shuffleFromValues(sa);
* }</pre>
*
* @return a shuffle representation of this vector
*/
! public abstract VectorShuffle<E> toShuffle();
// Bitwise preserving
/**
* Transforms this vector to a vector of the given species of element type {@code F}.
*** 711,733 ****
* The following pseudocode expresses the behaviour:
* <pre>{@code
* int blen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
* ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
* this.intoByteBuffer(bb, 0);
! * return s.fromByteBuffer(bb, 0);
* }</pre>
*
* @param s species of desired vector
* @param <F> the boxed element type of the species
* @return a vector transformed, by shape and element type, from this vector
*/
@ForceInline
! public abstract <F> Vector<F> reinterpret(Species<F> s);
@ForceInline
@SuppressWarnings("unchecked")
! <F> Vector<F> defaultReinterpret(Species<F> s) {
int blen = Math.max(s.bitSize(), this.species().bitSize()) / Byte.SIZE;
ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
this.intoByteBuffer(bb, 0);
Class<?> stype = s.elementType();
--- 715,737 ----
* The following pseudocode expresses the behaviour:
* <pre>{@code
* int blen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
* ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
* this.intoByteBuffer(bb, 0);
! * return $type$Vector.fromByteBuffer(s, bb, 0);
* }</pre>
*
* @param s species of desired vector
* @param <F> the boxed element type of the species
* @return a vector transformed, by shape and element type, from this vector
*/
@ForceInline
! public abstract <F> Vector<F> reinterpret(VectorSpecies<F> s);
@ForceInline
@SuppressWarnings("unchecked")
! <F> Vector<F> defaultReinterpret(VectorSpecies<F> s) {
int blen = Math.max(s.bitSize(), this.species().bitSize()) / Byte.SIZE;
ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
this.intoByteBuffer(bb, 0);
Class<?> stype = s.elementType();
*** 762,778 ****
* The following pseudocode expresses the behaviour:
* <pre>{@code
* int alen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
* byte[] a = new byte[alen];
* this.intoByteArray(a, 0);
! * return s.fromByteArray(a, 0);
* }</pre>
*
* @param s species of the desired vector
* @return a vector transformed, by shape, from this vector
*/
! public abstract Vector<E> reshape(Species<E> s);
// Cast
/**
* Converts this vector to a vector of the given species element type {@code F}.
--- 766,782 ----
* The following pseudocode expresses the behaviour:
* <pre>{@code
* int alen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
* byte[] a = new byte[alen];
* this.intoByteArray(a, 0);
! * return $type$Vector.fromByteArray(s, a, 0);
* }</pre>
*
* @param s species of the desired vector
* @return a vector transformed, by shape, from this vector
*/
! public abstract Vector<E> reshape(VectorSpecies<E> s);
// Cast
/**
* Converts this vector to a vector of the given species element type {@code F}.
*** 789,799 ****
*
* @param s species of the desired vector
* @param <F> the boxed element type of the species
* @return a vector converted by shape and element type from this vector
*/
! public abstract <F> Vector<F> cast(Species<F> s);
//Array stores
/**
* Stores this vector into a byte array starting at an offset.
--- 793,803 ----
*
* @param s species of the desired vector
* @param <F> the boxed element type of the species
* @return a vector converted by shape and element type from this vector
*/
! public abstract <F> Vector<F> cast(VectorSpecies<F> s);
//Array stores
/**
* Stores this vector into a byte array starting at an offset.
*** 801,811 ****
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
* <p>
* This method behaves as it calls the
* byte buffer, offset, and mask accepting
! * {@link #intoByteBuffer(ByteBuffer, int, Mask) method} as follows:
* <pre>{@code
* return this.intoByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
* }</pre>
*
* @param a the byte array
--- 805,815 ----
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
* <p>
* This method behaves as it calls the
* byte buffer, offset, and mask accepting
! * {@link #intoByteBuffer(ByteBuffer, int, VectorMask) method} as follows:
* <pre>{@code
* return this.intoByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
* }</pre>
*
* @param a the byte array
*** 822,832 ****
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
* <p>
* This method behaves as it calls the
* byte buffer, offset, and mask accepting
! * {@link #intoByteBuffer(ByteBuffer, int, Mask) method} as follows:
* <pre>{@code
* return this.intoByteBuffer(ByteBuffer.wrap(a), i, m);
* }</pre>
*
* @param a the byte array
--- 826,836 ----
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
* <p>
* This method behaves as it calls the
* byte buffer, offset, and mask accepting
! * {@link #intoByteBuffer(ByteBuffer, int, VectorMask) method} as follows:
* <pre>{@code
* return this.intoByteBuffer(ByteBuffer.wrap(a), i, m);
* }</pre>
*
* @param a the byte array
*** 836,857 ****
* or {@code > a.length},
* for any vector lane index {@code N} where the mask at lane {@code N}
* is set
* {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
*/
! public abstract void intoByteArray(byte[] a, int i, Mask<E> m);
/**
* Stores this vector into a {@link ByteBuffer byte buffer} starting at an
* offset into the byte buffer.
* <p>
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
* <p>
* This method behaves as if it calls the byte buffer, offset, and mask
* accepting
! * {@link #intoByteBuffer(ByteBuffer, int, Mask)} method} as follows:
* <pre>{@code
* this.intoByteBuffer(b, i, this.maskAllTrue())
* }</pre>
*
* @param b the byte buffer
--- 840,861 ----
* or {@code > a.length},
* for any vector lane index {@code N} where the mask at lane {@code N}
* is set
* {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
*/
! public abstract void intoByteArray(byte[] a, int i, VectorMask<E> m);
/**
* Stores this vector into a {@link ByteBuffer byte buffer} starting at an
* offset into the byte buffer.
* <p>
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
* <p>
* This method behaves as if it calls the byte buffer, offset, and mask
* accepting
! * {@link #intoByteBuffer(ByteBuffer, int, VectorMask)} method} as follows:
* <pre>{@code
* this.intoByteBuffer(b, i, this.maskAllTrue())
* }</pre>
*
* @param b the byte buffer
*** 896,1549 ****
* or {@code > b.limit()},
* for any vector lane index {@code N} where the mask at lane {@code N}
* is set
* {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes
*/
! public abstract void intoByteBuffer(ByteBuffer b, int i, Mask<E> m);
!
!
! /**
! * A {@code Shape} governs the total size, in bits, of a
! * {@link Vector}, {@link Mask}, or {@link Shuffle}. The shape in
! * combination with the element type together govern the number of lanes.
! */
! public enum Shape {
! /** Shape of length 64 bits */
! S_64_BIT(64),
! /** Shape of length 128 bits */
! S_128_BIT(128),
! /** Shape of length 256 bits */
! S_256_BIT(256),
! /** Shape of length 512 bits */
! S_512_BIT(512),
! /** Shape of maximum length supported on the platform */
! S_Max_BIT(Unsafe.getUnsafe().getMaxVectorSize(byte.class) * 8);
!
! @Stable
! final int bitSize;
!
! Shape(int bitSize) {
! this.bitSize = bitSize;
! }
!
! /**
! * Returns the size, in bits, of this shape.
! *
! * @return the size, in bits, of this shape.
! */
! public int bitSize() {
! return bitSize;
! }
!
! /**
! * Return the number of lanes of a vector of this shape and whose element
! * type is of the provided species
! *
! * @param s the species describing the element type
! * @return the number of lanes
! */
! int length(Species<?> s) {
! return bitSize() / s.elementSize();
! }
!
! /**
! * Finds appropriate shape depending on bitsize.
! *
! * @param bitSize the size in bits
! * @return the shape corresponding to bitsize
! * @see #bitSize
! */
! public static Shape forBitSize(int bitSize) {
! switch (bitSize) {
! case 64:
! return Shape.S_64_BIT;
! case 128:
! return Shape.S_128_BIT;
! case 256:
! return Shape.S_256_BIT;
! case 512:
! return Shape.S_512_BIT;
! default:
! if ((bitSize > 0) && (bitSize <= 2048) && (bitSize % 128 == 0)) {
! return Shape.S_Max_BIT;
! } else {
! throw new IllegalArgumentException("Bad vector bit size: " + bitSize);
! }
! }
! }
! }
!
!
! /**
! * Class representing vectors of same element type, {@code E} and {@link Vector.Shape Shape}.
! *
! * @param <E> the boxed element type of this species
! */
! public static abstract class Species<E> {
! Species() {}
!
! /**
! * Returns the primitive element type of vectors produced by this
! * species.
! *
! * @return the primitive element type
! */
! public abstract Class<E> elementType();
!
! /**
! * Returns the vector box type for this species
! *
! * @return the box type
! */
! abstract Class<?> boxType();
!
! /**
! * Returns the vector mask type for this species
! *
! * @return the box type
! */
! abstract Class<?> maskType();
!
! /**
! * Returns the element size, in bits, of vectors produced by this
! * species.
! *
! * @return the element size, in bits
! */
! public abstract int elementSize();
!
! /**
! * Returns the shape of masks, shuffles, and vectors produced by this
! * species.
! *
! * @return the primitive element type
! */
! public abstract Shape shape();
!
! /**
! * Returns the shape of the corresponding index species
! * @return the shape
! */
! @ForceInline
! public abstract Shape indexShape();
!
! /**
! * Returns the mask, shuffe, or vector lanes produced by this species.
! *
! * @return the the number of lanes
! */
! public int length() { return shape().length(this); }
!
! /**
! * Returns the total vector size, in bits, of vectors produced by this
! * species.
! *
! * @return the total vector size, in bits
! */
! public int bitSize() { return shape().bitSize(); }
!
! // Factory
!
! /**
! * Finds a species for an element type and shape.
! *
! * @param c the element type
! * @param s the shape
! * @param <E> the boxed element type
! * @return a species for an element type and shape
! * @throws IllegalArgumentException if no such species exists for the
! * element type and/or shape
! */
! @SuppressWarnings("unchecked")
! public static <E> Vector.Species<E> of(Class<E> c, Shape s) {
! if (c == float.class) {
! return (Vector.Species<E>) FloatVector.species(s);
! }
! else if (c == double.class) {
! return (Vector.Species<E>) DoubleVector.species(s);
! }
! else if (c == byte.class) {
! return (Vector.Species<E>) ByteVector.species(s);
! }
! else if (c == short.class) {
! return (Vector.Species<E>) ShortVector.species(s);
! }
! else if (c == int.class) {
! return (Vector.Species<E>) IntVector.species(s);
! }
! else if (c == long.class) {
! return (Vector.Species<E>) LongVector.species(s);
! }
! else {
! throw new IllegalArgumentException("Bad vector element type: " + c.getName());
! }
! }
!
! /**
! * Finds a preferred species for an element type.
! * <p>
! * A preferred species is a species chosen by the platform that has a
! * shape of maximal bit size. A preferred species for different element
! * types will have the same shape, and therefore vectors created from
! * such species will be shape compatible.
! *
! * @param c the element type
! * @param <E> the boxed element type
! * @return a preferred species for an element type
! * @throws IllegalArgumentException if no such species exists for the
! * element type
! */
! public static <E> Vector.Species<E> ofPreferred(Class<E> c) {
! Unsafe u = Unsafe.getUnsafe();
!
! int vectorLength = u.getMaxVectorSize(c);
! int vectorBitSize = bitSizeForVectorLength(c, vectorLength);
! Shape s = Shape.forBitSize(vectorBitSize);
! return Species.of(c, s);
! }
! }
!
! abstract static class AbstractSpecies<E> extends Vector.Species<E> {
! @Stable
! protected final Vector.Shape shape;
! @Stable
! protected final Class<E> elementType;
! @Stable
! protected final int elementSize;
! @Stable
! protected final Class<?> boxType;
! @Stable
! protected final Class<?> maskType;
! @Stable
! protected final Shape indexShape;
!
! AbstractSpecies(Vector.Shape shape, Class<E> elementType, int elementSize, Class<?> boxType, Class<?> maskType) {
! this.shape = shape;
! this.elementType = elementType;
! this.elementSize = elementSize;
! this.boxType = boxType;
! this.maskType = maskType;
!
! if (boxType == Long64Vector.class || boxType == Double64Vector.class) {
! indexShape = Vector.Shape.S_64_BIT;
! }
! else {
! int bitSize = Vector.bitSizeForVectorLength(int.class, shape.bitSize() / elementSize);
! indexShape = Vector.Shape.forBitSize(bitSize);
! }
! }
!
! @Override
! @ForceInline
! public int bitSize() {
! return shape.bitSize();
! }
!
! @Override
! @ForceInline
! public int length() {
! return shape.bitSize() / elementSize;
! }
!
! @Override
! @ForceInline
! public Class<E> elementType() {
! return elementType;
! }
!
! @Override
! @ForceInline
! public Class<?> boxType() {
! return boxType;
! }
!
! @Override
! @ForceInline
! public Class<?> maskType() {
! return maskType;
! }
!
! @Override
! @ForceInline
! public int elementSize() {
! return elementSize;
! }
!
! @Override
! @ForceInline
! public Vector.Shape shape() {
! return shape;
! }
!
! @Override
! @ForceInline
! public Vector.Shape indexShape() { return indexShape; }
!
! @Override
! public String toString() {
! return new StringBuilder("Shape[")
! .append(bitSize()).append(" bits, ")
! .append(length()).append(" ").append(elementType.getSimpleName()).append("s x ")
! .append(elementSize()).append(" bits")
! .append("]")
! .toString();
! }
! }
!
! /**
! * A {@code Mask} represents an ordered immutable sequence of {@code boolean}
! * values. A Mask can be used with a mask accepting vector operation to
! * control the selection and operation of lane elements of input vectors.
! * <p>
! * The number of values in the sequence is referred to as the Mask
! * {@link #length() length}. The length also corresponds to the number of
! * Mask lanes. The lane element at lane index {@code N} (from {@code 0},
! * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
! * value in the sequence.
! * A Mask and Vector of the same element type and shape have the same number
! * of lanes.
! * <p>
! * A lane is said to be <em>set</em> if the lane element is {@code true},
! * otherwise a lane is said to be <em>unset</em> if the lane element is
! * {@code false}.
! * <p>
! * Mask declares a limited set of unary, binary and reductive mask
! * operations.
! * <ul>
! * <li>
! * A mask unary operation (1-ary) operates on one input mask to produce a
! * result mask.
! * For each lane of the input mask the
! * lane element is operated on using the specified scalar unary operation and
! * the boolean result is placed into the mask result at the same lane.
! * The following pseudocode expresses the behaviour of this operation category:
! *
! * <pre>{@code
! * Mask<E> a = ...;
! * boolean[] ar = new boolean[a.length()];
! * for (int i = 0; i < a.length(); i++) {
! * ar[i] = boolean_unary_op(a.isSet(i));
! * }
! * Mask<E> r = a.species().maskFromArray(ar, 0);
! * }</pre>
! *
! * <li>
! * A mask binary operation (2-ary) operates on two input
! * masks to produce a result mask.
! * For each lane of the two input masks,
! * a and b say, the corresponding lane elements from a and b are operated on
! * using the specified scalar binary operation and the boolean result is placed
! * into the mask result at the same lane.
! * The following pseudocode expresses the behaviour of this operation category:
! *
! * <pre>{@code
! * Mask<E> a = ...;
! * Mask<E> b = ...;
! * boolean[] ar = new boolean[a.length()];
! * for (int i = 0; i < a.length(); i++) {
! * ar[i] = scalar_binary_op(a.isSet(i), b.isSet(i));
! * }
! * Mask<E> r = a.species().maskFromArray(ar, 0);
! * }</pre>
! *
! * </ul>
! * @param <E> the boxed element type of this mask
! */
! public static abstract class Mask<E> {
! Mask() {}
!
! /**
! * Returns the species of this mask.
! *
! * @return the species of this mask
! */
! public abstract Species<E> species();
!
! /**
! * Returns the number of mask lanes (the length).
! *
! * @return the number of mask lanes
! */
! public int length() { return species().length(); }
!
! /**
! * Converts this mask to a mask of the given species shape of element type {@code F}.
! * <p>
! * For each mask lane, where {@code N} is the lane index, if the
! * mask lane at index {@code N} is set, then the mask lane at index
! * {@code N} of the resulting mask is set, otherwise that mask lane is
! * not set.
! *
! * @param s the species of the desired mask
! * @param <F> the boxed element type of the species
! * @return a mask converted by shape and element type
! * @throws IllegalArgumentException if this mask length and the species
! * length differ
! */
! public abstract <F> Mask<F> cast(Species<F> s);
!
! /**
! * Returns the lane elements of this mask packed into a {@code long}
! * value for at most the first 64 lane elements.
! * <p>
! * The lane elements are packed in the order of least significant bit
! * to most significant bit.
! * For each mask lane where {@code N} is the mask lane index, if the
! * mask lane is set then the {@code N}'th bit is set to one in the
! * resulting {@code long} value, otherwise the {@code N}'th bit is set
! * to zero.
! *
! * @return the lane elements of this mask packed into a {@code long}
! * value.
! */
! public abstract long toLong();
!
! /**
! * Returns an {@code boolean} array containing the lane elements of this
! * mask.
! * <p>
! * This method behaves as if it {@link #intoArray(boolean[], int)} stores}
! * this mask into an allocated array and returns that array as
! * follows:
! * <pre>{@code
! * boolean[] a = new boolean[this.length()];
! * this.intoArray(a, 0);
! * return a;
! * }</pre>
! *
! * @return an array containing the the lane elements of this vector
! */
! public abstract boolean[] toArray();
!
! /**
! * Stores this mask into a {@code boolean} array starting at offset.
! * <p>
! * For each mask lane, where {@code N} is the mask lane index,
! * the lane element at index {@code N} is stored into the array at index
! * {@code i + N}.
! *
! * @param a the array
! * @param i the offset into the array
! * @throws IndexOutOfBoundsException if {@code i < 0}, or
! * {@code i > a.length - this.length()}
! */
! public abstract void intoArray(boolean[] a, int i);
!
! /**
! * Returns {@code true} if any of the mask lanes are set.
! *
! * @return {@code true} if any of the mask lanes are set, otherwise
! * {@code false}.
! */
! public abstract boolean anyTrue();
!
! /**
! * Returns {@code true} if all of the mask lanes are set.
! *
! * @return {@code true} if all of the mask lanes are set, otherwise
! * {@code false}.
! */
! public abstract boolean allTrue();
!
! /**
! * Returns the number of mask lanes that are set.
! *
! * @return the number of mask lanes that are set.
! */
! public abstract int trueCount();
!
! /**
! * Logically ands this mask with an input mask.
! * <p>
! * This is a mask binary operation where the logical and operation
! * ({@code &&} is applied to lane elements.
! *
! * @param o the input mask
! * @return the result of logically and'ing this mask with an input mask
! */
! public abstract Mask<E> and(Mask<E> o);
!
! /**
! * Logically ors this mask with an input mask.
! * <p>
! * This is a mask binary operation where the logical or operation
! * ({@code ||} is applied to lane elements.
! *
! * @param o the input mask
! * @return the result of logically or'ing this mask with an input mask
! */
! public abstract Mask<E> or(Mask<E> o);
!
! /**
! * Logically negates this mask.
! * <p>
! * This is a mask unary operation where the logical not operation
! * ({@code !} is applied to lane elements.
! *
! * @return the result of logically negating this mask.
! */
! public abstract Mask<E> not();
!
! /**
! * Returns a vector representation of this mask.
! * <p>
! * For each mask lane, where {@code N} is the mask lane index,
! * if the mask lane is set then an element value whose most significant
! * bit is set is placed into the resulting vector at lane index
! * {@code N}, otherwise the default element value is placed into the
! * resulting vector at lane index {@code N}.
! *
! * @return a vector representation of this mask.
! */
! public abstract Vector<E> toVector();
!
! /**
! * Tests if the lane at index {@code i} is set
! * @param i the lane index
! *
! * @return true if the lane at index {@code i} is set, otherwise false
! */
! public abstract boolean getElement(int i);
!
! /**
! * Tests if the lane at index {@code i} is set
! * @param i the lane index
! * @return true if the lane at index {@code i} is set, otherwise false
! * @see #getElement
! */
! public boolean isSet(int i) {
! return getElement(i);
! }
! }
!
! /**
! * A {@code Shuffle} represents an ordered immutable sequence of
! * {@code int} values. A Shuffle can be used with a shuffle accepting
! * vector operation to control the rearrangement of lane elements of input
! * vectors
! * <p>
! * The number of values in the sequence is referred to as the Shuffle
! * {@link #length() length}. The length also corresponds to the number of
! * Shuffle lanes. The lane element at lane index {@code N} (from {@code 0},
! * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
! * value in the sequence.
! * A Shuffle and Vector of the same element type and shape have the same
! * number of lanes.
! * <p>
! * A Shuffle describes how a lane element of a vector may cross lanes from
! * its lane index, {@code i} say, to another lane index whose value is the
! * Shuffle's lane element at lane index {@code i}. Shuffle lane elements
! * will be in the range of {@code 0} (inclusive) to the shuffle length
! * (exclusive), and therefore cannot induce out of bounds errors when
! * used with vectors operations and vectors of the same length.
! *
! * @param <E> the boxed element type of this mask
! */
! public static abstract class Shuffle<E> {
! Shuffle() {}
!
! /**
! * Returns the species of this shuffle.
! *
! * @return the species of this shuffle
! */
! public abstract Species<E> species();
!
! /**
! * Returns the number of shuffle lanes (the length).
! *
! * @return the number of shuffle lanes
! */
! public int length() { return species().length(); }
!
! /**
! * Converts this shuffle to a shuffle of the given species of element type {@code F}.
! * <p>
! * For each shuffle lane, where {@code N} is the lane index, the
! * shuffle element at index {@code N} is placed, unmodified, into the
! * resulting shuffle at index {@code N}.
! *
! * @param species species of desired shuffle
! * @param <F> the boxed element type of the species
! * @return a shuffle converted by shape and element type
! * @throws IllegalArgumentException if this shuffle length and the
! * species length differ
! */
! public abstract <F> Shuffle<F> cast(Species<F> species);
!
! /**
! * Returns an {@code int} array containing the lane elements of this
! * shuffle.
! * <p>
! * This method behaves as if it {@link #intoArray(int[], int)} stores}
! * this shuffle into an allocated array and returns that array as
! * follows:
! * <pre>{@code
! * int[] a = new int[this.length()];
! * this.intoArray(a, 0);
! * return a;
! * }</pre>
! *
! * @return an array containing the the lane elements of this vector
! */
! public abstract int[] toArray();
!
! /**
! * Stores this shuffle into an {@code int} array starting at offset.
! * <p>
! * For each shuffle lane, where {@code N} is the shuffle lane index,
! * the lane element at index {@code N} is stored into the array at index
! * {@code i + N}.
! *
! * @param a the array
! * @param i the offset into the array
! * @throws IndexOutOfBoundsException if {@code i < 0}, or
! * {@code i > a.length - this.length()}
! */
! public abstract void intoArray(int[] a, int i);
!
! /**
! * Converts this shuffle into a vector, creating a vector from shuffle
! * lane elements (int values) cast to the vector element type.
! * <p>
! * This method behaves as if it returns the result of creating a
! * vector given an {@code int} array obtained from this shuffle's
! * lane elements, as follows:
! * <pre>{@code
! * int[] sa = this.toArray();
! * $type$[] va = new $type$[a.length];
! * for (int i = 0; i < a.length; i++) {
! * va[i] = ($type$) sa[i];
! * }
! * return this.species().fromArray(va, 0);
! * }</pre>
! *
! * @return a vector representation of this shuffle
! */
! public abstract Vector<E> toVector();
!
! /**
! * Gets the {@code int} lane element at lane index {@code i}
! *
! * @param i the lane index
! * @return the {@code int} lane element at lane index {@code i}
! */
! public int getElement(int i) { return toArray()[i]; }
!
! /**
! * Rearranges the lane elements of this shuffle selecting lane indexes
! * controlled by another shuffle.
! * <p>
! * For each lane of the shuffle, at lane index {@code N} with lane
! * element {@code I}, the lane element at {@code I} from this shuffle is
! * selected and placed into the resulting shuffle at {@code N}.
! *
! * @param s the shuffle controlling lane index selection
! * @return the rearrangement of the lane elements of this shuffle
! */
! public abstract Shuffle<E> rearrange(Shuffle<E> s);
! }
/**
* Find bit size based on element type and number of elements.
*
* @param c the element type
--- 900,910 ----
* or {@code > b.limit()},
* for any vector lane index {@code N} where the mask at lane {@code N}
* is set
* {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes
*/
! public abstract void intoByteBuffer(ByteBuffer b, int i, VectorMask<E> m);
/**
* Find bit size based on element type and number of elements.
*
* @param c the element type
< prev index next >