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 java.nio.ByteBuffer;
  28 import java.nio.FloatBuffer;
  29 import java.nio.ByteOrder;
  30 import java.util.Objects;
  31 import java.util.function.IntUnaryOperator;
  32 import java.util.concurrent.ThreadLocalRandom;
  33 
  34 import jdk.internal.misc.Unsafe;
  35 import jdk.internal.vm.annotation.ForceInline;
  36 import static jdk.incubator.vector.VectorIntrinsics.*;
  37 
  38 
  39 /**
  40  * A specialized {@link Vector} representing an ordered immutable sequence of
  41  * {@code float} values.
  42  */
  43 @SuppressWarnings("cast")
  44 public abstract class FloatVector extends Vector<Float> {
  45 
  46     FloatVector() {}
  47 
  48     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_FLOAT_INDEX_SCALE);
  49 
  50     // Unary operator
  51 
  52     interface FUnOp {
  53         float apply(int i, float a);
  54     }
  55 
  56     abstract FloatVector uOp(FUnOp f);
  57 
  58     abstract FloatVector uOp(Mask<Float> m, FUnOp f);
  59 
  60     // Binary operator
  61 
  62     interface FBinOp {
  63         float apply(int i, float a, float b);
  64     }
  65 
  66     abstract FloatVector bOp(Vector<Float> v, FBinOp f);
  67 
  68     abstract FloatVector bOp(Vector<Float> v, Mask<Float> m, FBinOp f);
  69 
  70     // Trinary operator
  71 
  72     interface FTriOp {
  73         float apply(int i, float a, float b, float c);
  74     }
  75 
  76     abstract FloatVector tOp(Vector<Float> v1, Vector<Float> v2, FTriOp f);
  77 
  78     abstract FloatVector tOp(Vector<Float> v1, Vector<Float> v2, Mask<Float> m, FTriOp f);
  79 
  80     // Reduction operator
  81 
  82     abstract float rOp(float v, FBinOp f);
  83 
  84     // Binary test
  85 
  86     interface FBinTest {
  87         boolean apply(int i, float a, float b);
  88     }
  89 
  90     abstract Mask<Float> bTest(Vector<Float> v, FBinTest f);
  91 
  92     // Foreach
  93 
  94     interface FUnCon {
  95         void apply(int i, float a);
  96     }
  97 
  98     abstract void forEach(FUnCon f);
  99 
 100     abstract void forEach(Mask<Float> m, FUnCon f);
 101 
 102     // Static factories
 103 
 104     /**
 105      * Returns a vector where all lane elements are set to the default
 106      * primitive value.
 107      *
 108      * @param species species of desired vector
 109      * @return a zero vector of given species
 110      */
 111     @ForceInline
 112     @SuppressWarnings("unchecked")
 113     public static FloatVector zero(FloatSpecies species) {
 114         return species.zero();
 115     }
 116 
 117     /**
 118      * Loads a vector from a byte array starting at an offset.
 119      * <p>
 120      * Bytes are composed into primitive lane elements according to the
 121      * native byte order of the underlying platform
 122      * <p>
 123      * This method behaves as if it returns the result of calling the
 124      * byte buffer, offset, and mask accepting
 125      * {@link #fromByteBuffer(FloatSpecies, ByteBuffer, int, Mask) method} as follows:
 126      * <pre>{@code
 127      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 128      * }</pre>
 129      *
 130      * @param species species of desired vector
 131      * @param a the byte array
 132      * @param ix the offset into the array
 133      * @return a vector loaded from a byte array
 134      * @throws IndexOutOfBoundsException if {@code i < 0} or
 135      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 136      */
 137     @ForceInline
 138     @SuppressWarnings("unchecked")
 139     public static FloatVector fromByteArray(FloatSpecies species, byte[] a, int ix) {
 140         Objects.requireNonNull(a);
 141         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 142         return VectorIntrinsics.load((Class<FloatVector>) species.boxType(), float.class, species.length(),
 143                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 144                                      a, ix, species,
 145                                      (c, idx, s) -> {
 146                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 147                                          FloatBuffer tb = bbc.asFloatBuffer();
 148                                          return ((FloatSpecies)s).op(i -> tb.get());
 149                                      });
 150     }
 151 
 152     /**
 153      * Loads a vector from a byte array starting at an offset and using a
 154      * mask.
 155      * <p>
 156      * Bytes are composed into primitive lane elements according to the
 157      * native byte order of the underlying platform.
 158      * <p>
 159      * This method behaves as if it returns the result of calling the
 160      * byte buffer, offset, and mask accepting
 161      * {@link #fromByteBuffer(FloatSpecies, ByteBuffer, int, Mask) method} as follows:
 162      * <pre>{@code
 163      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 164      * }</pre>
 165      *
 166      * @param species species of desired vector
 167      * @param a the byte array
 168      * @param ix the offset into the array
 169      * @param m the mask
 170      * @return a vector loaded from a byte array
 171      * @throws IndexOutOfBoundsException if {@code i < 0} or
 172      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 173      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 174      * or {@code > a.length},
 175      * for any vector lane index {@code N} where the mask at lane {@code N}
 176      * is set
 177      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 178      */
 179     @ForceInline
 180     public static FloatVector fromByteArray(FloatSpecies species, byte[] a, int ix, Mask<Float> m) {
 181         return zero(species).blend(fromByteArray(species, a, ix), m);
 182     }
 183 
 184     /**
 185      * Loads a vector from an array starting at offset.
 186      * <p>
 187      * For each vector lane, where {@code N} is the vector lane index, the
 188      * array element at index {@code i + N} is placed into the
 189      * resulting vector at lane index {@code N}.
 190      *
 191      * @param species species of desired vector
 192      * @param a the array
 193      * @param i the offset into the array
 194      * @return the vector loaded from an array
 195      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 196      * {@code i > a.length - this.length()}
 197      */
 198     @ForceInline
 199     @SuppressWarnings("unchecked")
 200     public static FloatVector fromArray(FloatSpecies species, float[] a, int i){
 201         Objects.requireNonNull(a);
 202         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 203         return VectorIntrinsics.load((Class<FloatVector>) species.boxType(), float.class, species.length(),
 204                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_FLOAT_BASE_OFFSET,
 205                                      a, i, species,
 206                                      (c, idx, s) -> ((FloatSpecies)s).op(n -> c[idx + n]));
 207     }
 208 
 209 
 210     /**
 211      * Loads a vector from an array starting at offset and using a mask.
 212      * <p>
 213      * For each vector lane, where {@code N} is the vector lane index,
 214      * if the mask lane at index {@code N} is set then the array element at
 215      * index {@code i + N} is placed into the resulting vector at lane index
 216      * {@code N}, otherwise the default element value is placed into the
 217      * resulting vector at lane index {@code N}.
 218      *
 219      * @param species species of desired vector
 220      * @param a the array
 221      * @param i the offset into the array
 222      * @param m the mask
 223      * @return the vector loaded from an array
 224      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 225      * for any vector lane index {@code N} where the mask at lane {@code N}
 226      * is set {@code i > a.length - N}
 227      */
 228     @ForceInline
 229     public static FloatVector fromArray(FloatSpecies species, float[] a, int i, Mask<Float> m) {
 230         return zero(species).blend(fromArray(species, a, i), m);
 231     }
 232 
 233     /**
 234      * Loads a vector from an array using indexes obtained from an index
 235      * map.
 236      * <p>
 237      * For each vector lane, where {@code N} is the vector lane index, the
 238      * array element at index {@code i + indexMap[j + N]} is placed into the
 239      * resulting vector at lane index {@code N}.
 240      *
 241      * @param species species of desired vector
 242      * @param a the array
 243      * @param i the offset into the array, may be negative if relative
 244      * indexes in the index map compensate to produce a value within the
 245      * array bounds
 246      * @param indexMap the index map
 247      * @param j the offset into the index map
 248      * @return the vector loaded from an array
 249      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 250      * {@code j > indexMap.length - this.length()},
 251      * or for any vector lane index {@code N} the result of
 252      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 253      */
 254     @ForceInline
 255     @SuppressWarnings("unchecked")
 256     public static FloatVector fromArray(FloatSpecies species, float[] a, int i, int[] indexMap, int j) {
 257         Objects.requireNonNull(a);
 258         Objects.requireNonNull(indexMap);
 259 
 260 
 261         // Index vector: vix[0:n] = k -> i + indexMap[j + i]
 262         IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
 263 
 264         vix = VectorIntrinsics.checkIndex(vix, a.length);
 265 
 266         return VectorIntrinsics.loadWithMap((Class<FloatVector>) species.boxType(), float.class, species.length(),
 267                                             species.indexSpecies().vectorType(), a, Unsafe.ARRAY_FLOAT_BASE_OFFSET, vix,
 268                                             a, i, indexMap, j, species,
 269                                            (c, idx, iMap, idy, s) -> ((FloatSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 270         }
 271 
 272     /**
 273      * Loads a vector from an array using indexes obtained from an index
 274      * map and using a mask.
 275      * <p>
 276      * For each vector lane, where {@code N} is the vector lane index,
 277      * if the mask lane at index {@code N} is set then the array element at
 278      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 279      * at lane index {@code N}.
 280      *
 281      * @param species species of desired vector
 282      * @param a the array
 283      * @param i the offset into the array, may be negative if relative
 284      * indexes in the index map compensate to produce a value within the
 285      * array bounds
 286      * @param m the mask
 287      * @param indexMap the index map
 288      * @param j the offset into the index map
 289      * @return the vector loaded from an array
 290      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 291      * {@code j > indexMap.length - this.length()},
 292      * or for any vector lane index {@code N} where the mask at lane
 293      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 294      * {@code < 0} or {@code >= a.length}
 295      */
 296     @ForceInline
 297     @SuppressWarnings("unchecked")
 298     public static FloatVector fromArray(FloatSpecies species, float[] a, int i, Mask<Float> m, int[] indexMap, int j) {
 299         // @@@ This can result in out of bounds errors for unset mask lanes
 300         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 301     }
 302 
 303 
 304     /**
 305      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 306      * offset into the byte buffer.
 307      * <p>
 308      * Bytes are composed into primitive lane elements according to the
 309      * native byte order of the underlying platform.
 310      * <p>
 311      * This method behaves as if it returns the result of calling the
 312      * byte buffer, offset, and mask accepting
 313      * {@link #fromByteBuffer(FloatSpecies, ByteBuffer, int, Mask)} method} as follows:
 314      * <pre>{@code
 315      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 316      * }</pre>
 317      *
 318      * @param species species of desired vector
 319      * @param bb the byte buffer
 320      * @param ix the offset into the byte buffer
 321      * @return a vector loaded from a byte buffer
 322      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 323      * or {@code > b.limit()},
 324      * or if there are fewer than
 325      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 326      * remaining in the byte buffer from the given offset
 327      */
 328     @ForceInline
 329     @SuppressWarnings("unchecked")
 330     public static FloatVector fromByteBuffer(FloatSpecies species, ByteBuffer bb, int ix) {
 331         if (bb.order() != ByteOrder.nativeOrder()) {
 332             throw new IllegalArgumentException();
 333         }
 334         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 335         return VectorIntrinsics.load((Class<FloatVector>) species.boxType(), float.class, species.length(),
 336                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 337                                      bb, ix, species,
 338                                      (c, idx, s) -> {
 339                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 340                                          FloatBuffer tb = bbc.asFloatBuffer();
 341                                          return ((FloatSpecies)s).op(i -> tb.get());
 342                                      });
 343     }
 344 
 345     /**
 346      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 347      * offset into the byte buffer and using a mask.
 348      * <p>
 349      * This method behaves as if the byte buffer is viewed as a primitive
 350      * {@link java.nio.Buffer buffer} for the primitive element type,
 351      * according to the native byte order of the underlying platform, and
 352      * the returned vector is loaded with a mask from a primitive array
 353      * obtained from the primitive buffer.
 354      * The following pseudocode expresses the behaviour, where
 355      * {@coce EBuffer} is the primitive buffer type, {@code e} is the
 356      * primitive element type, and {@code ESpecies<S>} is the primitive
 357      * species for {@code e}:
 358      * <pre>{@code
 359      * EBuffer eb = b.duplicate().
 360      *     order(ByteOrder.nativeOrder()).position(i).
 361      *     asEBuffer();
 362      * e[] es = new e[this.length()];
 363      * for (int n = 0; n < t.length; n++) {
 364      *     if (m.isSet(n))
 365      *         es[n] = eb.get(n);
 366      * }
 367      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 368      * }</pre>
 369      *
 370      * @param species species of desired vector
 371      * @param bb the byte buffer
 372      * @param ix the offset into the byte buffer
 373      * @param m the mask
 374      * @return a vector loaded from a byte buffer
 375      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 376      * or {@code > b.limit()},
 377      * for any vector lane index {@code N} where the mask at lane {@code N}
 378      * is set
 379      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 380      */
 381     @ForceInline
 382     public static FloatVector fromByteBuffer(FloatSpecies species, ByteBuffer bb, int ix, Mask<Float> m) {
 383         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 384     }
 385 
 386     /**
 387      * Returns a mask where each lane is set or unset according to given
 388      * {@code boolean} values
 389      * <p>
 390      * For each mask lane, where {@code N} is the mask lane index,
 391      * if the given {@code boolean} value at index {@code N} is {@code true}
 392      * then the mask lane at index {@code N} is set, otherwise it is unset.
 393      *
 394      * @param species mask species
 395      * @param bits the given {@code boolean} values
 396      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 397      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 398      */
 399     @ForceInline
 400     public static Mask<Float> maskFromValues(FloatSpecies species, boolean... bits) {
 401         if (species.boxType() == FloatMaxVector.class)
 402             return new FloatMaxVector.FloatMaxMask(bits);
 403         switch (species.bitSize()) {
 404             case 64: return new Float64Vector.Float64Mask(bits);
 405             case 128: return new Float128Vector.Float128Mask(bits);
 406             case 256: return new Float256Vector.Float256Mask(bits);
 407             case 512: return new Float512Vector.Float512Mask(bits);
 408             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 409         }
 410     }
 411 
 412     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 413     static Mask<Float> trueMask(FloatSpecies species) {
 414         if (species.boxType() == FloatMaxVector.class)
 415             return FloatMaxVector.FloatMaxMask.TRUE_MASK;
 416         switch (species.bitSize()) {
 417             case 64: return Float64Vector.Float64Mask.TRUE_MASK;
 418             case 128: return Float128Vector.Float128Mask.TRUE_MASK;
 419             case 256: return Float256Vector.Float256Mask.TRUE_MASK;
 420             case 512: return Float512Vector.Float512Mask.TRUE_MASK;
 421             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 422         }
 423     }
 424 
 425     static Mask<Float> falseMask(FloatSpecies species) {
 426         if (species.boxType() == FloatMaxVector.class)
 427             return FloatMaxVector.FloatMaxMask.FALSE_MASK;
 428         switch (species.bitSize()) {
 429             case 64: return Float64Vector.Float64Mask.FALSE_MASK;
 430             case 128: return Float128Vector.Float128Mask.FALSE_MASK;
 431             case 256: return Float256Vector.Float256Mask.FALSE_MASK;
 432             case 512: return Float512Vector.Float512Mask.FALSE_MASK;
 433             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 434         }
 435     }
 436 
 437     /**
 438      * Loads a mask from a {@code boolean} array starting at an offset.
 439      * <p>
 440      * For each mask lane, where {@code N} is the mask lane index,
 441      * if the array element at index {@code ix + N} is {@code true} then the
 442      * mask lane at index {@code N} is set, otherwise it is unset.
 443      *
 444      * @param species mask species
 445      * @param bits the {@code boolean} array
 446      * @param ix the offset into the array
 447      * @return the mask loaded from a {@code boolean} array
 448      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 449      * {@code ix > bits.length - species.length()}
 450      */
 451     @ForceInline
 452     @SuppressWarnings("unchecked")
 453     public static Mask<Float> maskFromArray(FloatSpecies species, boolean[] bits, int ix) {
 454         Objects.requireNonNull(bits);
 455         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 456         return VectorIntrinsics.load((Class<Mask<Float>>) species.maskType(), int.class, species.length(),
 457                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 458                                      bits, ix, species,
 459                                      (c, idx, s) -> (Mask<Float>) ((FloatSpecies)s).opm(n -> c[idx + n]));
 460     }
 461 
 462     /**
 463      * Returns a mask where all lanes are set.
 464      *
 465      * @param species mask species
 466      * @return a mask where all lanes are set
 467      */
 468     @ForceInline
 469     @SuppressWarnings("unchecked")
 470     public static Mask<Float> maskAllTrue(FloatSpecies species) {
 471         return VectorIntrinsics.broadcastCoerced((Class<Mask<Float>>) species.maskType(), int.class, species.length(),
 472                                                  (int)-1,  species,
 473                                                  ((z, s) -> trueMask((FloatSpecies)s)));
 474     }
 475 
 476     /**
 477      * Returns a mask where all lanes are unset.
 478      *
 479      * @param species mask species
 480      * @return a mask where all lanes are unset
 481      */
 482     @ForceInline
 483     @SuppressWarnings("unchecked")
 484     public static Mask<Float> maskAllFalse(FloatSpecies species) {
 485         return VectorIntrinsics.broadcastCoerced((Class<Mask<Float>>) species.maskType(), int.class, species.length(),
 486                                                  0, species, 
 487                                                  ((z, s) -> falseMask((FloatSpecies)s)));
 488     }
 489 
 490     /**
 491      * Returns a shuffle of mapped indexes where each lane element is
 492      * the result of applying a mapping function to the corresponding lane
 493      * index.
 494      * <p>
 495      * Care should be taken to ensure Shuffle values produced from this
 496      * method are consumed as constants to ensure optimal generation of
 497      * code.  For example, values held in static final fields or values
 498      * held in loop constant local variables.
 499      * <p>
 500      * This method behaves as if a shuffle is created from an array of
 501      * mapped indexes as follows:
 502      * <pre>{@code
 503      *   int[] a = new int[species.length()];
 504      *   for (int i = 0; i < a.length; i++) {
 505      *       a[i] = f.applyAsInt(i);
 506      *   }
 507      *   return this.shuffleFromValues(a);
 508      * }</pre>
 509      *
 510      * @param species shuffle species
 511      * @param f the lane index mapping function
 512      * @return a shuffle of mapped indexes
 513      */
 514     @ForceInline
 515     public static Shuffle<Float> shuffle(FloatSpecies species, IntUnaryOperator f) {
 516         if (species.boxType() == FloatMaxVector.class)
 517             return new FloatMaxVector.FloatMaxShuffle(f);
 518         switch (species.bitSize()) {
 519             case 64: return new Float64Vector.Float64Shuffle(f);
 520             case 128: return new Float128Vector.Float128Shuffle(f);
 521             case 256: return new Float256Vector.Float256Shuffle(f);
 522             case 512: return new Float512Vector.Float512Shuffle(f);
 523             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 524         }
 525     }
 526 
 527     /**
 528      * Returns a shuffle where each lane element is the value of its
 529      * corresponding lane index.
 530      * <p>
 531      * This method behaves as if a shuffle is created from an identity
 532      * index mapping function as follows:
 533      * <pre>{@code
 534      *   return this.shuffle(i -> i);
 535      * }</pre>
 536      *
 537      * @param species shuffle species
 538      * @return a shuffle of lane indexes
 539      */
 540     @ForceInline
 541     public static Shuffle<Float> shuffleIota(FloatSpecies species) {
 542         if (species.boxType() == FloatMaxVector.class)
 543             return new FloatMaxVector.FloatMaxShuffle(AbstractShuffle.IDENTITY);
 544         switch (species.bitSize()) {
 545             case 64: return new Float64Vector.Float64Shuffle(AbstractShuffle.IDENTITY);
 546             case 128: return new Float128Vector.Float128Shuffle(AbstractShuffle.IDENTITY);
 547             case 256: return new Float256Vector.Float256Shuffle(AbstractShuffle.IDENTITY);
 548             case 512: return new Float512Vector.Float512Shuffle(AbstractShuffle.IDENTITY);
 549             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 550         }
 551     }
 552 
 553     /**
 554      * Returns a shuffle where each lane element is set to a given
 555      * {@code int} value logically AND'ed by the species length minus one.
 556      * <p>
 557      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 558      * the {@code int} value at index {@code N} logically AND'ed by
 559      * {@code species.length() - 1} is placed into the resulting shuffle at
 560      * lane index {@code N}.
 561      *
 562      * @param species shuffle species
 563      * @param ixs the given {@code int} values
 564      * @return a shuffle where each lane element is set to a given
 565      * {@code int} value
 566      * @throws IndexOutOfBoundsException if the number of int values is
 567      * {@code < species.length()}
 568      */
 569     @ForceInline
 570     public static Shuffle<Float> shuffleFromValues(FloatSpecies species, int... ixs) {
 571         if (species.boxType() == FloatMaxVector.class)
 572             return new FloatMaxVector.FloatMaxShuffle(ixs);
 573         switch (species.bitSize()) {
 574             case 64: return new Float64Vector.Float64Shuffle(ixs);
 575             case 128: return new Float128Vector.Float128Shuffle(ixs);
 576             case 256: return new Float256Vector.Float256Shuffle(ixs);
 577             case 512: return new Float512Vector.Float512Shuffle(ixs);
 578             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 579         }
 580     }
 581 
 582     /**
 583      * Loads a shuffle from an {@code int} array starting at an offset.
 584      * <p>
 585      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 586      * array element at index {@code i + N} logically AND'ed by
 587      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 588      * index {@code N}.
 589      *
 590      * @param species shuffle species
 591      * @param ixs the {@code int} array
 592      * @param i the offset into the array
 593      * @return a shuffle loaded from the {@code int} array
 594      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 595      * {@code i > a.length - species.length()}
 596      */
 597     @ForceInline
 598     public static Shuffle<Float> shuffleFromArray(FloatSpecies species, int[] ixs, int i) {
 599         if (species.boxType() == FloatMaxVector.class)
 600             return new FloatMaxVector.FloatMaxShuffle(ixs, i);
 601         switch (species.bitSize()) {
 602             case 64: return new Float64Vector.Float64Shuffle(ixs, i);
 603             case 128: return new Float128Vector.Float128Shuffle(ixs, i);
 604             case 256: return new Float256Vector.Float256Shuffle(ixs, i);
 605             case 512: return new Float512Vector.Float512Shuffle(ixs, i);
 606             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 607         }
 608     }
 609 
 610 
 611     // Ops
 612 
 613     @Override
 614     public abstract FloatVector add(Vector<Float> v);
 615 
 616     /**
 617      * Adds this vector to the broadcast of an input scalar.
 618      * <p>
 619      * This is a vector binary operation where the primitive addition operation
 620      * ({@code +}) is applied to lane elements.
 621      *
 622      * @param s the input scalar
 623      * @return the result of adding this vector to the broadcast of an input
 624      * scalar
 625      */
 626     public abstract FloatVector add(float s);
 627 
 628     @Override
 629     public abstract FloatVector add(Vector<Float> v, Mask<Float> m);
 630 
 631     /**
 632      * Adds this vector to broadcast of an input scalar,
 633      * selecting lane elements controlled by a mask.
 634      * <p>
 635      * This is a vector binary operation where the primitive addition operation
 636      * ({@code +}) is applied to lane elements.
 637      *
 638      * @param s the input scalar
 639      * @param m the mask controlling lane selection
 640      * @return the result of adding this vector to the broadcast of an input
 641      * scalar
 642      */
 643     public abstract FloatVector add(float s, Mask<Float> m);
 644 
 645     @Override
 646     public abstract FloatVector sub(Vector<Float> v);
 647 
 648     /**
 649      * Subtracts the broadcast of an input scalar from this vector.
 650      * <p>
 651      * This is a vector binary operation where the primitive subtraction
 652      * operation ({@code -}) is applied to lane elements.
 653      *
 654      * @param s the input scalar
 655      * @return the result of subtracting the broadcast of an input
 656      * scalar from this vector
 657      */
 658     public abstract FloatVector sub(float s);
 659 
 660     @Override
 661     public abstract FloatVector sub(Vector<Float> v, Mask<Float> m);
 662 
 663     /**
 664      * Subtracts the broadcast of an input scalar from this vector, selecting
 665      * lane elements controlled by a mask.
 666      * <p>
 667      * This is a vector binary operation where the primitive subtraction
 668      * operation ({@code -}) is applied to lane elements.
 669      *
 670      * @param s the input scalar
 671      * @param m the mask controlling lane selection
 672      * @return the result of subtracting the broadcast of an input
 673      * scalar from this vector
 674      */
 675     public abstract FloatVector sub(float s, Mask<Float> m);
 676 
 677     @Override
 678     public abstract FloatVector mul(Vector<Float> v);
 679 
 680     /**
 681      * Multiplies this vector with the broadcast of an input scalar.
 682      * <p>
 683      * This is a vector binary operation where the primitive multiplication
 684      * operation ({@code *}) is applied to lane elements.
 685      *
 686      * @param s the input scalar
 687      * @return the result of multiplying this vector with the broadcast of an
 688      * input scalar
 689      */
 690     public abstract FloatVector mul(float s);
 691 
 692     @Override
 693     public abstract FloatVector mul(Vector<Float> v, Mask<Float> m);
 694 
 695     /**
 696      * Multiplies this vector with the broadcast of an input scalar, selecting
 697      * lane elements controlled by a mask.
 698      * <p>
 699      * This is a vector binary operation where the primitive multiplication
 700      * operation ({@code *}) is applied to lane elements.
 701      *
 702      * @param s the input scalar
 703      * @param m the mask controlling lane selection
 704      * @return the result of multiplying this vector with the broadcast of an
 705      * input scalar
 706      */
 707     public abstract FloatVector mul(float s, Mask<Float> m);
 708 
 709     @Override
 710     public abstract FloatVector neg();
 711 
 712     @Override
 713     public abstract FloatVector neg(Mask<Float> m);
 714 
 715     @Override
 716     public abstract FloatVector abs();
 717 
 718     @Override
 719     public abstract FloatVector abs(Mask<Float> m);
 720 
 721     @Override
 722     public abstract FloatVector min(Vector<Float> v);
 723 
 724     @Override
 725     public abstract FloatVector min(Vector<Float> v, Mask<Float> m);
 726 
 727     /**
 728      * Returns the minimum of this vector and the broadcast of an input scalar.
 729      * <p>
 730      * This is a vector binary operation where the operation
 731      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 732      *
 733      * @param s the input scalar
 734      * @return the minimum of this vector and the broadcast of an input scalar
 735      */
 736     public abstract FloatVector min(float s);
 737 
 738     @Override
 739     public abstract FloatVector max(Vector<Float> v);
 740 
 741     @Override
 742     public abstract FloatVector max(Vector<Float> v, Mask<Float> m);
 743 
 744     /**
 745      * Returns the maximum of this vector and the broadcast of an input scalar.
 746      * <p>
 747      * This is a vector binary operation where the operation
 748      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 749      *
 750      * @param s the input scalar
 751      * @return the maximum of this vector and the broadcast of an input scalar
 752      */
 753     public abstract FloatVector max(float s);
 754 
 755     @Override
 756     public abstract Mask<Float> equal(Vector<Float> v);
 757 
 758     /**
 759      * Tests if this vector is equal to the broadcast of an input scalar.
 760      * <p>
 761      * This is a vector binary test operation where the primitive equals
 762      * operation ({@code ==}) is applied to lane elements.
 763      *
 764      * @param s the input scalar
 765      * @return the result mask of testing if this vector is equal to the
 766      * broadcast of an input scalar
 767      */
 768     public abstract Mask<Float> equal(float s);
 769 
 770     @Override
 771     public abstract Mask<Float> notEqual(Vector<Float> v);
 772 
 773     /**
 774      * Tests if this vector is not equal to the broadcast of an input scalar.
 775      * <p>
 776      * This is a vector binary test operation where the primitive not equals
 777      * operation ({@code !=}) is applied to lane elements.
 778      *
 779      * @param s the input scalar
 780      * @return the result mask of testing if this vector is not equal to the
 781      * broadcast of an input scalar
 782      */
 783     public abstract Mask<Float> notEqual(float s);
 784 
 785     @Override
 786     public abstract Mask<Float> lessThan(Vector<Float> v);
 787 
 788     /**
 789      * Tests if this vector is less than the broadcast of an input scalar.
 790      * <p>
 791      * This is a vector binary test operation where the primitive less than
 792      * operation ({@code <}) is applied to lane elements.
 793      *
 794      * @param s the input scalar
 795      * @return the mask result of testing if this vector is less than the
 796      * broadcast of an input scalar
 797      */
 798     public abstract Mask<Float> lessThan(float s);
 799 
 800     @Override
 801     public abstract Mask<Float> lessThanEq(Vector<Float> v);
 802 
 803     /**
 804      * Tests if this vector is less or equal to the broadcast of an input scalar.
 805      * <p>
 806      * This is a vector binary test operation where the primitive less than
 807      * or equal to operation ({@code <=}) is applied to lane elements.
 808      *
 809      * @param s the input scalar
 810      * @return the mask result of testing if this vector is less than or equal
 811      * to the broadcast of an input scalar
 812      */
 813     public abstract Mask<Float> lessThanEq(float s);
 814 
 815     @Override
 816     public abstract Mask<Float> greaterThan(Vector<Float> v);
 817 
 818     /**
 819      * Tests if this vector is greater than the broadcast of an input scalar.
 820      * <p>
 821      * This is a vector binary test operation where the primitive greater than
 822      * operation ({@code >}) is applied to lane elements.
 823      *
 824      * @param s the input scalar
 825      * @return the mask result of testing if this vector is greater than the
 826      * broadcast of an input scalar
 827      */
 828     public abstract Mask<Float> greaterThan(float s);
 829 
 830     @Override
 831     public abstract Mask<Float> greaterThanEq(Vector<Float> v);
 832 
 833     /**
 834      * Tests if this vector is greater than or equal to the broadcast of an
 835      * input scalar.
 836      * <p>
 837      * This is a vector binary test operation where the primitive greater than
 838      * or equal to operation ({@code >=}) is applied to lane elements.
 839      *
 840      * @param s the input scalar
 841      * @return the mask result of testing if this vector is greater than or
 842      * equal to the broadcast of an input scalar
 843      */
 844     public abstract Mask<Float> greaterThanEq(float s);
 845 
 846     @Override
 847     public abstract FloatVector blend(Vector<Float> v, Mask<Float> m);
 848 
 849     /**
 850      * Blends the lane elements of this vector with those of the broadcast of an
 851      * input scalar, selecting lanes controlled by a mask.
 852      * <p>
 853      * For each lane of the mask, at lane index {@code N}, if the mask lane
 854      * is set then the lane element at {@code N} from the input vector is
 855      * selected and placed into the resulting vector at {@code N},
 856      * otherwise the the lane element at {@code N} from this input vector is
 857      * selected and placed into the resulting vector at {@code N}.
 858      *
 859      * @param s the input scalar
 860      * @param m the mask controlling lane selection
 861      * @return the result of blending the lane elements of this vector with
 862      * those of the broadcast of an input scalar
 863      */
 864     public abstract FloatVector blend(float s, Mask<Float> m);
 865 
 866     @Override
 867     public abstract FloatVector rearrange(Vector<Float> v,
 868                                                       Shuffle<Float> s, Mask<Float> m);
 869 
 870     @Override
 871     public abstract FloatVector rearrange(Shuffle<Float> m);
 872 
 873     @Override
 874     public abstract FloatVector reshape(Species<Float> s);
 875 
 876     @Override
 877     public abstract FloatVector rotateEL(int i);
 878 
 879     @Override
 880     public abstract FloatVector rotateER(int i);
 881 
 882     @Override
 883     public abstract FloatVector shiftEL(int i);
 884 
 885     @Override
 886     public abstract FloatVector shiftER(int i);
 887 
 888     /**
 889      * Divides this vector by an input vector.
 890      * <p>
 891      * This is a vector binary operation where the primitive division
 892      * operation ({@code /}) is applied to lane elements.
 893      *
 894      * @param v the input vector
 895      * @return the result of dividing this vector by the input vector
 896      */
 897     public abstract FloatVector div(Vector<Float> v);
 898 
 899     /**
 900      * Divides this vector by the broadcast of an input scalar.
 901      * <p>
 902      * This is a vector binary operation where the primitive division
 903      * operation ({@code /}) is applied to lane elements.
 904      *
 905      * @param s the input scalar
 906      * @return the result of dividing this vector by the broadcast of an input
 907      * scalar
 908      */
 909     public abstract FloatVector div(float s);
 910 
 911     /**
 912      * Divides this vector by an input vector, selecting lane elements
 913      * controlled by a mask.
 914      * <p>
 915      * This is a vector binary operation where the primitive division
 916      * operation ({@code /}) is applied to lane elements.
 917      *
 918      * @param v the input vector
 919      * @param m the mask controlling lane selection
 920      * @return the result of dividing this vector by the input vector
 921      */
 922     public abstract FloatVector div(Vector<Float> v, Mask<Float> m);
 923 
 924     /**
 925      * Divides this vector by the broadcast of an input scalar, selecting lane
 926      * elements controlled by a mask.
 927      * <p>
 928      * This is a vector binary operation where the primitive division
 929      * operation ({@code /}) is applied to lane elements.
 930      *
 931      * @param s the input scalar
 932      * @param m the mask controlling lane selection
 933      * @return the result of dividing this vector by the broadcast of an input
 934      * scalar
 935      */
 936     public abstract FloatVector div(float s, Mask<Float> m);
 937 
 938     /**
 939      * Calculates the square root of this vector.
 940      * <p>
 941      * This is a vector unary operation where the {@link Math#sqrt} operation
 942      * is applied to lane elements.
 943      *
 944      * @return the square root of this vector
 945      */
 946     public abstract FloatVector sqrt();
 947 
 948     /**
 949      * Calculates the square root of this vector, selecting lane elements
 950      * controlled by a mask.
 951      * <p>
 952      * This is a vector unary operation where the {@link Math#sqrt} operation
 953      * is applied to lane elements.
 954      *
 955      * @param m the mask controlling lane selection
 956      * @return the square root of this vector
 957      */
 958     public FloatVector sqrt(Mask<Float> m) {
 959         return uOp(m, (i, a) -> (float) Math.sqrt((double) a));
 960     }
 961 
 962     /**
 963      * Calculates the trigonometric tangent of this vector.
 964      * <p>
 965      * This is a vector unary operation with same semantic definition as
 966      * {@link Math#tan} operation applied to lane elements.
 967      * The implementation is not required to return same
 968      * results as {@link Math#tan}, but adheres to rounding, monotonicity,
 969      * and special case semantics as defined in the {@link Math#tan}
 970      * specifications. The computed result will be within 1 ulp of the
 971      * exact result.
 972      *
 973      * @return the tangent of this vector
 974      */
 975     public FloatVector tan() {
 976         return uOp((i, a) -> (float) Math.tan((double) a));
 977     }
 978 
 979     /**
 980      * Calculates the trigonometric tangent of this vector, selecting lane
 981      * elements controlled by a mask.
 982      * <p>
 983      * Semantics for rounding, monotonicity, and special cases are
 984      * described in {@link FloatVector#tan}
 985      *
 986      * @param m the mask controlling lane selection
 987      * @return the tangent of this vector
 988      */
 989     public FloatVector tan(Mask<Float> m) {
 990         return uOp(m, (i, a) -> (float) Math.tan((double) a));
 991     }
 992 
 993     /**
 994      * Calculates the hyperbolic tangent of this vector.
 995      * <p>
 996      * This is a vector unary operation with same semantic definition as
 997      * {@link Math#tanh} operation applied to lane elements.
 998      * The implementation is not required to return same
 999      * results as {@link Math#tanh}, but adheres to rounding, monotonicity,
1000      * and special case semantics as defined in the {@link Math#tanh}
1001      * specifications. The computed result will be within 2.5 ulps of the
1002      * exact result.
1003      *
1004      * @return the hyperbolic tangent of this vector
1005      */
1006     public FloatVector tanh() {
1007         return uOp((i, a) -> (float) Math.tanh((double) a));
1008     }
1009 
1010     /**
1011      * Calculates the hyperbolic tangent of this vector, selecting lane elements
1012      * controlled by a mask.
1013      * <p>
1014      * Semantics for rounding, monotonicity, and special cases are
1015      * described in {@link FloatVector#tanh}
1016      *
1017      * @param m the mask controlling lane selection
1018      * @return the hyperbolic tangent of this vector
1019      */
1020     public FloatVector tanh(Mask<Float> m) {
1021         return uOp(m, (i, a) -> (float) Math.tanh((double) a));
1022     }
1023 
1024     /**
1025      * Calculates the trigonometric sine of this vector.
1026      * <p>
1027      * This is a vector unary operation with same semantic definition as
1028      * {@link Math#sin} operation applied to lane elements.
1029      * The implementation is not required to return same
1030      * results as {@link Math#sin}, but adheres to rounding, monotonicity,
1031      * and special case semantics as defined in the {@link Math#sin}
1032      * specifications. The computed result will be within 1 ulp of the
1033      * exact result.
1034      *
1035      * @return the sine of this vector
1036      */
1037     public FloatVector sin() {
1038         return uOp((i, a) -> (float) Math.sin((double) a));
1039     }
1040 
1041     /**
1042      * Calculates the trigonometric sine of this vector, selecting lane elements
1043      * controlled by a mask.
1044      * <p>
1045      * Semantics for rounding, monotonicity, and special cases are
1046      * described in {@link FloatVector#sin}
1047      *
1048      * @param m the mask controlling lane selection
1049      * @return the sine of this vector
1050      */
1051     public FloatVector sin(Mask<Float> m) {
1052         return uOp(m, (i, a) -> (float) Math.sin((double) a));
1053     }
1054 
1055     /**
1056      * Calculates the hyperbolic sine of this vector.
1057      * <p>
1058      * This is a vector unary operation with same semantic definition as
1059      * {@link Math#sinh} operation applied to lane elements.
1060      * The implementation is not required to return same
1061      * results as  {@link Math#sinh}, but adheres to rounding, monotonicity,
1062      * and special case semantics as defined in the {@link Math#sinh}
1063      * specifications. The computed result will be within 2.5 ulps of the
1064      * exact result.
1065      *
1066      * @return the hyperbolic sine of this vector
1067      */
1068     public FloatVector sinh() {
1069         return uOp((i, a) -> (float) Math.sinh((double) a));
1070     }
1071 
1072     /**
1073      * Calculates the hyperbolic sine of this vector, selecting lane elements
1074      * controlled by a mask.
1075      * <p>
1076      * Semantics for rounding, monotonicity, and special cases are
1077      * described in {@link FloatVector#sinh}
1078      *
1079      * @param m the mask controlling lane selection
1080      * @return the hyperbolic sine of this vector
1081      */
1082     public FloatVector sinh(Mask<Float> m) {
1083         return uOp(m, (i, a) -> (float) Math.sinh((double) a));
1084     }
1085 
1086     /**
1087      * Calculates the trigonometric cosine of this vector.
1088      * <p>
1089      * This is a vector unary operation with same semantic definition as
1090      * {@link Math#cos} operation applied to lane elements.
1091      * The implementation is not required to return same
1092      * results as {@link Math#cos}, but adheres to rounding, monotonicity,
1093      * and special case semantics as defined in the {@link Math#cos}
1094      * specifications. The computed result will be within 1 ulp of the
1095      * exact result.
1096      *
1097      * @return the cosine of this vector
1098      */
1099     public FloatVector cos() {
1100         return uOp((i, a) -> (float) Math.cos((double) a));
1101     }
1102 
1103     /**
1104      * Calculates the trigonometric cosine of this vector, selecting lane
1105      * elements controlled by a mask.
1106      * <p>
1107      * Semantics for rounding, monotonicity, and special cases are
1108      * described in {@link FloatVector#cos}
1109      *
1110      * @param m the mask controlling lane selection
1111      * @return the cosine of this vector
1112      */
1113     public FloatVector cos(Mask<Float> m) {
1114         return uOp(m, (i, a) -> (float) Math.cos((double) a));
1115     }
1116 
1117     /**
1118      * Calculates the hyperbolic cosine of this vector.
1119      * <p>
1120      * This is a vector unary operation with same semantic definition as
1121      * {@link Math#cosh} operation applied to lane elements.
1122      * The implementation is not required to return same
1123      * results as {@link Math#cosh}, but adheres to rounding, monotonicity,
1124      * and special case semantics as defined in the {@link Math#cosh}
1125      * specifications. The computed result will be within 2.5 ulps of the
1126      * exact result.
1127      *
1128      * @return the hyperbolic cosine of this vector
1129      */
1130     public FloatVector cosh() {
1131         return uOp((i, a) -> (float) Math.cosh((double) a));
1132     }
1133 
1134     /**
1135      * Calculates the hyperbolic cosine of this vector, selecting lane elements
1136      * controlled by a mask.
1137      * <p>
1138      * Semantics for rounding, monotonicity, and special cases are
1139      * described in {@link FloatVector#cosh}
1140      *
1141      * @param m the mask controlling lane selection
1142      * @return the hyperbolic cosine of this vector
1143      */
1144     public FloatVector cosh(Mask<Float> m) {
1145         return uOp(m, (i, a) -> (float) Math.cosh((double) a));
1146     }
1147 
1148     /**
1149      * Calculates the arc sine of this vector.
1150      * <p>
1151      * This is a vector unary operation with same semantic definition as
1152      * {@link Math#asin} operation applied to lane elements.
1153      * The implementation is not required to return same
1154      * results as {@link Math#asin}, but adheres to rounding, monotonicity,
1155      * and special case semantics as defined in the {@link Math#asin}
1156      * specifications. The computed result will be within 1 ulp of the
1157      * exact result.
1158      *
1159      * @return the arc sine of this vector
1160      */
1161     public FloatVector asin() {
1162         return uOp((i, a) -> (float) Math.asin((double) a));
1163     }
1164 
1165     /**
1166      * Calculates the arc sine of this vector, selecting lane elements
1167      * controlled by a mask.
1168      * <p>
1169      * Semantics for rounding, monotonicity, and special cases are
1170      * described in {@link FloatVector#asin}
1171      *
1172      * @param m the mask controlling lane selection
1173      * @return the arc sine of this vector
1174      */
1175     public FloatVector asin(Mask<Float> m) {
1176         return uOp(m, (i, a) -> (float) Math.asin((double) a));
1177     }
1178 
1179     /**
1180      * Calculates the arc cosine of this vector.
1181      * <p>
1182      * This is a vector unary operation with same semantic definition as
1183      * {@link Math#acos} operation applied to lane elements.
1184      * The implementation is not required to return same
1185      * results as {@link Math#acos}, but adheres to rounding, monotonicity,
1186      * and special case semantics as defined in the {@link Math#acos}
1187      * specifications. The computed result will be within 1 ulp of the
1188      * exact result.
1189      *
1190      * @return the arc cosine of this vector
1191      */
1192     public FloatVector acos() {
1193         return uOp((i, a) -> (float) Math.acos((double) a));
1194     }
1195 
1196     /**
1197      * Calculates the arc cosine of this vector, selecting lane elements
1198      * controlled by a mask.
1199      * <p>
1200      * Semantics for rounding, monotonicity, and special cases are
1201      * described in {@link FloatVector#acos}
1202      *
1203      * @param m the mask controlling lane selection
1204      * @return the arc cosine of this vector
1205      */
1206     public FloatVector acos(Mask<Float> m) {
1207         return uOp(m, (i, a) -> (float) Math.acos((double) a));
1208     }
1209 
1210     /**
1211      * Calculates the arc tangent of this vector.
1212      * <p>
1213      * This is a vector unary operation with same semantic definition as
1214      * {@link Math#atan} operation applied to lane elements.
1215      * The implementation is not required to return same
1216      * results as {@link Math#atan}, but adheres to rounding, monotonicity,
1217      * and special case semantics as defined in the {@link Math#atan}
1218      * specifications. The computed result will be within 1 ulp of the
1219      * exact result.
1220      *
1221      * @return the arc tangent of this vector
1222      */
1223     public FloatVector atan() {
1224         return uOp((i, a) -> (float) Math.atan((double) a));
1225     }
1226 
1227     /**
1228      * Calculates the arc tangent of this vector, selecting lane elements
1229      * controlled by a mask.
1230      * <p>
1231      * Semantics for rounding, monotonicity, and special cases are
1232      * described in {@link FloatVector#atan}
1233      *
1234      * @param m the mask controlling lane selection
1235      * @return the arc tangent of this vector
1236      */
1237     public FloatVector atan(Mask<Float> m) {
1238         return uOp(m, (i, a) -> (float) Math.atan((double) a));
1239     }
1240 
1241     /**
1242      * Calculates the arc tangent of this vector divided by an input vector.
1243      * <p>
1244      * This is a vector binary operation with same semantic definition as
1245      * {@link Math#atan2} operation applied to lane elements.
1246      * The implementation is not required to return same
1247      * results as {@link Math#atan2}, but adheres to rounding, monotonicity,
1248      * and special case semantics as defined in the {@link Math#atan2}
1249      * specifications. The computed result will be within 2 ulps of the
1250      * exact result.
1251      *
1252      * @param v the input vector
1253      * @return the arc tangent of this vector divided by the input vector
1254      */
1255     public FloatVector atan2(Vector<Float> v) {
1256         return bOp(v, (i, a, b) -> (float) Math.atan2((double) a, (double) b));
1257     }
1258 
1259     /**
1260      * Calculates the arc tangent of this vector divided by the broadcast of an
1261      * an input scalar.
1262      * <p>
1263      * This is a vector binary operation with same semantic definition as
1264      * {@link Math#atan2} operation applied to lane elements.
1265      * The implementation is not required to return same
1266      * results as {@link Math#atan2}, but adheres to rounding, monotonicity,
1267      * and special case semantics as defined in the {@link Math#atan2}
1268      * specifications. The computed result will be within 1 ulp of the
1269      * exact result.
1270      *
1271      * @param s the input scalar
1272      * @return the arc tangent of this vector over the input vector
1273      */
1274     public abstract FloatVector atan2(float s);
1275 
1276     /**
1277      * Calculates the arc tangent of this vector divided by an input vector,
1278      * selecting lane elements controlled by a mask.
1279      * <p>
1280      * Semantics for rounding, monotonicity, and special cases are
1281      * described in {@link FloatVector#atan2}
1282      *
1283      * @param v the input vector
1284      * @param m the mask controlling lane selection
1285      * @return the arc tangent of this vector divided by the input vector
1286      */
1287     public FloatVector atan2(Vector<Float> v, Mask<Float> m) {
1288         return bOp(v, m, (i, a, b) -> (float) Math.atan2((double) a, (double) b));
1289     }
1290 
1291     /**
1292      * Calculates the arc tangent of this vector divided by the broadcast of an
1293      * an input scalar, selecting lane elements controlled by a mask.
1294      * <p>
1295      * Semantics for rounding, monotonicity, and special cases are
1296      * described in {@link FloatVector#atan2}
1297      *
1298      * @param s the input scalar
1299      * @param m the mask controlling lane selection
1300      * @return the arc tangent of this vector over the input vector
1301      */
1302     public abstract FloatVector atan2(float s, Mask<Float> m);
1303 
1304     /**
1305      * Calculates the cube root of this vector.
1306      * <p>
1307      * This is a vector unary operation with same semantic definition as
1308      * {@link Math#cbrt} operation applied to lane elements.
1309      * The implementation is not required to return same
1310      * results as {@link Math#cbrt}, but adheres to rounding, monotonicity,
1311      * and special case semantics as defined in the {@link Math#cbrt}
1312      * specifications. The computed result will be within 1 ulp of the
1313      * exact result.
1314      *
1315      * @return the cube root of this vector
1316      */
1317     public FloatVector cbrt() {
1318         return uOp((i, a) -> (float) Math.cbrt((double) a));
1319     }
1320 
1321     /**
1322      * Calculates the cube root of this vector, selecting lane elements
1323      * controlled by a mask.
1324      * <p>
1325      * Semantics for rounding, monotonicity, and special cases are
1326      * described in {@link FloatVector#cbrt}
1327      *
1328      * @param m the mask controlling lane selection
1329      * @return the cube root of this vector
1330      */
1331     public FloatVector cbrt(Mask<Float> m) {
1332         return uOp(m, (i, a) -> (float) Math.cbrt((double) a));
1333     }
1334 
1335     /**
1336      * Calculates the natural logarithm of this vector.
1337      * <p>
1338      * This is a vector unary operation with same semantic definition as
1339      * {@link Math#log} operation applied to lane elements.
1340      * The implementation is not required to return same
1341      * results as {@link Math#log}, but adheres to rounding, monotonicity,
1342      * and special case semantics as defined in the {@link Math#log}
1343      * specifications. The computed result will be within 1 ulp of the
1344      * exact result.
1345      *
1346      * @return the natural logarithm of this vector
1347      */
1348     public FloatVector log() {
1349         return uOp((i, a) -> (float) Math.log((double) a));
1350     }
1351 
1352     /**
1353      * Calculates the natural logarithm of this vector, selecting lane elements
1354      * controlled by a mask.
1355      * <p>
1356      * Semantics for rounding, monotonicity, and special cases are
1357      * described in {@link FloatVector#log}
1358      *
1359      * @param m the mask controlling lane selection
1360      * @return the natural logarithm of this vector
1361      */
1362     public FloatVector log(Mask<Float> m) {
1363         return uOp(m, (i, a) -> (float) Math.log((double) a));
1364     }
1365 
1366     /**
1367      * Calculates the base 10 logarithm of this vector.
1368      * <p>
1369      * This is a vector unary operation with same semantic definition as
1370      * {@link Math#log10} operation applied to lane elements.
1371      * The implementation is not required to return same
1372      * results as {@link Math#log10}, but adheres to rounding, monotonicity,
1373      * and special case semantics as defined in the {@link Math#log10}
1374      * specifications. The computed result will be within 1 ulp of the
1375      * exact result.
1376      *
1377      * @return the base 10 logarithm of this vector
1378      */
1379     public FloatVector log10() {
1380         return uOp((i, a) -> (float) Math.log10((double) a));
1381     }
1382 
1383     /**
1384      * Calculates the base 10 logarithm of this vector, selecting lane elements
1385      * controlled by a mask.
1386      * <p>
1387      * Semantics for rounding, monotonicity, and special cases are
1388      * described in {@link FloatVector#log10}
1389      *
1390      * @param m the mask controlling lane selection
1391      * @return the base 10 logarithm of this vector
1392      */
1393     public FloatVector log10(Mask<Float> m) {
1394         return uOp(m, (i, a) -> (float) Math.log10((double) a));
1395     }
1396 
1397     /**
1398      * Calculates the natural logarithm of the sum of this vector and the
1399      * broadcast of {@code 1}.
1400      * <p>
1401      * This is a vector unary operation with same semantic definition as
1402      * {@link Math#log1p} operation applied to lane elements.
1403      * The implementation is not required to return same
1404      * results as  {@link Math#log1p}, but adheres to rounding, monotonicity,
1405      * and special case semantics as defined in the {@link Math#log1p}
1406      * specifications. The computed result will be within 1 ulp of the
1407      * exact result.
1408      *
1409      * @return the natural logarithm of the sum of this vector and the broadcast
1410      * of {@code 1}
1411      */
1412     public FloatVector log1p() {
1413         return uOp((i, a) -> (float) Math.log1p((double) a));
1414     }
1415 
1416     /**
1417      * Calculates the natural logarithm of the sum of this vector and the
1418      * broadcast of {@code 1}, selecting lane elements controlled by a mask.
1419      * <p>
1420      * Semantics for rounding, monotonicity, and special cases are
1421      * described in {@link FloatVector#log1p}
1422      *
1423      * @param m the mask controlling lane selection
1424      * @return the natural logarithm of the sum of this vector and the broadcast
1425      * of {@code 1}
1426      */
1427     public FloatVector log1p(Mask<Float> m) {
1428         return uOp(m, (i, a) -> (float) Math.log1p((double) a));
1429     }
1430 
1431     /**
1432      * Calculates this vector raised to the power of an input vector.
1433      * <p>
1434      * This is a vector binary operation with same semantic definition as
1435      * {@link Math#pow} operation applied to lane elements.
1436      * The implementation is not required to return same
1437      * results as {@link Math#pow}, but adheres to rounding, monotonicity,
1438      * and special case semantics as defined in the {@link Math#pow}
1439      * specifications. The computed result will be within 1 ulp of the
1440      * exact result.
1441      *
1442      * @param v the input vector
1443      * @return this vector raised to the power of an input vector
1444      */
1445     public FloatVector pow(Vector<Float> v) {
1446         return bOp(v, (i, a, b) -> (float) Math.pow((double) a, (double) b));
1447     }
1448 
1449     /**
1450      * Calculates this vector raised to the power of the broadcast of an input
1451      * scalar.
1452      * <p>
1453      * This is a vector binary operation with same semantic definition as
1454      * {@link Math#pow} operation applied to lane elements.
1455      * The implementation is not required to return same
1456      * results as {@link Math#pow}, but adheres to rounding, monotonicity,
1457      * and special case semantics as defined in the {@link Math#pow}
1458      * specifications. The computed result will be within 1 ulp of the
1459      * exact result.
1460      *
1461      * @param s the input scalar
1462      * @return this vector raised to the power of the broadcast of an input
1463      * scalar.
1464      */
1465     public abstract FloatVector pow(float s);
1466 
1467     /**
1468      * Calculates this vector raised to the power of an input vector, selecting
1469      * lane elements controlled by a mask.
1470      * <p>
1471      * Semantics for rounding, monotonicity, and special cases are
1472      * described in {@link FloatVector#pow}
1473      *
1474      * @param v the input vector
1475      * @param m the mask controlling lane selection
1476      * @return this vector raised to the power of an input vector
1477      */
1478     public FloatVector pow(Vector<Float> v, Mask<Float> m) {
1479         return bOp(v, m, (i, a, b) -> (float) Math.pow((double) a, (double) b));
1480     }
1481 
1482     /**
1483      * Calculates this vector raised to the power of the broadcast of an input
1484      * scalar, selecting lane elements controlled by a mask.
1485      * <p>
1486      * Semantics for rounding, monotonicity, and special cases are
1487      * described in {@link FloatVector#pow}
1488      *
1489      * @param s the input scalar
1490      * @param m the mask controlling lane selection
1491      * @return this vector raised to the power of the broadcast of an input
1492      * scalar.
1493      */
1494     public abstract FloatVector pow(float s, Mask<Float> m);
1495 
1496     /**
1497      * Calculates the broadcast of Euler's number {@code e} raised to the power
1498      * of this vector.
1499      * <p>
1500      * This is a vector unary operation with same semantic definition as
1501      * {@link Math#exp} operation applied to lane elements.
1502      * The implementation is not required to return same
1503      * results as {@link Math#exp}, but adheres to rounding, monotonicity,
1504      * and special case semantics as defined in the {@link Math#exp}
1505      * specifications. The computed result will be within 1 ulp of the
1506      * exact result.
1507      *
1508      * @return the broadcast of Euler's number {@code e} raised to the power of
1509      * this vector
1510      */
1511     public FloatVector exp() {
1512         return uOp((i, a) -> (float) Math.exp((double) a));
1513     }
1514 
1515     /**
1516      * Calculates the broadcast of Euler's number {@code e} raised to the power
1517      * of this vector, selecting lane elements controlled by a mask.
1518      * <p>
1519      * Semantics for rounding, monotonicity, and special cases are
1520      * described in {@link FloatVector#exp}
1521      *
1522      * @param m the mask controlling lane selection
1523      * @return the broadcast of Euler's number {@code e} raised to the power of
1524      * this vector
1525      */
1526     public FloatVector exp(Mask<Float> m) {
1527         return uOp(m, (i, a) -> (float) Math.exp((double) a));
1528     }
1529 
1530     /**
1531      * Calculates the broadcast of Euler's number {@code e} raised to the power
1532      * of this vector minus the broadcast of {@code -1}.
1533      * More specifically as if the following (ignoring any differences in
1534      * numerical accuracy):
1535      * <pre>{@code
1536      *   this.exp().sub(this.species().broadcast(1))
1537      * }</pre>
1538      * <p>
1539      * This is a vector unary operation with same semantic definition as
1540      * {@link Math#expm1} operation applied to lane elements.
1541      * The implementation is not required to return same
1542      * results as {@link Math#expm1}, but adheres to rounding, monotonicity,
1543      * and special case semantics as defined in the {@link Math#expm1}
1544      * specifications. The computed result will be within 1 ulp of the
1545      * exact result.
1546      *
1547      * @return the broadcast of Euler's number {@code e} raised to the power of
1548      * this vector minus the broadcast of {@code -1}
1549      */
1550     public FloatVector expm1() {
1551         return uOp((i, a) -> (float) Math.expm1((double) a));
1552     }
1553 
1554     /**
1555      * Calculates the broadcast of Euler's number {@code e} raised to the power
1556      * of this vector minus the broadcast of {@code -1}, selecting lane elements
1557      * controlled by a mask
1558      * More specifically as if the following (ignoring any differences in
1559      * numerical accuracy):
1560      * <pre>{@code
1561      *   this.exp(m).sub(this.species().broadcast(1), m)
1562      * }</pre>
1563      * <p>
1564      * Semantics for rounding, monotonicity, and special cases are
1565      * described in {@link FloatVector#expm1}
1566      *
1567      * @param m the mask controlling lane selection
1568      * @return the broadcast of Euler's number {@code e} raised to the power of
1569      * this vector minus the broadcast of {@code -1}
1570      */
1571     public FloatVector expm1(Mask<Float> m) {
1572         return uOp(m, (i, a) -> (float) Math.expm1((double) a));
1573     }
1574 
1575     /**
1576      * Calculates the product of this vector and a first input vector summed
1577      * with a second input vector.
1578      * More specifically as if the following (ignoring any differences in
1579      * numerical accuracy):
1580      * <pre>{@code
1581      *   this.mul(v1).add(v2)
1582      * }</pre>
1583      * <p>
1584      * This is a vector ternary operation where the {@link Math#fma} operation
1585      * is applied to lane elements.
1586      *
1587      * @param v1 the first input vector
1588      * @param v2 the second input vector
1589      * @return the product of this vector and the first input vector summed with
1590      * the second input vector
1591      */
1592     public abstract FloatVector fma(Vector<Float> v1, Vector<Float> v2);
1593 
1594     /**
1595      * Calculates the product of this vector and the broadcast of a first input
1596      * scalar summed with the broadcast of a second input scalar.
1597      * More specifically as if the following:
1598      * <pre>{@code
1599      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2))
1600      * }</pre>
1601      * <p>
1602      * This is a vector ternary operation where the {@link Math#fma} operation
1603      * is applied to lane elements.
1604      *
1605      * @param s1 the first input scalar
1606      * @param s2 the second input scalar
1607      * @return the product of this vector and the broadcast of a first input
1608      * scalar summed with the broadcast of a second input scalar
1609      */
1610     public abstract FloatVector fma(float s1, float s2);
1611 
1612     /**
1613      * Calculates the product of this vector and a first input vector summed
1614      * with a second input vector, selecting lane elements controlled by a mask.
1615      * More specifically as if the following (ignoring any differences in
1616      * numerical accuracy):
1617      * <pre>{@code
1618      *   this.mul(v1, m).add(v2, m)
1619      * }</pre>
1620      * <p>
1621      * This is a vector ternary operation where the {@link Math#fma} operation
1622      * is applied to lane elements.
1623      *
1624      * @param v1 the first input vector
1625      * @param v2 the second input vector
1626      * @param m the mask controlling lane selection
1627      * @return the product of this vector and the first input vector summed with
1628      * the second input vector
1629      */
1630     public FloatVector fma(Vector<Float> v1, Vector<Float> v2, Mask<Float> m) {
1631         return tOp(v1, v2, m, (i, a, b, c) -> Math.fma(a, b, c));
1632     }
1633 
1634     /**
1635      * Calculates the product of this vector and the broadcast of a first input
1636      * scalar summed with the broadcast of a second input scalar, selecting lane
1637      * elements controlled by a mask
1638      * More specifically as if the following:
1639      * <pre>{@code
1640      *   this.fma(this.species().broadcast(s1), this.species().broadcast(s2), m)
1641      * }</pre>
1642      * <p>
1643      * This is a vector ternary operation where the {@link Math#fma} operation
1644      * is applied to lane elements.
1645      *
1646      * @param s1 the first input scalar
1647      * @param s2 the second input scalar
1648      * @param m the mask controlling lane selection
1649      * @return the product of this vector and the broadcast of a first input
1650      * scalar summed with the broadcast of a second input scalar
1651      */
1652     public abstract FloatVector fma(float s1, float s2, Mask<Float> m);
1653 
1654     /**
1655      * Calculates square root of the sum of the squares of this vector and an
1656      * input vector.
1657      * More specifically as if the following (ignoring any differences in
1658      * numerical accuracy):
1659      * <pre>{@code
1660      *   this.mul(this).add(v.mul(v)).sqrt()
1661      * }</pre>
1662      * <p>
1663      * This is a vector binary operation with same semantic definition as
1664      * {@link Math#hypot} operation applied to lane elements.
1665      * The implementation is not required to return same
1666      * results as {@link Math#hypot}, but adheres to rounding, monotonicity,
1667      * and special case semantics as defined in the {@link Math#hypot}
1668      * specifications. The computed result will be within 1 ulp of the
1669      * exact result.
1670      *
1671      * @param v the input vector
1672      * @return square root of the sum of the squares of this vector and an input
1673      * vector
1674      */
1675     public FloatVector hypot(Vector<Float> v) {
1676         return bOp(v, (i, a, b) -> (float) Math.hypot((double) a, (double) b));
1677     }
1678 
1679     /**
1680      * Calculates square root of the sum of the squares of this vector and the
1681      * broadcast of an input scalar.
1682      * More specifically as if the following (ignoring any differences in
1683      * numerical accuracy):
1684      * <pre>{@code
1685      *   this.mul(this).add(this.species().broadcast(v * v)).sqrt()
1686      * }</pre>
1687      * <p>
1688      * This is a vector binary operation with same semantic definition as
1689      * {@link Math#hypot} operation applied to lane elements.
1690      * The implementation is not required to return same
1691      * results as {@link Math#hypot}, but adheres to rounding, monotonicity,
1692      * and special case semantics as defined in the {@link Math#hypot}
1693      * specifications. The computed result will be within 1 ulp of the
1694      * exact result.
1695      *
1696      * @param s the input scalar
1697      * @return square root of the sum of the squares of this vector and the
1698      * broadcast of an input scalar
1699      */
1700     public abstract FloatVector hypot(float s);
1701 
1702     /**
1703      * Calculates square root of the sum of the squares of this vector and an
1704      * input vector, selecting lane elements controlled by a mask.
1705      * More specifically as if the following (ignoring any differences in
1706      * numerical accuracy):
1707      * <pre>{@code
1708      *   this.mul(this, m).add(v.mul(v), m).sqrt(m)
1709      * }</pre>
1710      * <p>
1711      * Semantics for rounding, monotonicity, and special cases are
1712      * described in {@link FloatVector#hypot}
1713      *
1714      * @param v the input vector
1715      * @param m the mask controlling lane selection
1716      * @return square root of the sum of the squares of this vector and an input
1717      * vector
1718      */
1719     public FloatVector hypot(Vector<Float> v, Mask<Float> m) {
1720         return bOp(v, m, (i, a, b) -> (float) Math.hypot((double) a, (double) b));
1721     }
1722 
1723     /**
1724      * Calculates square root of the sum of the squares of this vector and the
1725      * broadcast of an input scalar, selecting lane elements controlled by a
1726      * mask.
1727      * More specifically as if the following (ignoring any differences in
1728      * numerical accuracy):
1729      * <pre>{@code
1730      *   this.mul(this, m).add(this.species().broadcast(v * v), m).sqrt(m)
1731      * }</pre>
1732      * <p>
1733      * Semantics for rounding, monotonicity, and special cases are
1734      * described in {@link FloatVector#hypot}
1735      *
1736      * @param s the input scalar
1737      * @param m the mask controlling lane selection
1738      * @return square root of the sum of the squares of this vector and the
1739      * broadcast of an input scalar
1740      */
1741     public abstract FloatVector hypot(float s, Mask<Float> m);
1742 
1743 
1744     @Override
1745     public abstract void intoByteArray(byte[] a, int ix);
1746 
1747     @Override
1748     public abstract void intoByteArray(byte[] a, int ix, Mask<Float> m);
1749 
1750     @Override
1751     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1752 
1753     @Override
1754     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Float> m);
1755 
1756 
1757     // Type specific horizontal reductions
1758     /**
1759      * Adds all lane elements of this vector.
1760      * <p>
1761      * This is a vector reduction operation where the addition
1762      * operation ({@code +}) is applied to lane elements,
1763      * and the identity value is {@code 0.0}.
1764      *
1765      * <p>The value of a floating-point sum is a function both of the input values as well
1766      * as the order of addition operations. The order of addition operations of this method
1767      * is intentionally not defined to allow for JVM to generate optimal machine
1768      * code for the underlying platform at runtime. If the platform supports a vector
1769      * instruction to add all values in the vector, or if there is some other efficient machine
1770      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1771      * the default implementation of adding vectors sequentially from left to right is used.
1772      * For this reason, the output of this method may vary for the same input values.
1773      *
1774      * @return the addition of all the lane elements of this vector
1775      */
1776     public abstract float addAll();
1777 
1778     /**
1779      * Adds all lane elements of this vector, selecting lane elements
1780      * controlled by a mask.
1781      * <p>
1782      * This is a vector reduction operation where the addition
1783      * operation ({@code +}) is applied to lane elements,
1784      * and the identity value is {@code 0.0}.
1785      *
1786      * <p>The value of a floating-point sum is a function both of the input values as well
1787      * as the order of addition operations. The order of addition operations of this method
1788      * is intentionally not defined to allow for JVM to generate optimal machine
1789      * code for the underlying platform at runtime. If the platform supports a vector
1790      * instruction to add all values in the vector, or if there is some other efficient machine
1791      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1792      * the default implementation of adding vectors sequentially from left to right is used.
1793      * For this reason, the output of this method may vary on the same input values.
1794      *
1795      * @param m the mask controlling lane selection
1796      * @return the addition of the selected lane elements of this vector
1797      */
1798     public abstract float addAll(Mask<Float> m);
1799 
1800     /**
1801      * Multiplies all lane elements of this vector.
1802      * <p>
1803      * This is a vector reduction operation where the
1804      * multiplication operation ({@code *}) is applied to lane elements,
1805      * and the identity value is {@code 1.0}.
1806      *
1807      * <p>The order of multiplication operations of this method
1808      * is intentionally not defined to allow for JVM to generate optimal machine
1809      * code for the underlying platform at runtime. If the platform supports a vector
1810      * instruction to multiply all values in the vector, or if there is some other efficient machine
1811      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1812      * the default implementation of multiplying vectors sequentially from left to right is used.
1813      * For this reason, the output of this method may vary on the same input values.
1814      *
1815      * @return the multiplication of all the lane elements of this vector
1816      */
1817     public abstract float mulAll();
1818 
1819     /**
1820      * Multiplies all lane elements of this vector, selecting lane elements
1821      * controlled by a mask.
1822      * <p>
1823      * This is a vector reduction operation where the
1824      * multiplication operation ({@code *}) is applied to lane elements,
1825      * and the identity value is {@code 1.0}.
1826      *
1827      * <p>The order of multiplication operations of this method
1828      * is intentionally not defined to allow for JVM to generate optimal machine
1829      * code for the underlying platform at runtime. If the platform supports a vector
1830      * instruction to multiply all values in the vector, or if there is some other efficient machine
1831      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1832      * the default implementation of multiplying vectors sequentially from left to right is used.
1833      * For this reason, the output of this method may vary on the same input values.
1834      *
1835      * @param m the mask controlling lane selection
1836      * @return the multiplication of all the lane elements of this vector
1837      */
1838     public abstract float mulAll(Mask<Float> m);
1839 
1840     /**
1841      * Returns the minimum lane element of this vector.
1842      * <p>
1843      * This is an associative vector reduction operation where the operation
1844      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1845      * and the identity value is
1846      * {@link Float#POSITIVE_INFINITY}.
1847      *
1848      * @return the minimum lane element of this vector
1849      */
1850     public abstract float minAll();
1851 
1852     /**
1853      * Returns the minimum lane element of this vector, selecting lane elements
1854      * controlled by a mask.
1855      * <p>
1856      * This is an associative vector reduction operation where the operation
1857      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1858      * and the identity value is
1859      * {@link Float#POSITIVE_INFINITY}.
1860      *
1861      * @param m the mask controlling lane selection
1862      * @return the minimum lane element of this vector
1863      */
1864     public abstract float minAll(Mask<Float> m);
1865 
1866     /**
1867      * Returns the maximum lane element of this vector.
1868      * <p>
1869      * This is an associative vector reduction operation where the operation
1870      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1871      * and the identity value is
1872      * {@link Float#NEGATIVE_INFINITY}.
1873      *
1874      * @return the maximum lane element of this vector
1875      */
1876     public abstract float maxAll();
1877 
1878     /**
1879      * Returns the maximum lane element of this vector, selecting lane elements
1880      * controlled by a mask.
1881      * <p>
1882      * This is an associative vector reduction operation where the operation
1883      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1884      * and the identity value is
1885      * {@link Float#NEGATIVE_INFINITY}.
1886      *
1887      * @param m the mask controlling lane selection
1888      * @return the maximum lane element of this vector
1889      */
1890     public abstract float maxAll(Mask<Float> m);
1891 
1892 
1893     // Type specific accessors
1894 
1895     /**
1896      * Gets the lane element at lane index {@code i}
1897      *
1898      * @param i the lane index
1899      * @return the lane element at lane index {@code i}
1900      * @throws IllegalArgumentException if the index is is out of range
1901      * ({@code < 0 || >= length()})
1902      */
1903     public abstract float get(int i);
1904 
1905     /**
1906      * Replaces the lane element of this vector at lane index {@code i} with
1907      * value {@code e}.
1908      * <p>
1909      * This is a cross-lane operation and behaves as if it returns the result
1910      * of blending this vector with an input vector that is the result of
1911      * broadcasting {@code e} and a mask that has only one lane set at lane
1912      * index {@code i}.
1913      *
1914      * @param i the lane index of the lane element to be replaced
1915      * @param e the value to be placed
1916      * @return the result of replacing the lane element of this vector at lane
1917      * index {@code i} with value {@code e}.
1918      * @throws IllegalArgumentException if the index is is out of range
1919      * ({@code < 0 || >= length()})
1920      */
1921     public abstract FloatVector with(int i, float e);
1922 
1923     // Type specific extractors
1924 
1925     /**
1926      * Returns an array containing the lane elements of this vector.
1927      * <p>
1928      * This method behaves as if it {@link #intoArray(float[], int)} stores}
1929      * this vector into an allocated array and returns the array as follows:
1930      * <pre>{@code
1931      *   float[] a = new float[this.length()];
1932      *   this.intoArray(a, 0);
1933      *   return a;
1934      * }</pre>
1935      *
1936      * @return an array containing the the lane elements of this vector
1937      */
1938     @ForceInline
1939     public final float[] toArray() {
1940         float[] a = new float[species().length()];
1941         intoArray(a, 0);
1942         return a;
1943     }
1944 
1945     /**
1946      * Stores this vector into an array starting at offset.
1947      * <p>
1948      * For each vector lane, where {@code N} is the vector lane index,
1949      * the lane element at index {@code N} is stored into the array at index
1950      * {@code i + N}.
1951      *
1952      * @param a the array
1953      * @param i the offset into the array
1954      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1955      * {@code i > a.length - this.length()}
1956      */
1957     public abstract void intoArray(float[] a, int i);
1958 
1959     /**
1960      * Stores this vector into an array starting at offset and using a mask.
1961      * <p>
1962      * For each vector lane, where {@code N} is the vector lane index,
1963      * if the mask lane at index {@code N} is set then the lane element at
1964      * index {@code N} is stored into the array index {@code i + N}.
1965      *
1966      * @param a the array
1967      * @param i the offset into the array
1968      * @param m the mask
1969      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1970      * for any vector lane index {@code N} where the mask at lane {@code N}
1971      * is set {@code i >= a.length - N}
1972      */
1973     public abstract void intoArray(float[] a, int i, Mask<Float> m);
1974 
1975     /**
1976      * Stores this vector into an array using indexes obtained from an index
1977      * map.
1978      * <p>
1979      * For each vector lane, where {@code N} is the vector lane index, the
1980      * lane element at index {@code N} is stored into the array at index
1981      * {@code i + indexMap[j + N]}.
1982      *
1983      * @param a the array
1984      * @param i the offset into the array, may be negative if relative
1985      * indexes in the index map compensate to produce a value within the
1986      * array bounds
1987      * @param indexMap the index map
1988      * @param j the offset into the index map
1989      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1990      * {@code j > indexMap.length - this.length()},
1991      * or for any vector lane index {@code N} the result of
1992      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1993      */
1994     public abstract void intoArray(float[] a, int i, int[] indexMap, int j);
1995 
1996     /**
1997      * Stores this vector into an array using indexes obtained from an index
1998      * map and using a mask.
1999      * <p>
2000      * For each vector lane, where {@code N} is the vector lane index,
2001      * if the mask lane at index {@code N} is set then the lane element at
2002      * index {@code N} is stored into the array at index
2003      * {@code i + indexMap[j + N]}.
2004      *
2005      * @param a the array
2006      * @param i the offset into the array, may be negative if relative
2007      * indexes in the index map compensate to produce a value within the
2008      * array bounds
2009      * @param m the mask
2010      * @param indexMap the index map
2011      * @param j the offset into the index map
2012      * @throws IndexOutOfBoundsException if {@code j < 0}, or
2013      * {@code j > indexMap.length - this.length()},
2014      * or for any vector lane index {@code N} where the mask at lane
2015      * {@code N} is set the result of {@code i + indexMap[j + N]} is
2016      * {@code < 0} or {@code >= a.length}
2017      */
2018     public abstract void intoArray(float[] a, int i, Mask<Float> m, int[] indexMap, int j);
2019     // Species
2020 
2021     @Override
2022     public abstract FloatSpecies species();
2023 
2024     /**
2025      * Class representing {@link FloatVector}'s of the same {@link Vector.Shape Shape}.
2026      */
2027     public static abstract class FloatSpecies extends Vector.Species<Float> {
2028         interface FOp {
2029             float apply(int i);
2030         }
2031 
2032         abstract FloatVector op(FOp f);
2033 
2034         abstract FloatVector op(Mask<Float> m, FOp f);
2035 
2036         interface FOpm {
2037             boolean apply(int i);
2038         }
2039 
2040         abstract Mask<Float> opm(FOpm f);
2041 
2042         abstract IntVector.IntSpecies indexSpecies();
2043 
2044 
2045         // Factories
2046 
2047         @Override
2048         public abstract FloatVector zero();
2049 
2050         /**
2051          * Returns a vector where all lane elements are set to the primitive
2052          * value {@code e}.
2053          *
2054          * @param e the value
2055          * @return a vector of vector where all lane elements are set to
2056          * the primitive value {@code e}
2057          */
2058         public abstract FloatVector broadcast(float e);
2059 
2060         /**
2061          * Returns a vector where the first lane element is set to the primtive
2062          * value {@code e}, all other lane elements are set to the default
2063          * value.
2064          *
2065          * @param e the value
2066          * @return a vector where the first lane element is set to the primitive
2067          * value {@code e}
2068          */
2069         @ForceInline
2070         public final FloatVector single(float e) {
2071             return zero().with(0, e);
2072         }
2073 
2074         /**
2075          * Returns a vector where each lane element is set to a randomly
2076          * generated primitive value.
2077          *
2078          * The semantics are equivalent to calling
2079          * {@code ThreadLocalRandom#nextFloat}.
2080          *
2081          * @return a vector where each lane elements is set to a randomly
2082          * generated primitive value
2083          */
2084         public FloatVector random() {
2085             ThreadLocalRandom r = ThreadLocalRandom.current();
2086             return op(i -> r.nextFloat());
2087         }
2088 
2089         /**
2090          * Returns a vector where each lane element is set to a given
2091          * primitive value.
2092          * <p>
2093          * For each vector lane, where {@code N} is the vector lane index, the
2094          * the primitive value at index {@code N} is placed into the resulting
2095          * vector at lane index {@code N}.
2096          *
2097          * @param es the given primitive values
2098          * @return a vector where each lane element is set to a given primitive
2099          * value
2100          * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
2101          */
2102         public abstract FloatVector scalars(float... es);
2103     }
2104 
2105     /**
2106      * Finds the preferred species for an element type of {@code float}.
2107      * <p>
2108      * A preferred species is a species chosen by the platform that has a
2109      * shape of maximal bit size.  A preferred species for different element
2110      * types will have the same shape, and therefore vectors, masks, and
2111      * shuffles created from such species will be shape compatible.
2112      *
2113      * @return the preferred species for an element type of {@code float}
2114      */
2115     @SuppressWarnings("unchecked")
2116     public static FloatSpecies preferredSpecies() {
2117         return (FloatSpecies) Species.ofPreferred(float.class);
2118     }
2119 
2120     /**
2121      * Finds a species for an element type of {@code float} and shape.
2122      *
2123      * @param s the shape
2124      * @return a species for an element type of {@code float} and shape
2125      * @throws IllegalArgumentException if no such species exists for the shape
2126      */
2127     @SuppressWarnings("unchecked")
2128     public static FloatSpecies species(Vector.Shape s) {
2129         Objects.requireNonNull(s);
2130         switch (s) {
2131             case S_64_BIT: return Float64Vector.SPECIES;
2132             case S_128_BIT: return Float128Vector.SPECIES;
2133             case S_256_BIT: return Float256Vector.SPECIES;
2134             case S_512_BIT: return Float512Vector.SPECIES;
2135             case S_Max_BIT: return FloatMaxVector.SPECIES;
2136             default: throw new IllegalArgumentException("Bad shape: " + s);
2137         }
2138     }
2139 }