88 * It is recommended that Species instances be held in {@code static final}
89 * fields for optimal creation and usage of Vector values by the runtime compiler.
90 * <p>
91 * Vector operations can be grouped into various categories and their behavior
92 * generally specified as follows:
93 * <ul>
94 * <li>
95 * A lane-wise unary operation operates on one input vector and produces 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 behavior 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 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));
109 * }
110 * EVector r = EVector.fromArray(a.species(), ar, 0);
111 * }</pre>
112 *
113 * Unless otherwise specified the input and result vectors will have the same
114 * element type and shape.
115 *
116 * <li>
117 * A lane-wise binary operation operates on two input
118 * vectors and produces a result vector.
119 * For each lane of the two input vectors a and b,
120 * the corresponding lane elements from a and b are operated on
121 * using the specified scalar binary operation and the element result is placed
122 * into the vector result at the same lane.
123 * The following pseudocode expresses the behavior of this operation category:
124 *
125 * <pre>{@code
126 * EVector a = ...;
127 * EVector b = ...;
128 * e[] ar = new e[a.length()];
129 * for (int i = 0; i < a.length(); i++) {
130 * ar[i] = scalar_binary_op(a.get(i), b.get(i));
131 * }
132 * EVector r = EVector.fromArray(a.species(), ar, 0);
133 * }</pre>
134 *
135 * Unless otherwise specified the two input and result vectors will have the
136 * same element type and shape.
137 *
138 * <li>
139 * Generalizing from unary and binary operations, a lane-wise n-ary
140 * operation operates on n input vectors and produces a result vector.
141 * N lane elements from each input vector are operated on
142 * using the specified n-ary scalar operation and the element result is placed
143 * into the vector result at the same lane.
144 * Unless otherwise specified the n input and result vectors will have the same
145 * element type and shape.
146 *
147 * <li>
148 * A cross-lane vector reduction operation operates on all the lane
149 * elements of an input vector.
150 * An accumulation function is applied to all the
151 * lane elements to produce a scalar result.
152 * If the reduction operation is associative then the result may be accumulated
153 * by operating on the lane elements in any order using a specified associative
154 * scalar binary operation and identity value. Otherwise, the reduction
155 * operation specifies the behavior of the accumulation function.
156 * The following pseudocode expresses the behavior of this operation category
157 * if it is associative:
158 * <pre>{@code
159 * EVector a = ...;
160 * e r = <identity value>;
161 * for (int i = 0; i < a.length(); i++) {
162 * r = assoc_scalar_binary_op(r, a.get(i));
163 * }
164 * }</pre>
165 *
166 * Unless otherwise specified the scalar result type and element type will be
167 * the same.
168 *
169 * <li>
170 * A lane-wise binary test operation operates on two input vectors and produces a
171 * result mask. For each lane of the two input vectors, a and b say, the
172 * the corresponding lane elements from a and b are operated on using the
173 * specified scalar binary test operation and the boolean result is placed
174 * into the mask at the same lane.
175 * The following pseudocode expresses the behavior of this operation category:
176 * <pre>{@code
177 * EVector a = ...;
178 * EVector b = ...;
179 * boolean[] ar = new boolean[a.length()];
180 * for (int i = 0; i < a.length(); i++) {
181 * ar[i] = scalar_binary_test_op(a.get(i), b.get(i));
182 * }
183 * VectorMask r = VectorMask.fromArray(a.species(), ar, 0);
184 * }</pre>
185 *
186 * Unless otherwise specified the two input vectors and result mask will have
187 * the same element type and shape.
188 *
189 * <li>
190 * The prior categories of operation can be said to operate within the vector
191 * lanes, where lane access is uniformly applied to all vectors, specifically
192 * the scalar operation is applied to elements taken from input vectors at the
193 * same lane, and if appropriate applied to the result vector at the same lane.
194 * A further category of operation is a cross-lane vector operation where lane
195 * access is defined by the arguments to the operation. Cross-lane operations
196 * generally rearrange lane elements, for example by permutation (commonly
197 * controlled by a {@link jdk.incubator.vector.VectorShuffle}) or by blending (commonly controlled by a
198 * {@link jdk.incubator.vector.VectorMask}). Such an operation explicitly specifies how it rearranges lane
199 * elements.
200 * </ul>
201 *
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 lane-wise binary operation which applies the primitive addition operation
312 * ({@code +}) to each lane.
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>
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 lane-wise unary operation which applies the primitive negation operation
384 * ({@code -}) to each lane.
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 lane-wise unary operation which applies the primitive negation operation
394 * ({@code -})to each lane.
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 lane-wise unary operation which applies the operation
407 * {@code (a) -> (a < 0) ? -a : a} to each lane.
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
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 lane-wise binary operation which applies the operation
465 * {@code (a, b) -> a > b ? a : b} to each lane.
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 lane-wise binary test operation where the primitive equals
479 * operation ({@code ==}) to each lane.
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 lane-wise binary test operation where the primitive not equals
491 * operation ({@code !=}) to each lane.
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 lane-wise binary test operation where the primitive less than
503 * operation ({@code <}) to each lane.
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 lane-wise binary test operation where the primitive less than
515 * or equal to operation ({@code <=}) to each lane.
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 lane-wise binary test operation where the primitive greater than
527 * operation ({@code >}) to each lane.
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 lane-wise binary test operation where the primitive greater than
539 * or equal to operation ({@code >=}) to each lane.
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 the result vector at lane index
557 * {@code (N + i) % 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 /**
566 * Rotates right the lane elements of this vector by the given number of
567 * lanes, {@code i}, modulus the vector length.
568 * <p>
569 * This is a cross-lane operation that permutes the lane elements of this
570 * vector.
571 * For each lane of the input vector, at lane index {@code N}, the lane
572 * element is placed into the result vector at lane index
573 * {@code (N + length() - (i % length())) % length()}
574 *
575 * @param i the number of lanes to rotate left
576 * @return the result of rotating right lane elements of this vector by the
577 * given number of lanes
578 */
579 public abstract Vector<E> rotateER(int i);
580
581 /**
582 * Shift left the lane elements of this vector by the given number of
583 * lanes, {@code i}, modulus the vector length.
584 * <p>
585 * This is a cross-lane operation that permutes the lane elements of this
586 * vector and behaves as if rotating left the lane elements by {@code i},
587 * and then the zero value is placed into the result vector at lane indexes
588 * less than {@code i % length()}.
589 *
590 * @param i the number of lanes to shift left
591 * @return the result of shifting left lane elements of this vector by the
592 * given number of lanes
593 * @throws IllegalArgumentException if {@code i} is {@code < 0}.
594 */
595 public abstract Vector<E> shiftEL(int i);
596
597 /**
598 * Shift right the lane elements of this vector by the given number of
599 * lanes, {@code i}, modulus the vector length.
600 * <p>
601 * This is a cross-lane operation that permutes the lane elements of this
602 * vector and behaves as if rotating right the lane elements by {@code i},
603 * and then the zero value is placed into the result vector at lane indexes
604 * greater or equal to {@code length() - (i % length())}.
605 *
606 * @param i the number of lanes to shift right
607 * @return the result of shifting right lane elements of this vector by the
608 * given number of lanes
609 * @throws IllegalArgumentException if {@code i} is {@code < 0}.
610 */
611 public abstract Vector<E> shiftER(int i);
612
613 /**
614 * Blends the lane elements of this vector with those of an input vector,
615 * selecting lanes controlled by a mask.
616 * <p>
617 * For each lane of the mask, at lane index {@code N}, if the mask lane
618 * is set then the lane element at {@code N} from the input vector is
619 * selected and placed into the resulting vector at {@code N},
620 * otherwise the lane element at {@code N} from this vector is
621 * selected and placed into the resulting vector at {@code N}.
622 *
623 * @param v the input vector
624 * @param m the mask controlling lane selection
625 * @return the result of blending the lane elements of this vector with
626 * those of an input vector
627 */
628 public abstract Vector<E> blend(Vector<E> v, VectorMask<E> m);
629
630 /**
631 * Rearranges the lane elements of this vector and those of an input vector,
632 * selecting lane indexes controlled by shuffles and a mask.
633 * <p>
634 * This is a cross-lane operation that rearranges the lane elements of this
635 * vector and the input vector. This method behaves as if it rearranges
636 * each vector with the corresponding shuffle and then blends the two
637 * results with the mask:
638 * <pre>{@code
639 * return this.rearrange(s1).blend(v.rearrange(s2), m);
640 * }</pre>
641 *
642 * @param v the input vector
643 * @param s the shuffle controlling lane index selection of the input vector
644 * if corresponding mask lanes are set, otherwise controlling lane
645 * index selection of this vector
646 * @param m the mask controlling shuffled lane selection
647 * @return the rearrangement of lane elements of this vector and
648 * those of an input vector
649 */
650 @ForceInline
651 // rearrange
652 public abstract Vector<E> rearrange(Vector<E> v,
653 VectorShuffle<E> s, VectorMask<E> m);
654
655 /**
656 * Rearranges the lane elements of this vector selecting lane indexes
657 * controlled by a shuffle.
658 * <p>
659 * This is a cross-lane operation that rearranges the lane elements of this
660 * vector.
661 * For each lane of the shuffle, at lane index {@code N} with lane
662 * element {@code I}, the lane element at {@code I} from this vector is
663 * selected and placed into the resulting vector at {@code N}.
664 *
665 * @param s the shuffle controlling lane index selection
666 * @return the rearrangement of the lane elements of this vector
667 */
668 // rearrange
669 public abstract Vector<E> rearrange(VectorShuffle<E> s);
670
671
672 // Conversions
673
674 /**
675 * Converts this vector into a shuffle, creating a shuffle from vector
676 * lane elements cast to {@code int} then logically AND'ed with the
677 * shuffle length minus one.
678 * <p>
679 * This methods behaves as if it returns the result of creating a shuffle
680 * given an array of the vector lane elements, as follows:
681 * <pre>{@code
682 * $type$[] a = this.toArray();
683 * int[] sa = new int[a.length];
684 * for (int i = 0; i < a.length; i++) {
685 * sa[i] = (int) a[i];
686 * }
687 * return this.species().shuffleFromValues(sa);
688 * }</pre>
689 *
699 * The underlying bits of this vector are copied to the resulting
700 * vector without modification, but those bits, before copying, may be
701 * truncated if the this vector's bit size is greater than desired vector's bit
702 * size, or appended to with zero bits if this vector's bit size is less
703 * than desired vector's bit size.
704 * <p>
705 * The method behaves as if this vector is stored into a byte buffer
706 * and then the desired vector is loaded from the byte buffer using
707 * native byte ordering. The implication is that ByteBuffer reads bytes
708 * and then composes them based on the byte ordering so the result
709 * depends on this composition.
710 * <p>
711 * For example, on a system with ByteOrder.LITTLE_ENDIAN, loading from
712 * byte array with values {0,1,2,3} and reshaping to int, leads to bytes
713 * being composed in order 0x3 0x2 0x1 0x0 which is decimal value 50462976.
714 * On a system with ByteOrder.BIG_ENDIAN, the value is instead 66051 because
715 * bytes are composed in order 0x0 0x1 0x2 0x3.
716 * <p>
717 * The following pseudocode expresses the behavior:
718 * <pre>{@code
719 * int blen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
720 * ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
721 * this.intoByteBuffer(bb, 0);
722 * return $type$Vector.fromByteBuffer(s, bb, 0);
723 * }</pre>
724 *
725 * @param s species of desired vector
726 * @param <F> the boxed element type of the species
727 * @return a vector transformed, by shape and element type, from this vector
728 */
729 @ForceInline
730 public abstract <F> Vector<F> reinterpret(VectorSpecies<F> s);
731
732 @ForceInline
733 @SuppressWarnings("unchecked")
734 <F> Vector<F> defaultReinterpret(VectorSpecies<F> s) {
735 int blen = Math.max(s.bitSize(), this.species().bitSize()) / Byte.SIZE;
736 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
737 this.intoByteBuffer(bb, 0);
738
739 Class<?> stype = s.elementType();
740 if (stype == byte.class) {
741 return (Vector) ByteVector.fromByteBuffer((ByteVector.ByteSpecies)s, bb, 0);
742 } else if (stype == short.class) {
743 return (Vector) ShortVector.fromByteBuffer((ShortVector.ShortSpecies)s, bb, 0);
744 } else if (stype == int.class) {
745 return (Vector) IntVector.fromByteBuffer((IntVector.IntSpecies)s, bb, 0);
746 } else if (stype == long.class) {
747 return (Vector) LongVector.fromByteBuffer((LongVector.LongSpecies)s, bb, 0);
748 } else if (stype == float.class) {
749 return (Vector) FloatVector.fromByteBuffer((FloatVector.FloatSpecies)s, bb, 0);
758 * Transforms this vector to a vector of same element type but different shape identified by species.
759 * <p>
760 * The lane elements of this vector are copied without
761 * modification to the resulting vector, but those lane elements, before
762 * copying, may be truncated if this vector's length is greater than the desired
763 * vector's length, or appended to with default element values if this
764 * vector's length is less than desired vector's length.
765 * <p>
766 * The method behaves as if this vector is stored into a byte array
767 * and then the returned vector is loaded from the byte array.
768 * The following pseudocode expresses the behavior:
769 * <pre>{@code
770 * int alen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
771 * byte[] a = new byte[alen];
772 * this.intoByteArray(a, 0);
773 * return $type$Vector.fromByteArray(s, a, 0);
774 * }</pre>
775 *
776 * @param s species of the desired vector
777 * @return a vector transformed, by shape, from this vector
778 */
779 public abstract Vector<E> reshape(VectorSpecies<E> s);
780
781 // Cast
782
783 /**
784 * Converts this vector to a vector of the given species element type {@code F}.
785 * <p>
786 * For each vector lane up to the length of this vector or
787 * desired vector, which ever is the minimum, and where {@code N} is the
788 * vector lane index, the element at index {@code N} of primitive type
789 * {@code E} is converted, according to primitive conversion rules
790 * specified by the Java Language Specification, to a value of primitive
791 * type {@code F} and placed into the resulting vector at lane index
792 * {@code N}. If desired vector's length is greater than this
793 * vector's length then the default primitive value is placed into
794 * subsequent lanes of the resulting vector.
795 *
796 * @param s species of the desired vector
797 * @param <F> the boxed element type of the species
798 * @return a vector converted by shape and element type from this vector
799 */
800 public abstract <F> Vector<F> cast(VectorSpecies<F> s);
801
802 //Array stores
803
804 /**
805 * Stores this vector into a byte array starting at an offset.
806 * <p>
807 * Bytes are extracted from primitive lane elements according to the
808 * native byte order of the underlying platform.
809 * <p>
810 * This method behaves as it calls the
811 * byte buffer, offset, and mask accepting
812 * {@link #intoByteBuffer(ByteBuffer, int, VectorMask) method} as follows:
813 * <pre>{@code
814 * return this.intoByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
815 * }</pre>
816 *
817 * @param a the byte array
818 * @param i the offset into the array
918 return Float.SIZE * numElem;
919 }
920 else if (c == double.class) {
921 return Double.SIZE * numElem;
922 }
923 else if (c == byte.class) {
924 return Byte.SIZE * numElem;
925 }
926 else if (c == short.class) {
927 return Short.SIZE * numElem;
928 }
929 else if (c == int.class) {
930 return Integer.SIZE * numElem;
931 }
932 else if (c == long.class) {
933 return Long.SIZE * numElem;
934 }
935 else {
936 throw new IllegalArgumentException("Bad vector type: " + c.getName());
937 }
938 }
939 }
|
88 * It is recommended that Species instances be held in {@code static final}
89 * fields for optimal creation and usage of Vector values by the runtime compiler.
90 * <p>
91 * Vector operations can be grouped into various categories and their behavior
92 * generally specified as follows:
93 * <ul>
94 * <li>
95 * A lane-wise unary operation operates on one input vector and produces 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 behavior 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 a = ...;
106 * e[] ar = new e[a.length()];
107 * for (int i = 0; i < a.length(); i++) {
108 * ar[i] = scalar_unary_op(a.lane(i));
109 * }
110 * EVector r = EVector.fromArray(a.species(), ar, 0);
111 * }</pre>
112 *
113 * Unless otherwise specified the input and result vectors will have the same
114 * element type and shape.
115 *
116 * <li>
117 * A lane-wise binary operation operates on two input
118 * vectors and produces a result vector.
119 * For each lane of the two input vectors a and b,
120 * the corresponding lane elements from a and b are operated on
121 * using the specified scalar binary operation and the element result is placed
122 * into the vector result at the same lane.
123 * The following pseudocode expresses the behavior of this operation category:
124 *
125 * <pre>{@code
126 * EVector a = ...;
127 * EVector b = ...;
128 * e[] ar = new e[a.length()];
129 * for (int i = 0; i < a.length(); i++) {
130 * ar[i] = scalar_binary_op(a.lane(i), b.lane(i));
131 * }
132 * EVector r = EVector.fromArray(a.species(), ar, 0);
133 * }</pre>
134 *
135 * Unless otherwise specified the two input and result vectors will have the
136 * same element type and shape.
137 *
138 * <li>
139 * Generalizing from unary and binary operations, a lane-wise n-ary
140 * operation operates on n input vectors and produces a result vector.
141 * N lane elements from each input vector are operated on
142 * using the specified n-ary scalar operation and the element result is placed
143 * into the vector result at the same lane.
144 * Unless otherwise specified the n input and result vectors will have the same
145 * element type and shape.
146 *
147 * <li>
148 * A cross-lane vector reduction operation operates on all the lane
149 * elements of an input vector.
150 * An accumulation function is applied to all the
151 * lane elements to produce a scalar result.
152 * If the reduction operation is associative then the result may be accumulated
153 * by operating on the lane elements in any order using a specified associative
154 * scalar binary operation and identity value. Otherwise, the reduction
155 * operation specifies the behavior of the accumulation function.
156 * The following pseudocode expresses the behavior of this operation category
157 * if it is associative:
158 * <pre>{@code
159 * EVector a = ...;
160 * e r = <identity value>;
161 * for (int i = 0; i < a.length(); i++) {
162 * r = assoc_scalar_binary_op(r, a.lane(i));
163 * }
164 * }</pre>
165 *
166 * Unless otherwise specified the scalar result type and element type will be
167 * the same.
168 *
169 * <li>
170 * A lane-wise binary test operation operates on two input vectors and produces a
171 * result mask. For each lane of the two input vectors, a and b say, the
172 * the corresponding lane elements from a and b are operated on using the
173 * specified scalar binary test operation and the boolean result is placed
174 * into the mask at the same lane.
175 * The following pseudocode expresses the behavior of this operation category:
176 * <pre>{@code
177 * EVector a = ...;
178 * EVector b = ...;
179 * boolean[] ar = new boolean[a.length()];
180 * for (int i = 0; i < a.length(); i++) {
181 * ar[i] = scalar_binary_test_op(a.lane(i), b.lane(i));
182 * }
183 * VectorMask r = VectorMask.fromArray(a.species(), ar, 0);
184 * }</pre>
185 *
186 * Unless otherwise specified the two input vectors and result mask will have
187 * the same element type and shape.
188 *
189 * <li>
190 * The prior categories of operation can be said to operate within the vector
191 * lanes, where lane access is uniformly applied to all vectors, specifically
192 * the scalar operation is applied to elements taken from input vectors at the
193 * same lane, and if appropriate applied to the result vector at the same lane.
194 * A further category of operation is a cross-lane vector operation where lane
195 * access is defined by the arguments to the operation. Cross-lane operations
196 * generally rearrange lane elements, for example by permutation (commonly
197 * controlled by a {@link jdk.incubator.vector.VectorShuffle}) or by blending (commonly controlled by a
198 * {@link jdk.incubator.vector.VectorMask}). Such an operation explicitly specifies how it rearranges lane
199 * elements.
200 * </ul>
201 *
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, of this vector
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 size, in bits, of this vector.
301 *
302 * @return the total size, in bits, of this vector
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 lane-wise binary operation which applies the primitive addition operation
312 * ({@code +}) to each lane.
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>
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 lane-wise unary operation which applies the primitive negation operation
384 * ({@code -}) to each lane.
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 lane-wise unary operation which applies the primitive negation operation
394 * ({@code -}) to each lane.
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 lane-wise unary operation which applies the operation
407 * {@code (a) -> (a < 0) ? -a : a} to each lane.
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
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 lane-wise binary operation which applies the operation
465 * {@code (a, b) -> a > b ? a : b} to each lane.
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 lane-wise binary test operation which applies the primitive equals
479 * operation ({@code ==}) to each lane.
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 lane-wise binary test operation which applies the primitive not equals
491 * operation ({@code !=}) to each lane.
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 lane-wise binary test operation which applies the primitive less than
503 * operation ({@code <}) to each lane.
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 lane-wise binary test operation which applies the primitive less than
515 * or equal to operation ({@code <=}) to each lane.
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 lane-wise binary test operation which applies the primitive greater than
527 * operation ({@code >}) to each lane.
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 lane-wise binary test operation which applies the primitive greater than
539 * or equal to operation ({@code >=}) to each lane.
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 the result vector at lane index
557 * {@code (N + i) % 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> rotateLanesLeft(int i);
564
565 /**
566 * Rotates right the lane elements of this vector by the given number of
567 * lanes, {@code i}, modulus the vector length.
568 * <p>
569 * This is a cross-lane operation that permutes the lane elements of this
570 * vector.
571 * For each lane of the input vector, at lane index {@code N}, the lane
572 * element is placed into the result vector at lane index
573 * {@code (N + length() - (i % length())) % length()}
574 *
575 * @param i the number of lanes to rotate right
576 * @return the result of rotating right lane elements of this vector by the
577 * given number of lanes
578 */
579 public abstract Vector<E> rotateLanesRight(int i);
580
581 /**
582 * Shift left the lane elements of this vector by the given number of
583 * lanes, {@code i}, modulus the vector length.
584 * <p>
585 * This is a cross-lane operation that permutes the lane elements of this
586 * vector and behaves as if rotating left the lane elements by {@code i},
587 * and then the zero value is placed into the result vector at lane indexes
588 * less than {@code i % length()}.
589 *
590 * @param i the number of lanes to shift left
591 * @return the result of shifting left lane elements of this vector by the
592 * given number of lanes
593 * @throws IllegalArgumentException if {@code i} is {@code < 0}.
594 */
595 public abstract Vector<E> shiftLanesLeft(int i);
596
597 /**
598 * Shift right the lane elements of this vector by the given number of
599 * lanes, {@code i}, modulus the vector length.
600 * <p>
601 * This is a cross-lane operation that permutes the lane elements of this
602 * vector and behaves as if rotating right the lane elements by {@code i},
603 * and then the zero value is placed into the result vector at lane indexes
604 * greater or equal to {@code length() - (i % length())}.
605 *
606 * @param i the number of lanes to shift right
607 * @return the result of shifting right lane elements of this vector by the
608 * given number of lanes
609 * @throws IllegalArgumentException if {@code i} is {@code < 0}.
610 */
611 public abstract Vector<E> shiftLanesRight(int i);
612
613 /**
614 * Blends the lane elements of this vector with those of an input vector,
615 * selecting lanes controlled by a mask.
616 * <p>
617 * For each lane of the mask, at lane index {@code N}, if the mask lane
618 * is set then the lane element at {@code N} from the input vector is
619 * selected and placed into the resulting vector at {@code N},
620 * otherwise the lane element at {@code N} from this vector is
621 * selected and placed into the resulting vector at {@code N}.
622 *
623 * @param v the input vector
624 * @param m the mask controlling lane selection
625 * @return the result of blending the lane elements of this vector with
626 * those of an input vector
627 */
628 public abstract Vector<E> blend(Vector<E> v, VectorMask<E> m);
629
630 /**
631 * Rearranges the lane elements of this vector selecting lane indexes
632 * controlled by a shuffle.
633 * <p>
634 * This is a cross-lane operation that rearranges the lane elements of this
635 * vector.
636 * For each lane of the shuffle, at lane index {@code N} with lane
637 * element {@code I}, the lane element at {@code I} from this vector is
638 * selected and placed into the resulting vector at {@code N}.
639 *
640 * @param s the shuffle controlling lane index selection
641 * @return the rearrangement of the lane elements of this vector
642 */
643 public abstract Vector<E> rearrange(VectorShuffle<E> s);
644
645 /**
646 * Rearranges the lane elements of this vector and those of an input vector,
647 * selecting lane indexes controlled by shuffles and a mask.
648 * <p>
649 * This is a cross-lane operation that rearranges the lane elements of this
650 * vector and the input vector. This method behaves as if it rearranges
651 * each vector with the corresponding shuffle and then blends the two
652 * results with the mask:
653 * <pre>{@code
654 * return this.rearrange(s1).blend(v.rearrange(s2), m);
655 * }</pre>
656 *
657 * @param v the input vector
658 * @param s the shuffle controlling lane index selection of the input vector
659 * if corresponding mask lanes are set, otherwise controlling lane
660 * index selection of this vector
661 * @param m the mask controlling shuffled lane selection
662 * @return the rearrangement of lane elements of this vector and
663 * those of an input vector
664 */
665 public abstract Vector<E> rearrange(Vector<E> v,
666 VectorShuffle<E> s, VectorMask<E> m);
667
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 *
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 behavior:
716 * <pre>{@code
717 * int bufferLen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
718 * ByteBuffer bb = ByteBuffer.allocate(bufferLen).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 * @see Vector#reshape(VectorSpecies)
727 * @see Vector#cast(VectorSpecies)
728 */
729 public abstract <F> Vector<F> reinterpret(VectorSpecies<F> s);
730
731 @ForceInline
732 @SuppressWarnings("unchecked")
733 <F> Vector<F> defaultReinterpret(VectorSpecies<F> s) {
734 int blen = Math.max(s.bitSize(), this.species().bitSize()) / Byte.SIZE;
735 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
736 this.intoByteBuffer(bb, 0);
737
738 Class<?> stype = s.elementType();
739 if (stype == byte.class) {
740 return (Vector) ByteVector.fromByteBuffer((ByteVector.ByteSpecies)s, bb, 0);
741 } else if (stype == short.class) {
742 return (Vector) ShortVector.fromByteBuffer((ShortVector.ShortSpecies)s, bb, 0);
743 } else if (stype == int.class) {
744 return (Vector) IntVector.fromByteBuffer((IntVector.IntSpecies)s, bb, 0);
745 } else if (stype == long.class) {
746 return (Vector) LongVector.fromByteBuffer((LongVector.LongSpecies)s, bb, 0);
747 } else if (stype == float.class) {
748 return (Vector) FloatVector.fromByteBuffer((FloatVector.FloatSpecies)s, bb, 0);
757 * Transforms this vector to a vector of same element type but different shape identified by species.
758 * <p>
759 * The lane elements of this vector are copied without
760 * modification to the resulting vector, but those lane elements, before
761 * copying, may be truncated if this vector's length is greater than the desired
762 * vector's length, or appended to with default element values if this
763 * vector's length is less than desired vector's length.
764 * <p>
765 * The method behaves as if this vector is stored into a byte array
766 * and then the returned vector is loaded from the byte array.
767 * The following pseudocode expresses the behavior:
768 * <pre>{@code
769 * int alen = Math.max(this.bitSize(), s.bitSize()) / Byte.SIZE;
770 * byte[] a = new byte[alen];
771 * this.intoByteArray(a, 0);
772 * return $type$Vector.fromByteArray(s, a, 0);
773 * }</pre>
774 *
775 * @param s species of the desired vector
776 * @return a vector transformed, by shape, from this vector
777 * @see Vector#reinterpret(VectorSpecies)
778 * @see Vector#cast(VectorSpecies)
779 */
780 public abstract Vector<E> reshape(VectorSpecies<E> s);
781
782 // Cast
783
784 /**
785 * Converts this vector to a vector of the given species element type {@code F}.
786 * <p>
787 * For each vector lane up to the length of this vector or
788 * desired vector, which ever is the minimum, and where {@code N} is the
789 * vector lane index, the element at index {@code N} of primitive type
790 * {@code E} is converted, according to primitive conversion rules
791 * specified by the Java Language Specification, to a value of primitive
792 * type {@code F} and placed into the resulting vector at lane index
793 * {@code N}. If desired vector's length is greater than this
794 * vector's length then the default primitive value is placed into
795 * subsequent lanes of the resulting vector.
796 *
797 * @param s species of the desired vector
798 * @param <F> the boxed element type of the species
799 * @return a vector converted by shape and element type from this vector
800 * @see Vector#reshape(VectorSpecies)
801 * @see Vector#reinterpret(VectorSpecies)
802 */
803 public abstract <F> Vector<F> cast(VectorSpecies<F> s);
804
805 //Array stores
806
807 /**
808 * Stores this vector into a byte array starting at an offset.
809 * <p>
810 * Bytes are extracted from primitive lane elements according to the
811 * native byte order of the underlying platform.
812 * <p>
813 * This method behaves as it calls the
814 * byte buffer, offset, and mask accepting
815 * {@link #intoByteBuffer(ByteBuffer, int, VectorMask) method} as follows:
816 * <pre>{@code
817 * return this.intoByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
818 * }</pre>
819 *
820 * @param a the byte array
821 * @param i the offset into the array
921 return Float.SIZE * numElem;
922 }
923 else if (c == double.class) {
924 return Double.SIZE * numElem;
925 }
926 else if (c == byte.class) {
927 return Byte.SIZE * numElem;
928 }
929 else if (c == short.class) {
930 return Short.SIZE * numElem;
931 }
932 else if (c == int.class) {
933 return Integer.SIZE * numElem;
934 }
935 else if (c == long.class) {
936 return Long.SIZE * numElem;
937 }
938 else {
939 throw new IllegalArgumentException("Bad vector type: " + c.getName());
940 }
941 }
942
943 /**
944 * Returns a mask of same species as {@code this} vector and where each lane is set or unset according to given
945 * {@code boolean} values.
946 * <p>
947 * This method behaves as if it returns the result of calling the static {@link VectorMask#fromValues(VectorSpecies, boolean...) fromValues()}
948 * method in VectorMask as follows:
949 * <pre> {@code
950 * return VectorMask.fromValues(this.species(), bits);
951 * } </pre>
952 *
953 * @param bits the given {@code boolean} values
954 * @return a mask where each lane is set or unset according to the given {@code boolean} value
955 * @throws IndexOutOfBoundsException if {@code bits.length < this.species().length()}
956 * @see VectorMask#fromValues(VectorSpecies, boolean...)
957 */
958 @ForceInline
959 public final VectorMask<E> maskFromValues(boolean... bits) {
960 return VectorMask.fromValues(this.species(), bits);
961 }
962
963 /**
964 * Loads a mask of same species as {@code this} vector from a {@code boolean} array starting at an offset.
965 * <p>
966 * This method behaves as if it returns the result of calling the static {@link VectorMask#fromArray(VectorSpecies, boolean[], int) fromArray()}
967 * method in VectorMask as follows:
968 * <pre> {@code
969 * return VectorMask.fromArray(this.species(), bits, offset);
970 * } </pre>
971 *
972 * @param bits the {@code boolean} array
973 * @param offset the offset into the array
974 * @return the mask loaded from a {@code boolean} array
975 * @throws IndexOutOfBoundsException if {@code offset < 0}, or
976 * {@code offset > bits.length - species.length()}
977 * @see VectorMask#fromArray(VectorSpecies, boolean[], int)
978 */
979 @ForceInline
980 public final VectorMask<E> maskFromArray(boolean[] bits, int offset) {
981 return VectorMask.fromArray(this.species(), bits, offset);
982 }
983
984 /**
985 * Returns a mask of same species as {@code this} vector and where all lanes are set.
986 *
987 * @return a mask where all lanes are set
988 * @see VectorMask#maskAllTrue(VectorSpecies)
989 */
990 @ForceInline
991 public final VectorMask<E> maskAllTrue() {
992 return VectorMask.maskAllTrue(this.species());
993 }
994
995 /**
996 * Returns a mask of same species as {@code this} vector and where all lanes are unset.
997 *
998 * @return a mask where all lanes are unset
999 * @see VectorMask#maskAllFalse(VectorSpecies)
1000 */
1001 @ForceInline
1002 public final VectorMask<E> maskAllFalse() {
1003 return VectorMask.maskAllFalse(this.species());
1004 }
1005
1006 /**
1007 * Returns a shuffle of same species as {@code this} vector and where each lane element is set to a given
1008 * {@code int} value logically AND'ed by the species length minus one.
1009 * <p>
1010 * This method behaves as if it returns the result of calling the static {@link VectorShuffle#fromValues(VectorSpecies, int...) fromValues()}
1011 * method in VectorShuffle as follows:
1012 * <pre> {@code
1013 * return VectorShuffle.fromValues(this.species(), ixs);
1014 * } </pre>
1015 *
1016 * @param ixs the given {@code int} values
1017 * @return a shuffle where each lane element is set to a given
1018 * {@code int} value
1019 * @throws IndexOutOfBoundsException if the number of int values is
1020 * {@code < this.species().length()}
1021 * @see AbstractShuffle#fromValues(VectorSpecies, int...)
1022 */
1023 @ForceInline
1024 public final VectorShuffle<E> shuffleFromValues(int... ixs) {
1025 return VectorShuffle.fromValues(this.species(), ixs);
1026 }
1027
1028 /**
1029 * Loads a shuffle of same species as {@code this} vector from an {@code int} array starting at an offset.
1030 * <p>
1031 * This method behaves as if it returns the result of calling the static {@link VectorShuffle#fromArray(VectorSpecies, int[], int) fromArray()}
1032 * method in VectorShuffle as follows:
1033 * <pre> {@code
1034 * return VectorShuffle.fromArray(this.species(), ixs, offset);
1035 * } </pre>
1036 *
1037 * @param ixs the {@code int} array
1038 * @param offset the offset into the array
1039 * @return a shuffle loaded from the {@code int} array
1040 * @throws IndexOutOfBoundsException if {@code offset < 0}, or
1041 * {@code offset > ixs.length - this.species().length()}
1042 * @see AbstractShuffle#fromArray(VectorSpecies, int[], int)
1043 */
1044 @ForceInline
1045 public final VectorShuffle<E> shuffleFromArray(int[] ixs, int offset) {
1046 return VectorShuffle.fromArray(this.species(), ixs, offset);
1047 }
1048
1049 /**
1050 * Returns a shuffle of same species as {@code this} vector of mapped indexes where each lane element is
1051 * the result of applying a mapping function to the corresponding lane
1052 * index.
1053 * <p>
1054 * This method behaves as if it returns the result of calling the static {@link VectorShuffle#shuffle(VectorSpecies, IntUnaryOperator) shuffle()}
1055 * method in VectorShuffle as follows:
1056 * <pre> {@code
1057 * return AbstractShuffle.shuffle(this.species(), f);
1058 * } </pre>
1059 *
1060 * @param f the lane index mapping function
1061 * @return a shuffle of mapped indexes
1062 * @see AbstractShuffle#shuffle(VectorSpecies, IntUnaryOperator)
1063 */
1064 @ForceInline
1065 public final VectorShuffle<E> shuffle(IntUnaryOperator f) {
1066 return AbstractShuffle.shuffle(this.species(), f);
1067 }
1068
1069 /**
1070 * Returns a shuffle of same species as {@code this} vector and where each lane element is the value of its
1071 * corresponding lane index.
1072 * <p>
1073 * This method behaves as if it returns the result of calling the static {@link VectorShuffle#shuffleIota(VectorSpecies) shuffleIota()}
1074 * method in VectorShuffle as follows:
1075 * <pre> {@code
1076 * return VectorShuffle.shuffleIota(this.species());
1077 * } </pre>
1078 *
1079 * @return a shuffle of lane indexes
1080 * @see AbstractShuffle#shuffleIota(VectorSpecies)
1081 */
1082 @ForceInline
1083 public final VectorShuffle<E> shuffleIota() {
1084 return VectorShuffle.shuffleIota(this.species());
1085 }
1086
1087 /**
1088 * Returns a shuffle of same species as {@code this} vector and with lane elements set to sequential {@code int}
1089 * values starting from {@code start}.
1090 * <p>
1091 * This method behaves as if it returns the result of calling the static {@link VectorShuffle#shuffleIota(VectorSpecies, int) shuffleIota()}
1092 * method in VectorShuffle as follows:
1093 * <pre> {@code
1094 * return VectorShuffle.shuffleIota(this.species(), start);
1095 * } </pre>
1096 *
1097 * @param start starting value of sequence
1098 * @return a shuffle of lane indexes
1099 * @see AbstractShuffle#shuffleIota(VectorSpecies, int)
1100 */
1101 @ForceInline
1102 public final VectorShuffle<E> shuffleIota(int start) {
1103 return VectorShuffle.shuffleIota(this.species(), start);
1104 }
1105
1106 /**
1107 * Returns a shuffle of same species as {@code this} vector and with lane elements set to sequential {@code int}
1108 * values starting from {@code start} and looping around species length.
1109 * <p>
1110 * This method behaves as if it returns the result of calling the static {@link VectorShuffle#shuffleOffset(VectorSpecies, int) shuffleOffset()}
1111 * method in VectorShuffle as follows:
1112 * <pre> {@code
1113 * return VectorShuffle.shuffleOffset(this.species(), start);
1114 * } </pre>
1115 *
1116 * @param start starting value of sequence
1117 * @return a shuffle of lane indexes
1118 * @see AbstractShuffle#shuffleOffset(VectorSpecies, int)
1119 */
1120 @ForceInline
1121 public final VectorShuffle<E> shuffleOffset(int start) {
1122 return VectorShuffle.shuffleOffset(this.species(), start);
1123 }
1124 }
|