< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template

Print this page
rev 55589 : Species-phase2
rev 55590 : added missing javadocs, changed jtreg test
rev 55591 : XxxSpecies made package private
rev 55592 : Capitalized Species names


  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 java.nio.ByteBuffer;
  28 #if[!byte]
  29 import java.nio.$Type$Buffer;
  30 #end[!byte]
  31 import java.nio.ByteOrder;
  32 import java.util.Objects;
  33 import java.util.function.IntUnaryOperator;

  34 import java.util.concurrent.ThreadLocalRandom;
  35 
  36 import jdk.internal.misc.Unsafe;
  37 import jdk.internal.vm.annotation.ForceInline;
  38 import static jdk.incubator.vector.VectorIntrinsics.*;
  39 
  40 
  41 /**
  42  * A specialized {@link Vector} representing an ordered immutable sequence of
  43  * {@code $type$} values.
  44  */
  45 @SuppressWarnings("cast")
  46 public abstract class $abstractvectortype$ extends Vector<$Boxtype$> {
  47 
  48     $abstractvectortype$() {}
  49 
  50     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_$TYPE$_INDEX_SCALE);
  51 
  52     // Unary operator
  53 


  95 
  96     interface FUnCon {
  97         void apply(int i, $type$ a);
  98     }
  99 
 100     abstract void forEach(FUnCon f);
 101 
 102     abstract void forEach(Mask<$Boxtype$> m, FUnCon f);
 103 
 104     // Static factories
 105 
 106     /**
 107      * Returns a vector where all lane elements are set to the default
 108      * primitive value.
 109      *
 110      * @param species species of desired vector
 111      * @return a zero vector of given species
 112      */
 113     @ForceInline
 114     @SuppressWarnings("unchecked")
 115     public static $abstractvectortype$ zero($Type$Species species) {
 116         return species.zero();








 117     }
 118 
 119     /**
 120      * Loads a vector from a byte array starting at an offset.
 121      * <p>
 122      * Bytes are composed into primitive lane elements according to the
 123      * native byte order of the underlying platform
 124      * <p>
 125      * This method behaves as if it returns the result of calling the
 126      * byte buffer, offset, and mask accepting
 127      * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask) method} as follows:
 128      * <pre>{@code
 129      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 130      * }</pre>
 131      *
 132      * @param species species of desired vector
 133      * @param a the byte array
 134      * @param ix the offset into the array
 135      * @return a vector loaded from a byte array
 136      * @throws IndexOutOfBoundsException if {@code i < 0} or
 137      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 138      */
 139     @ForceInline
 140     @SuppressWarnings("unchecked")
 141     public static $abstractvectortype$ fromByteArray($Type$Species species, byte[] a, int ix) {
 142         Objects.requireNonNull(a);
 143         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 144         return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 145                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 146                                      a, ix, species,
 147                                      (c, idx, s) -> {
 148                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 149                                          $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
 150                                          return (($Type$Species)s).op(i -> tb.get());
 151                                      });
 152     }
 153 
 154     /**
 155      * Loads a vector from a byte array starting at an offset and using a
 156      * mask.
 157      * <p>
 158      * Bytes are composed into primitive lane elements according to the
 159      * native byte order of the underlying platform.
 160      * <p>
 161      * This method behaves as if it returns the result of calling the
 162      * byte buffer, offset, and mask accepting
 163      * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask) method} as follows:
 164      * <pre>{@code
 165      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 166      * }</pre>
 167      *
 168      * @param species species of desired vector
 169      * @param a the byte array
 170      * @param ix the offset into the array
 171      * @param m the mask
 172      * @return a vector loaded from a byte array
 173      * @throws IndexOutOfBoundsException if {@code i < 0} or
 174      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 175      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 176      * or {@code > a.length},
 177      * for any vector lane index {@code N} where the mask at lane {@code N}
 178      * is set
 179      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 180      */
 181     @ForceInline
 182     public static $abstractvectortype$ fromByteArray($Type$Species species, byte[] a, int ix, Mask<$Boxtype$> m) {
 183         return zero(species).blend(fromByteArray(species, a, ix), m);
 184     }
 185 
 186     /**
 187      * Loads a vector from an array starting at offset.
 188      * <p>
 189      * For each vector lane, where {@code N} is the vector lane index, the
 190      * array element at index {@code i + N} is placed into the
 191      * resulting vector at lane index {@code N}.
 192      *
 193      * @param species species of desired vector
 194      * @param a the array
 195      * @param i the offset into the array
 196      * @return the vector loaded from an array
 197      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 198      * {@code i > a.length - this.length()}
 199      */
 200     @ForceInline
 201     @SuppressWarnings("unchecked")
 202     public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i){
 203         Objects.requireNonNull(a);
 204         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 205         return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 206                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_$TYPE$_BASE_OFFSET,
 207                                      a, i, species,
 208                                      (c, idx, s) -> (($Type$Species)s).op(n -> c[idx + n]));
 209     }
 210 
 211 
 212     /**
 213      * Loads a vector from an array starting at offset and using a mask.
 214      * <p>
 215      * For each vector lane, where {@code N} is the vector lane index,
 216      * if the mask lane at index {@code N} is set then the array element at
 217      * index {@code i + N} is placed into the resulting vector at lane index
 218      * {@code N}, otherwise the default element value is placed into the
 219      * resulting vector at lane index {@code N}.
 220      *
 221      * @param species species of desired vector
 222      * @param a the array
 223      * @param i the offset into the array
 224      * @param m the mask
 225      * @return the vector loaded from an array
 226      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 227      * for any vector lane index {@code N} where the mask at lane {@code N}
 228      * is set {@code i > a.length - N}
 229      */
 230     @ForceInline
 231     public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m) {
 232         return zero(species).blend(fromArray(species, a, i), m);
 233     }
 234 
 235     /**
 236      * Loads a vector from an array using indexes obtained from an index
 237      * map.
 238      * <p>
 239      * For each vector lane, where {@code N} is the vector lane index, the
 240      * array element at index {@code i + indexMap[j + N]} is placed into the
 241      * resulting vector at lane index {@code N}.
 242      *
 243      * @param species species of desired vector
 244      * @param a the array
 245      * @param i the offset into the array, may be negative if relative
 246      * indexes in the index map compensate to produce a value within the
 247      * array bounds
 248      * @param indexMap the index map
 249      * @param j the offset into the index map
 250      * @return the vector loaded from an array
 251      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 252      * {@code j > indexMap.length - this.length()},
 253      * or for any vector lane index {@code N} the result of
 254      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 255      */
 256 #if[byteOrShort]
 257     public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, int[] indexMap, int j) {
 258         return species.op(n -> a[i + indexMap[j + n]]);
 259     }
 260 #else[byteOrShort]
 261     @ForceInline
 262     @SuppressWarnings("unchecked")
 263     public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, int[] indexMap, int j) {
 264         Objects.requireNonNull(a);
 265         Objects.requireNonNull(indexMap);
 266 
 267 #if[longOrDouble]
 268         if (species.length() == 1) {
 269           return $abstractvectortype$.fromArray(species, a, i + indexMap[j]);
 270         }
 271 #end[longOrDouble]
 272 
 273         // Index vector: vix[0:n] = k -> i + indexMap[j + i]
 274         IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
 275 
 276         vix = VectorIntrinsics.checkIndex(vix, a.length);
 277 
 278         return VectorIntrinsics.loadWithMap((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 279                                             species.indexSpecies().vectorType(), a, Unsafe.ARRAY_$TYPE$_BASE_OFFSET, vix,
 280                                             a, i, indexMap, j, species,
 281                                            (c, idx, iMap, idy, s) -> (($Type$Species)s).op(n -> c[idx + iMap[idy+n]]));

 282         }
 283 
 284 #end[byteOrShort]
 285     /**
 286      * Loads a vector from an array using indexes obtained from an index
 287      * map and using a mask.
 288      * <p>
 289      * For each vector lane, where {@code N} is the vector lane index,
 290      * if the mask lane at index {@code N} is set then the array element at
 291      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 292      * at lane index {@code N}.
 293      *
 294      * @param species species of desired vector
 295      * @param a the array
 296      * @param i the offset into the array, may be negative if relative
 297      * indexes in the index map compensate to produce a value within the
 298      * array bounds
 299      * @param m the mask
 300      * @param indexMap the index map
 301      * @param j the offset into the index map
 302      * @return the vector loaded from an array
 303      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 304      * {@code j > indexMap.length - this.length()},
 305      * or for any vector lane index {@code N} where the mask at lane
 306      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 307      * {@code < 0} or {@code >= a.length}
 308      */
 309 #if[byteOrShort]
 310     public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
 311         return species.op(m, n -> a[i + indexMap[j + n]]);
 312     }
 313 #else[byteOrShort]
 314     @ForceInline
 315     @SuppressWarnings("unchecked")
 316     public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
 317         // @@@ This can result in out of bounds errors for unset mask lanes
 318         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 319     }
 320 
 321 #end[byteOrShort]
 322 
 323     /**
 324      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 325      * offset into the byte buffer.
 326      * <p>
 327      * Bytes are composed into primitive lane elements according to the
 328      * native byte order of the underlying platform.
 329      * <p>
 330      * This method behaves as if it returns the result of calling the
 331      * byte buffer, offset, and mask accepting
 332      * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask)} method} as follows:
 333      * <pre>{@code
 334      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 335      * }</pre>
 336      *
 337      * @param species species of desired vector
 338      * @param bb the byte buffer
 339      * @param ix the offset into the byte buffer
 340      * @return a vector loaded from a byte buffer
 341      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 342      * or {@code > b.limit()},
 343      * or if there are fewer than
 344      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 345      * remaining in the byte buffer from the given offset
 346      */
 347     @ForceInline
 348     @SuppressWarnings("unchecked")
 349     public static $abstractvectortype$ fromByteBuffer($Type$Species species, ByteBuffer bb, int ix) {
 350         if (bb.order() != ByteOrder.nativeOrder()) {
 351             throw new IllegalArgumentException();
 352         }
 353         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 354         return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 355                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 356                                      bb, ix, species,
 357                                      (c, idx, s) -> {
 358                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 359                                          $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
 360                                          return (($Type$Species)s).op(i -> tb.get());
 361                                      });
 362     }
 363 
 364     /**
 365      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 366      * offset into the byte buffer and using a mask.
 367      * <p>
 368      * This method behaves as if the byte buffer is viewed as a primitive
 369      * {@link java.nio.Buffer buffer} for the primitive element type,


 381      * e[] es = new e[this.length()];
 382      * for (int n = 0; n < t.length; n++) {
 383      *     if (m.isSet(n))
 384      *         es[n] = eb.get(n);
 385      * }
 386      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 387      * }</pre>
 388      *
 389      * @param species species of desired vector
 390      * @param bb the byte buffer
 391      * @param ix the offset into the byte buffer
 392      * @param m the mask
 393      * @return a vector loaded from a byte buffer
 394      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 395      * or {@code > b.limit()},
 396      * for any vector lane index {@code N} where the mask at lane {@code N}
 397      * is set
 398      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 399      */
 400     @ForceInline
 401     public static $abstractvectortype$ fromByteBuffer($Type$Species species, ByteBuffer bb, int ix, Mask<$Boxtype$> m) {
 402         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 403     }
 404 
 405     /**







































































































 406      * Returns a mask where each lane is set or unset according to given
 407      * {@code boolean} values
 408      * <p>
 409      * For each mask lane, where {@code N} is the mask lane index,
 410      * if the given {@code boolean} value at index {@code N} is {@code true}
 411      * then the mask lane at index {@code N} is set, otherwise it is unset.
 412      *
 413      * @param species mask species
 414      * @param bits the given {@code boolean} values
 415      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 416      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 417      */
 418     @ForceInline
 419     public static Mask<$Boxtype$> maskFromValues($Type$Species species, boolean... bits) {
 420         if (species.boxType() == $Type$MaxVector.class)
 421             return new $Type$MaxVector.$Type$MaxMask(bits);
 422         switch (species.bitSize()) {
 423             case 64: return new $Type$64Vector.$Type$64Mask(bits);
 424             case 128: return new $Type$128Vector.$Type$128Mask(bits);
 425             case 256: return new $Type$256Vector.$Type$256Mask(bits);
 426             case 512: return new $Type$512Vector.$Type$512Mask(bits);
 427             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 428         }
 429     }
 430 
 431     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 432     static Mask<$Boxtype$> trueMask($Type$Species species) {
 433         if (species.boxType() == $Type$MaxVector.class)
 434             return $Type$MaxVector.$Type$MaxMask.TRUE_MASK;
 435         switch (species.bitSize()) {
 436             case 64: return $Type$64Vector.$Type$64Mask.TRUE_MASK;
 437             case 128: return $Type$128Vector.$Type$128Mask.TRUE_MASK;
 438             case 256: return $Type$256Vector.$Type$256Mask.TRUE_MASK;
 439             case 512: return $Type$512Vector.$Type$512Mask.TRUE_MASK;
 440             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 441         }
 442     }
 443 
 444     static Mask<$Boxtype$> falseMask($Type$Species species) {
 445         if (species.boxType() == $Type$MaxVector.class)
 446             return $Type$MaxVector.$Type$MaxMask.FALSE_MASK;
 447         switch (species.bitSize()) {
 448             case 64: return $Type$64Vector.$Type$64Mask.FALSE_MASK;
 449             case 128: return $Type$128Vector.$Type$128Mask.FALSE_MASK;
 450             case 256: return $Type$256Vector.$Type$256Mask.FALSE_MASK;
 451             case 512: return $Type$512Vector.$Type$512Mask.FALSE_MASK;
 452             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 453         }
 454     }
 455 
 456     /**
 457      * Loads a mask from a {@code boolean} array starting at an offset.
 458      * <p>
 459      * For each mask lane, where {@code N} is the mask lane index,
 460      * if the array element at index {@code ix + N} is {@code true} then the
 461      * mask lane at index {@code N} is set, otherwise it is unset.
 462      *
 463      * @param species mask species
 464      * @param bits the {@code boolean} array
 465      * @param ix the offset into the array
 466      * @return the mask loaded from a {@code boolean} array
 467      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 468      * {@code ix > bits.length - species.length()}
 469      */
 470     @ForceInline
 471     @SuppressWarnings("unchecked")
 472     public static Mask<$Boxtype$> maskFromArray($Type$Species species, boolean[] bits, int ix) {
 473         Objects.requireNonNull(bits);
 474         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 475         return VectorIntrinsics.load((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
 476                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 477                                      bits, ix, species,
 478                                      (c, idx, s) -> (Mask<$Boxtype$>) (($Type$Species)s).opm(n -> c[idx + n]));
 479     }
 480 
 481     /**
 482      * Returns a mask where all lanes are set.
 483      *
 484      * @param species mask species
 485      * @return a mask where all lanes are set
 486      */
 487     @ForceInline
 488     @SuppressWarnings("unchecked")
 489     public static Mask<$Boxtype$> maskAllTrue($Type$Species species) {
 490         return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
 491                                                  ($bitstype$)-1,  species,
 492                                                  ((z, s) -> trueMask(($Type$Species)s)));
 493     }
 494 
 495     /**
 496      * Returns a mask where all lanes are unset.
 497      *
 498      * @param species mask species
 499      * @return a mask where all lanes are unset
 500      */
 501     @ForceInline
 502     @SuppressWarnings("unchecked")
 503     public static Mask<$Boxtype$> maskAllFalse($Type$Species species) {
 504         return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
 505                                                  0, species, 
 506                                                  ((z, s) -> falseMask(($Type$Species)s)));
 507     }
 508 
 509     /**
 510      * Returns a shuffle of mapped indexes where each lane element is
 511      * the result of applying a mapping function to the corresponding lane
 512      * index.
 513      * <p>
 514      * Care should be taken to ensure Shuffle values produced from this
 515      * method are consumed as constants to ensure optimal generation of
 516      * code.  For example, values held in static final fields or values
 517      * held in loop constant local variables.
 518      * <p>
 519      * This method behaves as if a shuffle is created from an array of
 520      * mapped indexes as follows:
 521      * <pre>{@code
 522      *   int[] a = new int[species.length()];
 523      *   for (int i = 0; i < a.length; i++) {
 524      *       a[i] = f.applyAsInt(i);
 525      *   }
 526      *   return this.shuffleFromValues(a);
 527      * }</pre>
 528      *
 529      * @param species shuffle species
 530      * @param f the lane index mapping function
 531      * @return a shuffle of mapped indexes
 532      */
 533     @ForceInline
 534     public static Shuffle<$Boxtype$> shuffle($Type$Species species, IntUnaryOperator f) {
 535         if (species.boxType() == $Type$MaxVector.class)
 536             return new $Type$MaxVector.$Type$MaxShuffle(f);
 537         switch (species.bitSize()) {
 538             case 64: return new $Type$64Vector.$Type$64Shuffle(f);
 539             case 128: return new $Type$128Vector.$Type$128Shuffle(f);
 540             case 256: return new $Type$256Vector.$Type$256Shuffle(f);
 541             case 512: return new $Type$512Vector.$Type$512Shuffle(f);
 542             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 543         }
 544     }
 545 
 546     /**
 547      * Returns a shuffle where each lane element is the value of its
 548      * corresponding lane index.
 549      * <p>
 550      * This method behaves as if a shuffle is created from an identity
 551      * index mapping function as follows:
 552      * <pre>{@code
 553      *   return this.shuffle(i -> i);
 554      * }</pre>
 555      *
 556      * @param species shuffle species
 557      * @return a shuffle of lane indexes
 558      */
 559     @ForceInline
 560     public static Shuffle<$Boxtype$> shuffleIota($Type$Species species) {
 561         if (species.boxType() == $Type$MaxVector.class)
 562             return new $Type$MaxVector.$Type$MaxShuffle(AbstractShuffle.IDENTITY);
 563         switch (species.bitSize()) {
 564             case 64: return new $Type$64Vector.$Type$64Shuffle(AbstractShuffle.IDENTITY);
 565             case 128: return new $Type$128Vector.$Type$128Shuffle(AbstractShuffle.IDENTITY);
 566             case 256: return new $Type$256Vector.$Type$256Shuffle(AbstractShuffle.IDENTITY);
 567             case 512: return new $Type$512Vector.$Type$512Shuffle(AbstractShuffle.IDENTITY);
 568             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 569         }
 570     }
 571 
 572     /**
 573      * Returns a shuffle where each lane element is set to a given
 574      * {@code int} value logically AND'ed by the species length minus one.
 575      * <p>
 576      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 577      * the {@code int} value at index {@code N} logically AND'ed by
 578      * {@code species.length() - 1} is placed into the resulting shuffle at
 579      * lane index {@code N}.
 580      *
 581      * @param species shuffle species
 582      * @param ixs the given {@code int} values
 583      * @return a shuffle where each lane element is set to a given
 584      * {@code int} value
 585      * @throws IndexOutOfBoundsException if the number of int values is
 586      * {@code < species.length()}
 587      */
 588     @ForceInline
 589     public static Shuffle<$Boxtype$> shuffleFromValues($Type$Species species, int... ixs) {
 590         if (species.boxType() == $Type$MaxVector.class)
 591             return new $Type$MaxVector.$Type$MaxShuffle(ixs);
 592         switch (species.bitSize()) {
 593             case 64: return new $Type$64Vector.$Type$64Shuffle(ixs);
 594             case 128: return new $Type$128Vector.$Type$128Shuffle(ixs);
 595             case 256: return new $Type$256Vector.$Type$256Shuffle(ixs);
 596             case 512: return new $Type$512Vector.$Type$512Shuffle(ixs);
 597             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 598         }
 599     }
 600 
 601     /**
 602      * Loads a shuffle from an {@code int} array starting at an offset.
 603      * <p>
 604      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 605      * array element at index {@code i + N} logically AND'ed by
 606      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 607      * index {@code N}.
 608      *
 609      * @param species shuffle species
 610      * @param ixs the {@code int} array
 611      * @param i the offset into the array
 612      * @return a shuffle loaded from the {@code int} array
 613      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 614      * {@code i > a.length - species.length()}
 615      */
 616     @ForceInline
 617     public static Shuffle<$Boxtype$> shuffleFromArray($Type$Species species, int[] ixs, int i) {
 618         if (species.boxType() == $Type$MaxVector.class)
 619             return new $Type$MaxVector.$Type$MaxShuffle(ixs, i);
 620         switch (species.bitSize()) {
 621             case 64: return new $Type$64Vector.$Type$64Shuffle(ixs, i);
 622             case 128: return new $Type$128Vector.$Type$128Shuffle(ixs, i);
 623             case 256: return new $Type$256Vector.$Type$256Shuffle(ixs, i);
 624             case 512: return new $Type$512Vector.$Type$512Shuffle(ixs, i);
 625             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 626         }
 627     }
 628 
 629 
 630     // Ops
 631 
 632     @Override
 633     public abstract $abstractvectortype$ add(Vector<$Boxtype$> v);
 634 
 635     /**
 636      * Adds this vector to the broadcast of an input scalar.
 637      * <p>
 638      * This is a vector binary operation where the primitive addition operation
 639      * ({@code +}) is applied to lane elements.
 640      *
 641      * @param s the input scalar
 642      * @return the result of adding this vector to the broadcast of an input
 643      * scalar
 644      */
 645     public abstract $abstractvectortype$ add($type$ s);
 646 
 647     @Override
 648     public abstract $abstractvectortype$ add(Vector<$Boxtype$> v, Mask<$Boxtype$> m);
 649 


