< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java

Print this page
rev 55589 : Species-phase2
rev 55590 : added missing javadocs, changed jtreg test
rev 55591 : XxxSpecies made package private
rev 55593 : making species.of(), ofPreferred() public again


   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.misc.Unsafe;
  28 import jdk.internal.vm.annotation.ForceInline;

  29 
  30 import java.nio.ByteBuffer;
  31 import java.nio.ByteOrder;
  32 import java.util.function.IntUnaryOperator;
  33 import jdk.incubator.vector.*;
  34 
  35 /**
  36  * A {@code Vector} is designed for use in computations that can be transformed
  37  * by a runtime compiler, on supported hardware, to Single Instruction Multiple
  38  * Data (SIMD) computations leveraging vector hardware registers and vector
  39  * hardware instructions.  Such SIMD computations exploit data parallelism to
  40  * perform the same operation on multiple data points simultaneously in a
  41  * faster time it would ordinarily take to perform the same operation
  42  * sequentially on each data point.
  43  * <p>
  44  * A Vector represents an ordered immutable sequence of values of the same
  45  * element type {@code e} that is one of the following primitive types
  46  * {@code byte}, {@code short}, {@code int}, {@code long}, {@code float}, or
  47  * {@code double}).  The type variable {@code E} corresponds to the boxed
  48  * element type, specifically the class that wraps a value of {@code e} in an


 900     public abstract void intoByteBuffer(ByteBuffer b, int i, Mask<E> m);
 901 
 902 
 903     /**
 904      * A {@code Shape} governs the total size, in bits, of a
 905      * {@link Vector}, {@link Mask}, or {@link Shuffle}.  The shape in
 906      * combination with the element type together govern the number of lanes.
 907      */
 908     public enum Shape {
 909         /** Shape of length 64 bits */
 910         S_64_BIT(64),
 911         /** Shape of length 128 bits */
 912         S_128_BIT(128),
 913         /** Shape of length 256 bits */
 914         S_256_BIT(256),
 915         /** Shape of length 512 bits */
 916         S_512_BIT(512),
 917         /** Shape of maximum length supported on the platform */
 918         S_Max_BIT(Unsafe.getUnsafe().getMaxVectorSize(byte.class) * 8);
 919 

 920         final int bitSize;
 921 
 922         Shape(int bitSize) {
 923             this.bitSize = bitSize;
 924         }
 925 
 926         /**
 927          * Returns the size, in bits, of this shape.
 928          *
 929          * @return the size, in bits, of this shape.
 930          */
 931         public int bitSize() {
 932             return bitSize;
 933         }
 934 
 935         /**
 936          * Return the number of lanes of a vector of this shape and whose element
 937          * type is of the provided species
 938          *
 939          * @param s the species describing the element type


 992          *
 993          * @return the box type
 994          */
 995         abstract Class<?> boxType();
 996 
 997         /**
 998          * Returns the vector mask type for this species
 999          *
1000          * @return the box type
1001          */
1002         abstract Class<?> maskType();
1003 
1004         /**
1005          * Returns the element size, in bits, of vectors produced by this
1006          * species.
1007          *
1008          * @return the element size, in bits
1009          */
1010         public abstract int elementSize();
1011 
1012         abstract Class<?> vectorType();
1013 
1014         /**
1015          * Returns the shape of masks, shuffles, and vectors produced by this
1016          * species.
1017          *
1018          * @return the primitive element type
1019          */
1020         public abstract Shape shape();
1021 
1022         /**







1023          * Returns the mask, shuffe, or vector lanes produced by this species.
1024          *
1025          * @return the the number of lanes
1026          */
1027         public int length() { return shape().length(this); }
1028 
1029         /**
1030          * Returns the total vector size, in bits, of vectors produced by this
1031          * species.
1032          *
1033          * @return the total vector size, in bits
1034          */
1035         public int bitSize() { return shape().bitSize(); }
1036 
1037         // Factory
1038 
1039         /**
1040          * Finds a species for an element type and shape.
1041          *
1042          * @param c the element type


1068             }
1069             else {
1070                 throw new IllegalArgumentException("Bad vector element type: " + c.getName());
1071             }
1072         }
1073 
1074         /**
1075          * Finds a preferred species for an element type.
1076          * <p>
1077          * A preferred species is a species chosen by the platform that has a
1078          * shape of maximal bit size.  A preferred species for different element
1079          * types will have the same shape, and therefore vectors created from
1080          * such species will be shape compatible.
1081          *
1082          * @param c the element type
1083          * @param <E> the boxed element type
1084          * @return a preferred species for an element type
1085          * @throws IllegalArgumentException if no such species exists for the
1086          * element type
1087          */
1088         @SuppressWarnings("unchecked")
1089         public static <E> Vector.Species<E> ofPreferred(Class<E> c) {
1090             Unsafe u = Unsafe.getUnsafe();
1091 
1092             int vectorLength = u.getMaxVectorSize(c);
1093             int vectorBitSize = bitSizeForVectorLength(c, vectorLength);
1094             Shape s = Shape.forBitSize(vectorBitSize);
1095             return Species.of(c, s);
1096         }

1097 
1098         /**
1099          * Returns a vector where all lane elements are set to the default
1100          * primitive value.
1101          *
1102          * @return a zero vector
1103          */
1104         public abstract Vector<E> zero();













1105 
1106         /**
1107          * Converts a given mask of shape {@code T} and element type
1108          * {@code F} to a mask of this species shape {@code S} and element
1109          * type {@code E}.
1110          * <p>
1111          * For each mask lane, where {@code N} is the mask lane index, if the
1112          * mask lane at index {@code N} is set, then the mask lane at index
1113          * {@code N} of the resulting mask is set, otherwise that mask lane is
1114          * not set.
1115          *
1116          * @param m the mask
1117          * @param <F> the boxed element type of the mask
1118          * @return a mask, converted by shape and element type, from a given
1119          * mask.
1120          * @throws IllegalArgumentException if the mask length and this species
1121          * length differ
1122          */
1123         public abstract <F> Mask<E> cast(Mask<F> m);
1124 
1125         /**
1126          * Converts a given shuffle of shape {@code T} and element type
1127          * {@code F} to a shuffle of this species shape {@code S} and element
1128          * type {@code E}.
1129          * <p>
1130          * For each shuffle lane, where {@code N} is the mask lane index, the
1131          * shuffle element at index {@code N} is placed, unmodified, into the
1132          * resulting shuffle at index {@code N}.
1133          *
1134          * @param s the shuffle
1135          * @param <F> the boxed element type of the mask
1136          * @return a shuffle, converted by shape and element type, from a given
1137          * shuffle.
1138          * @throws IllegalArgumentException if the shuffle length and this
1139          * species length differ
1140          */
1141         public abstract <F> Shuffle<E> cast(Shuffle<F> s);






































1142     }
1143 
1144     /**
1145      * A {@code Mask} represents an ordered immutable sequence of {@code boolean}
1146      * values.  A Mask can be used with a mask accepting vector operation to
1147      * control the selection and operation of lane elements of input vectors.
1148      * <p>
1149      * The number of values in the sequence is referred to as the Mask
1150      * {@link #length() length}.  The length also corresponds to the number of
1151      * Mask lanes.  The lane element at lane index {@code N} (from {@code 0},
1152      * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
1153      * value in the sequence.
1154      * A Mask and Vector of the same element type and shape have the same number
1155      * of lanes.
1156      * <p>
1157      * A lane is said to be <em>set</em> if the lane element is {@code true},
1158      * otherwise a lane is said to be <em>unset</em> if the lane element is
1159      * {@code false}.
1160      * <p>
1161      * Mask declares a limited set of unary, binary and reductive mask


1208          *
1209          * @return the species of this mask
1210          */
1211         public abstract Species<E> species();
1212 
1213         /**
1214          * Returns the number of mask lanes (the length).
1215          *
1216          * @return the number of mask lanes
1217          */
1218         public int length() { return species().length(); }
1219 
1220         /**
1221          * Converts this mask to a mask of the given species shape of element type {@code F}.
1222          * <p>
1223          * For each mask lane, where {@code N} is the lane index, if the
1224          * mask lane at index {@code N} is set, then the mask lane at index
1225          * {@code N} of the resulting mask is set, otherwise that mask lane is
1226          * not set.
1227          *
1228          * @param species the species of the desired mask
1229          * @param <F> the boxed element type of the species
1230          * @return a mask converted by shape and element type
1231          * @throws IllegalArgumentException if this mask length and the species
1232          * length differ
1233          */
1234         @ForceInline
1235         public <F> Mask<F> cast(Species<F> species) {
1236             return species.cast(this);
1237         }
1238 
1239         /**
1240          * Returns the lane elements of this mask packed into a {@code long}
1241          * value for at most the first 64 lane elements.
1242          * <p>
1243          * The lane elements are packed in the order of least significant bit
1244          * to most significant bit.
1245          * For each mask lane where {@code N} is the mask lane index, if the
1246          * mask lane is set then the {@code N}'th bit is set to one in the
1247          * resulting {@code long} value, otherwise the {@code N}'th bit is set
1248          * to zero.
1249          *
1250          * @return the lane elements of this mask packed into a {@code long}
1251          * value.
1252          */
1253         public abstract long toLong();
1254 
1255         /**
1256          * Returns an {@code boolean} array containing the lane elements of this
1257          * mask.


1406         /**
1407          * Returns the number of shuffle lanes (the length).
1408          *
1409          * @return the number of shuffle lanes
1410          */
1411         public int length() { return species().length(); }
1412 
1413         /**
1414          * Converts this shuffle to a shuffle of the given species of element type {@code F}.
1415          * <p>
1416          * For each shuffle lane, where {@code N} is the lane index, the
1417          * shuffle element at index {@code N} is placed, unmodified, into the
1418          * resulting shuffle at index {@code N}.
1419          *
1420          * @param species species of desired shuffle
1421          * @param <F> the boxed element type of the species
1422          * @return a shuffle converted by shape and element type
1423          * @throws IllegalArgumentException if this shuffle length and the
1424          * species length differ
1425          */
1426         @ForceInline
1427         public <F> Shuffle<F> cast(Species<F> species) {
1428             return species.cast(this);
1429         }
1430 
1431         /**
1432          * Returns an {@code int} array containing the lane elements of this
1433          * shuffle.
1434          * <p>
1435          * This method behaves as if it {@link #intoArray(int[], int)} stores}
1436          * this shuffle into an allocated array and returns that array as
1437          * follows:
1438          * <pre>{@code
1439          *   int[] a = new int[this.length()];
1440          *   this.intoArray(a, 0);
1441          *   return a;
1442          * }</pre>
1443          *
1444          * @return an array containing the the lane elements of this vector
1445          */
1446         public abstract int[] toArray();
1447 
1448         /**
1449          * Stores this shuffle into an {@code int} array starting at offset.




   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.misc.Unsafe;
  28 import jdk.internal.vm.annotation.ForceInline;
  29 import jdk.internal.vm.annotation.Stable;
  30 
  31 import java.nio.ByteBuffer;
  32 import java.nio.ByteOrder;
  33 import java.util.function.IntUnaryOperator;
  34 import jdk.incubator.vector.*;
  35 
  36 /**
  37  * A {@code Vector} is designed for use in computations that can be transformed
  38  * by a runtime compiler, on supported hardware, to Single Instruction Multiple
  39  * Data (SIMD) computations leveraging vector hardware registers and vector
  40  * hardware instructions.  Such SIMD computations exploit data parallelism to
  41  * perform the same operation on multiple data points simultaneously in a
  42  * faster time it would ordinarily take to perform the same operation
  43  * sequentially on each data point.
  44  * <p>
  45  * A Vector represents an ordered immutable sequence of values of the same
  46  * element type {@code e} that is one of the following primitive types
  47  * {@code byte}, {@code short}, {@code int}, {@code long}, {@code float}, or
  48  * {@code double}).  The type variable {@code E} corresponds to the boxed
  49  * element type, specifically the class that wraps a value of {@code e} in an


 901     public abstract void intoByteBuffer(ByteBuffer b, int i, Mask<E> m);
 902 
 903 
 904     /**
 905      * A {@code Shape} governs the total size, in bits, of a
 906      * {@link Vector}, {@link Mask}, or {@link Shuffle}.  The shape in
 907      * combination with the element type together govern the number of lanes.
 908      */
 909     public enum Shape {
 910         /** Shape of length 64 bits */
 911         S_64_BIT(64),
 912         /** Shape of length 128 bits */
 913         S_128_BIT(128),
 914         /** Shape of length 256 bits */
 915         S_256_BIT(256),
 916         /** Shape of length 512 bits */
 917         S_512_BIT(512),
 918         /** Shape of maximum length supported on the platform */
 919         S_Max_BIT(Unsafe.getUnsafe().getMaxVectorSize(byte.class) * 8);
 920 
 921         @Stable
 922         final int bitSize;
 923 
 924         Shape(int bitSize) {
 925             this.bitSize = bitSize;
 926         }
 927 
 928         /**
 929          * Returns the size, in bits, of this shape.
 930          *
 931          * @return the size, in bits, of this shape.
 932          */
 933         public int bitSize() {
 934             return bitSize;
 935         }
 936 
 937         /**
 938          * Return the number of lanes of a vector of this shape and whose element
 939          * type is of the provided species
 940          *
 941          * @param s the species describing the element type


 994          *
 995          * @return the box type
 996          */
 997         abstract Class<?> boxType();
 998 
 999         /**
1000          * Returns the vector mask type for this species
1001          *
1002          * @return the box type
1003          */
1004         abstract Class<?> maskType();
1005 
1006         /**
1007          * Returns the element size, in bits, of vectors produced by this
1008          * species.
1009          *
1010          * @return the element size, in bits
1011          */
1012         public abstract int elementSize();
1013 


1014         /**
1015          * Returns the shape of masks, shuffles, and vectors produced by this
1016          * species.
1017          *
1018          * @return the primitive element type
1019          */
1020         public abstract Shape shape();
1021 
1022         /**
1023          * Returns the shape of the corresponding index species
1024          * @return the shape
1025          */
1026         @ForceInline
1027         public abstract Shape indexShape();
1028 
1029         /**
1030          * Returns the mask, shuffe, or vector lanes produced by this species.
1031          *
1032          * @return the the number of lanes
1033          */
1034         public int length() { return shape().length(this); }
1035 
1036         /**
1037          * Returns the total vector size, in bits, of vectors produced by this
1038          * species.
1039          *
1040          * @return the total vector size, in bits
1041          */
1042         public int bitSize() { return shape().bitSize(); }
1043 
1044         // Factory
1045 
1046         /**
1047          * Finds a species for an element type and shape.
1048          *
1049          * @param c the element type


1075             }
1076             else {
1077                 throw new IllegalArgumentException("Bad vector element type: " + c.getName());
1078             }
1079         }
1080 
1081         /**
1082          * Finds a preferred species for an element type.
1083          * <p>
1084          * A preferred species is a species chosen by the platform that has a
1085          * shape of maximal bit size.  A preferred species for different element
1086          * types will have the same shape, and therefore vectors created from
1087          * such species will be shape compatible.
1088          *
1089          * @param c the element type
1090          * @param <E> the boxed element type
1091          * @return a preferred species for an element type
1092          * @throws IllegalArgumentException if no such species exists for the
1093          * element type
1094          */

1095         public static <E> Vector.Species<E> ofPreferred(Class<E> c) {
1096             Unsafe u = Unsafe.getUnsafe();
1097 
1098             int vectorLength = u.getMaxVectorSize(c);
1099             int vectorBitSize = bitSizeForVectorLength(c, vectorLength);
1100             Shape s = Shape.forBitSize(vectorBitSize);
1101             return Species.of(c, s);
1102         }
1103     }
1104 
1105     abstract static class AbstractSpecies<E> extends Vector.Species<E> {
1106         @Stable
1107         protected final Vector.Shape shape;
1108         @Stable
1109         protected final Class<E> elementType;
1110         @Stable
1111         protected final int elementSize;
1112         @Stable
1113         protected final Class<?> boxType;
1114         @Stable
1115         protected final Class<?> maskType;
1116         @Stable
1117         protected final Shape indexShape;
1118 
1119         AbstractSpecies(Vector.Shape shape, Class<E> elementType, int elementSize, Class<?> boxType, Class<?> maskType) {
1120             this.shape = shape;
1121             this.elementType = elementType;
1122             this.elementSize = elementSize;
1123             this.boxType = boxType;
1124             this.maskType = maskType;
1125 
1126             if (boxType == Long64Vector.class || boxType == Double64Vector.class) {
1127                 indexShape = Vector.Shape.S_64_BIT;
1128             }
1129             else {
1130                 int bitSize = Vector.bitSizeForVectorLength(int.class, shape.bitSize() / elementSize);
1131                 indexShape = Vector.Shape.forBitSize(bitSize);
1132             }
1133         }










1134 
1135         @Override
1136         @ForceInline
1137         public int bitSize() {
1138             return shape.bitSize();
1139         }
1140 
1141         @Override
1142         @ForceInline
1143         public int length() {
1144             return shape.bitSize() / elementSize;
1145         }
1146 
1147         @Override
1148         @ForceInline
1149         public Class<E> elementType() {
1150             return elementType;
1151         }
1152 
1153         @Override
1154         @ForceInline
1155         public Class<?> boxType() {
1156             return boxType;
1157         }
1158 
1159         @Override
1160         @ForceInline
1161         public Class<?> maskType() {
1162             return maskType;
1163         }
1164 
1165         @Override
1166         @ForceInline
1167         public int elementSize() {
1168             return elementSize;
1169         }
1170 
1171         @Override
1172         @ForceInline
1173         public Vector.Shape shape() {
1174             return shape;
1175         }
1176 
1177         @Override
1178         @ForceInline
1179         public Vector.Shape indexShape() { return indexShape; }
1180 
1181         @Override
1182         public String toString() {
1183             return new StringBuilder("Shape[")
1184                     .append(bitSize()).append(" bits, ")
1185                     .append(length()).append(" ").append(elementType.getSimpleName()).append("s x ")
1186                     .append(elementSize()).append(" bits")
1187                     .append("]")
1188                     .toString();
1189         }
1190     }
1191 
1192     /**
1193      * A {@code Mask} represents an ordered immutable sequence of {@code boolean}
1194      * values.  A Mask can be used with a mask accepting vector operation to
1195      * control the selection and operation of lane elements of input vectors.
1196      * <p>
1197      * The number of values in the sequence is referred to as the Mask
1198      * {@link #length() length}.  The length also corresponds to the number of
1199      * Mask lanes.  The lane element at lane index {@code N} (from {@code 0},
1200      * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
1201      * value in the sequence.
1202      * A Mask and Vector of the same element type and shape have the same number
1203      * of lanes.
1204      * <p>
1205      * A lane is said to be <em>set</em> if the lane element is {@code true},
1206      * otherwise a lane is said to be <em>unset</em> if the lane element is
1207      * {@code false}.
1208      * <p>
1209      * Mask declares a limited set of unary, binary and reductive mask


1256          *
1257          * @return the species of this mask
1258          */
1259         public abstract Species<E> species();
1260 
1261         /**
1262          * Returns the number of mask lanes (the length).
1263          *
1264          * @return the number of mask lanes
1265          */
1266         public int length() { return species().length(); }
1267 
1268         /**
1269          * Converts this mask to a mask of the given species shape of element type {@code F}.
1270          * <p>
1271          * For each mask lane, where {@code N} is the lane index, if the
1272          * mask lane at index {@code N} is set, then the mask lane at index
1273          * {@code N} of the resulting mask is set, otherwise that mask lane is
1274          * not set.
1275          *
1276          * @param s the species of the desired mask
1277          * @param <F> the boxed element type of the species
1278          * @return a mask converted by shape and element type
1279          * @throws IllegalArgumentException if this mask length and the species
1280          * length differ
1281          */
1282         public abstract <F> Mask<F> cast(Species<F> s);



