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 */
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:
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}
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
|
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(VectorOperators.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 */
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.
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#reinterpretShape(VectorSpecies, int) 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,int)
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 ETYPE}).
371 * 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:
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 * @return a shuffle where each lane's source index is set to the given
570 * {@code int} value, partially wrapped if exceptional
571 * @throws IndexOutOfBoundsException if {@code sourceIndexes.length != VLENGTH}
572 * @see VectorShuffle#fromValues(VectorSpecies,int...)
573 */
574 public abstract VectorShuffle<E> shuffleFromValues(int... sourceIndexes);
575
576 /**
577 * Loads a shuffle for this species from
578 * an {@code int} array starting at an offset.
579 *
580 * <p> For each shuffle lane, where {@code N} is the shuffle lane
581 * index, the array element at index {@code i + N} 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 * @param sourceIndexes the source indexes which the shuffle will draw from
587 * @param offset the offset into the array
588 * @return a shuffle where each lane's source index is set to the given
589 * {@code int} value, partially wrapped if exceptional
590 * @throws IndexOutOfBoundsException if {@code offset < 0}, or
591 * {@code offset > sourceIndexes.length - VLENGTH}
595
596 /**
597 * Loads a shuffle for this species from
598 * the successive values of an operator applied to
599 * the range {@code [0..VLENGTH-1]}.
600 *
601 * <p> For each shuffle lane, where {@code N} is the shuffle lane
602 * index, the {@code N}th index value is validated
603 * against the species {@code VLENGTH}, and (if invalid)
604 * is partially wrapped to an exceptional index in the
605 * range {@code [-VLENGTH..-1]}.
606 *
607 * <p> Care should be taken to ensure {@code VectorShuffle} values
608 * produced from this method are consumed as constants to ensure
609 * optimal generation of code. For example, shuffle values can be
610 * held in {@code static final} fields or loop-invariant local variables.
611 *
612 * <p> This method behaves as if a shuffle is created from an array of
613 * mapped indexes as follows:
614 * <pre>{@code
615 * int[] a = new int[VLENGTH];
616 * for (int i = 0; i < a.length; i++) {
617 * a[i] = fn.applyAsInt(i);
618 * }
619 * return VectorShuffle.fromArray(this, a, 0);
620 * }</pre>
621 *
622 * @param fn the lane index mapping function
623 * @return a shuffle of mapped indexes
624 * @see VectorShuffle#fromOp(VectorSpecies,IntUnaryOperator)
625 */
626 public abstract VectorShuffle<E> shuffleFromOp(IntUnaryOperator fn);
627
628 /**
629 * Loads a shuffle using source indexes set to sequential
630 * values starting from {@code start} and stepping
631 * by the given {@code step}.
632 * <p>
633 * This method returns the value of the expression
634 * {@code VectorShuffle.fromOp(this, i -> start + i * step)}.
635 *
636 * @param start the starting value of the source index sequence
637 * @param step the difference between adjacent source indexes
638 * @return a shuffle of sequential lane indexes
639 * @see VectorShuffle#iota(VectorSpecies,int,int)
640 */
641 public abstract VectorShuffle<E> iotaShuffle(int start, int step);
642
|