2797      * array bounds
2798      * @param m the mask
2799      * @param indexMap the index map
2800      * @param j the offset into the index map
2801      * @throws IndexOutOfBoundsException if {@code j < 0}, or
2802      * {@code j > indexMap.length - this.length()},
2803      * or for any vector lane index {@code N} where the mask at lane
2804      * {@code N} is set the result of {@code i + indexMap[j + N]} is
2805      * {@code < 0} or {@code >= a.length}
2806      */
2807 #if[byteOrShort]
2808     public void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
2809         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
2810     }
2811 #else[byteOrShort]
2812     public abstract void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j);
2813 #end[byteOrShort]
2814     // Species
2815 
2816     @Override
2817     public abstract $Type$Species species();
2818 
2819     /**
2820      * Class representing {@link $abstractvectortype$}'s of the same {@link Vector.Shape Shape}.
2821      */
2822     public static abstract class $Type$Species extends Vector.Species<$Boxtype$> {













2823         interface FOp {
2824             $type$ apply(int i);
2825         }
2826 
2827         abstract $abstractvectortype$ op(FOp f);
2828 
2829         abstract $abstractvectortype$ op(Mask<$Boxtype$> m, FOp f);
2830 
2831         interface FOpm {
2832             boolean apply(int i);
2833         }
2834 
2835         abstract Mask<$Boxtype$> opm(FOpm f);
2836 
2837 #if[!byteOrShort]
2838         abstract IntVector.IntSpecies indexSpecies();
2839 #end[!byteOrShort]
2840 
2841 
2842         // Factories
2843 
2844         @Override
2845         public abstract $abstractvectortype$ zero();
2846 
2847         /**
2848          * Returns a vector where all lane elements are set to the primitive
2849          * value {@code e}.
2850          *
2851          * @param e the value
2852          * @return a vector of vector where all lane elements are set to
2853          * the primitive value {@code e}
2854          */
2855         public abstract $abstractvectortype$ broadcast($type$ e);
2856 
2857         /**
2858          * Returns a vector where the first lane element is set to the primtive
2859          * value {@code e}, all other lane elements are set to the default
2860          * value.
2861          *
2862          * @param e the value
2863          * @return a vector where the first lane element is set to the primitive
2864          * value {@code e}
2865          */
2866         @ForceInline
2867         public final $abstractvectortype$ single($type$ e) {
2868             return zero().with(0, e);
2869         }
2870 
2871         /**
2872          * Returns a vector where each lane element is set to a randomly
2873          * generated primitive value.
2874          *
2875          * The semantics are equivalent to calling
2876 #if[FP]
2877          * {@code ThreadLocalRandom#next$Type$}.
2878 #else[FP]
2879          * {@code ($type$)ThreadLocalRandom#nextInt()}.
2880 #end[FP]
2881          *
2882          * @return a vector where each lane elements is set to a randomly
2883          * generated primitive value
2884          */
2885 #if[intOrLong]
2886         public $abstractvectortype$ random() {
2887             ThreadLocalRandom r = ThreadLocalRandom.current();
2888             return op(i -> r.next$Type$());
2889         }
2890 #else[intOrLong]
2891 #if[FP]
2892         public $abstractvectortype$ random() {
2893             ThreadLocalRandom r = ThreadLocalRandom.current();
2894             return op(i -> r.next$Type$());
2895         }
2896 #else[FP]
2897         public $abstractvectortype$ random() {
2898             ThreadLocalRandom r = ThreadLocalRandom.current();
2899             return op(i -> ($type$) r.nextInt());
2900         }
2901 #end[FP]
2902 #end[intOrLong]
2903 
2904         /**
2905          * Returns a vector where each lane element is set to a given
2906          * primitive value.
2907          * <p>
2908          * For each vector lane, where {@code N} is the vector lane index, the
2909          * the primitive value at index {@code N} is placed into the resulting
2910          * vector at lane index {@code N}.
2911          *
2912          * @param es the given primitive values
2913          * @return a vector where each lane element is set to a given primitive
2914          * value
2915          * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
2916          */
2917         public abstract $abstractvectortype$ scalars($type$... es);
2918     }
2919 
2920     /**
2921      * Finds the preferred species for an element type of {@code $type$}.
2922      * <p>
2923      * A preferred species is a species chosen by the platform that has a
2924      * shape of maximal bit size.  A preferred species for different element
2925      * types will have the same shape, and therefore vectors, masks, and
2926      * shuffles created from such species will be shape compatible.
2927      *
2928      * @return the preferred species for an element type of {@code $type$}
2929      */
2930     @SuppressWarnings("unchecked")
2931     public static $Type$Species preferredSpecies() {
2932         return ($Type$Species) Species.ofPreferred($type$.class);
2933     }
2934 
2935     /**
2936      * Finds a species for an element type of {@code $type$} and shape.
2937      *
2938      * @param s the shape
2939      * @return a species for an element type of {@code $type$} and shape
2940      * @throws IllegalArgumentException if no such species exists for the shape
2941      */
2942     @SuppressWarnings("unchecked")
2943     public static $Type$Species species(Vector.Shape s) {
2944         Objects.requireNonNull(s);
2945         switch (s) {
2946             case S_64_BIT: return $Type$64Vector.SPECIES;
2947             case S_128_BIT: return $Type$128Vector.SPECIES;
2948             case S_256_BIT: return $Type$256Vector.SPECIES;
2949             case S_512_BIT: return $Type$512Vector.SPECIES;
2950             case S_Max_BIT: return $Type$MaxVector.SPECIES;
2951             default: throw new IllegalArgumentException("Bad shape: " + s);
2952         }
2953     }


























