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