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