1 /* 2 * Copyright (c) 2017, 2022, 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 any 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import jdk.incubator.foreign.MemorySegment; 28 29 import java.nio.ByteOrder; 30 import java.util.function.IntUnaryOperator; 31 32 /** 33 * Interface for managing all vectors of the same combination 34 * of <a href="Vector.html#ETYPE">element type</a> ({@code ETYPE}) 35 * and {@link VectorShape shape}. 36 * 37 * @apiNote 38 * User code should not implement this interface. A future release of 39 * this type may restrict implementations to be members of the same 40 * package. 41 * 42 * @implNote 43 * The string representation of an instance of this interface will 44 * be of the form "Species[ETYPE, VLENGTH, SHAPE]", where {@code 45 * ETYPE} is the primitive {@linkplain #elementType() lane type}, 46 * {@code VLENGTH} is the {@linkplain #length() vector lane count} 47 * associated with the species, and {@code SHAPE} is the {@linkplain 48 * #vectorShape() vector shape} associated with the species. 49 * 50 * <p>Vector species objects can be stored in locals and parameters and as 51 * {@code static final} constants, but storing them in other Java 52 * fields or in array elements, while semantically valid, may incur 53 * performance penalties. 54 * 55 * @param <E> the boxed version of {@code ETYPE}, 56 * the element type of a vector 57 */ 58 public interface VectorSpecies<E> { 59 /** 60 * Returns the primitive element type of vectors of this 61 * species. 62 * 63 * @return the primitive element type ({@code ETYPE}) 64 * @see Class#arrayType() 65 */ 66 Class<E> elementType(); 67 68 /** 69 * Returns the vector type of this species. 70 * A vector is of this species if and only if 71 * it is of the corresponding vector type. 72 * 73 * @return the vector type of this species 74 */ 75 Class<? extends Vector<E>> vectorType(); 76 77 /** 78 * Returns the vector mask type for this species. 79 * 80 * @return the mask type 81 */ 82 Class<? extends VectorMask<E>> maskType(); 83 84 /** 85 * Returns the lane size, in bits, of vectors of this 86 * species. 87 * 88 * @return the element size, in bits 89 */ 90 int elementSize(); 91 92 /** 93 * Returns the shape of vectors produced by this 94 * species. 95 * 96 * @return the shape of any vectors of this species 97 */ 98 VectorShape vectorShape(); 99 100 /** 101 * Returns the number of lanes in a vector of this species. 102 * 103 * @apiNote This is also the number of lanes in a mask or 104 * shuffle associated with a vector of this species. 105 * 106 * @return the number of vector lanes 107 */ 108 int length(); 109 110 /** 111 * Returns the total vector size, in bits, of any vector 112 * of this species. 113 * This is the same value as {@code this.vectorShape().vectorBitSize()}. 114 * 115 * @apiNote This size may be distinct from the size in bits 116 * of a mask or shuffle of this species. 117 * 118 * @return the total vector size, in bits 119 */ 120 int vectorBitSize(); 121 122 /** 123 * Returns the total vector size, in bytes, of any vector 124 * of this species. 125 * This is the same value as {@code this.vectorShape().vectorBitSize() / Byte.SIZE}. 126 * 127 * @apiNote This size may be distinct from the size in bits 128 * of a mask or shuffle of this species. 129 * 130 * @return the total vector size, in bytes 131 */ 132 int vectorByteSize(); 133 134 /** 135 * Loop control function which returns the largest multiple of 136 * {@code VLENGTH} that is less than or equal to the given 137 * {@code length} value. 138 * Here, {@code VLENGTH} is the result of {@code this.length()}, 139 * and {@code length} is interpreted as a number of lanes. 140 * The resulting value {@code R} satisfies this inequality: 141 * <pre>{@code R <= length < R+VLENGTH} 142 * </pre> 143 * <p> Specifically, this method computes 144 * {@code length - floorMod(length, VLENGTH)}, where 145 * {@link Math#floorMod(int,int) floorMod} computes a remainder 146 * value by rounding its quotient toward negative infinity. 147 * As long as {@code VLENGTH} is a power of two, then the result 148 * is also equal to {@code length & ~(VLENGTH - 1)}. 149 * 150 * @param length the input length 151 * @return the largest multiple of the vector length not greater 152 * than the given length 153 * @throws IllegalArgumentException if the {@code length} is 154 * negative and the result would overflow to a positive value 155 * @see Math#floorMod(int, int) 156 */ 157 int loopBound(int length); 158 159 /** 160 * Loop control function which returns the largest multiple of 161 * {@code VLENGTH} that is less than or equal to the given 162 * {@code length} value. 163 * Here, {@code VLENGTH} is the result of {@code this.length()}, 164 * and {@code length} is interpreted as a number of lanes. 165 * The resulting value {@code R} satisfies this inequality: 166 * <pre>{@code R <= length < R+VLENGTH} 167 * </pre> 168 * <p> Specifically, this method computes 169 * {@code length - floorMod(length, VLENGTH)}, where 170 * {@link Math#floorMod(long,int) floorMod} computes a remainder 171 * value by rounding its quotient toward negative infinity. 172 * As long as {@code VLENGTH} is a power of two, then the result 173 * is also equal to {@code length & ~(VLENGTH - 1)}. 174 * 175 * @param length the input length 176 * @return the largest multiple of the vector length not greater 177 * than the given length 178 * @throws IllegalArgumentException if the {@code length} is 179 * negative and the result would overflow to a positive value 180 * @see Math#floorMod(long, int) 181 * @since 19 182 */ 183 long loopBound(long length); 184 185 /** 186 * Returns a mask of this species where only 187 * the lanes at index N such that the adjusted index 188 * {@code N+offset} is in the range {@code [0..limit-1]} 189 * are set. 190 * 191 * <p> 192 * This method returns the value of the expression 193 * {@code maskAll(true).indexInRange(offset, limit)} 194 * 195 * @param offset the starting index 196 * @param limit the upper-bound (exclusive) of index range 197 * @return a mask with out-of-range lanes unset 198 * @see VectorMask#indexInRange(int, int) 199 */ 200 VectorMask<E> indexInRange(int offset, int limit); 201 202 /** 203 * Returns a mask of this species where only 204 * the lanes at index N such that the adjusted index 205 * {@code N+offset} is in the range {@code [0..limit-1]} 206 * are set. 207 * 208 * <p> 209 * This method returns the value of the expression 210 * {@code maskAll(true).indexInRange(offset, limit)} 211 * 212 * @param offset the starting index 213 * @param limit the upper-bound (exclusive) of index range 214 * @return a mask with out-of-range lanes unset 215 * @see VectorMask#indexInRange(long, long) 216 * @since 19 217 */ 218 VectorMask<E> indexInRange(long offset, long limit); 219 220 /** 221 * Checks that this species has the given element type, 222 * and returns this species unchanged. 223 * The effect is similar to this pseudocode: 224 * {@code elementType == elementType() 225 * ? this 226 * : throw new ClassCastException()}. 227 * 228 * @param elementType the required lane type 229 * @param <F> the boxed element type of the required lane type 230 * @return the same species 231 * @throws ClassCastException if the species has the wrong element type 232 * @see Vector#check(Class) 233 * @see Vector#check(VectorSpecies) 234 */ 235 <F> VectorSpecies<F> check(Class<F> elementType); 236 237 /** 238 * Given this species and a second one, reports the net 239 * expansion or contraction of a (potentially) resizing 240 * {@linkplain Vector#reinterpretShape(VectorSpecies,int) reinterpretation cast} 241 * or 242 * {@link Vector#convertShape(VectorOperators.Conversion,VectorSpecies,int) lane-wise conversion} 243 * from this species to the second. 244 * 245 * The sign and magnitude of the return value depends on the size 246 * difference between the proposed input and output 247 * <em>shapes</em>, and (optionally, if {@code lanewise} is true) 248 * also on the size difference between the proposed input and 249 * output <em>lanes</em>. 250 * 251 * <ul> 252 * <li> First, a logical result size is determined. 253 * 254 * If {@code lanewise} is false, this size that of the input 255 * {@code VSHAPE}. If {@code lanewise} is true, the logical 256 * result size is the product of the input {@code VLENGTH} 257 * times the size of the <em>output</em> {@code ETYPE}. 258 * 259 * <li> Next, the logical result size is compared against 260 * the size of the proposed output shape, to see how it 261 * will fit. 262 * 263 * <li> If the logical result fits precisely in the 264 * output shape, the return value is zero, signifying 265 * no net expansion or contraction. 266 * 267 * <li> If the logical result would overflow the output shape, the 268 * return value is the ratio (greater than one) of the logical 269 * result size to the (smaller) output size. This ratio can be 270 * viewed as measuring the proportion of "dropped input bits" 271 * which must be deleted from the input in order for the result to 272 * fit in the output vector. It is also the <em>part limit</em>, 273 * a upper exclusive limit on the {@code part} parameter to a 274 * method that would transform the input species to the output 275 * species. 276 * 277 * <li> If the logical result would drop into the output shape 278 * with room to spare, the return value is a negative number whose 279 * absolute value the ratio (greater than one) between the output 280 * size and the (smaller) logical result size. This ratio can be 281 * viewed as measuring the proportion of "extra padding bits" 282 * which must be added to the logical result to fill up the output 283 * vector. It is also the <em>part limit</em>, an exclusive lower 284 * limit on the {@code part} parameter to a method that would 285 * transform the input species to the output species. 286 * 287 * </ul> 288 * 289 * @param outputSpecies the proposed output species 290 * @param lanewise whether to take lane sizes into account 291 * @return an indication of the size change, as a signed ratio or zero 292 * 293 * @see Vector#reinterpretShape(VectorSpecies,int) 294 * @see Vector#convertShape(VectorOperators.Conversion,VectorSpecies,int) 295 */ 296 int partLimit(VectorSpecies<?> outputSpecies, boolean lanewise); 297 298 // Factories 299 300 /** 301 * Finds a species with the given element type and the 302 * same shape as this species. 303 * Returns the same value as 304 * {@code VectorSpecies.of(newType, this.vectorShape())}. 305 * 306 * @param newType the new element type 307 * @param <F> the boxed element type 308 * @return a species for the new element type and the same shape 309 * @throws IllegalArgumentException if no such species exists for the 310 * given combination of element type and shape 311 * or if the given type is not a valid {@code ETYPE} 312 * @see #withShape(VectorShape) 313 * @see VectorSpecies#of(Class, VectorShape) 314 */ 315 <F> VectorSpecies<F> withLanes(Class<F> newType); 316 317 /** 318 * Finds a species with the given shape and the same 319 * elementType as this species. 320 * Returns the same value as 321 * {@code VectorSpecies.of(this.elementType(), newShape)}. 322 * 323 * @param newShape the new shape 324 * @return a species for the same element type and the new shape 325 * @throws IllegalArgumentException if no such species exists for the 326 * given combination of element type and shape 327 * @see #withLanes(Class) 328 * @see VectorSpecies#of(Class, VectorShape) 329 */ 330 VectorSpecies<E> withShape(VectorShape newShape); 331 332 /** 333 * Finds a species for an element type and shape. 334 * 335 * @param elementType the element type 336 * @param shape the shape 337 * @param <E> the boxed element type 338 * @return a species for the given element type and shape 339 * @throws IllegalArgumentException if no such species exists for the 340 * given combination of element type and shape 341 * or if the given type is not a valid {@code ETYPE} 342 * @see #withLanes(Class) 343 * @see #withShape(VectorShape) 344 */ 345 static <E> VectorSpecies<E> of(Class<E> elementType, VectorShape shape) { 346 LaneType laneType = LaneType.of(elementType); 347 return AbstractSpecies.findSpecies(elementType, laneType, shape); 348 } 349 350 /** 351 * Finds the largest vector species of the given element type. 352 * <p> 353 * The returned species is a species chosen by the platform that has a 354 * shape with the largest possible bit-size for the given element type. 355 * The underlying vector shape might not support other lane types 356 * on some platforms, which may limit the applicability of 357 * {@linkplain Vector#reinterpretShape(VectorSpecies,int) reinterpretation casts}. 358 * Vector algorithms which require reinterpretation casts will 359 * be more portable if they use the platform's 360 * {@linkplain #ofPreferred(Class) preferred species}. 361 * 362 * @param etype the element type 363 * @param <E> the boxed element type 364 * @return a preferred species for an element type 365 * @throws IllegalArgumentException if no such species exists for the 366 * element type 367 * or if the given type is not a valid {@code ETYPE} 368 * @see VectorSpecies#ofPreferred(Class) 369 */ 370 static <E> VectorSpecies<E> ofLargestShape(Class<E> etype) { 371 return VectorSpecies.of(etype, VectorShape.largestShapeFor(etype)); 372 } 373 374 /** 375 * Finds the species preferred by the current platform 376 * for a given vector element type. 377 * This is the same value as 378 * {@code VectorSpecies.of(etype, VectorShape.preferredShape())}. 379 * 380 * <p> This species is chosen by the platform so that it has the 381 * largest possible shape that supports all lane element types. 382 * This has the following implications: 383 * <ul> 384 * <li>The various preferred species for different element types 385 * will have the same underlying shape. 386 * <li>All vectors created from preferred species will have a 387 * common bit-size and information capacity. 388 * <li>{@linkplain Vector#reinterpretShape(VectorSpecies, int) Reinterpretation casts} 389 * between vectors of preferred species will neither truncate 390 * lanes nor fill them with default values. 391 * <li>For any particular element type, some platform might possibly 392 * provide a {@linkplain #ofLargestShape(Class) larger vector shape} 393 * that (as a trade-off) does not support all possible element types. 394 * </ul> 395 * 396 * @implNote On many platforms there is no behavioral difference 397 * between {@link #ofLargestShape(Class) ofLargestShape} and 398 * {@code ofPreferred}, because the preferred shape is usually 399 * also the largest available shape for every lane type. 400 * Therefore, most vector algorithms will perform well without 401 * {@code ofLargestShape}. 402 * 403 * @param etype the element type 404 * @param <E> the boxed element type 405 * @return a preferred species for this element type 406 * @throws IllegalArgumentException if no such species exists for the 407 * element type 408 * or if the given type is not a valid {@code ETYPE} 409 * @see Vector#reinterpretShape(VectorSpecies,int) 410 * @see VectorShape#preferredShape() 411 * @see VectorSpecies#ofLargestShape(Class) 412 */ 413 public static <E> VectorSpecies<E> ofPreferred(Class<E> etype) { 414 return of(etype, VectorShape.preferredShape()); 415 } 416 417 /** 418 * Returns the bit-size of the given vector element type ({@code ETYPE}). 419 * The element type must be a valid {@code ETYPE}, not a 420 * wrapper type or other object type. 421 * 422 * The element type argument must be a mirror for a valid vector 423 * {@code ETYPE}, such as {@code byte.class}, {@code int.class}, 424 * or {@code double.class}. The bit-size of such a type is the 425 * {@code SIZE} constant for the corresponding wrapper class, such 426 * as {@code Byte.SIZE}, or {@code Integer.SIZE}, or 427 * {@code Double.SIZE}. 428 * 429 * @param elementType a vector element type (an {@code ETYPE}) 430 * @return the bit-size of {@code elementType}, such as 32 for {@code int.class} 431 * @throws IllegalArgumentException 432 * if the given {@code elementType} argument is not 433 * a valid vector {@code ETYPE} 434 */ 435 static int elementSize(Class<?> elementType) { 436 return LaneType.of(elementType).elementSize; 437 } 438 439 /// Convenience factories: 440 441 /** 442 * Returns a vector of this species 443 * where all lane elements are set to 444 * the default primitive value, {@code (ETYPE)0}. 445 * 446 * Equivalent to {@code IntVector.zero(this)} 447 * or an equivalent {@code zero} method, 448 * on the vector type corresponding to 449 * this species. 450 * 451 * @return a zero vector of the given species 452 * @see IntVector#zero(VectorSpecies) 453 * @see FloatVector#zero(VectorSpecies) 454 */ 455 Vector<E> zero(); 456 457 /** 458 * Returns a vector of this species 459 * where lane elements are initialized 460 * from the given array at the given offset. 461 * The array must be of the the correct {@code ETYPE}. 462 * 463 * Equivalent to 464 * {@code IntVector.fromArray(this,a,offset)} 465 * or an equivalent {@code fromArray} method, 466 * on the vector type corresponding to 467 * this species. 468 * 469 * @param a an array of the {@code ETYPE} for this species 470 * @param offset the index of the first lane value to load 471 * @return a vector of the given species filled from the array 472 * @throws IndexOutOfBoundsException 473 * if {@code offset+N < 0} or {@code offset+N >= a.length} 474 * for any lane {@code N} in the vector 475 * @see IntVector#fromArray(VectorSpecies,int[],int) 476 * @see FloatVector#fromArray(VectorSpecies,float[],int) 477 */ 478 Vector<E> fromArray(Object a, int offset); 479 // Defined when ETYPE is known. 480 481 /** 482 * Loads a vector of this species from a {@linkplain MemorySegment memory segment} 483 * starting at an offset into the memory segment. 484 * Bytes are composed into primitive lane elements according 485 * to the specified byte order. 486 * The vector is arranged into lanes according to 487 * <a href="Vector.html#lane-order">memory ordering</a>. 488 * <p> 489 * Equivalent to 490 * {@code IntVector.fromMemorySegment(this,ms,offset,bo)}, 491 * on the vector type corresponding to 492 * this species. 493 * 494 * @param ms the memory segment 495 * @param offset the offset into the memory segment 496 * @param bo the intended byte order 497 * @return a vector of the given species filled from the memory segment 498 * @throws IndexOutOfBoundsException 499 * if {@code offset+N*ESIZE < 0} 500 * or {@code offset+(N+1)*ESIZE > a.length} 501 * for any lane {@code N} in the vector 502 * @see IntVector#fromMemorySegment(VectorSpecies, jdk.incubator.foreign.MemorySegment, long, java.nio.ByteOrder) 503 * @see FloatVector#fromMemorySegment(VectorSpecies, jdk.incubator.foreign.MemorySegment, long, java.nio.ByteOrder) 504 * @since 19 505 */ 506 Vector<E> fromMemorySegment(MemorySegment ms, long offset, ByteOrder bo); 507 508 /** 509 * Returns a mask of this species 510 * where lane elements are initialized 511 * from the given array at the given offset. 512 * 513 * Equivalent to 514 * {@code VectorMask.fromArray(this,a,offset)}. 515 * 516 * @param bits the {@code boolean} array 517 * @param offset the offset into the array 518 * @return the mask loaded from the {@code boolean} array 519 * @throws IndexOutOfBoundsException 520 * if {@code offset+N < 0} or {@code offset+N >= a.length} 521 * for any lane {@code N} in the vector mask 522 * @see VectorMask#fromArray(VectorSpecies,boolean[],int) 523 */ 524 VectorMask<E> loadMask(boolean[] bits, int offset); 525 526 /** 527 * Returns a mask of this species, 528 * where each lane is set or unset according to given 529 * single boolean, which is broadcast to all lanes. 530 * 531 * @param bit the given mask bit to be replicated 532 * @return a mask where each lane is set or unset according to 533 * the given bit 534 * @see Vector#maskAll(boolean) 535 */ 536 VectorMask<E> maskAll(boolean bit); 537 538 /** 539 * Returns a vector of the given species 540 * where all lane elements are set to 541 * the primitive value {@code e}. 542 * 543 * <p> This method returns the value of this expression: 544 * {@code EVector.broadcast(this, (ETYPE)e)}, where 545 * {@code EVector} is the vector class specific to the 546 * the {@code ETYPE} of this species. 547 * The {@code long} value must be accurately representable 548 * by {@code ETYPE}, so that {@code e==(long)(ETYPE)e}. 549 * 550 * @param e the value to broadcast 551 * @return a vector where all lane elements are set to 552 * the primitive value {@code e} 553 * @throws IllegalArgumentException 554 * if the given {@code long} value cannot 555 * be represented by the vector species {@code ETYPE} 556 * @see Vector#broadcast(long) 557 * @see #checkValue(long) 558 */ 559 Vector<E> broadcast(long e); 560 561 /** 562 * Checks that this species can represent the given element value, 563 * and returns the value unchanged. 564 * 565 * The {@code long} value must be accurately representable 566 * by the {@code ETYPE} of the vector species, so that 567 * {@code e==(long)(ETYPE)e}. 568 * 569 * The effect is similar to this pseudocode: 570 * {@code e == (long)(ETYPE)e 571 * ? e 572 * : throw new IllegalArgumentException()}. 573 * 574 * @param e the value to be checked 575 * @return {@code e} 576 * @throws IllegalArgumentException 577 * if the given {@code long} value cannot 578 * be represented by the vector species {@code ETYPE} 579 * @see #broadcast(long) 580 */ 581 long checkValue(long e); 582 583 /** 584 * Creates a shuffle for this species from 585 * a series of source indexes. 586 * 587 * <p> For each shuffle lane, where {@code N} is the shuffle lane 588 * index, the {@code N}th index value is validated 589 * against the species {@code VLENGTH}, and (if invalid) 590 * is partially wrapped to an exceptional index in the 591 * range {@code [-VLENGTH..-1]}. 592 * 593 * @param sourceIndexes the source indexes which the shuffle will draw from 594 * @return a shuffle where each lane's source index is set to the given 595 * {@code int} value, partially wrapped if exceptional 596 * @throws IndexOutOfBoundsException if {@code sourceIndexes.length != VLENGTH} 597 * @see VectorShuffle#fromValues(VectorSpecies,int...) 598 */ 599 VectorShuffle<E> shuffleFromValues(int... sourceIndexes); 600 601 /** 602 * Creates a shuffle for this species from 603 * an {@code int} array starting at an offset. 604 * 605 * <p> For each shuffle lane, where {@code N} is the shuffle lane 606 * index, the array element at index {@code i + N} is validated 607 * against the species {@code VLENGTH}, and (if invalid) 608 * is partially wrapped to an exceptional index in the 609 * range {@code [-VLENGTH..-1]}. 610 * 611 * @param sourceIndexes the source indexes which the shuffle will draw from 612 * @param offset the offset into the array 613 * @return a shuffle where each lane's source index is set to the given 614 * {@code int} value, partially wrapped if exceptional 615 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 616 * {@code offset > sourceIndexes.length - VLENGTH} 617 * @see VectorShuffle#fromArray(VectorSpecies,int[],int) 618 */ 619 VectorShuffle<E> shuffleFromArray(int[] sourceIndexes, int offset); 620 621 /** 622 * Creates a shuffle for this species from 623 * the successive values of an operator applied to 624 * the range {@code [0..VLENGTH-1]}. 625 * 626 * <p> For each shuffle lane, where {@code N} is the shuffle lane 627 * index, the {@code N}th index value is validated 628 * against the species {@code VLENGTH}, and (if invalid) 629 * is partially wrapped to an exceptional index in the 630 * range {@code [-VLENGTH..-1]}. 631 * 632 * <p> Care should be taken to ensure {@code VectorShuffle} values 633 * produced from this method are consumed as constants to ensure 634 * optimal generation of code. For example, shuffle values can be 635 * held in {@code static final} fields or loop-invariant local variables. 636 * 637 * <p> This method behaves as if a shuffle is created from an array of 638 * mapped indexes as follows: 639 * <pre>{@code 640 * int[] a = new int[VLENGTH]; 641 * for (int i = 0; i < a.length; i++) { 642 * a[i] = fn.applyAsInt(i); 643 * } 644 * return VectorShuffle.fromArray(this, a, 0); 645 * }</pre> 646 * 647 * @param fn the lane index mapping function 648 * @return a shuffle of mapped indexes 649 * @see VectorShuffle#fromOp(VectorSpecies,IntUnaryOperator) 650 */ 651 VectorShuffle<E> shuffleFromOp(IntUnaryOperator fn); 652 653 /** 654 * Creates a shuffle using source indexes set to sequential 655 * values starting from {@code start} and stepping 656 * by the given {@code step}. 657 * <p> 658 * This method returns the value of the expression 659 * {@code VectorSpecies.shuffleFromOp(i -> R(start + i * step))}, 660 * where {@code R} is {@link VectorShuffle#wrapIndex(int) wrapIndex} 661 * if {@code wrap} is true, and is the identity function otherwise. 662 * <p> 663 * If {@code wrap} is false each index is validated 664 * against the species {@code VLENGTH}, and (if invalid) 665 * is partially wrapped to an exceptional index in the 666 * range {@code [-VLENGTH..-1]}. 667 * Otherwise, if {@code wrap} is true, also reduce each index, as if 668 * by {@link VectorShuffle#wrapIndex(int) wrapIndex}, 669 * to the valid range {@code [0..VLENGTH-1]}. 670 * 671 * @apiNote The {@code wrap} parameter should be set to {@code 672 * true} if invalid source indexes should be wrapped. Otherwise, 673 * setting it to {@code false} allows invalid source indexes to be 674 * range-checked by later operations such as 675 * {@link Vector#rearrange(VectorShuffle) unary rearrange}. 676 * 677 * @param start the starting value of the source index sequence, typically {@code 0} 678 * @param step the difference between adjacent source indexes, typically {@code 1} 679 * @param wrap whether to wrap resulting indexes modulo {@code VLENGTH} 680 * @return a shuffle of sequential lane indexes 681 * @see VectorShuffle#iota(VectorSpecies,int,int,boolean) 682 */ 683 VectorShuffle<E> iotaShuffle(int start, int step, boolean wrap); 684 685 /** 686 * Returns a string of the form "Species[ETYPE, VLENGTH, SHAPE]", 687 * where {@code ETYPE} is the primitive {@linkplain #elementType() 688 * lane type}, {@code VLENGTH} is the {@linkplain #length() 689 * vector lane count} associated with the species, and {@code 690 * SHAPE} is the {@linkplain #vectorShape() vector shape} 691 * associated with the species. 692 * 693 * @return a string of the form "Species[ETYPE, VLENGTH, SHAPE]" 694 */ 695 @Override 696 String toString(); 697 698 /** 699 * Indicates whether this species is identical to some other object. 700 * Two species are identical only if they have the same shape 701 * and same element type. 702 * 703 * @return whether this species is identical to some other object 704 */ 705 @Override 706 boolean equals(Object obj); 707 708 /** 709 * Returns a hash code value for the species, 710 * based on the vector shape and element type. 711 * 712 * @return a hash code value for this species 713 */ 714 @Override 715 int hashCode(); 716 717 // ==== JROSE NAME CHANGES ==== 718 719 // ADDED: 720 // * genericElementType()-> E.class (interop) 721 // * arrayType()-> ETYPE[].class (interop) 722 // * withLanes(Class), withShape(VectorShape) strongly typed reinterpret casting 723 // * static ofLargestShape(Class<E> etype) -> possibly non-preferred 724 // * static preferredShape() -> common shape of all preferred species 725 // * toString(), equals(Object), hashCode() (documented) 726 // * elementSize(e) replaced bitSizeForVectorLength 727 // * zero(), broadcast(long), from[Byte]Array(), loadMask() (convenience constructors) 728 // * lanewise(op, [v], [m]), reduceLanesToLong(op, [m]) 729 730 }