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> o, FBinOp f); 64 65 abstract ShortVector<S> bOp(Vector<Short,S> o, 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> o1, Vector<Short,S> o2, FTriOp f); 74 75 abstract ShortVector<S> tOp(Vector<Short,S> o1, Vector<Short,S> o2, 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> o, 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 ShortVector<S> add(Vector<Short,S> o) { 103 return bOp(o, (i, a, b) -> (short) (a + b)); 104 } 105 106 /** 107 * Adds this vector to the result of broadcasting an input scalar. 108 * <p> 109 * This is a vector binary operation where the primitive addition operation 110 * ({@code +}) is applied to lane elements. 111 * 112 * @param b the input scalar 113 * @return the result of adding this vector to the broadcast of an input 114 * scalar 115 */ 116 public abstract ShortVector<S> add(short b); 117 118 @Override 119 public ShortVector<S> add(Vector<Short,S> o, Mask<Short, S> m) { 120 return bOp(o, m, (i, a, b) -> (short) (a + b)); 121 } 122 123 /** 124 * Adds this vector to the result of broadcasting an input scalar, 125 * selecting lane elements controlled by a mask. 126 * <p> 127 * This is a vector binary operation where the primitive addition operation 128 * ({@code +}) is applied to lane elements. 129 * 130 * @param b the input vector 131 * @param m the mask controlling lane selection 132 * @return the result of adding this vector to the broadcast of an input 133 * scalar 134 */ 135 public abstract ShortVector<S> add(short b, Mask<Short, S> m); 136 137 @Override 138 public ShortVector<S> addSaturate(Vector<Short,S> o) { 139 return bOp(o, (i, a, b) -> (short) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b)); 140 } 141 142 public abstract ShortVector<S> addSaturate(short o); 143 144 @Override 145 public ShortVector<S> addSaturate(Vector<Short,S> o, Mask<Short, S> m) { 146 return bOp(o, m, (i, a, b) -> (short) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b)); 147 } 148 149 public abstract ShortVector<S> addSaturate(short o, Mask<Short, S> m); 150 151 @Override 152 public ShortVector<S> sub(Vector<Short,S> o) { 153 return bOp(o, (i, a, b) -> (short) (a - b)); 154 } 155 156 public abstract ShortVector<S> sub(short o); 157 158 @Override 159 public ShortVector<S> sub(Vector<Short,S> o, Mask<Short, S> m) { 160 return bOp(o, m, (i, a, b) -> (short) (a - b)); 161 } 162 163 public abstract ShortVector<S> sub(short o, Mask<Short, S> m); 164 165 @Override 166 public ShortVector<S> subSaturate(Vector<Short,S> o) { 167 return bOp(o, (i, a, b) -> (short) ((a >= Integer.MIN_VALUE || Integer.MIN_VALUE + b > a) ? Integer.MAX_VALUE : a - b)); 168 } 169 170 public abstract ShortVector<S> subSaturate(short o); 171 172 @Override 173 public ShortVector<S> subSaturate(Vector<Short,S> o, Mask<Short, S> m) { 174 return bOp(o, m, (i, a, b) -> (short) ((a >= Integer.MIN_VALUE || Integer.MIN_VALUE + b > a) ? Integer.MAX_VALUE : a - b)); 175 } 176 177 public abstract ShortVector<S> subSaturate(short o, Mask<Short, S> m); 178 179 @Override 180 public ShortVector<S> mul(Vector<Short,S> o) { 181 return bOp(o, (i, a, b) -> (short) (a * b)); 182 } 183 184 public abstract ShortVector<S> mul(short o); 185 186 @Override 187 public ShortVector<S> mul(Vector<Short,S> o, Mask<Short, S> m) { 188 return bOp(o, m, (i, a, b) -> (short) (a * b)); 189 } 190 191 public abstract ShortVector<S> mul(short o, Mask<Short, S> m); 192 193 @Override 194 public ShortVector<S> neg() { 195 return uOp((i, a) -> (short) (-a)); 196 } 197 198 @Override 199 public ShortVector<S> neg(Mask<Short, S> m) { 200 return uOp(m, (i, a) -> (short) (-a)); 201 } 202 203 @Override 204 public ShortVector<S> abs() { 205 return uOp((i, a) -> (short) Math.abs(a)); 206 } 207 208 @Override 209 public ShortVector<S> abs(Mask<Short, S> m) { 210 return uOp(m, (i, a) -> (short) Math.abs(a)); 211 } 212 213 @Override 214 public ShortVector<S> min(Vector<Short,S> o) { 215 return bOp(o, (i, a, b) -> (a <= b) ? a : b); 216 } 217 218 public abstract ShortVector<S> min(short o); 219 220 @Override 221 public ShortVector<S> max(Vector<Short,S> o) { 222 return bOp(o, (i, a, b) -> (a >= b) ? a : b); 223 } 224 225 public abstract ShortVector<S> max(short o); 226 227 @Override 228 public Mask<Short, S> equal(Vector<Short,S> o) { 229 return bTest(o, (i, a, b) -> a == b); 230 } 231 232 public abstract Mask<Short, S> equal(short o); 233 234 @Override 235 public Mask<Short, S> notEqual(Vector<Short,S> o) { 236 return bTest(o, (i, a, b) -> a != b); 237 } 238 239 public abstract Mask<Short, S> notEqual(short o); 240 241 @Override 242 public Mask<Short, S> lessThan(Vector<Short,S> o) { 243 return bTest(o, (i, a, b) -> a < b); 244 } 245 246 public abstract Mask<Short, S> lessThan(short o); 247 248 @Override 249 public Mask<Short, S> lessThanEq(Vector<Short,S> o) { 250 return bTest(o, (i, a, b) -> a <= b); 251 } 252 253 public abstract Mask<Short, S> lessThanEq(short o); 254 255 @Override 256 public Mask<Short, S> greaterThan(Vector<Short,S> o) { 257 return bTest(o, (i, a, b) -> a > b); 258 } 259 260 public abstract Mask<Short, S> greaterThan(short o); 261 262 @Override 263 public Mask<Short, S> greaterThanEq(Vector<Short,S> o) { 264 return bTest(o, (i, a, b) -> a >= b); 265 } 266 267 public abstract Mask<Short, S> greaterThanEq(short o); 268 269 @Override 270 public ShortVector<S> blend(Vector<Short,S> o, Mask<Short, S> m) { 271 return bOp(o, (i, a, b) -> m.getElement(i) ? b : a); 272 } 273 274 public abstract ShortVector<S> blend(short o, Mask<Short, S> m); 275 276 @Override 277 public abstract ShortVector<S> shuffle(Vector<Short,S> o, Shuffle<Short, S> m); 278 279 @Override 280 public abstract ShortVector<S> swizzle(Shuffle<Short, S> m); 281 282 @Override 283 @ForceInline 284 public <T extends Shape> ShortVector<T> resize(Species<Short, T> species) { 285 return (ShortVector<T>) species.reshape(this); 286 } 287 288 @Override 289 public abstract ShortVector<S> rotateEL(int i); 290 291 @Override 292 public abstract ShortVector<S> rotateER(int i); 293 294 @Override 295 public abstract ShortVector<S> shiftEL(int i); 296 297 @Override 298 public abstract ShortVector<S> shiftER(int i); 299 300 301 public ShortVector<S> and(Vector<Short,S> o) { 302 return bOp(o, (i, a, b) -> (short) (a & b)); 303 } 304 305 public abstract ShortVector<S> and(short o); 306 307 public ShortVector<S> and(Vector<Short,S> o, Mask<Short, S> m) { 308 return bOp(o, m, (i, a, b) -> (short) (a & b)); 309 } 310 311 public abstract ShortVector<S> and(short o, Mask<Short, S> m); 312 313 public ShortVector<S> or(Vector<Short,S> o) { 314 return bOp(o, (i, a, b) -> (short) (a | b)); 315 } 316 317 public abstract ShortVector<S> or(short o); 318 319 public ShortVector<S> or(Vector<Short,S> o, Mask<Short, S> m) { 320 return bOp(o, m, (i, a, b) -> (short) (a | b)); 321 } 322 323 public abstract ShortVector<S> or(short o, Mask<Short, S> m); 324 325 public ShortVector<S> xor(Vector<Short,S> o) { 326 return bOp(o, (i, a, b) -> (short) (a ^ b)); 327 } 328 329 public abstract ShortVector<S> xor(short o); 330 331 public ShortVector<S> xor(Vector<Short,S> o, Mask<Short, S> m) { 332 return bOp(o, m, (i, a, b) -> (short) (a ^ b)); 333 } 334 335 public abstract ShortVector<S> xor(short o, Mask<Short, S> m); 336 337 public ShortVector<S> not() { 338 return uOp((i, a) -> (short) (~a)); 339 } 340 341 public ShortVector<S> not(Mask<Short, S> m) { 342 return uOp(m, (i, a) -> (short) (~a)); 343 } 344 345 // logical shift left 346 public ShortVector<S> shiftL(int s) { 347 return uOp((i, a) -> (short) (a << s)); 348 } 349 350 public ShortVector<S> shiftL(int s, Mask<Short, S> m) { 351 return uOp(m, (i, a) -> (short) (a << s)); 352 } 353 354 355 // logical, or unsigned, shift right 356 public ShortVector<S> shiftR(int s) { 357 return uOp((i, a) -> (short) (a >>> s)); 358 } 359 360 public ShortVector<S> shiftR(int s, Mask<Short, S> m) { 361 return uOp(m, (i, a) -> (short) (a >>> s)); 362 } 363 364 365 // arithmetic, or signed, shift right 366 public ShortVector<S> aShiftR(int s) { 367 return uOp((i, a) -> (short) (a >> s)); 368 } 369 370 public ShortVector<S> aShiftR(int s, Mask<Short, S> m) { 371 return uOp(m, (i, a) -> (short) (a >> s)); 372 } 373 374 375 public ShortVector<S> rotateL(int j) { 376 return uOp((i, a) -> (short) Integer.rotateLeft(a, j)); 377 } 378 379 public ShortVector<S> rotateR(int j) { 380 return uOp((i, a) -> (short) Integer.rotateRight(a, j)); 381 } 382 383 @Override 384 public void intoByteArray(byte[] a, int ix) { 385 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 386 intoByteBuffer(bb); 387 } 388 389 @Override 390 public void intoByteArray(byte[] a, int ix, Mask<Short, S> m) { 391 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 392 intoByteBuffer(bb, m); 393 } 394 395 @Override 396 public void intoByteBuffer(ByteBuffer bb) { 397 ShortBuffer fb = bb.asShortBuffer(); 398 forEach((i, a) -> fb.put(a)); 399 } 400 401 @Override 402 public void intoByteBuffer(ByteBuffer bb, Mask<Short, S> m) { 403 ShortBuffer fb = bb.asShortBuffer(); 404 forEach((i, a) -> { 405 if (m.getElement(i)) 406 fb.put(a); 407 else 408 fb.position(fb.position() + 1); 409 }); 410 } 411 412 @Override 413 public void intoByteBuffer(ByteBuffer bb, int ix) { 414 bb = bb.duplicate().position(ix); 415 ShortBuffer fb = bb.asShortBuffer(); 416 forEach((i, a) -> fb.put(i, a)); 417 } 418 419 @Override 420 public void intoByteBuffer(ByteBuffer bb, int ix, Mask<Short, S> m) { 421 bb = bb.duplicate().position(ix); 422 ShortBuffer fb = bb.asShortBuffer(); 423 forEach(m, (i, a) -> fb.put(i, a)); 424 } 425 426 427 // Type specific horizontal reductions 428 429 /** 430 * Sums all lane elements of this vector. 431 * <p> 432 * This is an associative vector reduction operation where the addition 433 * operation ({@code +}) is applied to lane elements, and the identity value 434 * is {@code 0}. 435 * 436 * @return the sum of all the lane elements of this vector 437 */ 438 public short addAll() { 439 return rOp((short) 0, (i, a, b) -> (short) (a + b)); 440 } 441 442 public short subAll() { 443 return rOp((short) 0, (i, a, b) -> (short) (a - b)); 444 } 445 446 public short mulAll() { 447 return rOp((short) 1, (i, a, b) -> (short) (a * b)); 448 } 449 450 public short minAll() { 451 return rOp(Short.MAX_VALUE, (i, a, b) -> a > b ? b : a); 452 } 453 454 public short maxAll() { 455 return rOp(Short.MIN_VALUE, (i, a, b) -> a < b ? b : a); 456 } 457 458 public short orAll() { 459 return rOp((short) 0, (i, a, b) -> (short) (a | b)); 460 } 461 462 public short andAll() { 463 return rOp((short) -1, (i, a, b) -> (short) (a & b)); 464 } 465 466 public short xorAll() { 467 return rOp((short) 0, (i, a, b) -> (short) (a ^ b)); 468 } 469 470 // Type specific accessors 471 472 /** 473 * Gets the lane element at lane index {@code i} 474 * 475 * @param i the lane index 476 * @return the lane element at lane index {@code i} 477 */ 478 public abstract short get(int i); 479 480 /** 481 * Replaces the lane element of this vector at lane index {@code i} with 482 * value {@code e}. 483 * <p> 484 * This is a cross-lane operation and behaves it returns the result of 485 * blending this vector with an input vector that is the result of 486 * broadcasting {@code e} and a mask that has only one lane set at lane 487 * index {@code i}. 488 * 489 * @param i the lane index of the lane element to be replaced 490 * @param e the value to be placed 491 * @return the result of replacing the lane element of this vector at lane 492 * index {@code i} with value {@code e}. 493 */ 494 public abstract ShortVector<S> with(int i, short e); 495 496 // Type specific extractors 497 498 /** 499 * Returns an array containing the lane elements of this vector. 500 * <p> 501 * This method behaves as if it {@link #intoArray(short[], int)} stores} 502 * this vector into an allocated array and returns the array as follows: 503 * <pre>{@code 504 * short[] a = new short[this.length()]; 505 * this.intoArray(a, 0); 506 * return a; 507 * }</pre> 508 * 509 * @return an array containing the the lane elements of this vector 510 */ 511 @ForceInline 512 public short[] toArray() { 513 short[] a = new short[species().length()]; 514 intoArray(a, 0); 515 return a; 516 } 517 518 /** 519 * Stores this vector into an array starting at offset. 520 * <p> 521 * For each vector lane, where {@code N} is the vector lane index, 522 * the lane element at index {@code N} is stored into the array at index 523 * {@code i + N}. 524 * 525 * @param a the array 526 * @param i the offset into the array 527 * @throws IndexOutOfBoundsException if {@code i < 0}, or 528 * {@code i > a.length - this.length()} 529 */ 530 public void intoArray(short[] a, int i) { 531 forEach((n, e) -> a[i + n] = e); 532 } 533 534 /** 535 * Stores this vector into an array starting at offset and using a mask. 536 * <p> 537 * For each vector lane, where {@code N} is the vector lane index, 538 * if the mask lane at index {@code N} is set then the lane element at 539 * index {@code N} is stored into the array index {@code i + N}. 540 * 541 * @param a the array 542 * @param i the offset into the array 543 * @param m the mask 544 * @throws IndexOutOfBoundsException if {@code i < 0}, or 545 * for any vector lane index {@code N} where the mask at lane {@code N} 546 * is set {@code i >= a.length - N} 547 */ 548 public void intoArray(short[] a, int i, Mask<Short, S> m) { 549 forEach(m, (n, e) -> a[i + n] = e); 550 } 551 552 /** 553 * Stores this vector into an array using indexes obtained from an index 554 * map. 555 * <p> 556 * For each vector lane, where {@code N} is the vector lane index, the 557 * lane element at index {@code N} is stored into the array at index 558 * {@code i + indexMap[j + N]}. 559 * 560 * @param a the array 561 * @param i the offset into the array, may be negative if relative 562 * indexes in the index map compensate to produce a value within the 563 * array bounds 564 * @param indexMap the index map 565 * @param j the offset into the index map 566 * @throws IndexOutOfBoundsException if {@code j < 0}, or 567 * {@code j > indexMap.length - this.length()}, 568 * or for any vector lane index {@code N} the result of 569 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 570 */ 571 public void intoArray(short[] a, int i, int[] indexMap, int j) { 572 forEach((n, e) -> a[i + indexMap[j + n]] = e); 573 } 574 575 /** 576 * Stores this vector into an array using indexes obtained from an index 577 * map and using a mask. 578 * <p> 579 * For each vector lane, where {@code N} is the vector lane index, 580 * if the mask lane at index {@code N} is set then the lane element at 581 * index {@code N} is stored into the array at index 582 * {@code i + indexMap[j + N]}. 583 * 584 * @param a the array 585 * @param i the offset into the array, may be negative if relative 586 * indexes in the index map compensate to produce a value within the 587 * array bounds 588 * @param m the mask 589 * @param indexMap the index map 590 * @param j the offset into the index map 591 * @throws IndexOutOfBoundsException if {@code j < 0}, or 592 * {@code j > indexMap.length - this.length()}, 593 * or for any vector lane index {@code N} where the mask at lane 594 * {@code N} is set the result of {@code i + indexMap[j + N]} is 595 * {@code < 0} or {@code >= a.length} 596 */ 597 public void intoArray(short[] a, int i, Mask<Short, S> m, int[] indexMap, int j) { 598 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e); 599 } 600 601 // Species 602 603 @Override 604 public abstract ShortSpecies<S> species(); 605 606 /** 607 * A specialized factory for creating {@link ShortVector} value of the same 608 * shape, and a {@link Mask} and {@link Shuffle} values of the same shape 609 * and {@code int} element type. 610 * 611 * @param <S> the type of shape of this species 612 */ 613 public static abstract class ShortSpecies<S extends Vector.Shape> extends Vector.Species<Short, S> { 614 interface FOp { 615 short apply(int i); 616 } 617 618 abstract ShortVector<S> op(FOp f); 619 620 abstract ShortVector<S> op(Mask<Short, S> m, FOp f); 621 622 // Factories 623 624 @Override 625 public ShortVector<S> zero() { 626 return op(i -> 0); 627 } 628 629 /** 630 * Returns a vector where all lane elements are set to the primitive 631 * value {@code e}. 632 * 633 * @param e the value 634 * @return a vector of vector where all lane elements are set to 635 * the primitive value {@code e} 636 */ 637 public ShortVector<S> broadcast(short e) { 638 return op(i -> e); 639 } 640 641 /** 642 * Returns a vector where the first lane element is set to the primtive 643 * value {@code e}, all other lane elements are set to the default 644 * value. 645 * 646 * @param e the value 647 * @return a vector where the first lane element is set to the primitive 648 * value {@code e} 649 */ 650 public ShortVector<S> single(short e) { 651 return op(i -> i == 0 ? e : (short) 0); 652 } 653 654 /** 655 * Returns a vector where each lane element is set to a randomly 656 * generated primitive value. 657 * @@@ what are the properties of the random number generator? 658 * 659 * @return a vector where each lane elements is set to a randomly 660 * generated primitive value 661 */ 662 public ShortVector<S> random() { 663 ThreadLocalRandom r = ThreadLocalRandom.current(); 664 return op(i -> (short) r.nextInt()); 665 } 666 667 /** 668 * Returns a vector where each lane element is set to a given 669 * primitive value. 670 * <p> 671 * For each vector lane, where {@code N} is the vector lane index, the 672 * the primitive value at index {@code N} is placed into the resulting 673 * vector at lane index {@code N}. 674 * 675 * @@@ What should happen if es.length < this.length() ? use the default 676 * value or throw IndexOutOfBoundsException 677 * 678 * @param es the given primitive values 679 * @return a vector where each lane element is set to a given primitive 680 * value 681 */ 682 public ShortVector<S> scalars(short... es) { 683 return op(i -> es[i]); 684 } 685 686 /** 687 * Loads a vector from an array starting at offset. 688 * <p> 689 * For each vector lane, where {@code N} is the vector lane index, the 690 * array element at index {@code i + N} is placed into the 691 * resulting vector at lane index {@code N}. 692 * 693 * @param a the array 694 * @param i the offset into the array 695 * @return the vector loaded from an array 696 * @throws IndexOutOfBoundsException if {@code i < 0}, or 697 * {@code i > a.length - this.length()} 698 */ 699 public ShortVector<S> fromArray(short[] a, int i) { 700 return op(n -> a[i + n]); 701 } 702 703 /** 704 * Loads a vector from an array starting at offset and using a mask. 705 * <p> 706 * For each vector lane, where {@code N} is the vector lane index, 707 * if the mask lane at index {@code N} is set then the array element at 708 * index {@code i + N} is placed into the resulting vector at lane index 709 * {@code N}, otherwise the default element value is placed into the 710 * resulting vector at lane index {@code N}. 711 * 712 * @param a the array 713 * @param i the offset into the array 714 * @param m the mask 715 * @return the vector loaded from an array 716 * @throws IndexOutOfBoundsException if {@code i < 0}, or 717 * for any vector lane index {@code N} where the mask at lane {@code N} 718 * is set {@code i > a.length - N} 719 */ 720 public ShortVector<S> fromArray(short[] a, int i, Mask<Short, S> m) { 721 return op(m, n -> a[i + n]); 722 } 723 724 /** 725 * Loads a vector from an array using indexes obtained from an index 726 * map. 727 * <p> 728 * For each vector lane, where {@code N} is the vector lane index, the 729 * array element at index {@code i + indexMap[j + N]} is placed into the 730 * resulting vector at lane index {@code N}. 731 * 732 * @param a the array 733 * @param i the offset into the array, may be negative if relative 734 * indexes in the index map compensate to produce a value within the 735 * array bounds 736 * @param indexMap the index map 737 * @param j the offset into the index map 738 * @return the vector loaded from an array 739 * @throws IndexOutOfBoundsException if {@code j < 0}, or 740 * {@code j > indexMap.length - this.length()}, 741 * or for any vector lane index {@code N} the result of 742 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 743 */ 744 public ShortVector<S> fromArray(short[] a, int i, int[] indexMap, int j) { 745 return op(n -> a[i + indexMap[j + n]]); 746 } 747 748 /** 749 * Loads a vector from an array using indexes obtained from an index 750 * map and using a mask. 751 * <p> 752 * For each vector lane, where {@code N} is the vector lane index, 753 * if the mask lane at index {@code N} is set then the array element at 754 * index {@code i + indexMap[j + N]} is placed into the resulting vector 755 * at lane index {@code N}. 756 * 757 * @param a the array 758 * @param i the offset into the array, may be negative if relative 759 * indexes in the index map compensate to produce a value within the 760 * array bounds 761 * @param indexMap the index map 762 * @param j the offset into the index map 763 * @return the vector loaded from an array 764 * @throws IndexOutOfBoundsException if {@code j < 0}, or 765 * {@code j > indexMap.length - this.length()}, 766 * or for any vector lane index {@code N} where the mask at lane 767 * {@code N} is set the result of {@code i + indexMap[j + N]} is 768 * {@code < 0} or {@code >= a.length} 769 */ 770 public ShortVector<S> fromArray(short[] a, int i, Mask<Short, S> m, int[] indexMap, int j) { 771 return op(m, n -> a[i + indexMap[j + n]]); 772 } 773 774 @Override 775 public ShortVector<S> fromByteArray(byte[] a, int ix) { 776 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 777 return fromByteBuffer(bb); 778 } 779 780 @Override 781 public ShortVector<S> fromByteArray(byte[] a, int ix, Mask<Short, S> m) { 782 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 783 return fromByteBuffer(bb, m); 784 } 785 786 @Override 787 public ShortVector<S> fromByteBuffer(ByteBuffer bb) { 788 ShortBuffer fb = bb.asShortBuffer(); 789 return op(i -> fb.get()); 790 } 791 792 @Override 793 public ShortVector<S> fromByteBuffer(ByteBuffer bb, Mask<Short, S> m) { 794 ShortBuffer fb = bb.asShortBuffer(); 795 return op(i -> { 796 if(m.getElement(i)) 797 return fb.get(); 798 else { 799 fb.position(fb.position() + 1); 800 return (short) 0; 801 } 802 }); 803 } 804 805 @Override 806 public ShortVector<S> fromByteBuffer(ByteBuffer bb, int ix) { 807 bb = bb.duplicate().order(ByteOrder.nativeOrder()).position(ix); 808 ShortBuffer fb = bb.asShortBuffer(); 809 return op(i -> fb.get(i)); 810 } 811 812 @Override 813 public ShortVector<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<Short, S> m) { 814 bb = bb.duplicate().order(ByteOrder.nativeOrder()).position(ix); 815 ShortBuffer fb = bb.asShortBuffer(); 816 return op(m, i -> fb.get(i)); 817 } 818 819 @Override 820 public <F, T extends Shape> ShortVector<S> reshape(Vector<F, T> o) { 821 int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE; 822 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder()); 823 o.intoByteBuffer(bb, 0); 824 return fromByteBuffer(bb, 0); 825 } 826 827 @Override 828 @ForceInline 829 public <F> ShortVector<S> rebracket(Vector<F, S> o) { 830 return reshape(o); 831 } 832 833 @Override 834 @ForceInline 835 public <T extends Shape> ShortVector<S> resize(Vector<Short, T> o) { 836 return reshape(o); 837 } 838 839 @Override 840 @SuppressWarnings("unchecked") 841 public <F, T extends Shape> ShortVector<S> cast(Vector<F, T> v) { 842 // Allocate array of required size 843 short[] a = new short[length()]; 844 845 Class<?> vtype = v.species().elementType(); 846 int limit = Math.min(v.species().length(), length()); 847 if (vtype == byte.class) { 848 ByteVector<T> tv = (ByteVector<T>)v; 849 for (int i = 0; i < limit; i++) { 850 a[i] = (short) tv.get(i); 851 } 852 } else if (vtype == short.class) { 853 ShortVector<T> tv = (ShortVector<T>)v; 854 for (int i = 0; i < limit; i++) { 855 a[i] = (short) tv.get(i); 856 } 857 } else if (vtype == int.class) { 858 IntVector<T> tv = (IntVector<T>)v; 859 for (int i = 0; i < limit; i++) { 860 a[i] = (short) tv.get(i); 861 } 862 } else if (vtype == long.class){ 863 LongVector<T> tv = (LongVector<T>)v; 864 for (int i = 0; i < limit; i++) { 865 a[i] = (short) tv.get(i); 866 } 867 } else if (vtype == float.class){ 868 FloatVector<T> tv = (FloatVector<T>)v; 869 for (int i = 0; i < limit; i++) { 870 a[i] = (short) tv.get(i); 871 } 872 } else if (vtype == double.class){ 873 DoubleVector<T> tv = (DoubleVector<T>)v; 874 for (int i = 0; i < limit; i++) { 875 a[i] = (short) tv.get(i); 876 } 877 } else { 878 throw new UnsupportedOperationException("Bad lane type for casting."); 879 } 880 881 return scalars(a); 882 } 883 884 } 885 886 /** 887 * Finds the preferred species for an element type of {@code short}. 888 * <p> 889 * A preferred species is a species chosen by the platform that has a 890 * shape of maximal bit size. A preferred species for different element 891 * types will have the same shape, and therefore vectors, masks, and 892 * shuffles created from such species will be shape compatible. 893 * 894 * @return the preferred species for an element type of {@code short} 895 */ 896 @SuppressWarnings("unchecked") 897 public static ShortSpecies<?> preferredSpeciesInstance() { 898 return (ShortSpecies<?>) Vector.preferredSpeciesInstance(short.class); 899 } 900 901 /** 902 * Finds a species for an element type of {@code short} and shape. 903 * 904 * @param s the shape 905 * @param <S> the type of shape 906 * @return a species for an element type of {@code short} and shape 907 * @throws IllegalArgumentException if no such species exists for the shape 908 */ 909 @SuppressWarnings("unchecked") 910 public static <S extends Shape> ShortSpecies<S> speciesInstance(S s) { 911 Objects.requireNonNull(s); 912 if (s == Shapes.S_64_BIT) { 913 return (ShortSpecies<S>) Short64Vector.SPECIES; 914 } else if (s == Shapes.S_128_BIT) { 915 return (ShortSpecies<S>) Short128Vector.SPECIES; 916 } else if (s == Shapes.S_256_BIT) { 917 return (ShortSpecies<S>) Short256Vector.SPECIES; 918 } else if (s == Shapes.S_512_BIT) { 919 return (ShortSpecies<S>) Short512Vector.SPECIES; 920 } else { 921 throw new IllegalArgumentException("Bad shape: " + s); 922 } 923 } 924 }