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