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