1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import jdk.internal.misc.Unsafe; 28 import jdk.internal.vm.annotation.ForceInline; 29 import jdk.internal.vm.annotation.Stable; 30 31 import java.nio.ByteBuffer; 32 import java.nio.ByteOrder; 33 import java.util.Objects; 34 import java.util.function.Function; 35 import java.util.function.IntUnaryOperator; 36 import java.util.function.UnaryOperator; 37 38 import jdk.incubator.vector.*; 39 40 /** 41 * A {@code Vector} is designed for use in computations that can be transformed 42 * by a runtime compiler, on supported hardware, to Single Instruction Multiple 43 * Data (SIMD) computations leveraging vector hardware registers and vector 44 * hardware instructions. Such SIMD computations exploit data parallelism to 45 * perform the same operation on multiple data points simultaneously in 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.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 * 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 */ 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> 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 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 * 688 * @return a shuffle representation of this vector 689 */ 690 public abstract VectorShuffle<E> toShuffle(); 691 692 // Bitwise preserving 693 694 /** 695 * Transforms this vector to a vector of the given species of element type {@code F}. 696 * <p> 697 * The underlying bits of this vector are copied to the resulting 698 * vector without modification, but those bits, before copying, may be 699 * truncated if the this vector's bit size is greater than desired vector's bit 700 * size, or appended to with zero bits if this vector's bit size is less 701 * than desired vector's bit size. 702 * <p> 703 * The method behaves as if this vector is stored into a byte buffer 704 * and then the desired vector is loaded from the byte buffer using 705 * native byte ordering. The implication is that ByteBuffer reads bytes 706 * and then composes them based on the byte ordering so the result 707 * depends on this composition. 708 * <p> 709 * For example, on a system with ByteOrder.LITTLE_ENDIAN, loading from 710 * byte array with values {0,1,2,3} and reshaping to int, leads to bytes 711 * being composed in order 0x3 0x2 0x1 0x0 which is decimal value 50462976. 712 * On a system with ByteOrder.BIG_ENDIAN, the value is instead 66051 because 713 * bytes are composed in order 0x0 0x1 0x2 0x3. 714 * <p> 715 * The following pseudocode expresses the 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); 749 } else if (stype == double.class) { 750 return (Vector) DoubleVector.fromByteBuffer((DoubleVector.DoubleSpecies)s, bb, 0); 751 } else { 752 throw new UnsupportedOperationException("Bad lane type for reinterpret."); 753 } 754 } 755 756 /** 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 822 * @return a vector loaded from a byte array 823 * @throws IndexOutOfBoundsException if {@code i < 0} or 824 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)} 825 */ 826 public abstract void intoByteArray(byte[] a, int i); 827 828 /** 829 * Stores this vector into a byte array starting at an offset and using a mask. 830 * <p> 831 * Bytes are extracted from primitive lane elements according to the 832 * native byte order of the underlying platform. 833 * <p> 834 * This method behaves as it calls the 835 * byte buffer, offset, and mask accepting 836 * {@link #intoByteBuffer(ByteBuffer, int, VectorMask) method} as follows: 837 * <pre>{@code 838 * return this.intoByteBuffer(ByteBuffer.wrap(a), i, m); 839 * }</pre> 840 * 841 * @param a the byte array 842 * @param i the offset into the array 843 * @param m the mask controlling lane selection 844 * @throws IndexOutOfBoundsException if the offset is {@code < 0}, 845 * or {@code > a.length}, 846 * for any vector lane index {@code N} where the mask at lane {@code N} 847 * is set 848 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)} 849 */ 850 public abstract void intoByteArray(byte[] a, int i, VectorMask<E> m); 851 852 /** 853 * Stores this vector into a {@link ByteBuffer byte buffer} starting at an 854 * offset into the byte buffer. 855 * <p> 856 * Bytes are extracted from primitive lane elements according to the 857 * native byte order of the underlying platform. 858 * <p> 859 * This method behaves as if it calls the byte buffer, offset, and mask 860 * accepting 861 * {@link #intoByteBuffer(ByteBuffer, int, VectorMask)} method} as follows: 862 * <pre>{@code 863 * this.intoByteBuffer(b, i, this.maskAllTrue()) 864 * }</pre> 865 * 866 * @param b the byte buffer 867 * @param i the offset into the byte buffer 868 * @throws IndexOutOfBoundsException if the offset is {@code < 0}, 869 * or {@code > b.limit()}, 870 * or if there are fewer than 871 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes 872 * remaining in the byte buffer from the given offset 873 */ 874 public abstract void intoByteBuffer(ByteBuffer b, int i); 875 876 /** 877 * Stores this vector into a {@link ByteBuffer byte buffer} starting at an 878 * offset into the byte buffer and using a mask. 879 * <p> 880 * This method behaves as if the byte buffer is viewed as a primitive 881 * {@link java.nio.Buffer buffer} for the primitive element type, 882 * according to the native byte order of the underlying platform, and 883 * the lane elements of this vector are put into the buffer if the 884 * corresponding mask lane is set. 885 * The following pseudocode expresses the behavior, where 886 * {@coce EBuffer} is the primitive buffer type, {@code e} is the 887 * primitive element type, and {@code EVector} is the primitive 888 * vector type for this vector: 889 * <pre>{@code 890 * EBuffer eb = b.duplicate(). 891 * order(ByteOrder.nativeOrder()).position(i). 892 * asEBuffer(); 893 * e[] es = ((EVector)this).toArray(); 894 * for (int n = 0; n < t.length; n++) { 895 * if (m.isSet(n)) { 896 * eb.put(n, es[n]); 897 * } 898 * } 899 * }</pre> 900 * 901 * @param b the byte buffer 902 * @param i the offset into the byte buffer 903 * @param m the mask 904 * @throws IndexOutOfBoundsException if the offset is {@code < 0}, 905 * or {@code > b.limit()}, 906 * for any vector lane index {@code N} where the mask at lane {@code N} 907 * is set 908 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes 909 */ 910 public abstract void intoByteBuffer(ByteBuffer b, int i, VectorMask<E> m); 911 912 /** 913 * Find bit size based on element type and number of elements. 914 * 915 * @param c the element type 916 * @param numElem number of lanes in the vector 917 * @return size in bits for vector 918 */ 919 public static int bitSizeForVectorLength(Class<?> c, int numElem) { 920 if (c == float.class) { 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 }