1283 
1284         /**
1285          * Returns the lane elements of this mask packed into a {@code long}
1286          * value for at most the first 64 lane elements.
1287          * <p>
1288          * The lane elements are packed in the order of least significant bit
1289          * to most significant bit.
1290          * For each mask lane where {@code N} is the mask lane index, if the
1291          * mask lane is set then the {@code N}'th bit is set to one in the
1292          * resulting {@code long} value, otherwise the {@code N}'th bit is set
1293          * to zero.
1294          *
1295          * @return the lane elements of this mask packed into a {@code long}
1296          * value.
1297          */
1298         public abstract long toLong();
1299 
1300         /**
1301          * Returns an {@code boolean} array containing the lane elements of this
1302          * mask.


1451         /**
1452          * Returns the number of shuffle lanes (the length).
1453          *
1454          * @return the number of shuffle lanes
1455          */
1456         public int length() { return species().length(); }
1457 
1458         /**
1459          * Converts this shuffle to a shuffle of the given species of element type {@code F}.
1460          * <p>
1461          * For each shuffle lane, where {@code N} is the lane index, the
1462          * shuffle element at index {@code N} is placed, unmodified, into the
1463          * resulting shuffle at index {@code N}.
1464          *
1465          * @param species species of desired shuffle
1466          * @param <F> the boxed element type of the species
1467          * @return a shuffle converted by shape and element type
1468          * @throws IllegalArgumentException if this shuffle length and the
1469          * species length differ
1470          */
1471         public abstract <F> Shuffle<F> cast(Species<F> species);



1472 
1473         /**
1474          * Returns an {@code int} array containing the lane elements of this
1475          * shuffle.
1476          * <p>
1477          * This method behaves as if it {@link #intoArray(int[], int)} stores}
1478          * this shuffle into an allocated array and returns that array as
1479          * follows:
1480          * <pre>{@code
1481          *   int[] a = new int[this.length()];
1482          *   this.intoArray(a, 0);
1483          *   return a;
1484          * }</pre>
1485          *
1486          * @return an array containing the the lane elements of this vector
1487          */
1488         public abstract int[] toArray();
1489 
1490         /**
1491          * Stores this shuffle into an {@code int} array starting at offset.


< prev index next >