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.vm.annotation.ForceInline; 28 29 import java.nio.ByteBuffer; 30 import java.nio.ByteOrder; 31 import java.nio.ShortBuffer; 32 import java.util.Objects; 33 import java.util.concurrent.ThreadLocalRandom; 34 35 36 /** 37 * A specialized {@link Vector} representing an ordered immutable sequence of 38 * {@code short} values. 39 * 40 * @param <S> the type of shape of this vector 41 */ 42 @SuppressWarnings("cast") 43 public abstract class ShortVector<S extends Vector.Shape> extends Vector<Short,S> { 44 45 ShortVector() {} 46 47 // Unary operator 48 49 interface FUnOp { 50 short apply(int i, short a); 51 } 52 53 abstract ShortVector<S> uOp(FUnOp f); 54 55 abstract ShortVector<S> uOp(Mask<Short, S> m, FUnOp f); 56 57 // Binary operator 58 59 interface FBinOp { 60 short apply(int i, short a, short b); 61 } 62 63 abstract ShortVector<S> bOp(Vector<Short,S> v, FBinOp f); 64 65 abstract ShortVector<S> bOp(Vector<Short,S> v, Mask<Short, S> m, FBinOp f); 66 67 // Trinary operator 68 69 interface FTriOp { 70 short apply(int i, short a, short b, short c); 71 } 72 73 abstract ShortVector<S> tOp(Vector<Short,S> v1, Vector<Short,S> v2, FTriOp f); 74 75 abstract ShortVector<S> tOp(Vector<Short,S> v1, Vector<Short,S> v2, Mask<Short, S> m, FTriOp f); 76 77 // Reduction operator 78 79 abstract short rOp(short v, FBinOp f); 80 81 // Binary test 82 83 interface FBinTest { 84 boolean apply(int i, short a, short b); 85 } 86 87 abstract Mask<Short, S> bTest(Vector<Short,S> v, FBinTest f); 88 89 // Foreach 90 91 interface FUnCon { 92 void apply(int i, short a); 93 } 94 95 abstract void forEach(FUnCon f); 96 97 abstract void forEach(Mask<Short, S> m, FUnCon f); 98 99 // 100 101 @Override 102 public abstract ShortVector<S> add(Vector<Short,S> v); 103 104 /** 105 * Adds this vector to the broadcast of an input scalar. 106 * <p> 107 * This is a vector binary operation where the primitive addition operation 108 * ({@code +}) is applied to lane elements. 109 * 110 * @param s the input scalar 111 * @return the result of adding this vector to the broadcast of an input 112 * scalar 113 */ 114 public abstract ShortVector<S> add(short s); 115 116 @Override 117 public abstract ShortVector<S> add(Vector<Short,S> v, Mask<Short, S> m); 118 119 /** 120 * Adds this vector to broadcast of an input scalar, 121 * selecting lane elements controlled by a mask. 122 * <p> 123 * This is a vector binary operation where the primitive addition operation 124 * ({@code +}) is applied to lane elements. 125 * 126 * @param s the input scalar 127 * @param m the mask controlling lane selection 128 * @return the result of adding this vector to the broadcast of an input 129 * scalar 130 */ 131 public abstract ShortVector<S> add(short s, Mask<Short, S> m); 132 133 @Override 134 public abstract ShortVector<S> sub(Vector<Short,S> v); 135 136 /** 137 * Subtracts the broadcast of an input scalar from this vector. 138 * <p> 139 * This is a vector binary operation where the primitive subtraction 140 * operation ({@code -}) is applied to lane elements. 141 * 142 * @param s the input scalar 143 * @return the result of subtracting the broadcast of an input 144 * scalar from this vector 145 */ 146 public abstract ShortVector<S> sub(short s); 147 148 @Override 149 public abstract ShortVector<S> sub(Vector<Short,S> v, Mask<Short, S> m); 150 151 /** 152 * Subtracts the broadcast of an input scalar from this vector, selecting 153 * lane elements controlled by a mask. 154 * <p> 155 * This is a vector binary operation where the primitive subtraction 156 * operation ({@code -}) is applied to lane elements. 157 * 158 * @param s the input scalar 159 * @param m the mask controlling lane selection 160 * @return the result of subtracting the broadcast of an input 161 * scalar from this vector 162 */ 163 public abstract ShortVector<S> sub(short s, Mask<Short, S> m); 164 165 @Override 166 public abstract ShortVector<S> mul(Vector<Short,S> v); 167 168 /** 169 * Multiplies this vector with the broadcast of an input scalar. 170 * <p> 171 * This is a vector binary operation where the primitive multiplication 172 * operation ({@code *}) is applied to lane elements. 173 * 174 * @param s the input scalar 175 * @return the result of multiplying this vector with the broadcast of an 176 * input scalar 177 */ 178 public abstract ShortVector<S> mul(short s); 179 180 @Override 181 public abstract ShortVector<S> mul(Vector<Short,S> v, Mask<Short, S> m); 182 183 /** 184 * Multiplies this vector with the broadcast of an input scalar, selecting 185 * lane elements controlled by a mask. 186 * <p> 187 * This is a vector binary operation where the primitive multiplication 188 * operation ({@code *}) is applied to lane elements. 189 * 190 * @param s the input scalar 191 * @param m the mask controlling lane selection 192 * @return the result of multiplying this vector with the broadcast of an 193 * input scalar 194 */ 195 public abstract ShortVector<S> mul(short s, Mask<Short, S> m); 196 197 @Override 198 public abstract ShortVector<S> neg(); 199 200 @Override 201 public abstract ShortVector<S> neg(Mask<Short, S> m); 202 203 @Override 204 public abstract ShortVector<S> abs(); 205 206 @Override 207 public abstract ShortVector<S> abs(Mask<Short, S> m); 208 209 @Override 210 public abstract ShortVector<S> min(Vector<Short,S> v); 211 212 /** 213 * Returns the minimum of this vector and the broadcast of an input scalar. 214 * <p> 215 * This is a vector binary operation where the operation 216 * {@code (a, b) -> a < b ? a : b} is applied to lane elements. 217 * 218 * @param s the input scalar 219 * @return the minimum of this vector and the broadcast of an input scalar 220 */ 221 public abstract ShortVector<S> min(short s); 222 223 @Override 224 public abstract ShortVector<S> max(Vector<Short,S> v); 225 226 /** 227 * Returns the maximum of this vector and the broadcast of an input scalar. 228 * <p> 229 * This is a vector binary operation where the operation 230 * {@code (a, b) -> a > b ? a : b} is applied to lane elements. 231 * 232 * @param s the input scalar 233 * @return the maximum of this vector and the broadcast of an input scalar 234 */ 235 public abstract ShortVector<S> max(short s); 236 237 @Override 238 public abstract Mask<Short, S> equal(Vector<Short,S> v); 239 240 /** 241 * Tests if this vector is equal to the broadcast of an input scalar. 242 * <p> 243 * This is a vector binary test operation where the primitive equals 244 * operation ({@code ==}) is applied to lane elements. 245 * 246 * @param s the input scalar 247 * @return the result mask of testing if this vector is equal to the 248 * broadcast of an input scalar 249 */ 250 public abstract Mask<Short, S> equal(short s); 251 252 @Override 253 public abstract Mask<Short, S> notEqual(Vector<Short,S> v); 254 255 /** 256 * Tests if this vector is not equal to the broadcast of an input scalar. 257 * <p> 258 * This is a vector binary test operation where the primitive not equals 259 * operation ({@code !=}) is applied to lane elements. 260 * 261 * @param s the input scalar 262 * @return the result mask of testing if this vector is not equal to the 263 * broadcast of an input scalar 264 */ 265 public abstract Mask<Short, S> notEqual(short s); 266 267 @Override 268 public abstract Mask<Short, S> lessThan(Vector<Short,S> v); 269 270 /** 271 * Tests if this vector is less than the broadcast of an input scalar. 272 * <p> 273 * This is a vector binary test operation where the primitive less than 274 * operation ({@code <}) is applied to lane elements. 275 * 276 * @param s the input scalar 277 * @return the mask result of testing if this vector is less than the 278 * broadcast of an input scalar 279 */ 280 public abstract Mask<Short, S> lessThan(short s); 281 282 @Override 283 public abstract Mask<Short, S> lessThanEq(Vector<Short,S> v); 284 285 /** 286 * Tests if this vector is less or equal to the broadcast of an input scalar. 287 * <p> 288 * This is a vector binary test operation where the primitive less than 289 * or equal to operation ({@code <=}) is applied to lane elements. 290 * 291 * @param s the input scalar 292 * @return the mask result of testing if this vector is less than or equal 293 * to the broadcast of an input scalar 294 */ 295 public abstract Mask<Short, S> lessThanEq(short s); 296 297 @Override 298 public abstract Mask<Short, S> greaterThan(Vector<Short,S> v); 299 300 /** 301 * Tests if this vector is greater than the broadcast of an input scalar. 302 * <p> 303 * This is a vector binary test operation where the primitive greater than 304 * operation ({@code >}) is applied to lane elements. 305 * 306 * @param s the input scalar 307 * @return the mask result of testing if this vector is greater than the 308 * broadcast of an input scalar 309 */ 310 public abstract Mask<Short, S> greaterThan(short s); 311 312 @Override 313 public abstract Mask<Short, S> greaterThanEq(Vector<Short,S> v); 314 315 /** 316 * Tests if this vector is greater than or equal to the broadcast of an 317 * input scalar. 318 * <p> 319 * This is a vector binary test operation where the primitive greater than 320 * or equal to operation ({@code >=}) is applied to lane elements. 321 * 322 * @param s the input scalar 323 * @return the mask result of testing if this vector is greater than or 324 * equal to the broadcast of an input scalar 325 */ 326 public abstract Mask<Short, S> greaterThanEq(short s); 327 328 @Override 329 public abstract ShortVector<S> blend(Vector<Short,S> v, Mask<Short, S> m); 330 331 /** 332 * Blends the lane elements of this vector with those of the broadcast of an 333 * input scalar, selecting lanes controlled by a mask. 334 * <p> 335 * For each lane of the mask, at lane index {@code N}, if the mask lane 336 * is set then the lane element at {@code N} from the input vector is 337 * selected and placed into the resulting vector at {@code N}, 338 * otherwise the the lane element at {@code N} from this input vector is 339 * selected and placed into the resulting vector at {@code N}. 340 * 341 * @param s the input scalar 342 * @param m the mask controlling lane selection 343 * @return the result of blending the lane elements of this vector with 344 * those of the broadcast of an input scalar 345 */ 346 public abstract ShortVector<S> blend(short s, Mask<Short, S> m); 347 348 @Override 349 public abstract ShortVector<S> rearrange(Vector<Short, S> v, 350 Shuffle<Short, S> s, Mask<Short, S> m); 351 352 @Override 353 public abstract ShortVector<S> rearrange(Shuffle<Short, S> m); 354 355 @Override 356 @ForceInline 357 public <T extends Shape> ShortVector<T> resize(Species<Short, T> species) { 358 return (ShortVector<T>) species.resize(this); 359 } 360 361 @Override 362 public abstract ShortVector<S> rotateEL(int i); 363 364 @Override 365 public abstract ShortVector<S> rotateER(int i); 366 367 @Override 368 public abstract ShortVector<S> shiftEL(int i); 369 370 @Override 371 public abstract ShortVector<S> shiftER(int i); 372 373 374 375 /** 376 * Bitwise ANDs this vector with an input vector. 377 * <p> 378 * This is a vector binary operation where the primitive bitwise AND 379 * operation ({@code &}) is applied to lane elements. 380 * 381 * @param v the input vector 382 * @return the bitwise AND of this vector with the input vector 383 */ 384 public abstract ShortVector<S> and(Vector<Short,S> v); 385 386 /** 387 * Bitwise ANDs this vector with the broadcast of an input scalar. 388 * <p> 389 * This is a vector binary operation where the primitive bitwise AND 390 * operation ({@code &}) is applied to lane elements. 391 * 392 * @param s the input scalar 393 * @return the bitwise AND of this vector with the broadcast of an input 394 * scalar 395 */ 396 public abstract ShortVector<S> and(short s); 397 398 /** 399 * Bitwise ANDs this vector with an input vector, selecting lane elements 400 * controlled by a mask. 401 * <p> 402 * This is a vector binary operation where the primitive bitwise AND 403 * operation ({@code &}) is applied to lane elements. 404 * 405 * @param v the input vector 406 * @param m the mask controlling lane selection 407 * @return the bitwise AND of this vector with the input vector 408 */ 409 public abstract ShortVector<S> and(Vector<Short,S> v, Mask<Short, S> m); 410 411 /** 412 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting 413 * lane elements controlled by a mask. 414 * <p> 415 * This is a vector binary operation where the primitive bitwise AND 416 * operation ({@code &}) is applied to lane elements. 417 * 418 * @param s the input scalar 419 * @param m the mask controlling lane selection 420 * @return the bitwise AND of this vector with the broadcast of an input 421 * scalar 422 */ 423 public abstract ShortVector<S> and(short s, Mask<Short, S> m); 424 425 /** 426 * Bitwise ORs this vector with an input vector. 427 * <p> 428 * This is a vector binary operation where the primitive bitwise OR 429 * operation ({@code |}) is applied to lane elements. 430 * 431 * @param v the input vector 432 * @return the bitwise OR of this vector with the input vector 433 */ 434 public abstract ShortVector<S> or(Vector<Short,S> v); 435 436 /** 437 * Bitwise ORs this vector with the broadcast of an input scalar. 438 * <p> 439 * This is a vector binary operation where the primitive bitwise OR 440 * operation ({@code |}) is applied to lane elements. 441 * 442 * @param s the input scalar 443 * @return the bitwise OR of this vector with the broadcast of an input 444 * scalar 445 */ 446 public abstract ShortVector<S> or(short s); 447 448 /** 449 * Bitwise ORs this vector with an input vector, selecting lane elements 450 * controlled by a mask. 451 * <p> 452 * This is a vector binary operation where the primitive bitwise OR 453 * operation ({@code |}) is applied to lane elements. 454 * 455 * @param v the input vector 456 * @param m the mask controlling lane selection 457 * @return the bitwise OR of this vector with the input vector 458 */ 459 public abstract ShortVector<S> or(Vector<Short,S> v, Mask<Short, S> m); 460 461 /** 462 * Bitwise ORs this vector with the broadcast of an input scalar, selecting 463 * lane elements controlled by a mask. 464 * <p> 465 * This is a vector binary operation where the primitive bitwise OR 466 * operation ({@code |}) is applied to lane elements. 467 * 468 * @param s the input scalar 469 * @param m the mask controlling lane selection 470 * @return the bitwise OR of this vector with the broadcast of an input 471 * scalar 472 */ 473 public abstract ShortVector<S> or(short s, Mask<Short, S> m); 474 475 /** 476 * Bitwise XORs this vector with an input vector. 477 * <p> 478 * This is a vector binary operation where the primitive bitwise XOR 479 * operation ({@code ^}) is applied to lane elements. 480 * 481 * @param v the input vector 482 * @return the bitwise XOR of this vector with the input vector 483 */ 484 public abstract ShortVector<S> xor(Vector<Short,S> v); 485 486 /** 487 * Bitwise XORs this vector with the broadcast of an input scalar. 488 * <p> 489 * This is a vector binary operation where the primitive bitwise XOR 490 * operation ({@code ^}) is applied to lane elements. 491 * 492 * @param s the input scalar 493 * @return the bitwise XOR of this vector with the broadcast of an input 494 * scalar 495 */ 496 public abstract ShortVector<S> xor(short s); 497 498 /** 499 * Bitwise XORs this vector with an input vector, selecting lane elements 500 * controlled by a mask. 501 * <p> 502 * This is a vector binary operation where the primitive bitwise XOR 503 * operation ({@code ^}) is applied to lane elements. 504 * 505 * @param v the input vector 506 * @param m the mask controlling lane selection 507 * @return the bitwise XOR of this vector with the input vector 508 */ 509 public abstract ShortVector<S> xor(Vector<Short,S> v, Mask<Short, S> m); 510 511 /** 512 * Bitwise XORs this vector with the broadcast of an input scalar, selecting 513 * lane elements controlled by a mask. 514 * <p> 515 * This is a vector binary operation where the primitive bitwise XOR 516 * operation ({@code ^}) is applied to lane elements. 517 * 518 * @param s the input scalar 519 * @param m the mask controlling lane selection 520 * @return the bitwise XOR of this vector with the broadcast of an input 521 * scalar 522 */ 523 public abstract ShortVector<S> xor(short s, Mask<Short, S> m); 524 525 /** 526 * Bitwise NOTs this vector. 527 * <p> 528 * This is a vector unary operation where the primitive bitwise NOT 529 * operation ({@code ~}) is applied to lane elements. 530 * 531 * @return the bitwise NOT of this vector 532 */ 533 public abstract ShortVector<S> not(); 534 535 /** 536 * Bitwise NOTs this vector, selecting lane elements controlled by a mask. 537 * <p> 538 * This is a vector unary operation where the primitive bitwise NOT 539 * operation ({@code ~}) is applied to lane elements. 540 * 541 * @param m the mask controlling lane selection 542 * @return the bitwise NOT of this vector 543 */ 544 public abstract ShortVector<S> not(Mask<Short, S> m); 545 546 /* 547 @@@ Check the shift operations against the JLS definition and vector 548 instructions. 549 550 For int values the low 5 bits of s are used. 551 For long values the low 6 bits of s are used. 552 */ 553 554 555 @Override 556 public abstract void intoByteArray(byte[] a, int ix); 557 558 @Override 559 public abstract void intoByteArray(byte[] a, int ix, Mask<Short, S> m); 560 561 @Override 562 public abstract void intoByteBuffer(ByteBuffer bb, int ix); 563 564 @Override 565 public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Short, S> m); 566 567 568 // Type specific horizontal reductions 569 570 // @@@ For floating point vectors order matters for reproducibility 571 // with equivalent sequential reduction. Some order needs to be specified 572 // by default. If that default is sequential encounter order then there 573 // could be a "go faster" option that is unspecified, essentially giving 574 // implementation flexibility at the expense of reproducibility and/or 575 // accuracy. 576 // @@@ Mask versions? 577 578 /** 579 * Adds all lane elements of this vector. 580 * <p> 581 * This is an associative vector reduction operation where the addition 582 * operation ({@code +}) is applied to lane elements, 583 * and the identity value is {@code 0}. 584 * 585 * @return the addition of all the lane elements of this vector 586 */ 587 public abstract short addAll(); 588 589 /** 590 * Adds all lane elements of this vector, selecting lane elements 591 * controlled by a mask. 592 * <p> 593 * This is an associative vector reduction operation where the addition 594 * operation ({@code +}) is applied to lane elements, 595 * and the identity value is {@code 0}. 596 * 597 * @param m the mask controlling lane selection 598 * @return the addition of all the lane elements of this vector 599 */ 600 public abstract short addAll(Mask<Short, S> m); 601 602 /** 603 * Subtracts all lane elements of this vector. 604 * <p> 605 * This is an associative vector reduction operation where the subtraction 606 * operation ({@code -}) is applied to lane elements, 607 * and the identity value is {@code 0}. 608 * 609 * @return the subtraction of all the lane elements of this vector 610 */ 611 public abstract short subAll(); 612 613 /** 614 * Subtracts all lane elements of this vector, selecting lane elements 615 * controlled by a mask. 616 * <p> 617 * This is an associative vector reduction operation where the subtraction 618 * operation ({@code -}) is applied to lane elements, 619 * and the identity value is {@code 0}. 620 * 621 * @param m the mask controlling lane selection 622 * @return the subtraction of all the lane elements of this vector 623 */ 624 public abstract short subAll(Mask<Short, S> m); 625 626 /** 627 * Multiplies all lane elements of this vector. 628 * <p> 629 * This is an associative vector reduction operation where the 630 * multiplication operation ({@code *}) is applied to lane elements, 631 * and the identity value is {@code 1}. 632 * 633 * @return the multiplication of all the lane elements of this vector 634 */ 635 public abstract short mulAll(); 636 637 /** 638 * Multiplies all lane elements of this vector, selecting lane elements 639 * controlled by a mask. 640 * <p> 641 * This is an associative vector reduction operation where the 642 * multiplication operation ({@code *}) is applied to lane elements, 643 * and the identity value is {@code 1}. 644 * 645 * @param m the mask controlling lane selection 646 * @return the multiplication of all the lane elements of this vector 647 */ 648 public abstract short mulAll(Mask<Short, S> m); 649 650 /** 651 * Returns the minimum lane element of this vector. 652 * <p> 653 * This is an associative vector reduction operation where the operation 654 * {@code (a, b) -> a > b ? b : a} is applied to lane elements, 655 * and the identity value is {@link Short.MAX_VALUE}. 656 * 657 * @return the minimum lane element of this vector 658 */ 659 public abstract short minAll(); 660 661 /** 662 * Returns the minimum lane element of this vector, selecting lane elements 663 * controlled by a mask. 664 * <p> 665 * This is an associative vector reduction operation where the operation 666 * {@code (a, b) -> a > b ? b : a} is applied to lane elements, 667 * and the identity value is {@link Short.MAX_VALUE}. 668 * 669 * @param m the mask controlling lane selection 670 * @return the minimum lane element of this vector 671 */ 672 public abstract short minAll(Mask<Short, S> m); 673 674 /** 675 * Returns the maximum lane element of this vector. 676 * <p> 677 * This is an associative vector reduction operation where the operation 678 * {@code (a, b) -> a < b ? b : a} is applied to lane elements, 679 * and the identity value is {@link Short.MIN_VALUE}. 680 * 681 * @return the maximum lane element of this vector 682 */ 683 public abstract short maxAll(); 684 685 /** 686 * Returns the maximum lane element of this vector, selecting lane elements 687 * controlled by a mask. 688 * <p> 689 * This is an associative vector reduction operation where the operation 690 * {@code (a, b) -> a < b ? b : a} is applied to lane elements, 691 * and the identity value is {@link Short.MIN_VALUE}. 692 * 693 * @param m the mask controlling lane selection 694 * @return the maximum lane element of this vector 695 */ 696 public abstract short maxAll(Mask<Short, S> m); 697 698 /** 699 * Logically ORs all lane elements of this vector. 700 * <p> 701 * This is an associative vector reduction operation where the logical OR 702 * operation ({@code |}) is applied to lane elements, 703 * and the identity value is {@code 0}. 704 * 705 * @return the logical OR all the lane elements of this vector 706 */ 707 public abstract short orAll(); 708 709 /** 710 * Logically ORs all lane elements of this vector, selecting lane elements 711 * controlled by a mask. 712 * <p> 713 * This is an associative vector reduction operation where the logical OR 714 * operation ({@code |}) is applied to lane elements, 715 * and the identity value is {@code 0}. 716 * 717 * @param m the mask controlling lane selection 718 * @return the logical OR all the lane elements of this vector 719 */ 720 public abstract short orAll(Mask<Short, S> m); 721 722 /** 723 * Logically ANDs all lane elements of this vector. 724 * <p> 725 * This is an associative vector reduction operation where the logical AND 726 * operation ({@code |}) is applied to lane elements, 727 * and the identity value is {@code -1}. 728 * 729 * @return the logical AND all the lane elements of this vector 730 */ 731 public abstract short andAll(); 732 733 /** 734 * Logically ANDs all lane elements of this vector, selecting lane elements 735 * controlled by a mask. 736 * <p> 737 * This is an associative vector reduction operation where the logical AND 738 * operation ({@code |}) is applied to lane elements, 739 * and the identity value is {@code -1}. 740 * 741 * @param m the mask controlling lane selection 742 * @return the logical AND all the lane elements of this vector 743 */ 744 public abstract short andAll(Mask<Short, S> m); 745 746 /** 747 * Logically XORs all lane elements of this vector. 748 * <p> 749 * This is an associative vector reduction operation where the logical XOR 750 * operation ({@code ^}) is applied to lane elements, 751 * and the identity value is {@code 0}. 752 * 753 * @return the logical XOR all the lane elements of this vector 754 */ 755 public abstract short xorAll(); 756 757 /** 758 * Logically XORs all lane elements of this vector, selecting lane elements 759 * controlled by a mask. 760 * <p> 761 * This is an associative vector reduction operation where the logical XOR 762 * operation ({@code ^}) is applied to lane elements, 763 * and the identity value is {@code 0}. 764 * 765 * @param m the mask controlling lane selection 766 * @return the logical XOR all the lane elements of this vector 767 */ 768 public abstract short xorAll(Mask<Short, S> m); 769 770 // Type specific accessors 771 772 /** 773 * Gets the lane element at lane index {@code i} 774 * 775 * @param i the lane index 776 * @return the lane element at lane index {@code i} 777 * @throws IllegalArgumentException if the index is is out of range 778 * ({@code < 0 || >= length()}) 779 */ 780 public abstract short get(int i); 781 782 /** 783 * Replaces the lane element of this vector at lane index {@code i} with 784 * value {@code e}. 785 * <p> 786 * This is a cross-lane operation and behaves as if it returns the result 787 * of blending this vector with an input vector that is the result of 788 * broadcasting {@code e} and a mask that has only one lane set at lane 789 * index {@code i}. 790 * 791 * @param i the lane index of the lane element to be replaced 792 * @param e the value to be placed 793 * @return the result of replacing the lane element of this vector at lane 794 * index {@code i} with value {@code e}. 795 * @throws IllegalArgumentException if the index is is out of range 796 * ({@code < 0 || >= length()}) 797 */ 798 public abstract ShortVector<S> with(int i, short e); 799 800 // Type specific extractors 801 802 /** 803 * Returns an array containing the lane elements of this vector. 804 * <p> 805 * This method behaves as if it {@link #intoArray(short[], int)} stores} 806 * this vector into an allocated array and returns the array as follows: 807 * <pre>{@code 808 * short[] a = new short[this.length()]; 809 * this.intoArray(a, 0); 810 * return a; 811 * }</pre> 812 * 813 * @return an array containing the the lane elements of this vector 814 */ 815 @ForceInline 816 public final short[] toArray() { 817 // @@@ could allocate without zeroing, see Unsafe.allocateUninitializedArray 818 short[] a = new short[species().length()]; 819 intoArray(a, 0); 820 return a; 821 } 822 823 /** 824 * Stores this vector into an array starting at offset. 825 * <p> 826 * For each vector lane, where {@code N} is the vector lane index, 827 * the lane element at index {@code N} is stored into the array at index 828 * {@code i + N}. 829 * 830 * @param a the array 831 * @param i the offset into the array 832 * @throws IndexOutOfBoundsException if {@code i < 0}, or 833 * {@code i > a.length - this.length()} 834 */ 835 public abstract void intoArray(short[] a, int i); 836 837 /** 838 * Stores this vector into an array starting at offset and using a mask. 839 * <p> 840 * For each vector lane, where {@code N} is the vector lane index, 841 * if the mask lane at index {@code N} is set then the lane element at 842 * index {@code N} is stored into the array index {@code i + N}. 843 * 844 * @param a the array 845 * @param i the offset into the array 846 * @param m the mask 847 * @throws IndexOutOfBoundsException if {@code i < 0}, or 848 * for any vector lane index {@code N} where the mask at lane {@code N} 849 * is set {@code i >= a.length - N} 850 */ 851 public abstract void intoArray(short[] a, int i, Mask<Short, S> m); 852 853 /** 854 * Stores this vector into an array using indexes obtained from an index 855 * map. 856 * <p> 857 * For each vector lane, where {@code N} is the vector lane index, the 858 * lane element at index {@code N} is stored into the array at index 859 * {@code i + indexMap[j + N]}. 860 * 861 * @param a the array 862 * @param i the offset into the array, may be negative if relative 863 * indexes in the index map compensate to produce a value within the 864 * array bounds 865 * @param indexMap the index map 866 * @param j the offset into the index map 867 * @throws IndexOutOfBoundsException if {@code j < 0}, or 868 * {@code j > indexMap.length - this.length()}, 869 * or for any vector lane index {@code N} the result of 870 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 871 */ 872 public void intoArray(short[] a, int i, int[] indexMap, int j) { 873 forEach((n, e) -> a[i + indexMap[j + n]] = e); 874 } 875 876 /** 877 * Stores this vector into an array using indexes obtained from an index 878 * map and using a mask. 879 * <p> 880 * For each vector lane, where {@code N} is the vector lane index, 881 * if the mask lane at index {@code N} is set then the lane element at 882 * index {@code N} is stored into the array at index 883 * {@code i + indexMap[j + N]}. 884 * 885 * @param a the array 886 * @param i the offset into the array, may be negative if relative 887 * indexes in the index map compensate to produce a value within the 888 * array bounds 889 * @param m the mask 890 * @param indexMap the index map 891 * @param j the offset into the index map 892 * @throws IndexOutOfBoundsException if {@code j < 0}, or 893 * {@code j > indexMap.length - this.length()}, 894 * or for any vector lane index {@code N} where the mask at lane 895 * {@code N} is set the result of {@code i + indexMap[j + N]} is 896 * {@code < 0} or {@code >= a.length} 897 */ 898 public void intoArray(short[] a, int i, Mask<Short, S> m, int[] indexMap, int j) { 899 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e); 900 } 901 902 // Species 903 904 @Override 905 public abstract ShortSpecies<S> species(); 906 907 /** 908 * A specialized factory for creating {@link ShortVector} value of the same 909 * shape, and a {@link Mask} and {@link Shuffle} values of the same shape 910 * and {@code int} element type. 911 * 912 * @param <S> the type of shape of this species 913 */ 914 public static abstract class ShortSpecies<S extends Vector.Shape> extends Vector.Species<Short, S> { 915 interface FOp { 916 short apply(int i); 917 } 918 919 abstract ShortVector<S> op(FOp f); 920 921 abstract ShortVector<S> op(Mask<Short, S> m, FOp f); 922 923 // Factories 924 925 @Override 926 public abstract ShortVector<S> zero(); 927 928 /** 929 * Returns a vector where all lane elements are set to the primitive 930 * value {@code e}. 931 * 932 * @param e the value 933 * @return a vector of vector where all lane elements are set to 934 * the primitive value {@code e} 935 */ 936 public abstract ShortVector<S> broadcast(short e); 937 938 /** 939 * Returns a vector where the first lane element is set to the primtive 940 * value {@code e}, all other lane elements are set to the default 941 * value. 942 * 943 * @param e the value 944 * @return a vector where the first lane element is set to the primitive 945 * value {@code e} 946 */ 947 @ForceInline 948 public final ShortVector<S> single(short e) { 949 return zero().with(0, e); 950 } 951 952 /** 953 * Returns a vector where each lane element is set to a randomly 954 * generated primitive value. 955 * @@@ what are the properties of the random number generator? 956 * 957 * @return a vector where each lane elements is set to a randomly 958 * generated primitive value 959 */ 960 public ShortVector<S> random() { 961 ThreadLocalRandom r = ThreadLocalRandom.current(); 962 return op(i -> (short) r.nextInt()); 963 } 964 965 /** 966 * Returns a vector where each lane element is set to a given 967 * primitive value. 968 * <p> 969 * For each vector lane, where {@code N} is the vector lane index, the 970 * the primitive value at index {@code N} is placed into the resulting 971 * vector at lane index {@code N}. 972 * 973 * @@@ What should happen if es.length < this.length() ? use the default 974 * value or throw IndexOutOfBoundsException 975 * 976 * @param es the given primitive values 977 * @return a vector where each lane element is set to a given primitive 978 * value 979 */ 980 public abstract ShortVector<S> scalars(short... es); 981 982 /** 983 * Loads a vector from an array starting at offset. 984 * <p> 985 * For each vector lane, where {@code N} is the vector lane index, the 986 * array element at index {@code i + N} is placed into the 987 * resulting vector at lane index {@code N}. 988 * 989 * @param a the array 990 * @param i the offset into the array 991 * @return the vector loaded from an array 992 * @throws IndexOutOfBoundsException if {@code i < 0}, or 993 * {@code i > a.length - this.length()} 994 */ 995 public abstract ShortVector<S> fromArray(short[] a, int i); 996 997 /** 998 * Loads a vector from an array starting at offset and using a mask. 999 * <p> 1000 * For each vector lane, where {@code N} is the vector lane index, 1001 * if the mask lane at index {@code N} is set then the array element at 1002 * index {@code i + N} is placed into the resulting vector at lane index 1003 * {@code N}, otherwise the default element value is placed into the 1004 * resulting vector at lane index {@code N}. 1005 * 1006 * @param a the array 1007 * @param i the offset into the array 1008 * @param m the mask 1009 * @return the vector loaded from an array 1010 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1011 * for any vector lane index {@code N} where the mask at lane {@code N} 1012 * is set {@code i > a.length - N} 1013 */ 1014 public abstract ShortVector<S> fromArray(short[] a, int i, Mask<Short, S> m); 1015 1016 /** 1017 * Loads a vector from an array using indexes obtained from an index 1018 * map. 1019 * <p> 1020 * For each vector lane, where {@code N} is the vector lane index, the 1021 * array element at index {@code i + indexMap[j + N]} is placed into the 1022 * resulting vector at lane index {@code N}. 1023 * 1024 * @param a the array 1025 * @param i the offset into the array, may be negative if relative 1026 * indexes in the index map compensate to produce a value within the 1027 * array bounds 1028 * @param indexMap the index map 1029 * @param j the offset into the index map 1030 * @return the vector loaded from an array 1031 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1032 * {@code j > indexMap.length - this.length()}, 1033 * or for any vector lane index {@code N} the result of 1034 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 1035 */ 1036 public ShortVector<S> fromArray(short[] a, int i, int[] indexMap, int j) { 1037 return op(n -> a[i + indexMap[j + n]]); 1038 } 1039 1040 /** 1041 * Loads a vector from an array using indexes obtained from an index 1042 * map and using a mask. 1043 * <p> 1044 * For each vector lane, where {@code N} is the vector lane index, 1045 * if the mask lane at index {@code N} is set then the array element at 1046 * index {@code i + indexMap[j + N]} is placed into the resulting vector 1047 * at lane index {@code N}. 1048 * 1049 * @param a the array 1050 * @param i the offset into the array, may be negative if relative 1051 * indexes in the index map compensate to produce a value within the 1052 * array bounds 1053 * @param indexMap the index map 1054 * @param j the offset into the index map 1055 * @return the vector loaded from an array 1056 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1057 * {@code j > indexMap.length - this.length()}, 1058 * or for any vector lane index {@code N} where the mask at lane 1059 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1060 * {@code < 0} or {@code >= a.length} 1061 */ 1062 public ShortVector<S> fromArray(short[] a, int i, Mask<Short, S> m, int[] indexMap, int j) { 1063 return op(m, n -> a[i + indexMap[j + n]]); 1064 } 1065 1066 @Override 1067 public abstract ShortVector<S> fromByteArray(byte[] a, int ix); 1068 1069 @Override 1070 public abstract ShortVector<S> fromByteArray(byte[] a, int ix, Mask<Short, S> m); 1071 1072 @Override 1073 public abstract ShortVector<S> fromByteBuffer(ByteBuffer bb, int ix); 1074 1075 @Override 1076 public abstract ShortVector<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<Short, S> m); 1077 1078 @Override 1079 public <F, T extends Shape> ShortVector<S> reshape(Vector<F, T> o) { 1080 int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE; 1081 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder()); 1082 o.intoByteBuffer(bb, 0); 1083 return fromByteBuffer(bb, 0); 1084 } 1085 1086 @Override 1087 public abstract <F> ShortVector<S> rebracket(Vector<F, S> o); 1088 1089 @Override 1090 public abstract <T extends Shape> ShortVector<S> resize(Vector<Short, T> o); 1091 1092 @Override 1093 public abstract <F, T extends Shape> ShortVector<S> cast(Vector<F, T> v); 1094 1095 } 1096 1097 /** 1098 * Finds the preferred species for an element type of {@code short}. 1099 * <p> 1100 * A preferred species is a species chosen by the platform that has a 1101 * shape of maximal bit size. A preferred species for different element 1102 * types will have the same shape, and therefore vectors, masks, and 1103 * shuffles created from such species will be shape compatible. 1104 * 1105 * @return the preferred species for an element type of {@code short} 1106 */ 1107 @SuppressWarnings("unchecked") 1108 public static ShortSpecies<?> preferredSpecies() { 1109 return (ShortSpecies<?>) Vector.preferredSpecies(short.class); 1110 } 1111 1112 /** 1113 * Finds a species for an element type of {@code short} and shape. 1114 * 1115 * @param s the shape 1116 * @param <S> the type of shape 1117 * @return a species for an element type of {@code short} and shape 1118 * @throws IllegalArgumentException if no such species exists for the shape 1119 */ 1120 @SuppressWarnings("unchecked") 1121 public static <S extends Shape> ShortSpecies<S> species(S s) { 1122 Objects.requireNonNull(s); 1123 if (s == Shapes.S_64_BIT) { 1124 return (ShortSpecies<S>) Short64Vector.SPECIES; 1125 } else if (s == Shapes.S_128_BIT) { 1126 return (ShortSpecies<S>) Short128Vector.SPECIES; 1127 } else if (s == Shapes.S_256_BIT) { 1128 return (ShortSpecies<S>) Short256Vector.SPECIES; 1129 } else if (s == Shapes.S_512_BIT) { 1130 return (ShortSpecies<S>) Short512Vector.SPECIES; 1131 } else { 1132 throw new IllegalArgumentException("Bad shape: " + s); 1133 } 1134 } 1135 }