E
- the boxed version of ETYPE
, the element type of a vectorpublic abstract class VectorShuffle<E> extends Object
VectorShuffle
represents an ordered immutable sequence of int
values called source indexes, where each source index numerically selects a source lane from a compatible Vector
. A VectorShuffle
and Vector
of the same element type (ETYPE
) and shape
have the same number of lanes, and are therefore compatible (specifically, their vector species
are compatible).
A shuffle is applied to a (compatible) source vector with the rearrange
method.
A shuffle has a lane structure derived from its vector species, but it stores lane indexes, as int
s, rather than lane values.
This method gathers lane values by random access to the source vector, selecting lanes by consulting the source indexes. If a source index appears more than once in a shuffle, then the selected lane's value is copied more than once into the result. If a particular lane is never selected by a source index, that lane's value is ignored. The resulting vector contains all the source lane values selected by the source indexes of the shuffle. The resulting lane values are ordered according to the shuffle's source indexes, not according to the original vector's lane order.
Each shuffle has a vectorSpecies()
property which determines the compatibility of vectors the shuffle operates on. This ensures that the length()
of a shuffle is always equal to the VLENGTH of any vector it operates on. The element type and shape of the shuffle's species are not directly relevant to the behavior of the shuffle. Shuffles can easily be converted to other lane types, as long as the lane count stays constant.
In its internal state, a shuffle always holds integral values in a narrow range from [-VLENGTH..VLENGTH-1]
. The positive numbers are self-explanatory; they are lane numbers applied to any source vector. The negative numbers, when present, are a sign that the shuffle was created from a raw integer value which was not a valid lane index.
An invalid source index, represented in a shuffle by a negative number, is called an exceptional index.
Exceptional indexes are processed in a variety of ways:
ArrayIndexOutOfBoundsException
when a lane is processed by an exceptional index. [-VLENGTH..-1]
as if by wrapIndex()
. This treatment of exceptional indexes is called partial wrapping, because it preserves the distinction between normal and exceptional indexes, while wrapping them into adjacent ranges of positive and non-positive numbers. A partially wrapped index can later on be fully wrapped into the positive range by adding a final offset of VLENGTH
. [-VLENGTH..-1]
, are cycled up to the valid range [0..VLENGTH-1]
and used on the second source vector. VLENGTH
, all indexes are re-validated against the new VLENGTH
, and some may be converted to exceptional indexes. In any case, shuffle casting never converts exceptional indexes to normal ones. VectorShuffle
, along with Vector
is a value-based class. Identity-sensitive operations such as ==
may yield unpredictable results, or reduced performance. Also, vector shuffle objects can be stored in locals and parameters and as static final
constants, but storing them in other Java fields or in array elements, while semantically valid, may incur performance penalties. Finally, vector shuffles should not be computed in loops, when possible, but instead should be stored in loop-invariant locals or as static final
constants.Modifier and Type | Method | Description |
---|---|---|
abstract <F> VectorShuffle |
cast |
Converts this shuffle to a shuffle of the given species of element type F . |
abstract <F> VectorShuffle |
check |
Checks that this shuffle has the given species, and returns this shuffle unchanged. |
abstract int |
checkIndex |
Validation function for lane indexes which may be out of the valid range of [0..VLENGTH-1] . |
abstract VectorShuffle |
checkIndexes() |
Apply the checkIndex() validation function to all lanes, throwing IndexOutOfBoundsException if there are any exceptional indexes in this shuffle. |
final boolean |
equals |
Indicates whether this shuffle is identical to some other object. |
static <E> VectorShuffle |
fromArray |
Creates a shuffle for a given species from an int array starting at an offset. |
static <E> VectorShuffle |
fromOp |
Creates a shuffle for a given species from the successive values of an operator applied to the range [0..VLENGTH-1] . |
static <E> VectorShuffle |
fromValues |
Creates a shuffle for a given species from a series of source indexes. |
protected final Object |
getPayload() |
|
final int |
hashCode() |
Returns a hash code value for the shuffle, based on the lane source indexes and the vector species. |
abstract void |
intoArray |
Stores this shuffle into an int array starting at offset. |
static <E> VectorShuffle |
iota |
Creates a shuffle using source indexes set to sequential values starting from start and stepping by the given step . |
abstract VectorMask |
laneIsValid() |
Find all lanes containing valid indexes (non-negative values) and return a mask where exactly those lanes are set. |
int |
laneSource |
Gets the int lane element at lane index i
|
final int |
length() |
Returns the number of lanes processed by this shuffle. |
static <E> VectorShuffle |
makeUnzip |
Creates a shuffle which will unzip the concatenation of two vectors, alternatively storing input lanes into one or the other output vector. |
static <E> VectorShuffle |
makeZip |
Creates a shuffle which will zip together two vectors, alternatively selecting lanes from one or the other. |
abstract VectorShuffle |
rearrange |
Rearranges the lane elements of this shuffle selecting lane indexes controlled by another shuffle. |
abstract int[] |
toArray() |
Returns an int array containing the lane source indexes of this shuffle. |
final String |
toString() |
Returns a string representation of this shuffle, of the form "Shuffle[0,1,2...]" , reporting the source indexes in lane order. |
abstract Vector |
toVector() |
Converts this shuffle into a vector, creating a vector of integral values corresponding to the lane source indexes of the shuffle. |
abstract VectorSpecies |
vectorSpecies() |
Returns the species of this shuffle. |
abstract int |
wrapIndex |
Validation function for lane indexes which may be out of the valid range of [0..VLENGTH-1] . |
abstract VectorShuffle |
wrapIndexes() |
Apply the wrapIndex() validation function to all lanes, replacing any exceptional indexes with wrapped normal indexes. |
public abstract VectorSpecies<E> vectorSpecies()
public final int length()
VLENGTH
of any vector it operates on.public abstract <F> VectorShuffle<F> cast(VectorSpecies<F> species)
F
. The various lane source indexes are unmodified. Exceptional source indexes remain exceptional and valid indexes remain valid.F
- the boxed element type of the speciesspecies
- the species of desired shuffleIllegalArgumentException
- if this shuffle length and the species length differpublic abstract <F> VectorShuffle<F> check(VectorSpecies<F> species)
species == vectorSpecies()
? this
: throw new ClassCastException()
.F
- the boxed element type of the required speciesspecies
- the required speciesClassCastException
- if the shuffle species is wrongpublic abstract int checkIndex(int index)
[0..VLENGTH-1]
. If index
is in this range, it is returned unchanged. Otherwise, an IndexOutOfBoundsException
is thrown.index
- the lane indexindex
IndexOutOfBoundsException
- if the index
is not less than VLENGTH
, or is negativepublic abstract int wrapIndex(int index)
[0..VLENGTH-1]
. The index
is forced into this range by adding or subtracting a suitable multiple of VLENGTH
. Specifically, the index is reduced into the required range by computing the value of length-floor
, where floor=vectorSpecies().loopBound(length)
is the next lower multiple of VLENGTH
. As long as VLENGTH
is a power of two, then the reduced index also equal to index & (VLENGTH - 1)
.index
- the lane indexindex
, adjusted to the range [0..VLENGTH-1
} by an appropriate multiple of VLENGTH
public abstract VectorShuffle<E> checkIndexes()
checkIndex()
validation function to all lanes, throwing IndexOutOfBoundsException
if there are any exceptional indexes in this shuffle.IndexOutOfBoundsException
- if any lanes in this shuffle contain exceptional indexespublic abstract VectorShuffle<E> wrapIndexes()
wrapIndex()
validation function to all lanes, replacing any exceptional indexes with wrapped normal indexes.public abstract VectorMask<E> laneIsValid()
public static <E> VectorShuffle<E> fromValues(VectorSpecies<E> species, int... sourceIndexes)
For each shuffle lane, where N
is the shuffle lane index, the N
th index value is validated against the species VLENGTH
, and (if invalid) is partially wrapped to an exceptional index in the range [-VLENGTH..-1]
.
E
- the boxed element typespecies
- shuffle speciessourceIndexes
- the source indexes which the shuffle will draw fromint
value, partially wrapped if exceptionalIndexOutOfBoundsException
- if sourceIndexes.length != VLENGTH
public static <E> VectorShuffle<E> fromArray(VectorSpecies<E> species, int[] sourceIndexes, int offset)
int
array starting at an offset. For each shuffle lane, where N
is the shuffle lane index, the array element at index offset + N
is validated against the species VLENGTH
, and (if invalid) is partially wrapped to an exceptional index in the range [-VLENGTH..-1]
.
E
- the boxed element typespecies
- shuffle speciessourceIndexes
- the source indexes which the shuffle will draw fromoffset
- the offset into the arrayint
value, partially wrapped if exceptionalIndexOutOfBoundsException
- if offset < 0
, or offset > sourceIndexes.length - VLENGTH
public static <E> VectorShuffle<E> fromOp(VectorSpecies<E> species, IntUnaryOperator fn)
[0..VLENGTH-1]
. For each shuffle lane, where N
is the shuffle lane index, the N
th index value is validated against the species VLENGTH
, and (if invalid) is partially wrapped to an exceptional index in the range [-VLENGTH..-1]
.
Care should be taken to ensure VectorShuffle
values produced from this method are consumed as constants to ensure optimal generation of code. For example, shuffle values can be held in static final
fields or loop-invariant local variables.
This method behaves as if a shuffle is created from an array of mapped indexes as follows:
int[] a = new int[species.length()];
for (int i = 0; i < a.length; i++) {
a[i] = fn.applyAsInt(i);
}
return VectorShuffle.fromArray(a, 0);
E
- the boxed element typespecies
- shuffle speciesfn
- the lane index mapping functionpublic static <E> VectorShuffle<E> iota(VectorSpecies<E> species, int start, int step, boolean wrap)
start
and stepping by the given step
. This method returns the value of the expression VectorShuffle.fromOp(species, i -> R(start + i * step))
, where R
is wrapIndex
if wrap
is true, and is the identity function otherwise.
If wrap
is false each index is validated against the species VLENGTH
, and (if invalid) is partially wrapped to an exceptional index in the range [-VLENGTH..-1]
. Otherwise, if wrap
is true, also reduce each index, as if by wrapIndex
, to the valid range [0..VLENGTH-1]
.
wrap
parameter should be set to
true
if invalid source indexes should be wrapped. Otherwise, setting it to false
allows invalid source indexes to be range-checked by later operations such as unary rearrange
.E
- the boxed element typespecies
- shuffle speciesstart
- the starting value of the source index sequencestep
- the difference between adjacent source indexeswrap
- whether to wrap resulting indexespublic static <E> VectorShuffle<E> makeZip(VectorSpecies<E> species, int part)
[a,b,c,d]
and [1,2,3,4]
will yield the expanded logical result [a,1,b,2,c,3,d,4]
which must be obtained in two parts, [a,1,b,2]
and [c,3,d,4]
. This method returns the value of the expression VectorShuffle.fromOp(species, i -> i/2 + (i%2)*VLENGTH + P
, where P
is part*VLENGTH/2
.
s Note that the source indexes in the odd lanes of the shuffle will be invalid indexes (>= VLENGTH
, or < 0
after partial normalization), which will select from the second vector.
E
- the boxed element typespecies
- the shuffle speciespart
- the part number of the result (either zero or one)2*VLENGTH
lanes, returning the selected partArrayIndexOutOfBoundsException
- if part
is not zero or onepublic static <E> VectorShuffle<E> makeUnzip(VectorSpecies<E> species, int part)
[a,1,b,2][c,3,d,4]
will yield a result in two parts, [a,b,c,d]
and [1,2,3,4]
. This method returns the value of the expression VectorShuffle.fromOp(species, i -> i*2+part
.
Note that the source indexes in upper half of the shuffle will be invalid indexes (>= VLENGTH
, or < 0
after partial normalization), which will select from the second vector.
E
- the boxed element typespecies
- the shuffle speciespart
- the part number of the result (either zero or one)2*VLENGTH
lanes into two vectors, returning the selected partArrayIndexOutOfBoundsException
- if part
is not zero or onepublic abstract int[] toArray()
int
array containing the lane source indexes of this shuffle. This method behaves as if it stores this shuffle into an allocated array (using intoArray
) and returns that array as follows:
int[] a = new int[this.length()];
VectorShuffle.intoArray(a, 0);
return a;
-VLENGTH
to VLENGTH-1
. A source index is exceptional if and only if it is negative.public abstract void intoArray(int[] a, int offset)
int
array starting at offset. For each shuffle lane N
, the lane source index stored for that lane element is stored into the array element a[offset+N]
.
-VLENGTH
to VLENGTH-1
.a
- the array, of type int[]
offset
- the offset into the arrayIndexOutOfBoundsException
- if offset < 0
or offset > a.length - this.length()
public abstract Vector<E> toVector()
This method behaves as if it returns the result of creating a vector given an int
array obtained from this shuffle's lane elements, as follows:
int[] sa = this.toArray();
$type$[] va = new $type$[a.length];
for (int i = 0; i < a.length; i++) {
va[i] = ($type$) sa[i];
}
return IntVector.fromArray(va, 0);
-VLENGTH
to VLENGTH-1
. These values are converted to the ETYPE
of the resulting vector, even if it is a floating point type.public int laneSource(int i)
int
lane element at lane index i
i
- the lane indexint
lane element at lane index i
public abstract VectorShuffle<E> rearrange(VectorShuffle<E> s)
For each lane of the specified shuffle, at lane index N
with lane element I
, the lane element at I
from this shuffle is selected and placed into the resulting shuffle at N
.
s
- the shuffle controlling lane index selectionpublic final String toString()
"Shuffle[0,1,2...]"
, reporting the source indexes in lane order.public final boolean equals(Object obj)
public final int hashCode()
protected final Object getPayload()
© 1993, 2023, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/21/docs/api/jdk.incubator.vector/jdk/incubator/vector/VectorShuffle.html