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));
109 * }
110 * EVector<S> r = a.species().fromArray(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 vector binary operation (2-ary) operates on two input
118 * vectors to produce a result vector.
119 * For each lane of the two input vectors,
120 * a and b say, 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 behaviour of this operation category:
124 *
125 * <pre>{@code
126 * EVector<S> a = ...;
127 * EVector<S> 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<S> r = a.species().fromArray(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 (1-ary) and binary (2-ary) operations, a vector n-ary
140 * operation operates in n input vectors to produce a
141 * result vector.
142 * N lane elements from each input vector are operated on
143 * using the specified n-ary scalar operation and the element result is placed
144 * into the vector result at the same lane.
145 * Unless otherwise specified the n input and result vectors will have the same
146 * element type and shape.
147 *
148 * <li>
149 * A vector reduction operation operates on all the lane
150 * elements of an input vector.
151 * An accumulation function is applied to all the
152 * lane elements to produce a scalar result.
153 * If the reduction operation is associative then the result may be accumulated
154 * by operating on the lane elements in any order using a specified associative
155 * scalar binary operation and identity value. Otherwise, the reduction
156 * operation specifies the behaviour of the accumulation function.
157 * The following pseudocode expresses the behaviour of this operation category
158 * if it is associative:
159 * <pre>{@code
160 * EVector<S> a = ...;
161 * e r = <identity value>;
162 * for (int i = 0; i < a.length(); i++) {
163 * r = assoc_scalar_binary_op(r, 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 */
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 /**
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 and behaves as if rotating left the lane elements by
571 * {@code this.length() - (i % this.length())} lanes.
572 *
573 * @param i the number of lanes to rotate left
574 * @return the result of rotating right lane elements of this vector by the
575 * given number of lanes
576 */
577 public abstract Vector<E> rotateER(int i);
578
579 /**
580 * Shift left the lane elements of this vector by the given number of
581 * lanes, {@code i}, modulus the vector length.
582 * <p>
583 * This is a cross-lane operation that permutes the lane elements of this
584 * vector and behaves as if rotating left the lane elements by {@code i},
585 * and then the zero value is placed into the result vector at lane indexes
586 * less than {@code i % this.length()}.
587 *
588 * @param i the number of lanes to shift left
589 * @return the result of shifting left lane elements of this vector by the
590 * given number of lanes
591 * @throws IllegalArgumentException if {@code i} is {@code < 0}.
592 */
593 public abstract Vector<E> shiftEL(int i);
594
595 /**
596 * Shift right the lane elements of this vector by the given number of
597 * lanes, {@code i}, modulus the vector length.
598 * <p>
599 * This is a cross-lane operation that permutes the lane elements of this
600 * vector and behaves as if rotating right the lane elements by {@code i},
601 * and then the zero value is placed into the result vector at lane indexes
602 * greater or equal to {@code this.length() - (i % this.length())}.
603 *
604 * @param i the number of lanes to shift left
605 * @return the result of shifting left lane elements of this vector by the
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>
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);
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
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,
877 * according to the native byte order of the underlying platform, and
878 * the lane elements of this vector are put into the buffer if the
879 * corresponding mask lane is set.
880 * The following pseudocode expresses the behaviour, where
881 * {@coce EBuffer} is the primitive buffer type, {@code e} is the
882 * primitive element type, and {@code EVector<S>} is the primitive
883 * vector type for this vector:
884 * <pre>{@code
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.
|
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
46 * less time than 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 {@link VectorShape},
56 * that governs the total {@link #bitSize() size} in bits of the sequence of values.
57 * The combination of element type and shape determines a <em>vector species</em>,
58 * represented by {@link jdk.incubator.vector.VectorSpecies}.
59 * <p>
60 * The number of values in the sequence is referred to as the Vector
61 * {@link #length() length}. The length also corresponds to the number of
62 * Vector lanes. The lane element at lane index {@code N} (from {@code 0},
63 * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th value in
64 * the sequence.
65 * Note: this arrangement
66 * of Vector bit size, Vector length, element bit size, and lane element index
67 * has no bearing on how a Vector instance and its sequence of elements may be
68 * arranged in memory or represented as a value in a vector hardware register.
69 * <p>
70 * Vector declares a set of vector operations (methods) that are common to all
71 * element types (such as addition). Sub-classes of Vector with a concrete
72 * boxed element type declare further operations that are specific to that
73 * element type (such as access to element values in lanes, logical operations
74 * on values of integral elements types, or transcendental operations on values
75 * of floating point element types).
76 * There are six abstract sub-classes of Vector corresponding to the supported set
77 * of element types, {@link ByteVector}, {@link ShortVector},
78 * {@link IntVector} {@link LongVector}, {@link FloatVector}, and
79 * {@link DoubleVector}. Along with type-specific operations these classes
80 * support creation of vector values (instances of Vector).
81 * They expose static constants corresponding to the supported species,
82 * and static methods on these types generally take a species as a parameter.
83 * For example,
84 * {@link jdk.incubator.vector.FloatVector#fromArray(VectorSpecies, float[], int) FloatVector.fromArray()}
85 * creates and returns a float vector of the specified species, with elements
86 * loaded from the specified float array.
87 * <p>
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 *
202 * <p>
203 * If a vector operation does not belong to one of the above categories then
204 * the operation explicitly specifies how it processes the lane elements of
205 * input vectors, and where appropriate expresses the behavior using
206 * pseudocode.
207 *
208 * <p>
209 * Many vector operations provide an additional {@link VectorMask mask} accepting
210 * variant.
211 * The mask controls which lanes are selected for application of the scalar
212 * operation. Masks are a key component for the support of control flow in
213 * vector computations.
214 * <p>
215 * Many vector operations provide an additional {@link jdk.incubator.vector.VectorMask mask}-accepting
216 * variant.
217 * The mask controls which lanes are selected for application of the scalar
218 * operation. Masks are a key component for the support of control flow in
219 * vector computations.
220 * <p>
221 * For certain operation categories the mask accepting variants can be specified
222 * in generic terms. If a lane of the mask is set then the scalar operation is
223 * applied to corresponding lane elements, otherwise if a lane of a mask is not
224 * set then a default scalar operation is applied and its result is placed into
225 * the vector result at the same lane. The default operation is specified as follows:
226 * <ul>
227 * <li>
228 * For a lane-wise n-ary operation the default operation is a function that returns
229 * it's first argument, specifically the 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 lane-wise 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 behavior using pseudocode.
240 *
241 * <p>
242 * For convenience, many vector operations of arity greater than one provide
243 * an additional scalar-accepting variant (such as adding a constant scalar
244 * value to all lanes of a vector). This variant accepts compatible
245 * scalar values instead of vectors for the second and subsequent input vectors,
246 * if any.
247 * Unless otherwise specified the scalar variant behaves as if each scalar value
248 * is transformed to a vector using the appropriate vector {@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 */
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>
323 * This is a lane-wise binary operation which applies the primitive addition operation
324 * ({@code +}) to each lane.
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 lane-wise binary operation which applies the primitive subtraction
336 * operation ({@code -}) to each lane.
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 lane-wise binary operation which applies the primitive subtraction
348 * operation ({@code -}) to each lane.
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 lane-wise binary operation which applies the primitive multiplication
360 * operation ({@code *}) to each lane.
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 lane-wise binary operation which applies the primitive multiplication
372 * operation ({@code *}) to each lane.
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 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
415 * a mask.
416 * <p>
417 * This is a lane-wise unary operation which applies the operation
418 * {@code (a) -> (a < 0) ? -a : a} to each lane.
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 lane-wise binary operation which applies the operation
429 * {@code (a, b) -> a < b ? a : b} to each lane.
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 lane-wise binary operation which applies the operation
441 * {@code (a, b) -> a < b ? a : b} to each lane.
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 lane-wise binary operation which applies the operation
453 * {@code (a, b) -> a > b ? a : b} to each lane.
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 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>
697 * Transforms this vector to a vector of the given species of element type {@code F}.
698 * <p>
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);
748 } else if (stype == float.class) {
749 return (Vector) FloatVector.fromByteBuffer((FloatVector.FloatSpecies)s, bb, 0);
750 } else if (stype == double.class) {
751 return (Vector) DoubleVector.fromByteBuffer((DoubleVector.DoubleSpecies)s, bb, 0);
752 } else {
753 throw new UnsupportedOperationException("Bad lane type for reinterpret.");
754 }
755 }
756
757 /**
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
862 *
863 * @param b the byte buffer
864 * @param i the offset into the byte buffer
865 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
866 * or {@code > b.limit()},
867 * or if there are fewer than
868 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
869 * remaining in the byte buffer from the given offset
870 */
871 public abstract void intoByteBuffer(ByteBuffer b, int i);
872
873 /**
874 * Stores this vector into a {@link ByteBuffer byte buffer} starting at an
875 * offset into the byte buffer and using a mask.
876 * <p>
877 * This method behaves as if the byte buffer is viewed as a primitive
878 * {@link java.nio.Buffer buffer} for the primitive element type,
879 * according to the native byte order of the underlying platform, and
880 * the lane elements of this vector are put into the buffer if the
881 * corresponding mask lane is set.
882 * The following pseudocode expresses the behavior, where
883 * {@coce EBuffer} is the primitive buffer type, {@code e} is the
884 * primitive element type, and {@code EVector} is the primitive
885 * vector type for this vector:
886 * <pre>{@code
887 * EBuffer eb = b.duplicate().
888 * order(ByteOrder.nativeOrder()).position(i).
889 * asEBuffer();
890 * e[] es = ((EVector)this).toArray();
891 * for (int n = 0; n < t.length; n++) {
892 * if (m.isSet(n)) {
893 * eb.put(n, es[n]);
894 * }
895 * }
896 * }</pre>
897 *
898 * @param b the byte buffer
899 * @param i the offset into the byte buffer
900 * @param m the mask
901 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
902 * or {@code > b.limit()},
903 * for any vector lane index {@code N} where the mask at lane {@code N}
904 * is set
905 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes
906 */
907 public abstract void intoByteBuffer(ByteBuffer b, int i, VectorMask<E> m);
908
909 /**
910 * Find bit size based on element type and number of elements.
|