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