Summary
Adding access to and from MemorySegments for VectorShuffle
in the Vector API incubator. These methods mirror VectorShuffle
access to and from arrays.
Problem
The Vector
class currently supports access to and from MemorySegments
, but VectorShuffle
does not.
Solution
We will add and implement intoMemorySegment
and fromMemorySegment
to the VectorShuffle
class and its corresponding subclasses to add this functionality to VectorShuffle
.
Specification
Adding the following to src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShuffle.java
diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShuffle.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShuffle.java
index bc1780a81ac..9b9322c302a 100644
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShuffle.java
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShuffle.java
@@ -314,6 +318,52 @@ public static <E> VectorShuffle<E> fromArray(VectorSpecies<E> species, int[] sou
return vsp.shuffleFromArray(sourceIndexes, offset);
}
+ /**
+ * Loads a shuffle from a {@linkplain MemorySegment memory segment}
+ * starting at an offset into the memory segment.
+ * Bytes are composed into shuffle lanes according
+ * to the specified byte order.
+ * The shuffle is arranged into lanes according to
+ * <a href="Vector.html#lane-order">memory ordering</a>.
+ * <p>
+ * The following pseudocode illustrates the behavior:
+ * <pre>{@code
+ * var slice = ms.asSlice(offset);
+ * int[] ar = new int[species.length()];
+ * for (int n = 0; n < ar.length; n++) {
+ * ar[n] = slice.getAtIndex(ValuaLayout.JAVA_INT_UNALIGNED, n);
+ * }
+ * VectorShuffle<E> r = VectorShuffle.fromArray(species, ar, 0);
+ * }</pre>
+ *
+ * @implNote
+ * This operation is likely to be more efficient if
+ * the specified byte order is the same as
+ * {@linkplain ByteOrder#nativeOrder()
+ * the platform native order},
+ * since this method will not need to reorder
+ * the bytes of lane values.
+ *
+ * @param species the shuffle species
+ * @param ms the source indexes in memory which the shuffle will draw from
+ * @param offset the offset into the segment
+ * @param bo the byte order
+ * @param <E> the boxed element type
+ * @return a shuffle where each lane's source index is set to the given
+ * {@code int} value, partially wrapped if exceptional
+ * @throws IndexOutOfBoundsException if {@code offset < 0}, or
+ * {@code offset > sourceIndexes.byteSize() - VLENGTH * 4}
+ * @since 25
+ */
+ @ForceInline
+ public static final <E> VectorShuffle<E> fromMemorySegment(VectorSpecies<E> species, MemorySegment ms,
+ long offset, ByteOrder bo) {
+ long memsize = species.length() * 4;
+ MemorySegment arraySlice = ms.asSlice(offset, memsize);
+ int[] indices = arraySlice.toArray(ValueLayout.JAVA_INT_UNALIGNED.withOrder(bo));
+ return species.shuffleFromArray(indices,0);
+ }
+
/**
* Creates a shuffle for a given species from
* the successive values of an operator applied to
@@ -523,6 +573,45 @@ private static int unzipIndex(int i, int vlen, int part) {
*/
public abstract void intoArray(int[] a, int offset);
+ /**
+ * Stores this shuffle into a {@linkplain MemorySegment memory segment}
+ * starting at an offset using explicit byte order.
+ * <p>
+ * Bytes are extracted from shuffle lanes according
+ * to the specified byte ordering.
+ * The shuffle lanes are stored according to their
+ * <a href="Vector.html#lane-order">memory ordering</a>.
+ * <p>
+ * The following pseudocode illustrates the behavior:
+ * <pre>{@code
+ * int[] a = this.toArray();
+ * var slice = ms.asSlice(offset)
+ * for (int n = 0; n < a.length; n++) {
+ * slice.setAtIndex(ValueLayout.JAVA_INT_UNALIGNED, n, a[n]);
+ * }
+ * }</pre>
+ *
+ * @implNote
+ * This operation is likely to be more efficient if
+ * the specified byte order is the same as
+ * {@linkplain ByteOrder#nativeOrder()
+ * the platform native order},
+ * since this method will not need to reorder
+ * the bytes of lane values.
+ *
+ * @apiNote Shuffle source indexes are always in the
+ * range from {@code -VLENGTH} to {@code VLENGTH-1}.
+ * @param ms the memory segment
+ * @param offset the offset into the segment
+ * @param bo the byte order
+ * @throws IndexOutOfBoundsException if {@code offset < 0} or
+ * {@code offset > a.byteSize() - this.length() * 4}
+ * @throws IllegalArgumentException if the segment {@code ms} is read-only
+ * @since 25
+ */
+ public abstract void intoMemorySegment(MemorySegment ms, long offset, ByteOrder bo);
+
+
/**
* Converts this shuffle into a vector, creating a vector
* of integral values corresponding to the lane source
- csr of
-
JDK-8351993 VectorShuffle access to and from MemorySegments
-
- Resolved
-