/* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have * questions. */ package jdk.incubator.vector; import jdk.internal.misc.Unsafe; import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.Stable; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.function.IntUnaryOperator; 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 * Data (SIMD) computations leveraging vector hardware registers and vector * hardware instructions. Such SIMD computations exploit data parallelism to * perform the same operation on multiple data points simultaneously in a * faster time it would ordinarily take to perform the same operation * sequentially on each data point. *
* A Vector represents an ordered immutable sequence of values of the same * element type {@code e} that is one of the following primitive types * {@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. *
* 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}, * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th value in * the sequence. * Note: this arrangement * of Vector bit size, Vector length, element bit size, and lane element index * has no bearing on how a Vector instance and its sequence of elements may be * arranged in memory or represented as a value in a vector hardware register. *
* Vector declares a set of vector operations (methods) that are common to all * element types (such as addition). Sub-classes of Vector with a concrete * boxed element type declare further operations that are specific to that * element type (such as access to element values in lanes, logical operations * on values of integral elements types, or transcendental operations on values * of floating point element types). * There are six sub-classes of Vector corresponding to the supported set * of element types, {@link ByteVector}, {@link ShortVector}, * {@link IntVector} {@link LongVector}, {@link FloatVector}, and * {@link DoubleVector}. *
* 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. *
* Vector operations can be grouped into various categories and their behaviour * generally specified as follows: *
{@code * EVector* * Unless otherwise specified the input and result vectors will have the same * element type and shape. * *a = ...; * e[] ar = new e[a.length()]; * for (int i = 0; i < a.length(); i++) { * ar[i] = scalar_unary_op(a.get(i)); * } * EVectorr = a.species().fromArray(ar, 0); * }
{@code * EVector* * Unless otherwise specified the two input and result vectors will have the * same element type and shape. * *a = ...; * EVectorb = ...; * e[] ar = new e[a.length()]; * for (int i = 0; i < a.length(); i++) { * ar[i] = scalar_binary_op(a.get(i), b.get(i)); * } * EVectorr = a.species().fromArray(ar, 0); * }
{@code * EVector* * Unless otherwise specified the scalar result type and element type will be * the same. * *a = ...; * e r =; * for (int i = 0; i < a.length(); i++) { * r = assoc_scalar_binary_op(r, a.get(i)); * } * }
{@code * EVector* * Unless otherwise specified the two input vectors and result mask will have * the same element type and shape. * *a = ...; * EVectorb = ...; * 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)); * } * Maskr = a.species().maskFromArray(ar, 0); * }
* If a vector operation does not belong to one of the above categories then * the operation explicitly specifies how it processes the lane elements of * input vectors, and where appropriate expresses the behaviour using * pseudocode. * *
* 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. *
* For certain operation categories the mask accepting variants can be specified * in generic terms. If a lane of the mask is set then the scalar operation is * applied to corresponding lane elements, otherwise if a lane of a mask is not * set then a default scalar operation is applied and its result is placed into * the vector result at the same lane. The default operation is specified for * the following operation categories: *
* 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. * *
* This is a value-based
* class; use of identity-sensitive operations (including reference equality
* ({@code ==}), identity hash code, or synchronization) on instances of
* {@code Vector} may have unpredictable results and should be avoided.
*
* @param
* This is a vector binary operation where the primitive addition operation
* ({@code +}) is applied to lane elements.
*
* @param v the input vector
* @return the result of adding this vector to the input vector
*/
public abstract Vector
* This is a vector binary operation where the primitive addition operation
* ({@code +}) is applied to lane elements.
*
* @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
* This is a vector binary operation where the primitive subtraction
* operation ({@code -}) is applied to lane elements.
*
* @param v the input vector
* @return the result of subtracting the input vector from this vector
*/
public abstract Vector
* This is a vector binary operation where the primitive subtraction
* operation ({@code -}) is applied to lane elements.
*
* @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
* This is a vector binary operation where the primitive multiplication
* operation ({@code *}) is applied to lane elements.
*
* @param v the input vector
* @return the result of multiplying this vector with the input vector
*/
public abstract Vector
* This is a vector binary operation where the primitive multiplication
* operation ({@code *}) is applied to lane elements.
*
* @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
* This is a vector unary operation where the primitive negation operation
* ({@code -}) is applied to lane elements.
*
* @return the negation this vector
*/
public abstract Vector
* This is a vector unary operation where the primitive negation operation
* ({@code -})is applied to lane elements.
*
* @param m the mask controlling lane selection
* @return the negation this vector
*/
public abstract Vector
* This is a vector unary operation where the operation
* {@code (a) -> (a < 0) ? -a : a} is applied to lane elements.
*
* @return the modulus this vector
*/
public abstract Vector
* This is a vector unary operation where the operation
* {@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
* This is a vector binary operation where the operation
* {@code (a, b) -> a < b ? a : b} is applied to lane elements.
*
* @param v the input vector
* @return the minimum of this vector and the input vector
*/
public abstract Vector
* This is a vector binary operation where the operation
* {@code (a, b) -> a < b ? a : b} is applied to lane elements.
*
* @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
* This is a vector binary operation where the operation
* {@code (a, b) -> a > b ? a : b} is applied to lane elements.
*
* @param v the input vector
* @return the maximum of this vector and the input vector
*/
public abstract Vector
* This is a vector binary operation where the operation
* {@code (a, b) -> a > b ? a : b} is applied to lane elements.
*
* @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
* This is a vector binary test operation where the primitive equals
* operation ({@code ==}) is applied to lane elements.
*
* @param v the input vector
* @return the result mask of testing if this vector is equal to the input
* vector
*/
public abstract Mask
* This is a vector binary test operation where the primitive not equals
* operation ({@code !=}) is applied to lane elements.
*
* @param v the input vector
* @return the result mask of testing if this vector is not equal to the
* input vector
*/
public abstract Mask
* This is a vector binary test operation where the primitive less than
* operation ({@code <}) is applied to lane elements.
*
* @param v the input vector
* @return the mask result of testing if this vector is less than the input
* vector
*/
public abstract Mask
* This is a vector binary test operation where the primitive less than
* or equal to operation ({@code <=}) is applied to lane elements.
*
* @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
* This is a vector binary test operation where the primitive greater than
* operation ({@code >}) is applied to lane elements.
*
* @param v the input vector
* @return the mask result of testing if this vector is greater than the
* input vector
*/
public abstract Mask
* This is a vector binary test operation where the primitive greater than
* or equal to operation ({@code >=}) is applied to lane elements.
*
* @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
* This is a cross-lane operation that permutes the lane elements of this
* vector.
* For each lane of the input vector, at lane index {@code N}, the lane
* element is placed into to the result vector at lane index
* {@code (i + N) % this.length()}.
*
* @param i the number of lanes to rotate left
* @return the result of rotating left lane elements of this vector by the
* given number of lanes
*/
public abstract Vector
* This is a cross-lane operation that permutes the lane elements of this
* vector and behaves as if rotating left the lane elements by
* {@code this.length() - (i % this.length())} lanes.
*
* @param i the number of lanes to rotate left
* @return the result of rotating right lane elements of this vector by the
* given number of lanes
*/
public abstract Vector
* This is a cross-lane operation that permutes the lane elements of this
* vector and behaves as if rotating left the lane elements by {@code i},
* and then the zero value is placed into the result vector at lane indexes
* less than {@code i % this.length()}.
*
* @param i the number of lanes to shift left
* @return the result of shifting left lane elements of this vector by the
* given number of lanes
* @throws IllegalArgumentException if {@code i} is {@code < 0}.
*/
public abstract Vector
* This is a cross-lane operation that permutes the lane elements of this
* vector and behaves as if rotating right the lane elements by {@code i},
* and then the zero value is placed into the result vector at lane indexes
* greater or equal to {@code this.length() - (i % this.length())}.
*
* @param i the number of lanes to shift left
* @return the result of shifting left lane elements of this vector by the
* given number of lanes
* @throws IllegalArgumentException if {@code i} is {@code < 0}.
*/
public abstract Vector
* For each lane of the mask, at lane index {@code N}, if the mask lane
* is set then the lane element at {@code N} from the input vector is
* selected and placed into the resulting vector at {@code N},
* otherwise the the lane element at {@code N} from this input vector is
* selected and placed into the resulting vector at {@code N}.
*
* @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
* This is a cross-lane operation that rearranges the lane elements of this
* vector and the input vector. This method behaves as if it rearranges
* each vector with the corresponding shuffle and then blends the two
* results with the mask:
*
* This is a cross-lane operation that rearranges the lane elements of this
* vector.
* For each lane of the shuffle, at lane index {@code N} with lane
* element {@code I}, the lane element at {@code I} from this vector is
* selected and placed into the resulting vector at {@code N}.
*
* @param s the shuffle controlling lane index selection
* @return the rearrangement of the lane elements of this vector
*/
// rearrange
public abstract Vector
* This methods behaves as if it returns the result of creating a shuffle
* given an array of the vector lane elements, as follows:
*
* The underlying bits of this vector are copied to the resulting
* vector without modification, but those bits, before copying, may be
* truncated if the this vector's bit size is greater than desired vector's bit
* size, or appended to with zero bits if this vector's bit size is less
* than desired vector's bit size.
*
* The method behaves as if this vector is stored into a byte buffer
* and then the desired vector is loaded from the byte buffer using
* native byte ordering. The implication is that ByteBuffer reads bytes
* and then composes them based on the byte ordering so the result
* depends on this composition.
*
* For example, on a system with ByteOrder.LITTLE_ENDIAN, loading from
* byte array with values {0,1,2,3} and reshaping to int, leads to bytes
* being composed in order 0x3 0x2 0x1 0x0 which is decimal value 50462976.
* On a system with ByteOrder.BIG_ENDIAN, the value is instead 66051 because
* bytes are composed in order 0x0 0x1 0x2 0x3.
*
* The following pseudocode expresses the behaviour:
*
* The lane elements of this vector are copied without
* modification to the resulting vector, but those lane elements, before
* copying, may be truncated if this vector's length is greater than the desired
* vector's length, or appended to with default element values if this
* vector's length is less than desired vector's length.
*
* The method behaves as if this vector is stored into a byte array
* and then the returned vector is loaded from the byte array.
* The following pseudocode expresses the behaviour:
*
* For each vector lane up to the length of this vector or
* desired vector, which ever is the minimum, and where {@code N} is the
* vector lane index, the element at index {@code N} of primitive type
* {@code E} is converted, according to primitive conversion rules
* specified by the Java Language Specification, to a value of primitive
* type {@code F} and placed into the resulting vector at lane index
* {@code N}. If desired vector's length is greater than this
* vector's length then the default primitive value is placed into
* subsequent lanes of the resulting vector.
*
* @param s species of the desired vector
* @param
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
*
* This method behaves as it calls the
* byte buffer, offset, and mask accepting
* {@link #intoByteBuffer(ByteBuffer, int, Mask) method} as follows:
*
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
*
* This method behaves as it calls the
* byte buffer, offset, and mask accepting
* {@link #intoByteBuffer(ByteBuffer, int, Mask) method} as follows:
*
* Bytes are extracted from primitive lane elements according to the
* native byte order of the underlying platform.
*
* This method behaves as if it calls the byte buffer, offset, and mask
* accepting
* {@link #intoByteBuffer(ByteBuffer, int, Mask)} method} as follows:
*
* This method behaves as if the byte buffer is viewed as a primitive
* {@link java.nio.Buffer buffer} for the primitive element type,
* according to the native byte order of the underlying platform, and
* the lane elements of this vector are put into the buffer if the
* corresponding mask lane is set.
* The following pseudocode expresses the behaviour, where
* {@coce EBuffer} is the primitive buffer type, {@code e} is the
* primitive element type, and {@code EVector
* 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
* 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.
*
* A lane is said to be set if the lane element is {@code true},
* otherwise a lane is said to be unset if the lane element is
* {@code false}.
*
* Mask declares a limited set of unary, binary and reductive mask
* operations.
*
* 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
* 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.
*
* This method behaves as if it {@link #intoArray(boolean[], int)} stores}
* this mask into an allocated array and returns that array as
* follows:
*
* 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.
*
* 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
* 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
* 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
* 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
* 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.
*
* 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
* 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
* This method behaves as if it {@link #intoArray(int[], int)} stores}
* this shuffle into an allocated array and returns that array as
* follows:
*
* 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.
*
* 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:
*
* 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{@code
* return this.rearrange(s1).blend(v.rearrange(s2), m);
* }
*
* @param v the input vector
* @param s the shuffle controlling lane index selection of the input vector
* if corresponding mask lanes are set, otherwise controlling lane
* index selection of this vector
* @param m the mask controlling shuffled lane selection
* @return the rearrangement of lane elements of this vector and
* those of an input vector
*/
@ForceInline
// rearrange
public abstract Vector{@code
* $type$[] a = this.toArray();
* int[] sa = new int[a.length];
* for (int i = 0; i < a.length; i++) {
* sa[i] = (int) a[i];
* }
* return this.species().shuffleFromValues(sa);
* }
*
* @return a shuffle representation of this vector
*/
public abstract Shuffle{@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);
* }
*
* @param s species of desired vector
* @param {@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);
* }
*
* @param s species of the desired vector
* @return a vector transformed, by shape, from this vector
*/
public abstract Vector{@code
* return this.intoByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
* }
*
* @param a the byte array
* @param i the offset into the array
* @return a vector loaded from a byte array
* @throws IndexOutOfBoundsException if {@code i < 0} or
* {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
*/
public abstract void intoByteArray(byte[] a, int i);
/**
* Stores this vector into a byte array starting at an offset and using a mask.
* {@code
* return this.intoByteBuffer(ByteBuffer.wrap(a), i, m);
* }
*
* @param a the byte array
* @param i the offset into the array
* @param m the mask controlling lane selection
* @throws IndexOutOfBoundsException if the offset is {@code < 0},
* 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{@code
* this.intoByteBuffer(b, i, this.maskAllTrue())
* }
*
* @param b the byte buffer
* @param i the offset into the byte buffer
* @throws IndexOutOfBoundsException if the offset is {@code < 0},
* or {@code > b.limit()},
* or if there are fewer than
* {@code this.length() * this.elementSize() / Byte.SIZE} bytes
* remaining in the byte buffer from the given offset
*/
public abstract void intoByteBuffer(ByteBuffer b, int i);
/**
* Stores this vector into a {@link ByteBuffer byte buffer} starting at an
* offset into the byte buffer and using a mask.
* } is the primitive
* vector type for this vector:
* {@code
* EBuffer eb = b.duplicate().
* order(ByteOrder.nativeOrder()).position(i).
* asEBuffer();
* e[] es = ((EVector
*
* @param b the byte buffer
* @param i the offset into the byte buffer
* @param m the mask
* @throws IndexOutOfBoundsException if the offset is {@code < 0},
* 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)this).toArray();
* for (int n = 0; n < t.length; n++) {
* if (m.isSet(n)) {
* eb.put(n, es[n]);
* }
* }
* }
*
* @param {@code
* Mask
*
* {@code
* Mask
*
* {@code
* boolean[] a = new boolean[this.length()];
* this.intoArray(a, 0);
* return a;
* }
*
* @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.
* {@code
* int[] a = new int[this.length()];
* this.intoArray(a, 0);
* return a;
* }
*
* @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.
* {@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);
* }
*
* @return a vector representation of this shuffle
*/
public abstract Vector