13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have
23 * questions.
24 */
25 package jdk.incubator.vector;
26
27 import jdk.internal.misc.Unsafe;
28 import jdk.internal.vm.annotation.ForceInline;
29 import jdk.internal.vm.annotation.Stable;
30
31 import java.nio.ByteBuffer;
32 import java.nio.ByteOrder;
33 import java.util.function.IntUnaryOperator;
34 import jdk.incubator.vector.*;
35
36 /**
37 * A {@code Vector} is designed for use in computations that can be transformed
38 * by a runtime compiler, on supported hardware, to Single Instruction Multiple
39 * Data (SIMD) computations leveraging vector hardware registers and vector
40 * hardware instructions. Such SIMD computations exploit data parallelism to
41 * perform the same operation on multiple data points simultaneously in a
42 * faster time it would ordinarily take to perform the same operation
43 * sequentially on each data point.
44 * <p>
45 * A Vector represents an ordered immutable sequence of values of the same
46 * element type {@code e} that is one of the following primitive types
47 * {@code byte}, {@code short}, {@code int}, {@code long}, {@code float}, or
48 * {@code double}). The type variable {@code E} corresponds to the boxed
49 * element type, specifically the class that wraps a value of {@code e} in an
50 * object (such the {@code Integer} class that wraps a value of {@code int}}.
51 * A Vector has a {@link #shape() shape} {@code S}, extending type
52 * {@link Shape}, that governs the total {@link #bitSize() size} in bits
53 * of the sequence of values.
54 * <p>
55 * The number of values in the sequence is referred to as the Vector
56 * {@link #length() length}. The length also corresponds to the number of
57 * Vector lanes. The lane element at lane index {@code N} (from {@code 0},
58 * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th value in
59 * the sequence.
60 * Note: this arrangement
61 * of Vector bit size, Vector length, element bit size, and lane element index
62 * has no bearing on how a Vector instance and its sequence of elements may be
63 * arranged in memory or represented as a value in a vector hardware register.
64 * <p>
65 * Vector declares a set of vector operations (methods) that are common to all
66 * element types (such as addition). Sub-classes of Vector with a concrete
67 * boxed element type declare further operations that are specific to that
68 * element type (such as access to element values in lanes, logical operations
69 * on values of integral elements types, or transcendental operations on values
70 * of floating point element types).
71 * There are six sub-classes of Vector corresponding to the supported set
72 * of element types, {@link ByteVector}, {@link ShortVector},
73 * {@link IntVector} {@link LongVector}, {@link FloatVector}, and
74 * {@link DoubleVector}.
75 * <p>
76 * Vector values, instances of Vector, are created from a special kind of
77 * factory called a {@link Species}. A Species has an
78 * element type and shape and creates Vector values of the same element type
79 * and shape.
80 * A species can be {@link Species#of(Class, Shape)} obtained} given an element
81 * type and shape, or a preferred species can be
82 * {@link Species#ofPreferred(Class)} obtained} given just an element type where the most
83 * optimal shape is selected for the current platform. It is recommended that
84 * Species instances be held in {@code static final} fields for optimal creation
85 * and usage of Vector values by the runtime compiler.
86 * <p>
87 * Vector operations can be grouped into various categories and their behaviour
88 * generally specified as follows:
89 * <ul>
90 * <li>
91 * A vector unary operation (1-ary) operates on one input vector to produce a
92 * result vector.
93 * For each lane of the input vector the
94 * lane element is operated on using the specified scalar unary operation and
95 * the element result is placed into the vector result at the same lane.
96 * The following pseudocode expresses the behaviour of this operation category,
97 * where {@code e} is the element type and {@code EVector} corresponds to the
98 * primitive Vector type:
99 *
100 * <pre>{@code
101 * EVector<S> a = ...;
102 * e[] ar = new e[a.length()];
103 * for (int i = 0; i < a.length(); i++) {
104 * ar[i] = scalar_unary_op(a.get(i));
160 * }
161 * }</pre>
162 *
163 * Unless otherwise specified the scalar result type and element type will be
164 * the same.
165 *
166 * <li>
167 * A vector binary test operation operates on two input vectors to produce a
168 * result mask. For each lane of the two input vectors, a and b say, the
169 * the corresponding lane elements from a and b are operated on using the
170 * specified scalar binary test operation and the boolean result is placed
171 * into the mask at the same lane.
172 * The following pseudocode expresses the behaviour of this operation category:
173 * <pre>{@code
174 * EVector<S> a = ...;
175 * EVector<S> b = ...;
176 * boolean[] ar = new boolean[a.length()];
177 * for (int i = 0; i < a.length(); i++) {
178 * ar[i] = scalar_binary_test_op(a.get(i), b.get(i));
179 * }
180 * Mask<E> r = a.species().maskFromArray(ar, 0);
181 * }</pre>
182 *
183 * Unless otherwise specified the two input vectors and result mask will have
184 * the same element type and shape.
185 *
186 * <li>
187 * The prior categories of operation can be said to operate within the vector
188 * lanes, where lane access is uniformly applied to all vectors, specifically
189 * the scalar operation is applied to elements taken from input vectors at the
190 * same lane, and if appropriate applied to the result vector at the same lane.
191 * A further category of operation is a cross-lane vector operation where lane
192 * access is defined by the arguments to the operation. Cross-lane operations
193 * generally rearrange lane elements, for example by permutation (commonly
194 * controlled by a {@link Shuffle}) or by blending (commonly controlled by a
195 * {@link Mask}). Such an operation explicitly specifies how it rearranges lane
196 * elements.
197 * </ul>
198 *
199 * If a vector operation is represented as an instance method then first input
200 * vector corresponds to {@code this} vector and subsequent input vectors are
201 * arguments of the method. Otherwise, if the an operation is represented as a
202 * static method then all input vectors are arguments of the method.
203 * <p>
204 * If a vector operation does not belong to one of the above categories then
205 * the operation explicitly specifies how it processes the lane elements of
206 * input vectors, and where appropriate expresses the behaviour using
207 * pseudocode.
208 *
209 * <p>
210 * Many vector operations provide an additional {@link Mask mask} accepting
211 * variant.
212 * The mask controls which lanes are selected for application of the scalar
213 * operation. Masks are a key component for the support of control flow in
214 * vector computations.
215 * <p>
216 * For certain operation categories the mask accepting variants can be specified
217 * in generic terms. If a lane of the mask is set then the scalar operation is
218 * applied to corresponding lane elements, otherwise if a lane of a mask is not
219 * set then a default scalar operation is applied and its result is placed into
220 * the vector result at the same lane. The default operation is specified for
221 * the following operation categories:
222 * <ul>
223 * <li>
224 * For a vector n-ary operation the default operation is a function that returns
225 * it's first argument, specifically a lane element of the first input vector.
226 * <li>
227 * For an associative vector reduction operation the default operation is a
228 * function that returns the identity value.
229 * <li>
230 * For vector binary test operation the default operation is a function that
231 * returns false.
232 *</ul>
233 * Otherwise, the mask accepting variant of the operation explicitly specifies
234 * how it processes the lane elements of input vectors, and where appropriate
235 * expresses the behaviour using pseudocode.
236 *
237 * <p>
238 * For convenience many vector operations, of arity greater than one, provide
239 * an additional scalar accepting variant. This variant accepts compatible
240 * scalar values instead of vectors for the second and subsequent input vectors,
241 * if any.
242 * Unless otherwise specified the scalar variant behaves as if each scalar value
243 * is transformed to a vector using the vector Species
244 * {@code broadcast} operation, and
245 * then the vector accepting vector operation is applied using the transformed
246 * values.
247 *
248 * <p>
249 * This is a value-based
250 * class; use of identity-sensitive operations (including reference equality
251 * ({@code ==}), identity hash code, or synchronization) on instances of
252 * {@code Vector} may have unpredictable results and should be avoided.
253 *
254 * @param <E> the boxed element type of elements in this vector
255 */
256 public abstract class Vector<E> {
257
258 Vector() {}
259
260 /**
261 * Returns the species of this vector.
262 *
263 * @return the species of this vector
264 */
265 public abstract Species<E> species();
266
267 /**
268 * Returns the primitive element type of this vector.
269 *
270 * @return the primitive element type of this vector
271 */
272 public Class<E> elementType() { return species().elementType(); }
273
274 /**
275 * Returns the element size, in bits, of this vector.
276 *
277 * @return the element size, in bits
278 */
279 public int elementSize() { return species().elementSize(); }
280
281 /**
282 * Returns the shape of this vector.
283 *
284 * @return the shape of this vector
285 */
286 public Shape shape() { return species().shape(); }
287
288 /**
289 * Returns the number of vector lanes (the length).
290 *
291 * @return the number of vector lanes
292 */
293 public int length() { return species().length(); }
294
295 /**
296 * Returns the total vector size, in bits.
297 *
298 * @return the total vector size, in bits
299 */
300 public int bitSize() { return species().bitSize(); }
301
302 //Arithmetic
303
304 /**
305 * Adds this vector to an input vector.
306 * <p>
307 * This is a vector binary operation where the primitive addition operation
308 * ({@code +}) is applied to lane elements.
309 *
310 * @param v the input vector
311 * @return the result of adding this vector to the input vector
312 */
313 public abstract Vector<E> add(Vector<E> v);
314
315 /**
316 * Adds this vector to an input vector, selecting lane elements
317 * controlled by a mask.
318 * <p>
319 * This is a vector binary operation where the primitive addition operation
320 * ({@code +}) is applied to lane elements.
321 *
322 * @param v the input vector
323 * @param m the mask controlling lane selection
324 * @return the result of adding this vector to the given vector
325 */
326 public abstract Vector<E> add(Vector<E> v, Mask<E> m);
327
328 /**
329 * Subtracts an input vector from this vector.
330 * <p>
331 * This is a vector binary operation where the primitive subtraction
332 * operation ({@code -}) is applied to lane elements.
333 *
334 * @param v the input vector
335 * @return the result of subtracting the input vector from this vector
336 */
337 public abstract Vector<E> sub(Vector<E> v);
338
339 /**
340 * Subtracts an input vector from this vector, selecting lane elements
341 * controlled by a mask.
342 * <p>
343 * This is a vector binary operation where the primitive subtraction
344 * operation ({@code -}) is applied to lane elements.
345 *
346 * @param v the input vector
347 * @param m the mask controlling lane selection
348 * @return the result of subtracting the input vector from this vector
349 */
350 public abstract Vector<E> sub(Vector<E> v, Mask<E> m);
351
352 /**
353 * Multiplies this vector with an input vector.
354 * <p>
355 * This is a vector binary operation where the primitive multiplication
356 * operation ({@code *}) is applied to lane elements.
357 *
358 * @param v the input vector
359 * @return the result of multiplying this vector with the input vector
360 */
361 public abstract Vector<E> mul(Vector<E> v);
362
363 /**
364 * Multiplies this vector with an input vector, selecting lane elements
365 * controlled by a mask.
366 * <p>
367 * This is a vector binary operation where the primitive multiplication
368 * operation ({@code *}) is applied to lane elements.
369 *
370 * @param v the input vector
371 * @param m the mask controlling lane selection
372 * @return the result of multiplying this vector with the input vector
373 */
374 public abstract Vector<E> mul(Vector<E> v, Mask<E> m);
375
376 /**
377 * Negates this vector.
378 * <p>
379 * This is a vector unary operation where the primitive negation operation
380 * ({@code -}) is applied to lane elements.
381 *
382 * @return the negation this vector
383 */
384 public abstract Vector<E> neg();
385
386 /**
387 * Negates this vector, selecting lane elements controlled by a mask.
388 * <p>
389 * This is a vector unary operation where the primitive negation operation
390 * ({@code -})is applied to lane elements.
391 *
392 * @param m the mask controlling lane selection
393 * @return the negation this vector
394 */
395 public abstract Vector<E> neg(Mask<E> m);
396
397 // Maths from java.math
398
399 /**
400 * Returns the modulus of this vector.
401 * <p>
402 * This is a vector unary operation where the operation
403 * {@code (a) -> (a < 0) ? -a : a} is applied to lane elements.
404 *
405 * @return the modulus this vector
406 */
407 public abstract Vector<E> abs();
408
409 /**
410 * Returns the modulus of this vector, selecting lane elements controlled by
411 * a mask.
412 * <p>
413 * This is a vector unary operation where the operation
414 * {@code (a) -> (a < 0) ? -a : a} is applied to lane elements.
415 *
416 * @param m the mask controlling lane selection
417 * @return the modulus this vector
418 */
419 public abstract Vector<E> abs(Mask<E> m);
420
421 /**
422 * Returns the minimum of this vector and an input vector.
423 * <p>
424 * This is a vector binary operation where the operation
425 * {@code (a, b) -> a < b ? a : b} is applied to lane elements.
426 *
427 * @param v the input vector
428 * @return the minimum of this vector and the input vector
429 */
430 public abstract Vector<E> min(Vector<E> v);
431
432 /**
433 * Returns the minimum of this vector and an input vector,
434 * selecting lane elements controlled by a mask.
435 * <p>
436 * This is a vector binary operation where the operation
437 * {@code (a, b) -> a < b ? a : b} is applied to lane elements.
438 *
439 * @param v the input vector
440 * @param m the mask controlling lane selection
441 * @return the minimum of this vector and the input vector
442 */
443 public abstract Vector<E> min(Vector<E> v, Mask<E> m);
444
445 /**
446 * Returns the maximum of this vector and an input vector.
447 * <p>
448 * This is a vector binary operation where the operation
449 * {@code (a, b) -> a > b ? a : b} is applied to lane elements.
450 *
451 * @param v the input vector
452 * @return the maximum of this vector and the input vector
453 */
454 public abstract Vector<E> max(Vector<E> v);
455
456 /**
457 * Returns the maximum of this vector and an input vector,
458 * selecting lane elements controlled by a mask.
459 * <p>
460 * This is a vector binary operation where the operation
461 * {@code (a, b) -> a > b ? a : b} is applied to lane elements.
462 *
463 * @param v the input vector
464 * @param m the mask controlling lane selection
465 * @return the maximum of this vector and the input vector
466 */
467 public abstract Vector<E> max(Vector<E> v, Mask<E> m);
468
469 // Comparisons
470
471 /**
472 * Tests if this vector is equal to an input vector.
473 * <p>
474 * This is a vector binary test operation where the primitive equals
475 * operation ({@code ==}) is applied to lane elements.
476 *
477 * @param v the input vector
478 * @return the result mask of testing if this vector is equal to the input
479 * vector
480 */
481 public abstract Mask<E> equal(Vector<E> v);
482
483 /**
484 * Tests if this vector is not equal to an input vector.
485 * <p>
486 * This is a vector binary test operation where the primitive not equals
487 * operation ({@code !=}) is applied to lane elements.
488 *
489 * @param v the input vector
490 * @return the result mask of testing if this vector is not equal to the
491 * input vector
492 */
493 public abstract Mask<E> notEqual(Vector<E> v);
494
495 /**
496 * Tests if this vector is less than an input vector.
497 * <p>
498 * This is a vector binary test operation where the primitive less than
499 * operation ({@code <}) is applied to lane elements.
500 *
501 * @param v the input vector
502 * @return the mask result of testing if this vector is less than the input
503 * vector
504 */
505 public abstract Mask<E> lessThan(Vector<E> v);
506
507 /**
508 * Tests if this vector is less or equal to an input vector.
509 * <p>
510 * This is a vector binary test operation where the primitive less than
511 * or equal to operation ({@code <=}) is applied to lane elements.
512 *
513 * @param v the input vector
514 * @return the mask result of testing if this vector is less than or equal
515 * to the input vector
516 */
517 public abstract Mask<E> lessThanEq(Vector<E> v);
518
519 /**
520 * Tests if this vector is greater than an input vector.
521 * <p>
522 * This is a vector binary test operation where the primitive greater than
523 * operation ({@code >}) is applied to lane elements.
524 *
525 * @param v the input vector
526 * @return the mask result of testing if this vector is greater than the
527 * input vector
528 */
529 public abstract Mask<E> greaterThan(Vector<E> v);
530
531 /**
532 * Tests if this vector is greater than or equal to an input vector.
533 * <p>
534 * This is a vector binary test operation where the primitive greater than
535 * or equal to operation ({@code >=}) is applied to lane elements.
536 *
537 * @param v the input vector
538 * @return the mask result of testing if this vector is greater than or
539 * equal to the given vector
540 */
541 public abstract Mask<E> greaterThanEq(Vector<E> v);
542
543 // Elemental shifting
544
545 /**
546 * Rotates left the lane elements of this vector by the given number of
547 * lanes, {@code i}, modulus the vector length.
548 * <p>
549 * This is a cross-lane operation that permutes the lane elements of this
550 * vector.
551 * For each lane of the input vector, at lane index {@code N}, the lane
552 * element is placed into to the result vector at lane index
553 * {@code (i + N) % this.length()}.
554 *
555 * @param i the number of lanes to rotate left
556 * @return the result of rotating left lane elements of this vector by the
557 * given number of lanes
558 */
559 public abstract Vector<E> rotateEL(int i);
560
561 /**
602 * given number of lanes
603 * @throws IllegalArgumentException if {@code i} is {@code < 0}.
604 */
605 public abstract Vector<E> shiftER(int i);
606
607 /**
608 * Blends the lane elements of this vector with those of an input vector,
609 * selecting lanes controlled by a mask.
610 * <p>
611 * For each lane of the mask, at lane index {@code N}, if the mask lane
612 * is set then the lane element at {@code N} from the input vector is
613 * selected and placed into the resulting vector at {@code N},
614 * otherwise the the lane element at {@code N} from this input vector is
615 * selected and placed into the resulting vector at {@code N}.
616 *
617 * @param v the input vector
618 * @param m the mask controlling lane selection
619 * @return the result of blending the lane elements of this vector with
620 * those of an input vector
621 */
622 public abstract Vector<E> blend(Vector<E> v, Mask<E> m);
623
624 /**
625 * Rearranges the lane elements of this vector and those of an input vector,
626 * selecting lane indexes controlled by shuffles and a mask.
627 * <p>
628 * This is a cross-lane operation that rearranges the lane elements of this
629 * vector and the input vector. This method behaves as if it rearranges
630 * each vector with the corresponding shuffle and then blends the two
631 * results with the mask:
632 * <pre>{@code
633 * return this.rearrange(s1).blend(v.rearrange(s2), m);
634 * }</pre>
635 *
636 * @param v the input vector
637 * @param s the shuffle controlling lane index selection of the input vector
638 * if corresponding mask lanes are set, otherwise controlling lane
639 * index selection of this vector
640 * @param m the mask controlling shuffled lane selection
641 * @return the rearrangement of lane elements of this vector and
642 * those of an input vector
643 */
644 @ForceInline
645 // rearrange
646 public abstract Vector<E> rearrange(Vector<E> v,
647 Shuffle<E> s, Mask<E> m);
648
649 /**
650 * Rearranges the lane elements of this vector selecting lane indexes
651 * controlled by a shuffle.
652 * <p>
653 * This is a cross-lane operation that rearranges the lane elements of this
654 * vector.
655 * For each lane of the shuffle, at lane index {@code N} with lane
656 * element {@code I}, the lane element at {@code I} from this vector is
657 * selected and placed into the resulting vector at {@code N}.
658 *
659 * @param s the shuffle controlling lane index selection
660 * @return the rearrangement of the lane elements of this vector
661 */
662 // rearrange
663 public abstract Vector<E> rearrange(Shuffle<E> s);
664
665
666 // Conversions
667
668 /**
669 * Converts this vector into a shuffle, creating a shuffle from vector
670 * lane elements cast to {@code int} then logically AND'ed with the
671 * shuffle length minus one.
672 * <p>
673 * This methods behaves as if it returns the result of creating a shuffle
674 * given an array of the vector lane elements, as follows:
675 * <pre>{@code
676 * $type$[] a = this.toArray();
677 * int[] sa = new int[a.length];
678 * for (int i = 0; i < a.length; i++) {
679 * sa[i] = (int) a[i];
680 * }
681 * return this.species().shuffleFromValues(sa);
682 * }</pre>
683 *
684 * @return a shuffle representation of this vector
685 */
686 public abstract Shuffle<E> toShuffle();
687
688 // Bitwise preserving
689
690 /**
691 * Transforms this vector to a vector of the given species of element type {@code F}.
692 * <p>
693 * The underlying bits of this vector are copied to the resulting
694 * vector without modification, but those bits, before copying, may be
695 * truncated if the this vector's bit size is greater than desired vector's bit
696 * size, or appended to with zero bits if this vector's bit size is less
697 * than desired vector's bit size.
698 * <p>
699 * The method behaves as if this vector is stored into a byte buffer
700 * and then the desired vector is loaded from the byte buffer using
701 * native byte ordering. The implication is that ByteBuffer reads bytes
702 * and then composes them based on the byte ordering so the result
703 * depends on this composition.
704 * <p>
705 * For example, on a system with ByteOrder.LITTLE_ENDIAN, loading from
706 * byte array with values {0,1,2,3} and reshaping to int, leads to bytes
707 * being composed in order 0x3 0x2 0x1 0x0 which is decimal value 50462976.
708 * On a system with ByteOrder.BIG_ENDIAN, the value is instead 66051 because
709 * bytes are composed in order 0x0 0x1 0x2 0x3.
710 * <p>
711 * The following pseudocode expresses the behaviour:
712 * <pre>{@code
713 * int blen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
714 * ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
715 * this.intoByteBuffer(bb, 0);
716 * return s.fromByteBuffer(bb, 0);
717 * }</pre>
718 *
719 * @param s species of desired vector
720 * @param <F> the boxed element type of the species
721 * @return a vector transformed, by shape and element type, from this vector
722 */
723 @ForceInline
724 public abstract <F> Vector<F> reinterpret(Species<F> s);
725
726 @ForceInline
727 @SuppressWarnings("unchecked")
728 <F> Vector<F> defaultReinterpret(Species<F> s) {
729 int blen = Math.max(s.bitSize(), this.species().bitSize()) / Byte.SIZE;
730 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
731 this.intoByteBuffer(bb, 0);
732
733 Class<?> stype = s.elementType();
734 if (stype == byte.class) {
735 return (Vector) ByteVector.fromByteBuffer((ByteVector.ByteSpecies)s, bb, 0);
736 } else if (stype == short.class) {
737 return (Vector) ShortVector.fromByteBuffer((ShortVector.ShortSpecies)s, bb, 0);
738 } else if (stype == int.class) {
739 return (Vector) IntVector.fromByteBuffer((IntVector.IntSpecies)s, bb, 0);
740 } else if (stype == long.class) {
741 return (Vector) LongVector.fromByteBuffer((LongVector.LongSpecies)s, bb, 0);
742 } else if (stype == float.class) {
743 return (Vector) FloatVector.fromByteBuffer((FloatVector.FloatSpecies)s, bb, 0);
744 } else if (stype == double.class) {
745 return (Vector) DoubleVector.fromByteBuffer((DoubleVector.DoubleSpecies)s, bb, 0);
746 } else {
747 throw new UnsupportedOperationException("Bad lane type for reinterpret.");
748 }
749 }
750
751 /**
752 * Transforms this vector to a vector of same element type but different shape identified by species.
753 * <p>
754 * The lane elements of this vector are copied without
755 * modification to the resulting vector, but those lane elements, before
756 * copying, may be truncated if this vector's length is greater than the desired
757 * vector's length, or appended to with default element values if this
758 * vector's length is less than desired vector's length.
759 * <p>
760 * The method behaves as if this vector is stored into a byte array
761 * and then the returned vector is loaded from the byte array.
762 * The following pseudocode expresses the behaviour:
763 * <pre>{@code
764 * int alen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
765 * byte[] a = new byte[alen];
766 * this.intoByteArray(a, 0);
767 * return s.fromByteArray(a, 0);
768 * }</pre>
769 *
770 * @param s species of the desired vector
771 * @return a vector transformed, by shape, from this vector
772 */
773 public abstract Vector<E> reshape(Species<E> s);
774
775 // Cast
776
777 /**
778 * Converts this vector to a vector of the given species element type {@code F}.
779 * <p>
780 * For each vector lane up to the length of this vector or
781 * desired vector, which ever is the minimum, and where {@code N} is the
782 * vector lane index, the element at index {@code N} of primitive type
783 * {@code E} is converted, according to primitive conversion rules
784 * specified by the Java Language Specification, to a value of primitive
785 * type {@code F} and placed into the resulting vector at lane index
786 * {@code N}. If desired vector's length is greater than this
787 * vector's length then the default primitive value is placed into
788 * subsequent lanes of the resulting vector.
789 *
790 * @param s species of the desired vector
791 * @param <F> the boxed element type of the species
792 * @return a vector converted by shape and element type from this vector
793 */
794 public abstract <F> Vector<F> cast(Species<F> s);
795
796 //Array stores
797
798 /**
799 * Stores this vector into a byte array starting at an offset.
800 * <p>
801 * Bytes are extracted from primitive lane elements according to the
802 * native byte order of the underlying platform.
803 * <p>
804 * This method behaves as it calls the
805 * byte buffer, offset, and mask accepting
806 * {@link #intoByteBuffer(ByteBuffer, int, Mask) method} as follows:
807 * <pre>{@code
808 * return this.intoByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
809 * }</pre>
810 *
811 * @param a the byte array
812 * @param i the offset into the array
813 * @return a vector loaded from a byte array
814 * @throws IndexOutOfBoundsException if {@code i < 0} or
815 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
816 */
817 public abstract void intoByteArray(byte[] a, int i);
818
819 /**
820 * Stores this vector into a byte array starting at an offset and using a mask.
821 * <p>
822 * Bytes are extracted from primitive lane elements according to the
823 * native byte order of the underlying platform.
824 * <p>
825 * This method behaves as it calls the
826 * byte buffer, offset, and mask accepting
827 * {@link #intoByteBuffer(ByteBuffer, int, Mask) method} as follows:
828 * <pre>{@code
829 * return this.intoByteBuffer(ByteBuffer.wrap(a), i, m);
830 * }</pre>
831 *
832 * @param a the byte array
833 * @param i the offset into the array
834 * @param m the mask controlling lane selection
835 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
836 * or {@code > a.length},
837 * for any vector lane index {@code N} where the mask at lane {@code N}
838 * is set
839 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
840 */
841 public abstract void intoByteArray(byte[] a, int i, Mask<E> m);
842
843 /**
844 * Stores this vector into a {@link ByteBuffer byte buffer} starting at an
845 * offset into the byte buffer.
846 * <p>
847 * Bytes are extracted from primitive lane elements according to the
848 * native byte order of the underlying platform.
849 * <p>
850 * This method behaves as if it calls the byte buffer, offset, and mask
851 * accepting
852 * {@link #intoByteBuffer(ByteBuffer, int, Mask)} method} as follows:
853 * <pre>{@code
854 * this.intoByteBuffer(b, i, this.maskAllTrue())
855 * }</pre>
856 *
857 * @param b the byte buffer
858 * @param i the offset into the byte buffer
859 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
860 * or {@code > b.limit()},
861 * or if there are fewer than
862 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
863 * remaining in the byte buffer from the given offset
864 */
865 public abstract void intoByteBuffer(ByteBuffer b, int i);
866
867 /**
868 * Stores this vector into a {@link ByteBuffer byte buffer} starting at an
869 * offset into the byte buffer and using a mask.
870 * <p>
871 * This method behaves as if the byte buffer is viewed as a primitive
872 * {@link java.nio.Buffer buffer} for the primitive element type,
881 * EBuffer eb = b.duplicate().
882 * order(ByteOrder.nativeOrder()).position(i).
883 * asEBuffer();
884 * e[] es = ((EVector<S>)this).toArray();
885 * for (int n = 0; n < t.length; n++) {
886 * if (m.isSet(n)) {
887 * eb.put(n, es[n]);
888 * }
889 * }
890 * }</pre>
891 *
892 * @param b the byte buffer
893 * @param i the offset into the byte buffer
894 * @param m the mask
895 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
896 * or {@code > b.limit()},
897 * for any vector lane index {@code N} where the mask at lane {@code N}
898 * is set
899 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes
900 */
901 public abstract void intoByteBuffer(ByteBuffer b, int i, Mask<E> m);
902
903
904 /**
905 * A {@code Shape} governs the total size, in bits, of a
906 * {@link Vector}, {@link Mask}, or {@link Shuffle}. The shape in
907 * combination with the element type together govern the number of lanes.
908 */
909 public enum Shape {
910 /** Shape of length 64 bits */
911 S_64_BIT(64),
912 /** Shape of length 128 bits */
913 S_128_BIT(128),
914 /** Shape of length 256 bits */
915 S_256_BIT(256),
916 /** Shape of length 512 bits */
917 S_512_BIT(512),
918 /** Shape of maximum length supported on the platform */
919 S_Max_BIT(Unsafe.getUnsafe().getMaxVectorSize(byte.class) * 8);
920
921 @Stable
922 final int bitSize;
923
924 Shape(int bitSize) {
925 this.bitSize = bitSize;
926 }
927
928 /**
929 * Returns the size, in bits, of this shape.
930 *
931 * @return the size, in bits, of this shape.
932 */
933 public int bitSize() {
934 return bitSize;
935 }
936
937 /**
938 * Return the number of lanes of a vector of this shape and whose element
939 * type is of the provided species
940 *
941 * @param s the species describing the element type
942 * @return the number of lanes
943 */
944 int length(Species<?> s) {
945 return bitSize() / s.elementSize();
946 }
947
948 /**
949 * Finds appropriate shape depending on bitsize.
950 *
951 * @param bitSize the size in bits
952 * @return the shape corresponding to bitsize
953 * @see #bitSize
954 */
955 public static Shape forBitSize(int bitSize) {
956 switch (bitSize) {
957 case 64:
958 return Shape.S_64_BIT;
959 case 128:
960 return Shape.S_128_BIT;
961 case 256:
962 return Shape.S_256_BIT;
963 case 512:
964 return Shape.S_512_BIT;
965 default:
966 if ((bitSize > 0) && (bitSize <= 2048) && (bitSize % 128 == 0)) {
967 return Shape.S_Max_BIT;
968 } else {
969 throw new IllegalArgumentException("Bad vector bit size: " + bitSize);
970 }
971 }
972 }
973 }
974
975
976 /**
977 * Class representing vectors of same element type, {@code E} and {@link Vector.Shape Shape}.
978 *
979 * @param <E> the boxed element type of this species
980 */
981 public static abstract class Species<E> {
982 Species() {}
983
984 /**
985 * Returns the primitive element type of vectors produced by this
986 * species.
987 *
988 * @return the primitive element type
989 */
990 public abstract Class<E> elementType();
991
992 /**
993 * Returns the vector box type for this species
994 *
995 * @return the box type
996 */
997 abstract Class<?> boxType();
998
999 /**
1000 * Returns the vector mask type for this species
1001 *
1002 * @return the box type
1003 */
1004 abstract Class<?> maskType();
1005
1006 /**
1007 * Returns the element size, in bits, of vectors produced by this
1008 * species.
1009 *
1010 * @return the element size, in bits
1011 */
1012 public abstract int elementSize();
1013
1014 /**
1015 * Returns the shape of masks, shuffles, and vectors produced by this
1016 * species.
1017 *
1018 * @return the primitive element type
1019 */
1020 public abstract Shape shape();
1021
1022 /**
1023 * Returns the shape of the corresponding index species
1024 * @return the shape
1025 */
1026 @ForceInline
1027 public abstract Shape indexShape();
1028
1029 /**
1030 * Returns the mask, shuffe, or vector lanes produced by this species.
1031 *
1032 * @return the the number of lanes
1033 */
1034 public int length() { return shape().length(this); }
1035
1036 /**
1037 * Returns the total vector size, in bits, of vectors produced by this
1038 * species.
1039 *
1040 * @return the total vector size, in bits
1041 */
1042 public int bitSize() { return shape().bitSize(); }
1043
1044 // Factory
1045
1046 /**
1047 * Finds a species for an element type and shape.
1048 *
1049 * @param c the element type
1050 * @param s the shape
1051 * @param <E> the boxed element type
1052 * @return a species for an element type and shape
1053 * @throws IllegalArgumentException if no such species exists for the
1054 * element type and/or shape
1055 */
1056 @SuppressWarnings("unchecked")
1057 public static <E> Vector.Species<E> of(Class<E> c, Shape s) {
1058 if (c == float.class) {
1059 return (Vector.Species<E>) FloatVector.species(s);
1060 }
1061 else if (c == double.class) {
1062 return (Vector.Species<E>) DoubleVector.species(s);
1063 }
1064 else if (c == byte.class) {
1065 return (Vector.Species<E>) ByteVector.species(s);
1066 }
1067 else if (c == short.class) {
1068 return (Vector.Species<E>) ShortVector.species(s);
1069 }
1070 else if (c == int.class) {
1071 return (Vector.Species<E>) IntVector.species(s);
1072 }
1073 else if (c == long.class) {
1074 return (Vector.Species<E>) LongVector.species(s);
1075 }
1076 else {
1077 throw new IllegalArgumentException("Bad vector element type: " + c.getName());
1078 }
1079 }
1080
1081 /**
1082 * Finds a preferred species for an element type.
1083 * <p>
1084 * A preferred species is a species chosen by the platform that has a
1085 * shape of maximal bit size. A preferred species for different element
1086 * types will have the same shape, and therefore vectors created from
1087 * such species will be shape compatible.
1088 *
1089 * @param c the element type
1090 * @param <E> the boxed element type
1091 * @return a preferred species for an element type
1092 * @throws IllegalArgumentException if no such species exists for the
1093 * element type
1094 */
1095 public static <E> Vector.Species<E> ofPreferred(Class<E> c) {
1096 Unsafe u = Unsafe.getUnsafe();
1097
1098 int vectorLength = u.getMaxVectorSize(c);
1099 int vectorBitSize = bitSizeForVectorLength(c, vectorLength);
1100 Shape s = Shape.forBitSize(vectorBitSize);
1101 return Species.of(c, s);
1102 }
1103 }
1104
1105 abstract static class AbstractSpecies<E> extends Vector.Species<E> {
1106 @Stable
1107 protected final Vector.Shape shape;
1108 @Stable
1109 protected final Class<E> elementType;
1110 @Stable
1111 protected final int elementSize;
1112 @Stable
1113 protected final Class<?> boxType;
1114 @Stable
1115 protected final Class<?> maskType;
1116 @Stable
1117 protected final Shape indexShape;
1118
1119 AbstractSpecies(Vector.Shape shape, Class<E> elementType, int elementSize, Class<?> boxType, Class<?> maskType) {
1120 this.shape = shape;
1121 this.elementType = elementType;
1122 this.elementSize = elementSize;
1123 this.boxType = boxType;
1124 this.maskType = maskType;
1125
1126 if (boxType == Long64Vector.class || boxType == Double64Vector.class) {
1127 indexShape = Vector.Shape.S_64_BIT;
1128 }
1129 else {
1130 int bitSize = Vector.bitSizeForVectorLength(int.class, shape.bitSize() / elementSize);
1131 indexShape = Vector.Shape.forBitSize(bitSize);
1132 }
1133 }
1134
1135 @Override
1136 @ForceInline
1137 public int bitSize() {
1138 return shape.bitSize();
1139 }
1140
1141 @Override
1142 @ForceInline
1143 public int length() {
1144 return shape.bitSize() / elementSize;
1145 }
1146
1147 @Override
1148 @ForceInline
1149 public Class<E> elementType() {
1150 return elementType;
1151 }
1152
1153 @Override
1154 @ForceInline
1155 public Class<?> boxType() {
1156 return boxType;
1157 }
1158
1159 @Override
1160 @ForceInline
1161 public Class<?> maskType() {
1162 return maskType;
1163 }
1164
1165 @Override
1166 @ForceInline
1167 public int elementSize() {
1168 return elementSize;
1169 }
1170
1171 @Override
1172 @ForceInline
1173 public Vector.Shape shape() {
1174 return shape;
1175 }
1176
1177 @Override
1178 @ForceInline
1179 public Vector.Shape indexShape() { return indexShape; }
1180
1181 @Override
1182 public String toString() {
1183 return new StringBuilder("Shape[")
1184 .append(bitSize()).append(" bits, ")
1185 .append(length()).append(" ").append(elementType.getSimpleName()).append("s x ")
1186 .append(elementSize()).append(" bits")
1187 .append("]")
1188 .toString();
1189 }
1190 }
1191
1192 /**
1193 * A {@code Mask} represents an ordered immutable sequence of {@code boolean}
1194 * values. A Mask can be used with a mask accepting vector operation to
1195 * control the selection and operation of lane elements of input vectors.
1196 * <p>
1197 * The number of values in the sequence is referred to as the Mask
1198 * {@link #length() length}. The length also corresponds to the number of
1199 * Mask lanes. The lane element at lane index {@code N} (from {@code 0},
1200 * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
1201 * value in the sequence.
1202 * A Mask and Vector of the same element type and shape have the same number
1203 * of lanes.
1204 * <p>
1205 * A lane is said to be <em>set</em> if the lane element is {@code true},
1206 * otherwise a lane is said to be <em>unset</em> if the lane element is
1207 * {@code false}.
1208 * <p>
1209 * Mask declares a limited set of unary, binary and reductive mask
1210 * operations.
1211 * <ul>
1212 * <li>
1213 * A mask unary operation (1-ary) operates on one input mask to produce a
1214 * result mask.
1215 * For each lane of the input mask the
1216 * lane element is operated on using the specified scalar unary operation and
1217 * the boolean result is placed into the mask result at the same lane.
1218 * The following pseudocode expresses the behaviour of this operation category:
1219 *
1220 * <pre>{@code
1221 * Mask<E> a = ...;
1222 * boolean[] ar = new boolean[a.length()];
1223 * for (int i = 0; i < a.length(); i++) {
1224 * ar[i] = boolean_unary_op(a.isSet(i));
1225 * }
1226 * Mask<E> r = a.species().maskFromArray(ar, 0);
1227 * }</pre>
1228 *
1229 * <li>
1230 * A mask binary operation (2-ary) operates on two input
1231 * masks to produce a result mask.
1232 * For each lane of the two input masks,
1233 * a and b say, the corresponding lane elements from a and b are operated on
1234 * using the specified scalar binary operation and the boolean result is placed
1235 * into the mask result at the same lane.
1236 * The following pseudocode expresses the behaviour of this operation category:
1237 *
1238 * <pre>{@code
1239 * Mask<E> a = ...;
1240 * Mask<E> b = ...;
1241 * boolean[] ar = new boolean[a.length()];
1242 * for (int i = 0; i < a.length(); i++) {
1243 * ar[i] = scalar_binary_op(a.isSet(i), b.isSet(i));
1244 * }
1245 * Mask<E> r = a.species().maskFromArray(ar, 0);
1246 * }</pre>
1247 *
1248 * </ul>
1249 * @param <E> the boxed element type of this mask
1250 */
1251 public static abstract class Mask<E> {
1252 Mask() {}
1253
1254 /**
1255 * Returns the species of this mask.
1256 *
1257 * @return the species of this mask
1258 */
1259 public abstract Species<E> species();
1260
1261 /**
1262 * Returns the number of mask lanes (the length).
1263 *
1264 * @return the number of mask lanes
1265 */
1266 public int length() { return species().length(); }
1267
1268 /**
1269 * Converts this mask to a mask of the given species shape of element type {@code F}.
1270 * <p>
1271 * For each mask lane, where {@code N} is the lane index, if the
1272 * mask lane at index {@code N} is set, then the mask lane at index
1273 * {@code N} of the resulting mask is set, otherwise that mask lane is
1274 * not set.
1275 *
1276 * @param s the species of the desired mask
1277 * @param <F> the boxed element type of the species
1278 * @return a mask converted by shape and element type
1279 * @throws IllegalArgumentException if this mask length and the species
1280 * length differ
1281 */
1282 public abstract <F> Mask<F> cast(Species<F> s);
1283
1284 /**
1285 * Returns the lane elements of this mask packed into a {@code long}
1286 * value for at most the first 64 lane elements.
1287 * <p>
1288 * The lane elements are packed in the order of least significant bit
1289 * to most significant bit.
1290 * For each mask lane where {@code N} is the mask lane index, if the
1291 * mask lane is set then the {@code N}'th bit is set to one in the
1292 * resulting {@code long} value, otherwise the {@code N}'th bit is set
1293 * to zero.
1294 *
1295 * @return the lane elements of this mask packed into a {@code long}
1296 * value.
1297 */
1298 public abstract long toLong();
1299
1300 /**
1301 * Returns an {@code boolean} array containing the lane elements of this
1302 * mask.
1303 * <p>
1304 * This method behaves as if it {@link #intoArray(boolean[], int)} stores}
1305 * this mask into an allocated array and returns that array as
1306 * follows:
1307 * <pre>{@code
1308 * boolean[] a = new boolean[this.length()];
1309 * this.intoArray(a, 0);
1310 * return a;
1311 * }</pre>
1312 *
1313 * @return an array containing the the lane elements of this vector
1314 */
1315 public abstract boolean[] toArray();
1316
1317 /**
1318 * Stores this mask into a {@code boolean} array starting at offset.
1319 * <p>
1320 * For each mask lane, where {@code N} is the mask lane index,
1321 * the lane element at index {@code N} is stored into the array at index
1322 * {@code i + N}.
1323 *
1324 * @param a the array
1325 * @param i the offset into the array
1326 * @throws IndexOutOfBoundsException if {@code i < 0}, or
1327 * {@code i > a.length - this.length()}
1328 */
1329 public abstract void intoArray(boolean[] a, int i);
1330
1331 /**
1332 * Returns {@code true} if any of the mask lanes are set.
1333 *
1334 * @return {@code true} if any of the mask lanes are set, otherwise
1335 * {@code false}.
1336 */
1337 public abstract boolean anyTrue();
1338
1339 /**
1340 * Returns {@code true} if all of the mask lanes are set.
1341 *
1342 * @return {@code true} if all of the mask lanes are set, otherwise
1343 * {@code false}.
1344 */
1345 public abstract boolean allTrue();
1346
1347 /**
1348 * Returns the number of mask lanes that are set.
1349 *
1350 * @return the number of mask lanes that are set.
1351 */
1352 public abstract int trueCount();
1353
1354 /**
1355 * Logically ands this mask with an input mask.
1356 * <p>
1357 * This is a mask binary operation where the logical and operation
1358 * ({@code &&} is applied to lane elements.
1359 *
1360 * @param o the input mask
1361 * @return the result of logically and'ing this mask with an input mask
1362 */
1363 public abstract Mask<E> and(Mask<E> o);
1364
1365 /**
1366 * Logically ors this mask with an input mask.
1367 * <p>
1368 * This is a mask binary operation where the logical or operation
1369 * ({@code ||} is applied to lane elements.
1370 *
1371 * @param o the input mask
1372 * @return the result of logically or'ing this mask with an input mask
1373 */
1374 public abstract Mask<E> or(Mask<E> o);
1375
1376 /**
1377 * Logically negates this mask.
1378 * <p>
1379 * This is a mask unary operation where the logical not operation
1380 * ({@code !} is applied to lane elements.
1381 *
1382 * @return the result of logically negating this mask.
1383 */
1384 public abstract Mask<E> not();
1385
1386 /**
1387 * Returns a vector representation of this mask.
1388 * <p>
1389 * For each mask lane, where {@code N} is the mask lane index,
1390 * if the mask lane is set then an element value whose most significant
1391 * bit is set is placed into the resulting vector at lane index
1392 * {@code N}, otherwise the default element value is placed into the
1393 * resulting vector at lane index {@code N}.
1394 *
1395 * @return a vector representation of this mask.
1396 */
1397 public abstract Vector<E> toVector();
1398
1399 /**
1400 * Tests if the lane at index {@code i} is set
1401 * @param i the lane index
1402 *
1403 * @return true if the lane at index {@code i} is set, otherwise false
1404 */
1405 public abstract boolean getElement(int i);
1406
1407 /**
1408 * Tests if the lane at index {@code i} is set
1409 * @param i the lane index
1410 * @return true if the lane at index {@code i} is set, otherwise false
1411 * @see #getElement
1412 */
1413 public boolean isSet(int i) {
1414 return getElement(i);
1415 }
1416 }
1417
1418 /**
1419 * A {@code Shuffle} represents an ordered immutable sequence of
1420 * {@code int} values. A Shuffle can be used with a shuffle accepting
1421 * vector operation to control the rearrangement of lane elements of input
1422 * vectors
1423 * <p>
1424 * The number of values in the sequence is referred to as the Shuffle
1425 * {@link #length() length}. The length also corresponds to the number of
1426 * Shuffle lanes. The lane element at lane index {@code N} (from {@code 0},
1427 * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
1428 * value in the sequence.
1429 * A Shuffle and Vector of the same element type and shape have the same
1430 * number of lanes.
1431 * <p>
1432 * A Shuffle describes how a lane element of a vector may cross lanes from
1433 * its lane index, {@code i} say, to another lane index whose value is the
1434 * Shuffle's lane element at lane index {@code i}. Shuffle lane elements
1435 * will be in the range of {@code 0} (inclusive) to the shuffle length
1436 * (exclusive), and therefore cannot induce out of bounds errors when
1437 * used with vectors operations and vectors of the same length.
1438 *
1439 * @param <E> the boxed element type of this mask
1440 */
1441 public static abstract class Shuffle<E> {
1442 Shuffle() {}
1443
1444 /**
1445 * Returns the species of this shuffle.
1446 *
1447 * @return the species of this shuffle
1448 */
1449 public abstract Species<E> species();
1450
1451 /**
1452 * Returns the number of shuffle lanes (the length).
1453 *
1454 * @return the number of shuffle lanes
1455 */
1456 public int length() { return species().length(); }
1457
1458 /**
1459 * Converts this shuffle to a shuffle of the given species of element type {@code F}.
1460 * <p>
1461 * For each shuffle lane, where {@code N} is the lane index, the
1462 * shuffle element at index {@code N} is placed, unmodified, into the
1463 * resulting shuffle at index {@code N}.
1464 *
1465 * @param species species of desired shuffle
1466 * @param <F> the boxed element type of the species
1467 * @return a shuffle converted by shape and element type
1468 * @throws IllegalArgumentException if this shuffle length and the
1469 * species length differ
1470 */
1471 public abstract <F> Shuffle<F> cast(Species<F> species);
1472
1473 /**
1474 * Returns an {@code int} array containing the lane elements of this
1475 * shuffle.
1476 * <p>
1477 * This method behaves as if it {@link #intoArray(int[], int)} stores}
1478 * this shuffle into an allocated array and returns that array as
1479 * follows:
1480 * <pre>{@code
1481 * int[] a = new int[this.length()];
1482 * this.intoArray(a, 0);
1483 * return a;
1484 * }</pre>
1485 *
1486 * @return an array containing the the lane elements of this vector
1487 */
1488 public abstract int[] toArray();
1489
1490 /**
1491 * Stores this shuffle into an {@code int} array starting at offset.
1492 * <p>
1493 * For each shuffle lane, where {@code N} is the shuffle lane index,
1494 * the lane element at index {@code N} is stored into the array at index
1495 * {@code i + N}.
1496 *
1497 * @param a the array
1498 * @param i the offset into the array
1499 * @throws IndexOutOfBoundsException if {@code i < 0}, or
1500 * {@code i > a.length - this.length()}
1501 */
1502 public abstract void intoArray(int[] a, int i);
1503
1504 /**
1505 * Converts this shuffle into a vector, creating a vector from shuffle
1506 * lane elements (int values) cast to the vector element type.
1507 * <p>
1508 * This method behaves as if it returns the result of creating a
1509 * vector given an {@code int} array obtained from this shuffle's
1510 * lane elements, as follows:
1511 * <pre>{@code
1512 * int[] sa = this.toArray();
1513 * $type$[] va = new $type$[a.length];
1514 * for (int i = 0; i < a.length; i++) {
1515 * va[i] = ($type$) sa[i];
1516 * }
1517 * return this.species().fromArray(va, 0);
1518 * }</pre>
1519 *
1520 * @return a vector representation of this shuffle
1521 */
1522 public abstract Vector<E> toVector();
1523
1524 /**
1525 * Gets the {@code int} lane element at lane index {@code i}
1526 *
1527 * @param i the lane index
1528 * @return the {@code int} lane element at lane index {@code i}
1529 */
1530 public int getElement(int i) { return toArray()[i]; }
1531
1532 /**
1533 * Rearranges the lane elements of this shuffle selecting lane indexes
1534 * controlled by another shuffle.
1535 * <p>
1536 * For each lane of the shuffle, at lane index {@code N} with lane
1537 * element {@code I}, the lane element at {@code I} from this shuffle is
1538 * selected and placed into the resulting shuffle at {@code N}.
1539 *
1540 * @param s the shuffle controlling lane index selection
1541 * @return the rearrangement of the lane elements of this shuffle
1542 */
1543 public abstract Shuffle<E> rearrange(Shuffle<E> s);
1544 }
1545
1546 /**
1547 * Find bit size based on element type and number of elements.
1548 *
1549 * @param c the element type
1550 * @param numElem number of lanes in the vector
1551 * @return size in bits for vector
1552 */
1553 public static int bitSizeForVectorLength(Class<?> c, int numElem) {
1554 if (c == float.class) {
1555 return Float.SIZE * numElem;
1556 }
1557 else if (c == double.class) {
1558 return Double.SIZE * numElem;
1559 }
1560 else if (c == byte.class) {
1561 return Byte.SIZE * numElem;
1562 }
1563 else if (c == short.class) {
1564 return Short.SIZE * numElem;
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have
23 * questions.
24 */
25 package jdk.incubator.vector;
26
27 import jdk.internal.misc.Unsafe;
28 import jdk.internal.vm.annotation.ForceInline;
29 import jdk.internal.vm.annotation.Stable;
30
31 import java.nio.ByteBuffer;
32 import java.nio.ByteOrder;
33 import java.util.Objects;
34 import java.util.function.Function;
35 import java.util.function.IntUnaryOperator;
36 import java.util.function.UnaryOperator;
37
38 import jdk.incubator.vector.*;
39
40 /**
41 * A {@code Vector} is designed for use in computations that can be transformed
42 * by a runtime compiler, on supported hardware, to Single Instruction Multiple
43 * Data (SIMD) computations leveraging vector hardware registers and vector
44 * hardware instructions. Such SIMD computations exploit data parallelism to
45 * perform the same operation on multiple data points simultaneously in a
46 * faster time it would ordinarily take to perform the same operation
47 * sequentially on each data point.
48 * <p>
49 * A Vector represents an ordered immutable sequence of values of the same
50 * element type {@code e} that is one of the following primitive types
51 * {@code byte}, {@code short}, {@code int}, {@code long}, {@code float}, or
52 * {@code double}). The type variable {@code E} corresponds to the boxed
53 * element type, specifically the class that wraps a value of {@code e} in an
54 * object (such the {@code Integer} class that wraps a value of {@code int}}.
55 * A Vector has a {@link #shape() shape} {@code S}, extending type
56 * {@link VectorShape}, that governs the total {@link #bitSize() size} in bits
57 * of the sequence of values.
58 * <p>
59 * The number of values in the sequence is referred to as the Vector
60 * {@link #length() length}. The length also corresponds to the number of
61 * Vector lanes. The lane element at lane index {@code N} (from {@code 0},
62 * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th value in
63 * the sequence.
64 * Note: this arrangement
65 * of Vector bit size, Vector length, element bit size, and lane element index
66 * has no bearing on how a Vector instance and its sequence of elements may be
67 * arranged in memory or represented as a value in a vector hardware register.
68 * <p>
69 * Vector declares a set of vector operations (methods) that are common to all
70 * element types (such as addition). Sub-classes of Vector with a concrete
71 * boxed element type declare further operations that are specific to that
72 * element type (such as access to element values in lanes, logical operations
73 * on values of integral elements types, or transcendental operations on values
74 * of floating point element types).
75 * There are six sub-classes of Vector corresponding to the supported set
76 * of element types, {@link ByteVector}, {@link ShortVector},
77 * {@link IntVector} {@link LongVector}, {@link FloatVector}, and
78 * {@link DoubleVector}.
79 * <p>
80 * Vector values, instances of Vector, are created from a special kind of
81 * factory called a {@link VectorSpecies}. A VectorSpecies has an
82 * element type and shape and creates Vector values of the same element type
83 * and shape.
84 * A species can be {@link VectorSpecies#of(Class, VectorShape)} obtained} given an element
85 * type and shape, or a preferred species can be
86 * {@link VectorSpecies#ofPreferred(Class)} obtained} given just an element type where the most
87 * optimal shape is selected for the current platform. It is recommended that
88 * VectorSpecies instances be held in {@code static final} fields for optimal creation
89 * and usage of Vector values by the runtime compiler.
90 * <p>
91 * Vector operations can be grouped into various categories and their behaviour
92 * generally specified as follows:
93 * <ul>
94 * <li>
95 * A vector unary operation (1-ary) operates on one input vector to produce a
96 * result vector.
97 * For each lane of the input vector the
98 * lane element is operated on using the specified scalar unary operation and
99 * the element result is placed into the vector result at the same lane.
100 * The following pseudocode expresses the behaviour of this operation category,
101 * where {@code e} is the element type and {@code EVector} corresponds to the
102 * primitive Vector type:
103 *
104 * <pre>{@code
105 * EVector<S> a = ...;
106 * e[] ar = new e[a.length()];
107 * for (int i = 0; i < a.length(); i++) {
108 * ar[i] = scalar_unary_op(a.get(i));
164 * }
165 * }</pre>
166 *
167 * Unless otherwise specified the scalar result type and element type will be
168 * the same.
169 *
170 * <li>
171 * A vector binary test operation operates on two input vectors to produce a
172 * result mask. For each lane of the two input vectors, a and b say, the
173 * the corresponding lane elements from a and b are operated on using the
174 * specified scalar binary test operation and the boolean result is placed
175 * into the mask at the same lane.
176 * The following pseudocode expresses the behaviour of this operation category:
177 * <pre>{@code
178 * EVector<S> a = ...;
179 * EVector<S> b = ...;
180 * boolean[] ar = new boolean[a.length()];
181 * for (int i = 0; i < a.length(); i++) {
182 * ar[i] = scalar_binary_test_op(a.get(i), b.get(i));
183 * }
184 * VectorMask<E> r = a.species().maskFromArray(ar, 0);
185 * }</pre>
186 *
187 * Unless otherwise specified the two input vectors and result mask will have
188 * the same element type and shape.
189 *
190 * <li>
191 * The prior categories of operation can be said to operate within the vector
192 * lanes, where lane access is uniformly applied to all vectors, specifically
193 * the scalar operation is applied to elements taken from input vectors at the
194 * same lane, and if appropriate applied to the result vector at the same lane.
195 * A further category of operation is a cross-lane vector operation where lane
196 * access is defined by the arguments to the operation. Cross-lane operations
197 * generally rearrange lane elements, for example by permutation (commonly
198 * controlled by a {@link VectorShuffle}) or by blending (commonly controlled by a
199 * {@link VectorMask}). Such an operation explicitly specifies how it rearranges lane
200 * elements.
201 * </ul>
202 *
203 * If a vector operation is represented as an instance method then first input
204 * vector corresponds to {@code this} vector and subsequent input vectors are
205 * arguments of the method. Otherwise, if the an operation is represented as a
206 * static method then all input vectors are arguments of the method.
207 * <p>
208 * If a vector operation does not belong to one of the above categories then
209 * the operation explicitly specifies how it processes the lane elements of
210 * input vectors, and where appropriate expresses the behaviour using
211 * pseudocode.
212 *
213 * <p>
214 * Many vector operations provide an additional {@link VectorMask mask} accepting
215 * variant.
216 * The mask controls which lanes are selected for application of the scalar
217 * operation. Masks are a key component for the support of control flow in
218 * vector computations.
219 * <p>
220 * For certain operation categories the mask accepting variants can be specified
221 * in generic terms. If a lane of the mask is set then the scalar operation is
222 * applied to corresponding lane elements, otherwise if a lane of a mask is not
223 * set then a default scalar operation is applied and its result is placed into
224 * the vector result at the same lane. The default operation is specified for
225 * the following operation categories:
226 * <ul>
227 * <li>
228 * For a vector n-ary operation the default operation is a function that returns
229 * it's first argument, specifically a lane element of the first input vector.
230 * <li>
231 * For an associative vector reduction operation the default operation is a
232 * function that returns the identity value.
233 * <li>
234 * For vector binary test operation the default operation is a function that
235 * returns false.
236 *</ul>
237 * Otherwise, the mask accepting variant of the operation explicitly specifies
238 * how it processes the lane elements of input vectors, and where appropriate
239 * expresses the behaviour using pseudocode.
240 *
241 * <p>
242 * For convenience many vector operations, of arity greater than one, provide
243 * an additional scalar accepting variant. This variant accepts compatible
244 * scalar values instead of vectors for the second and subsequent input vectors,
245 * if any.
246 * Unless otherwise specified the scalar variant behaves as if each scalar value
247 * is transformed to a vector using the vector species
248 * {@code broadcast} operation, and
249 * then the vector accepting vector operation is applied using the transformed
250 * values.
251 *
252 * <p>
253 * This is a value-based
254 * class; use of identity-sensitive operations (including reference equality
255 * ({@code ==}), identity hash code, or synchronization) on instances of
256 * {@code Vector} may have unpredictable results and should be avoided.
257 *
258 * @param <E> the boxed element type of elements in this vector
259 */
260 public abstract class Vector<E> {
261
262 Vector() {}
263
264 /**
265 * Returns the species of this vector.
266 *
267 * @return the species of this vector
268 */
269 public abstract VectorSpecies<E> species();
270
271 /**
272 * Returns the primitive element type of this vector.
273 *
274 * @return the primitive element type of this vector
275 */
276 public Class<E> elementType() { return species().elementType(); }
277
278 /**
279 * Returns the element size, in bits, of this vector.
280 *
281 * @return the element size, in bits
282 */
283 public int elementSize() { return species().elementSize(); }
284
285 /**
286 * Returns the shape of this vector.
287 *
288 * @return the shape of this vector
289 */
290 public VectorShape shape() { return species().shape(); }
291
292 /**
293 * Returns the number of vector lanes (the length).
294 *
295 * @return the number of vector lanes
296 */
297 public int length() { return species().length(); }
298
299 /**
300 * Returns the total vector size, in bits.
301 *
302 * @return the total vector size, in bits
303 */
304 public int bitSize() { return species().bitSize(); }
305
306 //Arithmetic
307
308 /**
309 * Adds this vector to an input vector.
310 * <p>
311 * This is a vector binary operation where the primitive addition operation
312 * ({@code +}) is applied to lane elements.
313 *
314 * @param v the input vector
315 * @return the result of adding this vector to the input vector
316 */
317 public abstract Vector<E> add(Vector<E> v);
318
319 /**
320 * Adds this vector to an input vector, selecting lane elements
321 * controlled by a mask.
322 * <p>
323 * This is a vector binary operation where the primitive addition operation
324 * ({@code +}) is applied to lane elements.
325 *
326 * @param v the input vector
327 * @param m the mask controlling lane selection
328 * @return the result of adding this vector to the given vector
329 */
330 public abstract Vector<E> add(Vector<E> v, VectorMask<E> m);
331
332 /**
333 * Subtracts an input vector from this vector.
334 * <p>
335 * This is a vector binary operation where the primitive subtraction
336 * operation ({@code -}) is applied to lane elements.
337 *
338 * @param v the input vector
339 * @return the result of subtracting the input vector from this vector
340 */
341 public abstract Vector<E> sub(Vector<E> v);
342
343 /**
344 * Subtracts an input vector from this vector, selecting lane elements
345 * controlled by a mask.
346 * <p>
347 * This is a vector binary operation where the primitive subtraction
348 * operation ({@code -}) is applied to lane elements.
349 *
350 * @param v the input vector
351 * @param m the mask controlling lane selection
352 * @return the result of subtracting the input vector from this vector
353 */
354 public abstract Vector<E> sub(Vector<E> v, VectorMask<E> m);
355
356 /**
357 * Multiplies this vector with an input vector.
358 * <p>
359 * This is a vector binary operation where the primitive multiplication
360 * operation ({@code *}) is applied to lane elements.
361 *
362 * @param v the input vector
363 * @return the result of multiplying this vector with the input vector
364 */
365 public abstract Vector<E> mul(Vector<E> v);
366
367 /**
368 * Multiplies this vector with an input vector, selecting lane elements
369 * controlled by a mask.
370 * <p>
371 * This is a vector binary operation where the primitive multiplication
372 * operation ({@code *}) is applied to lane elements.
373 *
374 * @param v the input vector
375 * @param m the mask controlling lane selection
376 * @return the result of multiplying this vector with the input vector
377 */
378 public abstract Vector<E> mul(Vector<E> v, VectorMask<E> m);
379
380 /**
381 * Negates this vector.
382 * <p>
383 * This is a vector unary operation where the primitive negation operation
384 * ({@code -}) is applied to lane elements.
385 *
386 * @return the negation this vector
387 */
388 public abstract Vector<E> neg();
389
390 /**
391 * Negates this vector, selecting lane elements controlled by a mask.
392 * <p>
393 * This is a vector unary operation where the primitive negation operation
394 * ({@code -})is applied to lane elements.
395 *
396 * @param m the mask controlling lane selection
397 * @return the negation this vector
398 */
399 public abstract Vector<E> neg(VectorMask<E> m);
400
401 // Maths from java.math
402
403 /**
404 * Returns the modulus of this vector.
405 * <p>
406 * This is a vector unary operation where the operation
407 * {@code (a) -> (a < 0) ? -a : a} is applied to lane elements.
408 *
409 * @return the modulus this vector
410 */
411 public abstract Vector<E> abs();
412
413 /**
414 * Returns the modulus of this vector, selecting lane elements controlled by
415 * a mask.
416 * <p>
417 * This is a vector unary operation where the operation
418 * {@code (a) -> (a < 0) ? -a : a} is applied to lane elements.
419 *
420 * @param m the mask controlling lane selection
421 * @return the modulus this vector
422 */
423 public abstract Vector<E> abs(VectorMask<E> m);
424
425 /**
426 * Returns the minimum of this vector and an input vector.
427 * <p>
428 * This is a vector binary operation where the operation
429 * {@code (a, b) -> a < b ? a : b} is applied to lane elements.
430 *
431 * @param v the input vector
432 * @return the minimum of this vector and the input vector
433 */
434 public abstract Vector<E> min(Vector<E> v);
435
436 /**
437 * Returns the minimum of this vector and an input vector,
438 * selecting lane elements controlled by a mask.
439 * <p>
440 * This is a vector binary operation where the operation
441 * {@code (a, b) -> a < b ? a : b} is applied to lane elements.
442 *
443 * @param v the input vector
444 * @param m the mask controlling lane selection
445 * @return the minimum of this vector and the input vector
446 */
447 public abstract Vector<E> min(Vector<E> v, VectorMask<E> m);
448
449 /**
450 * Returns the maximum of this vector and an input vector.
451 * <p>
452 * This is a vector binary operation where the operation
453 * {@code (a, b) -> a > b ? a : b} is applied to lane elements.
454 *
455 * @param v the input vector
456 * @return the maximum of this vector and the input vector
457 */
458 public abstract Vector<E> max(Vector<E> v);
459
460 /**
461 * Returns the maximum of this vector and an input vector,
462 * selecting lane elements controlled by a mask.
463 * <p>
464 * This is a vector binary operation where the operation
465 * {@code (a, b) -> a > b ? a : b} is applied to lane elements.
466 *
467 * @param v the input vector
468 * @param m the mask controlling lane selection
469 * @return the maximum of this vector and the input vector
470 */
471 public abstract Vector<E> max(Vector<E> v, VectorMask<E> m);
472
473 // Comparisons
474
475 /**
476 * Tests if this vector is equal to an input vector.
477 * <p>
478 * This is a vector binary test operation where the primitive equals
479 * operation ({@code ==}) is applied to lane elements.
480 *
481 * @param v the input vector
482 * @return the result mask of testing if this vector is equal to the input
483 * vector
484 */
485 public abstract VectorMask<E> equal(Vector<E> v);
486
487 /**
488 * Tests if this vector is not equal to an input vector.
489 * <p>
490 * This is a vector binary test operation where the primitive not equals
491 * operation ({@code !=}) is applied to lane elements.
492 *
493 * @param v the input vector
494 * @return the result mask of testing if this vector is not equal to the
495 * input vector
496 */
497 public abstract VectorMask<E> notEqual(Vector<E> v);
498
499 /**
500 * Tests if this vector is less than an input vector.
501 * <p>
502 * This is a vector binary test operation where the primitive less than
503 * operation ({@code <}) is applied to lane elements.
504 *
505 * @param v the input vector
506 * @return the mask result of testing if this vector is less than the input
507 * vector
508 */
509 public abstract VectorMask<E> lessThan(Vector<E> v);
510
511 /**
512 * Tests if this vector is less or equal to an input vector.
513 * <p>
514 * This is a vector binary test operation where the primitive less than
515 * or equal to operation ({@code <=}) is applied to lane elements.
516 *
517 * @param v the input vector
518 * @return the mask result of testing if this vector is less than or equal
519 * to the input vector
520 */
521 public abstract VectorMask<E> lessThanEq(Vector<E> v);
522
523 /**
524 * Tests if this vector is greater than an input vector.
525 * <p>
526 * This is a vector binary test operation where the primitive greater than
527 * operation ({@code >}) is applied to lane elements.
528 *
529 * @param v the input vector
530 * @return the mask result of testing if this vector is greater than the
531 * input vector
532 */
533 public abstract VectorMask<E> greaterThan(Vector<E> v);
534
535 /**
536 * Tests if this vector is greater than or equal to an input vector.
537 * <p>
538 * This is a vector binary test operation where the primitive greater than
539 * or equal to operation ({@code >=}) is applied to lane elements.
540 *
541 * @param v the input vector
542 * @return the mask result of testing if this vector is greater than or
543 * equal to the given vector
544 */
545 public abstract VectorMask<E> greaterThanEq(Vector<E> v);
546
547 // Elemental shifting
548
549 /**
550 * Rotates left the lane elements of this vector by the given number of
551 * lanes, {@code i}, modulus the vector length.
552 * <p>
553 * This is a cross-lane operation that permutes the lane elements of this
554 * vector.
555 * For each lane of the input vector, at lane index {@code N}, the lane
556 * element is placed into to the result vector at lane index
557 * {@code (i + N) % this.length()}.
558 *
559 * @param i the number of lanes to rotate left
560 * @return the result of rotating left lane elements of this vector by the
561 * given number of lanes
562 */
563 public abstract Vector<E> rotateEL(int i);
564
565 /**
606 * given number of lanes
607 * @throws IllegalArgumentException if {@code i} is {@code < 0}.
608 */
609 public abstract Vector<E> shiftER(int i);
610
611 /**
612 * Blends the lane elements of this vector with those of an input vector,
613 * selecting lanes controlled by a mask.
614 * <p>
615 * For each lane of the mask, at lane index {@code N}, if the mask lane
616 * is set then the lane element at {@code N} from the input vector is
617 * selected and placed into the resulting vector at {@code N},
618 * otherwise the the lane element at {@code N} from this input vector is
619 * selected and placed into the resulting vector at {@code N}.
620 *
621 * @param v the input vector
622 * @param m the mask controlling lane selection
623 * @return the result of blending the lane elements of this vector with
624 * those of an input vector
625 */
626 public abstract Vector<E> blend(Vector<E> v, VectorMask<E> m);
627
628 /**
629 * Rearranges the lane elements of this vector and those of an input vector,
630 * selecting lane indexes controlled by shuffles and a mask.
631 * <p>
632 * This is a cross-lane operation that rearranges the lane elements of this
633 * vector and the input vector. This method behaves as if it rearranges
634 * each vector with the corresponding shuffle and then blends the two
635 * results with the mask:
636 * <pre>{@code
637 * return this.rearrange(s1).blend(v.rearrange(s2), m);
638 * }</pre>
639 *
640 * @param v the input vector
641 * @param s the shuffle controlling lane index selection of the input vector
642 * if corresponding mask lanes are set, otherwise controlling lane
643 * index selection of this vector
644 * @param m the mask controlling shuffled lane selection
645 * @return the rearrangement of lane elements of this vector and
646 * those of an input vector
647 */
648 @ForceInline
649 // rearrange
650 public abstract Vector<E> rearrange(Vector<E> v,
651 VectorShuffle<E> s, VectorMask<E> m);
652
653 /**
654 * Rearranges the lane elements of this vector selecting lane indexes
655 * controlled by a shuffle.
656 * <p>
657 * This is a cross-lane operation that rearranges the lane elements of this
658 * vector.
659 * For each lane of the shuffle, at lane index {@code N} with lane
660 * element {@code I}, the lane element at {@code I} from this vector is
661 * selected and placed into the resulting vector at {@code N}.
662 *
663 * @param s the shuffle controlling lane index selection
664 * @return the rearrangement of the lane elements of this vector
665 */
666 // rearrange
667 public abstract Vector<E> rearrange(VectorShuffle<E> s);
668
669
670 // Conversions
671
672 /**
673 * Converts this vector into a shuffle, creating a shuffle from vector
674 * lane elements cast to {@code int} then logically AND'ed with the
675 * shuffle length minus one.
676 * <p>
677 * This methods behaves as if it returns the result of creating a shuffle
678 * given an array of the vector lane elements, as follows:
679 * <pre>{@code
680 * $type$[] a = this.toArray();
681 * int[] sa = new int[a.length];
682 * for (int i = 0; i < a.length; i++) {
683 * sa[i] = (int) a[i];
684 * }
685 * return this.species().shuffleFromValues(sa);
686 * }</pre>
687 *
688 * @return a shuffle representation of this vector
689 */
690 public abstract VectorShuffle<E> toShuffle();
691
692 // Bitwise preserving
693
694 /**
695 * Transforms this vector to a vector of the given species of element type {@code F}.
696 * <p>
697 * The underlying bits of this vector are copied to the resulting
698 * vector without modification, but those bits, before copying, may be
699 * truncated if the this vector's bit size is greater than desired vector's bit
700 * size, or appended to with zero bits if this vector's bit size is less
701 * than desired vector's bit size.
702 * <p>
703 * The method behaves as if this vector is stored into a byte buffer
704 * and then the desired vector is loaded from the byte buffer using
705 * native byte ordering. The implication is that ByteBuffer reads bytes
706 * and then composes them based on the byte ordering so the result
707 * depends on this composition.
708 * <p>
709 * For example, on a system with ByteOrder.LITTLE_ENDIAN, loading from
710 * byte array with values {0,1,2,3} and reshaping to int, leads to bytes
711 * being composed in order 0x3 0x2 0x1 0x0 which is decimal value 50462976.
712 * On a system with ByteOrder.BIG_ENDIAN, the value is instead 66051 because
713 * bytes are composed in order 0x0 0x1 0x2 0x3.
714 * <p>
715 * The following pseudocode expresses the behaviour:
716 * <pre>{@code
717 * int blen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
718 * ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
719 * this.intoByteBuffer(bb, 0);
720 * return $type$Vector.fromByteBuffer(s, bb, 0);
721 * }</pre>
722 *
723 * @param s species of desired vector
724 * @param <F> the boxed element type of the species
725 * @return a vector transformed, by shape and element type, from this vector
726 */
727 @ForceInline
728 public abstract <F> Vector<F> reinterpret(VectorSpecies<F> s);
729
730 @ForceInline
731 @SuppressWarnings("unchecked")
732 <F> Vector<F> defaultReinterpret(VectorSpecies<F> s) {
733 int blen = Math.max(s.bitSize(), this.species().bitSize()) / Byte.SIZE;
734 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
735 this.intoByteBuffer(bb, 0);
736
737 Class<?> stype = s.elementType();
738 if (stype == byte.class) {
739 return (Vector) ByteVector.fromByteBuffer((ByteVector.ByteSpecies)s, bb, 0);
740 } else if (stype == short.class) {
741 return (Vector) ShortVector.fromByteBuffer((ShortVector.ShortSpecies)s, bb, 0);
742 } else if (stype == int.class) {
743 return (Vector) IntVector.fromByteBuffer((IntVector.IntSpecies)s, bb, 0);
744 } else if (stype == long.class) {
745 return (Vector) LongVector.fromByteBuffer((LongVector.LongSpecies)s, bb, 0);
746 } else if (stype == float.class) {
747 return (Vector) FloatVector.fromByteBuffer((FloatVector.FloatSpecies)s, bb, 0);
748 } else if (stype == double.class) {
749 return (Vector) DoubleVector.fromByteBuffer((DoubleVector.DoubleSpecies)s, bb, 0);
750 } else {
751 throw new UnsupportedOperationException("Bad lane type for reinterpret.");
752 }
753 }
754
755 /**
756 * Transforms this vector to a vector of same element type but different shape identified by species.
757 * <p>
758 * The lane elements of this vector are copied without
759 * modification to the resulting vector, but those lane elements, before
760 * copying, may be truncated if this vector's length is greater than the desired
761 * vector's length, or appended to with default element values if this
762 * vector's length is less than desired vector's length.
763 * <p>
764 * The method behaves as if this vector is stored into a byte array
765 * and then the returned vector is loaded from the byte array.
766 * The following pseudocode expresses the behaviour:
767 * <pre>{@code
768 * int alen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
769 * byte[] a = new byte[alen];
770 * this.intoByteArray(a, 0);
771 * return $type$Vector.fromByteArray(s, a, 0);
772 * }</pre>
773 *
774 * @param s species of the desired vector
775 * @return a vector transformed, by shape, from this vector
776 */
777 public abstract Vector<E> reshape(VectorSpecies<E> s);
778
779 // Cast
780
781 /**
782 * Converts this vector to a vector of the given species element type {@code F}.
783 * <p>
784 * For each vector lane up to the length of this vector or
785 * desired vector, which ever is the minimum, and where {@code N} is the
786 * vector lane index, the element at index {@code N} of primitive type
787 * {@code E} is converted, according to primitive conversion rules
788 * specified by the Java Language Specification, to a value of primitive
789 * type {@code F} and placed into the resulting vector at lane index
790 * {@code N}. If desired vector's length is greater than this
791 * vector's length then the default primitive value is placed into
792 * subsequent lanes of the resulting vector.
793 *
794 * @param s species of the desired vector
795 * @param <F> the boxed element type of the species
796 * @return a vector converted by shape and element type from this vector
797 */
798 public abstract <F> Vector<F> cast(VectorSpecies<F> s);
799
800 //Array stores
801
802 /**
803 * Stores this vector into a byte array starting at an offset.
804 * <p>
805 * Bytes are extracted from primitive lane elements according to the
806 * native byte order of the underlying platform.
807 * <p>
808 * This method behaves as it calls the
809 * byte buffer, offset, and mask accepting
810 * {@link #intoByteBuffer(ByteBuffer, int, VectorMask) method} as follows:
811 * <pre>{@code
812 * return this.intoByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
813 * }</pre>
814 *
815 * @param a the byte array
816 * @param i the offset into the array
817 * @return a vector loaded from a byte array
818 * @throws IndexOutOfBoundsException if {@code i < 0} or
819 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
820 */
821 public abstract void intoByteArray(byte[] a, int i);
822
823 /**
824 * Stores this vector into a byte array starting at an offset and using a mask.
825 * <p>
826 * Bytes are extracted from primitive lane elements according to the
827 * native byte order of the underlying platform.
828 * <p>
829 * This method behaves as it calls the
830 * byte buffer, offset, and mask accepting
831 * {@link #intoByteBuffer(ByteBuffer, int, VectorMask) method} as follows:
832 * <pre>{@code
833 * return this.intoByteBuffer(ByteBuffer.wrap(a), i, m);
834 * }</pre>
835 *
836 * @param a the byte array
837 * @param i the offset into the array
838 * @param m the mask controlling lane selection
839 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
840 * or {@code > a.length},
841 * for any vector lane index {@code N} where the mask at lane {@code N}
842 * is set
843 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
844 */
845 public abstract void intoByteArray(byte[] a, int i, VectorMask<E> m);
846
847 /**
848 * Stores this vector into a {@link ByteBuffer byte buffer} starting at an
849 * offset into the byte buffer.
850 * <p>
851 * Bytes are extracted from primitive lane elements according to the
852 * native byte order of the underlying platform.
853 * <p>
854 * This method behaves as if it calls the byte buffer, offset, and mask
855 * accepting
856 * {@link #intoByteBuffer(ByteBuffer, int, VectorMask)} method} as follows:
857 * <pre>{@code
858 * this.intoByteBuffer(b, i, this.maskAllTrue())
859 * }</pre>
860 *
861 * @param b the byte buffer
862 * @param i the offset into the byte buffer
863 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
864 * or {@code > b.limit()},
865 * or if there are fewer than
866 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
867 * remaining in the byte buffer from the given offset
868 */
869 public abstract void intoByteBuffer(ByteBuffer b, int i);
870
871 /**
872 * Stores this vector into a {@link ByteBuffer byte buffer} starting at an
873 * offset into the byte buffer and using a mask.
874 * <p>
875 * This method behaves as if the byte buffer is viewed as a primitive
876 * {@link java.nio.Buffer buffer} for the primitive element type,
885 * EBuffer eb = b.duplicate().
886 * order(ByteOrder.nativeOrder()).position(i).
887 * asEBuffer();
888 * e[] es = ((EVector<S>)this).toArray();
889 * for (int n = 0; n < t.length; n++) {
890 * if (m.isSet(n)) {
891 * eb.put(n, es[n]);
892 * }
893 * }
894 * }</pre>
895 *
896 * @param b the byte buffer
897 * @param i the offset into the byte buffer
898 * @param m the mask
899 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
900 * or {@code > b.limit()},
901 * for any vector lane index {@code N} where the mask at lane {@code N}
902 * is set
903 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes
904 */
905 public abstract void intoByteBuffer(ByteBuffer b, int i, VectorMask<E> m);
906
907 /**
908 * Find bit size based on element type and number of elements.
909 *
910 * @param c the element type
911 * @param numElem number of lanes in the vector
912 * @return size in bits for vector
913 */
914 public static int bitSizeForVectorLength(Class<?> c, int numElem) {
915 if (c == float.class) {
916 return Float.SIZE * numElem;
917 }
918 else if (c == double.class) {
919 return Double.SIZE * numElem;
920 }
921 else if (c == byte.class) {
922 return Byte.SIZE * numElem;
923 }
924 else if (c == short.class) {
925 return Short.SIZE * numElem;
|