2954 }


  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 java.nio.ByteBuffer;
  28 #if[!byte]
  29 import java.nio.$Type$Buffer;
  30 #end[!byte]
  31 import java.nio.ByteOrder;
  32 import java.util.Objects;
  33 import java.util.function.IntUnaryOperator;
  34 import java.util.function.Function;
  35 import java.util.concurrent.ThreadLocalRandom;
  36 
  37 import jdk.internal.misc.Unsafe;
  38 import jdk.internal.vm.annotation.ForceInline;
  39 import static jdk.incubator.vector.VectorIntrinsics.*;
  40 
  41 
  42 /**
  43  * A specialized {@link Vector} representing an ordered immutable sequence of
  44  * {@code $type$} values.
  45  */
  46 @SuppressWarnings("cast")
  47 public abstract class $abstractvectortype$ extends Vector<$Boxtype$> {
  48 
  49     $abstractvectortype$() {}
  50 
  51     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_$TYPE$_INDEX_SCALE);
  52 
  53     // Unary operator
  54 


  96 
  97     interface FUnCon {
  98         void apply(int i, $type$ a);
  99     }
 100 
 101     abstract void forEach(FUnCon f);
 102 
 103     abstract void forEach(Mask<$Boxtype$> m, FUnCon f);
 104 
 105     // Static factories
 106 
 107     /**
 108      * Returns a vector where all lane elements are set to the default
 109      * primitive value.
 110      *
 111      * @param species species of desired vector
 112      * @return a zero vector of given species
 113      */
 114     @ForceInline
 115     @SuppressWarnings("unchecked")
 116     public static $abstractvectortype$ zero(Species<$Boxtype$> species) {
 117 #if[FP]
 118         return VectorIntrinsics.broadcastCoerced((Class<$Type$Vector>) species.boxType(), $type$.class, species.length(),
 119                                                  $Type$.$type$To$Bitstype$Bits(0.0f), species,
 120                                                  ((bits, s) -> (($Type$Species)s).op(i -> $Type$.$bitstype$BitsTo$Type$(($bitstype$)bits))));
 121 #else[FP]
 122         return VectorIntrinsics.broadcastCoerced((Class<$Type$Vector>) species.boxType(), $type$.class, species.length(),
 123                                                  0, species,
 124                                                  ((bits, s) -> (($Type$Species)s).op(i -> ($type$)bits)));
 125 #end[FP]
 126     }
 127 
 128     /**
 129      * Loads a vector from a byte array starting at an offset.
 130      * <p>
 131      * Bytes are composed into primitive lane elements according to the
 132      * native byte order of the underlying platform
 133      * <p>
 134      * This method behaves as if it returns the result of calling the
 135      * byte buffer, offset, and mask accepting
 136      * {@link #fromByteBuffer(Species<$Boxtype$>, ByteBuffer, int, Mask) method} as follows:
 137      * <pre>{@code
 138      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 139      * }</pre>
 140      *
 141      * @param species species of desired vector
 142      * @param a the byte array
 143      * @param ix the offset into the array
 144      * @return a vector loaded from a byte array
 145      * @throws IndexOutOfBoundsException if {@code i < 0} or
 146      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 147      */
 148     @ForceInline
 149     @SuppressWarnings("unchecked")
 150     public static $abstractvectortype$ fromByteArray(Species<$Boxtype$> species, byte[] a, int ix) {
 151         Objects.requireNonNull(a);
 152         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 153         return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 154                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 155                                      a, ix, species,
 156                                      (c, idx, s) -> {
 157                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 158                                          $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
 159                                          return (($Type$Species)s).op(i -> tb.get());
 160                                      });
 161     }
 162 
 163     /**
 164      * Loads a vector from a byte array starting at an offset and using a
 165      * mask.
 166      * <p>
 167      * Bytes are composed into primitive lane elements according to the
 168      * native byte order of the underlying platform.
 169      * <p>
 170      * This method behaves as if it returns the result of calling the
 171      * byte buffer, offset, and mask accepting
 172      * {@link #fromByteBuffer(Species<$Boxtype$>, ByteBuffer, int, Mask) method} as follows:
 173      * <pre>{@code
 174      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 175      * }</pre>
 176      *
 177      * @param species species of desired vector
 178      * @param a the byte array
 179      * @param ix the offset into the array
 180      * @param m the mask
 181      * @return a vector loaded from a byte array
 182      * @throws IndexOutOfBoundsException if {@code i < 0} or
 183      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 184      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 185      * or {@code > a.length},
 186      * for any vector lane index {@code N} where the mask at lane {@code N}
 187      * is set
 188      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 189      */
 190     @ForceInline
 191     public static $abstractvectortype$ fromByteArray(Species<$Boxtype$> species, byte[] a, int ix, Mask<$Boxtype$> m) {
 192         return zero(species).blend(fromByteArray(species, a, ix), m);
 193     }
 194 
 195     /**
 196      * Loads a vector from an array starting at offset.
 197      * <p>
 198      * For each vector lane, where {@code N} is the vector lane index, the
 199      * array element at index {@code i + N} is placed into the
 200      * resulting vector at lane index {@code N}.
 201      *
 202      * @param species species of desired vector
 203      * @param a the array
 204      * @param i the offset into the array
 205      * @return the vector loaded from an array
 206      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 207      * {@code i > a.length - this.length()}
 208      */
 209     @ForceInline
 210     @SuppressWarnings("unchecked")
 211     public static $abstractvectortype$ fromArray(Species<$Boxtype$> species, $type$[] a, int i){
 212         Objects.requireNonNull(a);
 213         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 214         return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 215                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_$TYPE$_BASE_OFFSET,
 216                                      a, i, species,
 217                                      (c, idx, s) -> (($Type$Species)s).op(n -> c[idx + n]));
 218     }
 219 
 220 
 221     /**
 222      * Loads a vector from an array starting at offset and using a mask.
 223      * <p>
 224      * For each vector lane, where {@code N} is the vector lane index,
 225      * if the mask lane at index {@code N} is set then the array element at
 226      * index {@code i + N} is placed into the resulting vector at lane index
 227      * {@code N}, otherwise the default element value is placed into the
 228      * resulting vector at lane index {@code N}.
 229      *
 230      * @param species species of desired vector
 231      * @param a the array
 232      * @param i the offset into the array
 233      * @param m the mask
 234      * @return the vector loaded from an array
 235      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 236      * for any vector lane index {@code N} where the mask at lane {@code N}
 237      * is set {@code i > a.length - N}
 238      */
 239     @ForceInline
 240     public static $abstractvectortype$ fromArray(Species<$Boxtype$> species, $type$[] a, int i, Mask<$Boxtype$> m) {
 241         return zero(species).blend(fromArray(species, a, i), m);
 242     }
 243 
 244     /**
 245      * Loads a vector from an array using indexes obtained from an index
 246      * map.
 247      * <p>
 248      * For each vector lane, where {@code N} is the vector lane index, the
 249      * array element at index {@code i + indexMap[j + N]} is placed into the
 250      * resulting vector at lane index {@code N}.
 251      *
 252      * @param species species of desired vector
 253      * @param a the array
 254      * @param i the offset into the array, may be negative if relative
 255      * indexes in the index map compensate to produce a value within the
 256      * array bounds
 257      * @param indexMap the index map
 258      * @param j the offset into the index map
 259      * @return the vector loaded from an array
 260      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 261      * {@code j > indexMap.length - this.length()},
 262      * or for any vector lane index {@code N} the result of
 263      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 264      */
 265 #if[byteOrShort]
 266     public static $abstractvectortype$ fromArray(Species<$Boxtype$> species, $type$[] a, int i, int[] indexMap, int j) {
 267         return (($Type$Species)species).op(n -> a[i + indexMap[j + n]]);
 268     }
 269 #else[byteOrShort]
 270     @ForceInline
 271     @SuppressWarnings("unchecked")
 272     public static $abstractvectortype$ fromArray(Species<$Boxtype$> species, $type$[] a, int i, int[] indexMap, int j) {
 273         Objects.requireNonNull(a);
 274         Objects.requireNonNull(indexMap);
 275 
 276 #if[longOrDouble]
 277         if (species.length() == 1) {
 278           return $abstractvectortype$.fromArray(species, a, i + indexMap[j]);
 279         }
 280 #end[longOrDouble]
 281 
 282         // Index vector: vix[0:n] = k -> i + indexMap[j + k]
 283         IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, j).add(i);
 284 
 285         vix = VectorIntrinsics.checkIndex(vix, a.length);
 286 
 287         return VectorIntrinsics.loadWithMap((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 288                                             IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_$TYPE$_BASE_OFFSET, vix,
 289                                             a, i, indexMap, j, species,
 290                                             ($type$[] c, int idx, int[] iMap, int idy, Species<$Boxtype$> s) ->
 291                                                 (($Type$Species)s).op(n -> c[idx + iMap[idy+n]]));
 292         }
 293 
 294 #end[byteOrShort]
 295     /**
 296      * Loads a vector from an array using indexes obtained from an index
 297      * map and using a mask.
 298      * <p>
 299      * For each vector lane, where {@code N} is the vector lane index,
 300      * if the mask lane at index {@code N} is set then the array element at
 301      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 302      * at lane index {@code N}.
 303      *
 304      * @param species species of desired vector
 305      * @param a the array
 306      * @param i the offset into the array, may be negative if relative
 307      * indexes in the index map compensate to produce a value within the
 308      * array bounds
 309      * @param m the mask
 310      * @param indexMap the index map
 311      * @param j the offset into the index map
 312      * @return the vector loaded from an array
 313      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 314      * {@code j > indexMap.length - this.length()},
 315      * or for any vector lane index {@code N} where the mask at lane
 316      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 317      * {@code < 0} or {@code >= a.length}
 318      */
 319 #if[byteOrShort]
 320     public static $abstractvectortype$ fromArray(Species<$Boxtype$> species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
 321         return (($Type$Species)species).op(m, n -> a[i + indexMap[j + n]]);
 322     }
 323 #else[byteOrShort]
 324     @ForceInline
 325     @SuppressWarnings("unchecked")
 326     public static $abstractvectortype$ fromArray(Species<$Boxtype$> species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
 327         // @@@ This can result in out of bounds errors for unset mask lanes
 328         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 329     }
 330 
 331 #end[byteOrShort]
 332 
 333     /**
 334      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 335      * offset into the byte buffer.
 336      * <p>
 337      * Bytes are composed into primitive lane elements according to the
 338      * native byte order of the underlying platform.
 339      * <p>
 340      * This method behaves as if it returns the result of calling the
 341      * byte buffer, offset, and mask accepting
 342      * {@link #fromByteBuffer(Species<$Boxtype$>, ByteBuffer, int, Mask)} method} as follows:
 343      * <pre>{@code
 344      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 345      * }</pre>
 346      *
 347      * @param species species of desired vector
 348      * @param bb the byte buffer
 349      * @param ix the offset into the byte buffer
 350      * @return a vector loaded from a byte buffer
 351      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 352      * or {@code > b.limit()},
 353      * or if there are fewer than
 354      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 355      * remaining in the byte buffer from the given offset
 356      */
 357     @ForceInline
 358     @SuppressWarnings("unchecked")
 359     public static $abstractvectortype$ fromByteBuffer(Species<$Boxtype$> species, ByteBuffer bb, int ix) {
 360         if (bb.order() != ByteOrder.nativeOrder()) {
 361             throw new IllegalArgumentException();
 362         }
 363         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 364         return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
 365                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 366                                      bb, ix, species,
 367                                      (c, idx, s) -> {
 368                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 369                                          $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
 370                                          return (($Type$Species)s).op(i -> tb.get());
 371                                      });
 372     }
 373 
 374     /**
 375      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 376      * offset into the byte buffer and using a mask.
 377      * <p>
 378      * This method behaves as if the byte buffer is viewed as a primitive
 379      * {@link java.nio.Buffer buffer} for the primitive element type,


 391      * e[] es = new e[this.length()];
 392      * for (int n = 0; n < t.length; n++) {
 393      *     if (m.isSet(n))
 394      *         es[n] = eb.get(n);
 395      * }
 396      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 397      * }</pre>
 398      *
 399      * @param species species of desired vector
 400      * @param bb the byte buffer
 401      * @param ix the offset into the byte buffer
 402      * @param m the mask
 403      * @return a vector loaded from a byte buffer
 404      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 405      * or {@code > b.limit()},
 406      * for any vector lane index {@code N} where the mask at lane {@code N}
 407      * is set
 408      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 409      */
 410     @ForceInline
 411     public static $abstractvectortype$ fromByteBuffer(Species<$Boxtype$> species, ByteBuffer bb, int ix, Mask<$Boxtype$> m) {
 412         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 413     }
 414 
 415     /**
 416      * Returns a vector where all lane elements are set to the primitive
 417      * value {@code e}.
 418      *
 419      * @param s species of the desired vector
 420      * @param e the value
 421      * @return a vector of vector where all lane elements are set to
 422      * the primitive value {@code e}
 423      */
 424 #if[FP]
 425     @ForceInline
 426     @SuppressWarnings("unchecked")
 427     public static $abstractvectortype$ broadcast(Species<$Boxtype$> s, $type$ e) {
 428         return VectorIntrinsics.broadcastCoerced(
 429             (Class<$abstractvectortype$>) s.boxType(), $type$.class, s.length(),
 430             $Type$.$type$To$Bitstype$Bits(e), s,
 431             ((bits, sp) -> (($Type$Species)sp).op(i -> $Type$.$bitstype$BitsTo$Type$(($bitstype$)bits))));
 432     }
 433 #else[FP]
 434     @ForceInline
 435     @SuppressWarnings("unchecked")
 436     public static $abstractvectortype$ broadcast(Species<$Boxtype$> s, $type$ e) {
 437         return VectorIntrinsics.broadcastCoerced(
 438             (Class<$abstractvectortype$>) s.boxType(), $type$.class, s.length(),
 439             e, s,
 440             ((bits, sp) -> (($Type$Species)sp).op(i -> ($type$)bits)));
 441     }
 442 #end[FP]
 443 
 444     /**
 445      * Returns a vector where each lane element is set to a given
 446      * primitive value.
 447      * <p>
 448      * For each vector lane, where {@code N} is the vector lane index, the
 449      * the primitive value at index {@code N} is placed into the resulting
 450      * vector at lane index {@code N}.
 451      *
 452      * @param s species of the desired vector
 453      * @param es the given primitive values
 454      * @return a vector where each lane element is set to a given primitive
 455      * value
 456      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 457      */
 458     @ForceInline
 459     @SuppressWarnings("unchecked")
 460     public static $abstractvectortype$ scalars(Species<$Boxtype$> s, $type$... es) {
 461         Objects.requireNonNull(es);
 462         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 463         return VectorIntrinsics.load((Class<$abstractvectortype$>) s.boxType(), $type$.class, s.length(),
 464                                      es, Unsafe.ARRAY_$TYPE$_BASE_OFFSET,
 465                                      es, ix, s,
 466                                      (c, idx, sp) -> (($Type$Species)sp).op(n -> c[idx + n]));
 467     }
 468 
 469     /**
 470      * Returns a vector where the first lane element is set to the primtive
 471      * value {@code e}, all other lane elements are set to the default
 472      * value.
 473      *
 474      * @param s species of the desired vector
 475      * @param e the value
 476      * @return a vector where the first lane element is set to the primitive
 477      * value {@code e}
 478      */
 479     @ForceInline
 480     public static final $abstractvectortype$ single(Species<$Boxtype$> s, $type$ e) {
 481         return zero(s).with(0, e);
 482     }
 483 
 484     /**
 485      * Returns a vector where each lane element is set to a randomly
 486      * generated primitive value.
 487      *
 488      * The semantics are equivalent to calling
 489 #if[byteOrShort]
 490      * ($type$){@link ThreadLocalRandom#nextInt()}
 491 #else[byteOrShort]
 492      * {@link ThreadLocalRandom#next$Type$()}
 493 #end[byteOrShort]
 494      *
 495      * @param s species of the desired vector
 496      * @return a vector where each lane elements is set to a randomly
 497      * generated primitive value
 498      */
 499 #if[intOrLong]
 500     public static $abstractvectortype$ random(Species<$Boxtype$> s) {
 501         ThreadLocalRandom r = ThreadLocalRandom.current();
 502         return (($Type$Species)s).op(i -> r.next$Type$());
 503     }
 504 #else[intOrLong]
 505 #if[FP]
 506     public static $abstractvectortype$ random(Species<$Boxtype$> s) {
 507         ThreadLocalRandom r = ThreadLocalRandom.current();
 508         return (($Type$Species)s).op(i -> r.next$Type$());
 509     }
 510 #else[FP]
 511     public static $abstractvectortype$ random(Species<$Boxtype$> s) {
 512         ThreadLocalRandom r = ThreadLocalRandom.current();
 513         return (($Type$Species)s).op(i -> ($type$) r.nextInt());
 514     }
 515 #end[FP]
 516 #end[intOrLong]
 517 
 518     /**
 519      * Returns a mask where each lane is set or unset according to given
 520      * {@code boolean} values
 521      * <p>
 522      * For each mask lane, where {@code N} is the mask lane index,
 523      * if the given {@code boolean} value at index {@code N} is {@code true}
 524      * then the mask lane at index {@code N} is set, otherwise it is unset.
 525      *
 526      * @param species mask species
 527      * @param bits the given {@code boolean} values
 528      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 529      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 530      */
 531     @ForceInline
 532     public static Mask<$Boxtype$> maskFromValues(Species<$Boxtype$> species, boolean... bits) {
 533         if (species.boxType() == $Type$MaxVector.class)
 534             return new $Type$MaxVector.$Type$MaxMask(bits);
 535         switch (species.bitSize()) {
 536             case 64: return new $Type$64Vector.$Type$64Mask(bits);
 537             case 128: return new $Type$128Vector.$Type$128Mask(bits);
 538             case 256: return new $Type$256Vector.$Type$256Mask(bits);
 539             case 512: return new $Type$512Vector.$Type$512Mask(bits);
 540             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 541         }
 542     }
 543 
 544     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 545     static Mask<$Boxtype$> trueMask(Species<$Boxtype$> species) {
 546         if (species.boxType() == $Type$MaxVector.class)
 547             return $Type$MaxVector.$Type$MaxMask.TRUE_MASK;
 548         switch (species.bitSize()) {
 549             case 64: return $Type$64Vector.$Type$64Mask.TRUE_MASK;
 550             case 128: return $Type$128Vector.$Type$128Mask.TRUE_MASK;
 551             case 256: return $Type$256Vector.$Type$256Mask.TRUE_MASK;
 552             case 512: return $Type$512Vector.$Type$512Mask.TRUE_MASK;
 553             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 554         }
 555     }
 556 
 557     static Mask<$Boxtype$> falseMask(Species<$Boxtype$> species) {
 558         if (species.boxType() == $Type$MaxVector.class)
 559             return $Type$MaxVector.$Type$MaxMask.FALSE_MASK;
 560         switch (species.bitSize()) {
 561             case 64: return $Type$64Vector.$Type$64Mask.FALSE_MASK;
 562             case 128: return $Type$128Vector.$Type$128Mask.FALSE_MASK;
 563             case 256: return $Type$256Vector.$Type$256Mask.FALSE_MASK;
 564             case 512: return $Type$512Vector.$Type$512Mask.FALSE_MASK;
 565             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 566         }
 567     }
 568 
 569     /**
 570      * Loads a mask from a {@code boolean} array starting at an offset.
 571      * <p>
 572      * For each mask lane, where {@code N} is the mask lane index,
 573      * if the array element at index {@code ix + N} is {@code true} then the
 574      * mask lane at index {@code N} is set, otherwise it is unset.
 575      *
 576      * @param species mask species
 577      * @param bits the {@code boolean} array
 578      * @param ix the offset into the array
 579      * @return the mask loaded from a {@code boolean} array
 580      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 581      * {@code ix > bits.length - species.length()}
 582      */
 583     @ForceInline
 584     @SuppressWarnings("unchecked")
 585     public static Mask<$Boxtype$> maskFromArray(Species<$Boxtype$> species, boolean[] bits, int ix) {
 586         Objects.requireNonNull(bits);
 587         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 588         return VectorIntrinsics.load((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
 589                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 590                                      bits, ix, species,
 591                                      (c, idx, s) -> (Mask<$Boxtype$>) (($Type$Species)s).opm(n -> c[idx + n]));
 592     }
 593 
 594     /**
 595      * Returns a mask where all lanes are set.
 596      *
 597      * @param species mask species
 598      * @return a mask where all lanes are set
 599      */
 600     @ForceInline
 601     @SuppressWarnings("unchecked")
 602     public static Mask<$Boxtype$> maskAllTrue(Species<$Boxtype$> species) {
 603         return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
 604                                                  ($bitstype$)-1,  species,
 605                                                  ((z, s) -> trueMask(s)));
 606     }
 607 
 608     /**
 609      * Returns a mask where all lanes are unset.
 610      *
 611      * @param species mask species
 612      * @return a mask where all lanes are unset
 613      */
 614     @ForceInline
 615     @SuppressWarnings("unchecked")
 616     public static Mask<$Boxtype$> maskAllFalse(Species<$Boxtype$> species) {
 617         return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
 618                                                  0, species, 
 619                                                  ((z, s) -> falseMask(s)));
 620     }
 621 
 622     /**
 623      * Returns a shuffle of mapped indexes where each lane element is
 624      * the result of applying a mapping function to the corresponding lane
 625      * index.
 626      * <p>
 627      * Care should be taken to ensure Shuffle values produced from this
 628      * method are consumed as constants to ensure optimal generation of
 629      * code.  For example, values held in static final fields or values
 630      * held in loop constant local variables.
 631      * <p>
 632      * This method behaves as if a shuffle is created from an array of
 633      * mapped indexes as follows:
 634      * <pre>{@code
 635      *   int[] a = new int[species.length()];
 636      *   for (int i = 0; i < a.length; i++) {
 637      *       a[i] = f.applyAsInt(i);
 638      *   }
 639      *   return this.shuffleFromValues(a);
 640      * }</pre>
 641      *
 642      * @param species shuffle species
 643      * @param f the lane index mapping function
 644      * @return a shuffle of mapped indexes
 645      */
 646     @ForceInline
 647     public static Shuffle<$Boxtype$> shuffle(Species<$Boxtype$> species, IntUnaryOperator f) {
 648         if (species.boxType() == $Type$MaxVector.class)
 649             return new $Type$MaxVector.$Type$MaxShuffle(f);
 650         switch (species.bitSize()) {
 651             case 64: return new $Type$64Vector.$Type$64Shuffle(f);
 652             case 128: return new $Type$128Vector.$Type$128Shuffle(f);
 653             case 256: return new $Type$256Vector.$Type$256Shuffle(f);
 654             case 512: return new $Type$512Vector.$Type$512Shuffle(f);
 655             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 656         }
 657     }
 658 
 659     /**
 660      * Returns a shuffle where each lane element is the value of its
 661      * corresponding lane index.
 662      * <p>
 663      * This method behaves as if a shuffle is created from an identity
 664      * index mapping function as follows:
 665      * <pre>{@code
 666      *   return this.shuffle(i -> i);
 667      * }</pre>
 668      *
 669      * @param species shuffle species
 670      * @return a shuffle of lane indexes
 671      */
 672     @ForceInline
 673     public static Shuffle<$Boxtype$> shuffleIota(Species<$Boxtype$> species) {
 674         if (species.boxType() == $Type$MaxVector.class)
 675             return new $Type$MaxVector.$Type$MaxShuffle(AbstractShuffle.IDENTITY);
 676         switch (species.bitSize()) {
 677             case 64: return new $Type$64Vector.$Type$64Shuffle(AbstractShuffle.IDENTITY);
 678             case 128: return new $Type$128Vector.$Type$128Shuffle(AbstractShuffle.IDENTITY);
 679             case 256: return new $Type$256Vector.$Type$256Shuffle(AbstractShuffle.IDENTITY);
 680             case 512: return new $Type$512Vector.$Type$512Shuffle(AbstractShuffle.IDENTITY);
 681             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 682         }
 683     }
 684 
 685     /**
 686      * Returns a shuffle where each lane element is set to a given
 687      * {@code int} value logically AND'ed by the species length minus one.
 688      * <p>
 689      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 690      * the {@code int} value at index {@code N} logically AND'ed by
 691      * {@code species.length() - 1} is placed into the resulting shuffle at
 692      * lane index {@code N}.
 693      *
 694      * @param species shuffle species
 695      * @param ixs the given {@code int} values
 696      * @return a shuffle where each lane element is set to a given
 697      * {@code int} value
 698      * @throws IndexOutOfBoundsException if the number of int values is
 699      * {@code < species.length()}
 700      */
 701     @ForceInline
 702     public static Shuffle<$Boxtype$> shuffleFromValues(Species<$Boxtype$> species, int... ixs) {
 703         if (species.boxType() == $Type$MaxVector.class)
 704             return new $Type$MaxVector.$Type$MaxShuffle(ixs);
 705         switch (species.bitSize()) {
 706             case 64: return new $Type$64Vector.$Type$64Shuffle(ixs);
 707             case 128: return new $Type$128Vector.$Type$128Shuffle(ixs);
 708             case 256: return new $Type$256Vector.$Type$256Shuffle(ixs);
 709             case 512: return new $Type$512Vector.$Type$512Shuffle(ixs);
 710             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 711         }
 712     }
 713 
 714     /**
 715      * Loads a shuffle from an {@code int} array starting at an offset.
 716      * <p>
 717      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 718      * array element at index {@code i + N} logically AND'ed by
 719      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 720      * index {@code N}.
 721      *
 722      * @param species shuffle species
 723      * @param ixs the {@code int} array
 724      * @param i the offset into the array
 725      * @return a shuffle loaded from the {@code int} array
 726      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 727      * {@code i > a.length - species.length()}
 728      */
 729     @ForceInline
 730     public static Shuffle<$Boxtype$> shuffleFromArray(Species<$Boxtype$> species, int[] ixs, int i) {
 731         if (species.boxType() == $Type$MaxVector.class)
 732             return new $Type$MaxVector.$Type$MaxShuffle(ixs, i);
 733         switch (species.bitSize()) {
 734             case 64: return new $Type$64Vector.$Type$64Shuffle(ixs, i);
 735             case 128: return new $Type$128Vector.$Type$128Shuffle(ixs, i);
 736             case 256: return new $Type$256Vector.$Type$256Shuffle(ixs, i);
 737             case 512: return new $Type$512Vector.$Type$512Shuffle(ixs, i);
 738             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 739         }
 740     }
 741 

 742     // Ops
 743 
 744     @Override
 745     public abstract $abstractvectortype$ add(Vector<$Boxtype$> v);
 746 
 747     /**
 748      * Adds this vector to the broadcast of an input scalar.
 749      * <p>
 750      * This is a vector binary operation where the primitive addition operation
 751      * ({@code +}) is applied to lane elements.
 752      *
 753      * @param s the input scalar
 754      * @return the result of adding this vector to the broadcast of an input
 755      * scalar
 756      */
 757     public abstract $abstractvectortype$ add($type$ s);
 758 
 759     @Override
 760     public abstract $abstractvectortype$ add(Vector<$Boxtype$> v, Mask<$Boxtype$> m);
 761 


