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