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