2909      * array bounds
2910      * @param m the mask
2911      * @param indexMap the index map
2912      * @param j the offset into the index map
2913      * @throws IndexOutOfBoundsException if {@code j < 0}, or
2914      * {@code j > indexMap.length - this.length()},
2915      * or for any vector lane index {@code N} where the mask at lane
2916      * {@code N} is set the result of {@code i + indexMap[j + N]} is
2917      * {@code < 0} or {@code >= a.length}
2918      */
2919 #if[byteOrShort]
2920     public void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
2921         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
2922     }
2923 #else[byteOrShort]
2924     public abstract void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j);
2925 #end[byteOrShort]
2926     // Species
2927 
2928     @Override
2929     public abstract Species<$Boxtype$> species();
2930 
2931     /**
2932      * Class representing {@link $abstractvectortype$}'s of the same {@link Vector.Shape Shape}.
2933      */
2934     static final class $Type$Species extends Vector.AbstractSpecies<$Boxtype$> {
2935         final Function<$type$[], $Type$Vector> vectorFactory;
2936         final Function<boolean[], Vector.Mask<$Boxtype$>> maskFactory;
2937 
2938         private $Type$Species(Vector.Shape shape,
2939                           Class<?> boxType,
2940                           Class<?> maskType,
2941                           Function<$type$[], $Type$Vector> vectorFactory,
2942                           Function<boolean[], Vector.Mask<$Boxtype$>> maskFactory) {
2943             super(shape, $type$.class, $Boxtype$.SIZE, boxType, maskType);
2944             this.vectorFactory = vectorFactory;
2945             this.maskFactory = maskFactory;
2946         }
2947 
2948         interface FOp {
2949             $type$ apply(int i);
2950         }
2951 




2952         interface FOpm {
2953             boolean apply(int i);
2954         }
2955 
2956         $Type$Vector op(FOp f) {
2957             $type$[] res = new $type$[length()];
2958             for (int i = 0; i < length(); i++) {
2959                 res[i] = f.apply(i);
2960             }
2961             return vectorFactory.apply(res);




























2962         }
2963 
2964         $Type$Vector op(Vector.Mask<$Boxtype$> o, FOp f) {
2965             $type$[] res = new $type$[length()];
2966             boolean[] mbits = ((AbstractMask<$Boxtype$>)o).getBits();
2967             for (int i = 0; i < length(); i++) {
2968                 if (mbits[i]) {
2969                     res[i] = f.apply(i);












2970                 }





2971             }
2972             return vectorFactory.apply(res);



2973         }


2974 
2975         Vector.Mask<$Boxtype$> opm(IntVector.IntSpecies.FOpm f) {
2976             boolean[] res = new boolean[length()];
2977             for (int i = 0; i < length(); i++) {
2978                 res[i] = (boolean)f.apply(i);
2979             }
2980             return maskFactory.apply(res);
2981         }







2982     }
2983 
2984     /**
2985      * Finds the preferred species for an element type of {@code $type$}.
2986      * <p>
2987      * A preferred species is a species chosen by the platform that has a
2988      * shape of maximal bit size.  A preferred species for different element
2989      * types will have the same shape, and therefore vectors, masks, and
2990      * shuffles created from such species will be shape compatible.
2991      *
2992      * @return the preferred species for an element type of {@code $type$}
2993      */
2994     private static $Type$Species preferredSpecies() {

2995         return ($Type$Species) Species.ofPreferred($type$.class);
2996     }
2997 
2998     /**
2999      * Finds a species for an element type of {@code $type$} and shape.
3000      *
3001      * @param s the shape
3002      * @return a species for an element type of {@code $type$} and shape
3003      * @throws IllegalArgumentException if no such species exists for the shape
3004      */
3005     static $Type$Species species(Vector.Shape s) {

3006         Objects.requireNonNull(s);
3007         switch (s) {
3008             case S_64_BIT: return ($Type$Species) SPECIES_64;
3009             case S_128_BIT: return ($Type$Species) SPECIES_128;
3010             case S_256_BIT: return ($Type$Species) SPECIES_256;
3011             case S_512_BIT: return ($Type$Species) SPECIES_512;
3012             case S_Max_BIT: return ($Type$Species) SPECIES_MAX;
3013             default: throw new IllegalArgumentException("Bad shape: " + s);
3014         }
3015     }
3016 
3017     /** Species representing {@link $Type$Vector}s of {@link Vector.Shape#S_64_BIT Shape.S_64_BIT}. */
3018     public static final Species<$Boxtype$> SPECIES_64 = new $Type$Species(Shape.S_64_BIT, $Type$64Vector.class, $Type$64Vector.$Type$64Mask.class,
3019                                                                      $Type$64Vector::new, $Type$64Vector.$Type$64Mask::new);
3020 
3021     /** Species representing {@link $Type$Vector}s of {@link Vector.Shape#S_128_BIT Shape.S_128_BIT}. */
3022     public static final Species<$Boxtype$> SPECIES_128 = new $Type$Species(Shape.S_128_BIT, $Type$128Vector.class, $Type$128Vector.$Type$128Mask.class,
3023                                                                       $Type$128Vector::new, $Type$128Vector.$Type$128Mask::new);
3024 
3025     /** Species representing {@link $Type$Vector}s of {@link Vector.Shape#S_256_BIT Shape.S_256_BIT}. */
3026     public static final Species<$Boxtype$> SPECIES_256 = new $Type$Species(Shape.S_256_BIT, $Type$256Vector.class, $Type$256Vector.$Type$256Mask.class,
3027                                                                       $Type$256Vector::new, $Type$256Vector.$Type$256Mask::new);
3028 
3029     /** Species representing {@link $Type$Vector}s of {@link Vector.Shape#S_512_BIT Shape.S_512_BIT}. */
3030     public static final Species<$Boxtype$> SPECIES_512 = new $Type$Species(Shape.S_512_BIT, $Type$512Vector.class, $Type$512Vector.$Type$512Mask.class,
3031                                                                       $Type$512Vector::new, $Type$512Vector.$Type$512Mask::new);
3032 
3033     /** Species representing {@link $Type$Vector}s of {@link Vector.Shape#S_Max_BIT Shape.S_Max_BIT}. */
3034     public static final Species<$Boxtype$> SPECIES_MAX = new $Type$Species(Shape.S_Max_BIT, $Type$MaxVector.class, $Type$MaxVector.$Type$MaxMask.class,
3035                                                                       $Type$MaxVector::new, $Type$MaxVector.$Type$MaxMask::new);
3036 
3037     /**
3038      * Preferred species for {@link $Type$Vector}s.
3039      * A preferred species is a species of maximal bit size for the platform.
3040      */
3041     public static final Species<$Boxtype$> SPECIES_PREFERRED = (Species<$Boxtype$>) preferredSpecies();
3042 }
< prev index next >