< prev index next >

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

Print this page




  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
  50  * object (such the {@code Integer} class that wraps a value of {@code int}}.
  51  * A Vector has a {@link #shape() shape} {@code S}, extending type
  52  * {@link Shape}, that governs the total {@link #bitSize() size} in bits
  53  * of the sequence of values.


 882      *     order(ByteOrder.nativeOrder()).position(i).
 883      *     asEBuffer();
 884      * e[] es = ((EVector<S>)this).toArray();
 885      * for (int n = 0; n < t.length; n++) {
 886      *     if (m.isSet(n)) {
 887      *         eb.put(n, es[n]);
 888      *     }
 889      * }
 890      * }</pre>
 891      *
 892      * @param b the byte buffer
 893      * @param i the offset into the byte buffer
 894      * @param m the mask
 895      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 896      * or {@code > b.limit()},
 897      * for any vector lane index {@code N} where the mask at lane {@code N}
 898      * is set
 899      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes
 900      */
 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
 942          * @return the number of lanes
 943          */
 944         int length(Species<?> s) {
 945             return bitSize() / s.elementSize();
 946         }
 947 
 948         /**
 949          * Finds appropriate shape depending on bitsize.
 950          *
 951          * @param bitSize the size in bits
 952          * @return the shape corresponding to bitsize
 953          * @see #bitSize
 954          */
 955         public static Shape forBitSize(int bitSize) {
 956             switch (bitSize) {
 957                 case 64:
 958                     return Shape.S_64_BIT;
 959                 case 128:
 960                     return Shape.S_128_BIT;
 961                 case 256:
 962                     return Shape.S_256_BIT;
 963                 case 512:
 964                     return Shape.S_512_BIT;
 965                 default:
 966                     if ((bitSize > 0) && (bitSize <= 2048) && (bitSize % 128 == 0)) {
 967                         return Shape.S_Max_BIT;
 968                     } else {
 969                         throw new IllegalArgumentException("Bad vector bit size: " + bitSize);
 970                     }
 971             }
 972         }
 973     }
 974 
 975 
 976     /**
 977      * Class representing vectors of same element type, {@code E} and {@link Vector.Shape Shape}.
 978      *
 979      * @param <E> the boxed element type of this species
 980      */
 981     public static abstract class Species<E> {
 982         Species() {}
 983 
 984         /**
 985          * Returns the primitive element type of vectors produced by this
 986          * species.
 987          *
 988          * @return the primitive element type
 989          */
 990         public abstract Class<E> elementType();
 991 
 992         /**
 993          * Returns the vector box type for this species
 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
1050          * @param s the shape
1051          * @param <E> the boxed element type
1052          * @return a species for an element type and shape
1053          * @throws IllegalArgumentException if no such species exists for the
1054          * element type and/or shape
1055          */
1056         @SuppressWarnings("unchecked")
1057         public static <E> Vector.Species<E> of(Class<E> c, Shape s) {
1058             if (c == float.class) {
1059                 return (Vector.Species<E>) FloatVector.species(s);
1060             }
1061             else if (c == double.class) {
1062                 return (Vector.Species<E>) DoubleVector.species(s);
1063             }
1064             else if (c == byte.class) {
1065                 return (Vector.Species<E>) ByteVector.species(s);
1066             }
1067             else if (c == short.class) {
1068                 return (Vector.Species<E>) ShortVector.species(s);
1069             }
1070             else if (c == int.class) {
1071                 return (Vector.Species<E>) IntVector.species(s);
1072             }
1073             else if (c == long.class) {
1074                 return (Vector.Species<E>) LongVector.species(s);
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
1210      * operations.
1211      * <ul>
1212      * <li>
1213      * A mask unary operation (1-ary) operates on one input mask to produce a
1214      * result mask.
1215      * For each lane of the input mask the
1216      * lane element is operated on using the specified scalar unary operation and
1217      * the boolean result is placed into the mask result at the same lane.
1218      * The following pseudocode expresses the behaviour of this operation category:
1219      *
1220      * <pre>{@code
1221      * Mask<E> a = ...;
1222      * boolean[] ar = new boolean[a.length()];
1223      * for (int i = 0; i < a.length(); i++) {
1224      *     ar[i] = boolean_unary_op(a.isSet(i));
1225      * }
1226      * Mask<E> r = a.species().maskFromArray(ar, 0);
1227      * }</pre>
1228      *
1229      * <li>
1230      * A mask binary operation (2-ary) operates on two input
1231      * masks to produce a result mask.
1232      * For each lane of the two input masks,
1233      * a and b say, the corresponding lane elements from a and b are operated on
1234      * using the specified scalar binary operation and the boolean result is placed
1235      * into the mask result at the same lane.
1236      * The following pseudocode expresses the behaviour of this operation category:
1237      *
1238      * <pre>{@code
1239      * Mask<E> a = ...;
1240      * Mask<E> b = ...;
1241      * boolean[] ar = new boolean[a.length()];
1242      * for (int i = 0; i < a.length(); i++) {
1243      *     ar[i] = scalar_binary_op(a.isSet(i), b.isSet(i));
1244      * }
1245      * Mask<E> r = a.species().maskFromArray(ar, 0);
1246      * }</pre>
1247      *
1248      * </ul>
1249      * @param <E> the boxed element type of this mask
1250      */
1251     public static abstract class Mask<E> {
1252         Mask() {}
1253 
1254         /**
1255          * Returns the species of this 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.
1303          * <p>
1304          * This method behaves as if it {@link #intoArray(boolean[], int)} stores}
1305          * this mask into an allocated array and returns that array as
1306          * follows:
1307          * <pre>{@code
1308          * boolean[] a = new boolean[this.length()];
1309          * this.intoArray(a, 0);
1310          * return a;
1311          * }</pre>
1312          *
1313          * @return an array containing the the lane elements of this vector
1314          */
1315         public abstract boolean[] toArray();
1316 
1317         /**
1318          * Stores this mask into a {@code boolean} array starting at offset.
1319          * <p>
1320          * For each mask lane, where {@code N} is the mask lane index,
1321          * the lane element at index {@code N} is stored into the array at index
1322          * {@code i + N}.
1323          *
1324          * @param a the array
1325          * @param i the offset into the array
1326          * @throws IndexOutOfBoundsException if {@code i < 0}, or
1327          * {@code i > a.length - this.length()}
1328          */
1329         public abstract void intoArray(boolean[] a, int i);
1330 
1331         /**
1332          * Returns {@code true} if any of the mask lanes are set.
1333          *
1334          * @return {@code true} if any of the mask lanes are set, otherwise
1335          * {@code false}.
1336          */
1337         public abstract boolean anyTrue();
1338 
1339         /**
1340          * Returns {@code true} if all of the mask lanes are set.
1341          *
1342          * @return {@code true} if all of the mask lanes are set, otherwise
1343          * {@code false}.
1344          */
1345         public abstract boolean allTrue();
1346 
1347         /**
1348          * Returns the number of mask lanes that are set.
1349          *
1350          * @return the number of mask lanes that are set.
1351          */
1352         public abstract int trueCount();
1353 
1354         /**
1355          * Logically ands this mask with an input mask.
1356          * <p>
1357          * This is a mask binary operation where the logical and operation
1358          * ({@code &&} is applied to lane elements.
1359          *
1360          * @param o the input mask
1361          * @return the result of logically and'ing this mask with an input mask
1362          */
1363         public abstract Mask<E> and(Mask<E> o);
1364 
1365         /**
1366          * Logically ors this mask with an input mask.
1367          * <p>
1368          * This is a mask binary operation where the logical or operation
1369          * ({@code ||} is applied to lane elements.
1370          *
1371          * @param o the input mask
1372          * @return the result of logically or'ing this mask with an input mask
1373          */
1374         public abstract Mask<E> or(Mask<E> o);
1375 
1376         /**
1377          * Logically negates this mask.
1378          * <p>
1379          * This is a mask unary operation where the logical not operation
1380          * ({@code !} is applied to lane elements.
1381          *
1382          * @return the result of logically negating this mask.
1383          */
1384         public abstract Mask<E> not();
1385 
1386         /**
1387          * Returns a vector representation of this mask.
1388          * <p>
1389          * For each mask lane, where {@code N} is the mask lane index,
1390          * if the mask lane is set then an element value whose most significant
1391          * bit is set is placed into the resulting vector at lane index
1392          * {@code N}, otherwise the default element value is placed into the
1393          * resulting vector at lane index {@code N}.
1394          *
1395          * @return a vector representation of this mask.
1396          */
1397         public abstract Vector<E> toVector();
1398 
1399         /**
1400          * Tests if the lane at index {@code i} is set
1401          * @param i the lane index
1402          *
1403          * @return true if the lane at index {@code i} is set, otherwise false
1404          */
1405         public abstract boolean getElement(int i);
1406 
1407         /**
1408          * Tests if the lane at index {@code i} is set
1409          * @param i the lane index
1410          * @return true if the lane at index {@code i} is set, otherwise false
1411          * @see #getElement
1412          */
1413         public boolean isSet(int i) {
1414             return getElement(i);
1415         }
1416     }
1417 
1418     /**
1419      * A {@code Shuffle} represents an ordered immutable sequence of
1420      * {@code int} values.  A Shuffle can be used with a shuffle accepting
1421      * vector operation to control the rearrangement of lane elements of input
1422      * vectors
1423      * <p>
1424      * The number of values in the sequence is referred to as the Shuffle
1425      * {@link #length() length}.  The length also corresponds to the number of
1426      * Shuffle lanes.  The lane element at lane index {@code N} (from {@code 0},
1427      * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
1428      * value in the sequence.
1429      * A Shuffle and Vector of the same element type and shape have the same
1430      * number of lanes.
1431      * <p>
1432      * A Shuffle describes how a lane element of a vector may cross lanes from
1433      * its lane index, {@code i} say, to another lane index whose value is the
1434      * Shuffle's lane element at lane index {@code i}.  Shuffle lane elements
1435      * will be in the range of {@code 0} (inclusive) to the shuffle length
1436      * (exclusive), and therefore cannot induce out of bounds errors when
1437      * used with vectors operations and vectors of the same length.
1438      *
1439      * @param <E> the boxed element type of this mask
1440      */
1441     public static abstract class Shuffle<E> {
1442         Shuffle() {}
1443 
1444         /**
1445          * Returns the species of this shuffle.
1446          *
1447          * @return the species of this shuffle
1448          */
1449         public abstract Species<E> species();
1450 
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.
1492          * <p>
1493          * For each shuffle lane, where {@code N} is the shuffle lane index,
1494          * the lane element at index {@code N} is stored into the array at index
1495          * {@code i + N}.
1496          *
1497          * @param a the array
1498          * @param i the offset into the array
1499          * @throws IndexOutOfBoundsException if {@code i < 0}, or
1500          * {@code i > a.length - this.length()}
1501          */
1502         public abstract void intoArray(int[] a, int i);
1503 
1504         /**
1505          * Converts this shuffle into a vector, creating a vector from shuffle
1506          * lane elements (int values) cast to the vector element type.
1507          * <p>
1508          * This method behaves as if it returns the result of creating a
1509          * vector given an {@code int} array obtained from this shuffle's
1510          * lane elements, as follows:
1511          * <pre>{@code
1512          *   int[] sa = this.toArray();
1513          *   $type$[] va = new $type$[a.length];
1514          *   for (int i = 0; i < a.length; i++) {
1515          *       va[i] = ($type$) sa[i];
1516          *   }
1517          *   return this.species().fromArray(va, 0);
1518          * }</pre>
1519          *
1520          * @return a vector representation of this shuffle
1521          */
1522         public abstract Vector<E> toVector();
1523 
1524         /**
1525          * Gets the {@code int} lane element at lane index {@code i}
1526          *
1527          * @param i the lane index
1528          * @return the {@code int} lane element at lane index {@code i}
1529          */
1530         public int getElement(int i) { return toArray()[i]; }
1531 
1532         /**
1533          * Rearranges the lane elements of this shuffle selecting lane indexes
1534          * controlled by another shuffle.
1535          * <p>
1536          * For each lane of the shuffle, at lane index {@code N} with lane
1537          * element {@code I}, the lane element at {@code I} from this shuffle is
1538          * selected and placed into the resulting shuffle at {@code N}.
1539          *
1540          * @param s the shuffle controlling lane index selection
1541          * @return the rearrangement of the lane elements of this shuffle
1542          */
1543         public abstract Shuffle<E> rearrange(Shuffle<E> s);
1544     }
1545 
1546     /**
1547      * Find bit size based on element type and number of elements.
1548      *
1549      * @param c the element type
1550      * @param numElem number of lanes in the vector
1551      * @return size in bits for vector
1552      */
1553     public static int bitSizeForVectorLength(Class<?> c, int numElem) {
1554         if (c == float.class) {
1555             return Float.SIZE * numElem;
1556         }
1557         else if (c == double.class) {
1558             return Double.SIZE * numElem;
1559         }
1560         else if (c == byte.class) {
1561             return Byte.SIZE * numElem;
1562         }
1563         else if (c == short.class) {
1564             return Short.SIZE * numElem;


  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.Objects;
  34 import java.util.function.Function;
  35 import java.util.function.IntUnaryOperator;
  36 import java.util.function.UnaryOperator;
  37 
  38 import jdk.incubator.vector.*;
  39 
  40 /**
  41  * A {@code Vector} is designed for use in computations that can be transformed
  42  * by a runtime compiler, on supported hardware, to Single Instruction Multiple
  43  * Data (SIMD) computations leveraging vector hardware registers and vector
  44  * hardware instructions.  Such SIMD computations exploit data parallelism to
  45  * perform the same operation on multiple data points simultaneously in a
  46  * faster time it would ordinarily take to perform the same operation
  47  * sequentially on each data point.
  48  * <p>
  49  * A Vector represents an ordered immutable sequence of values of the same
  50  * element type {@code e} that is one of the following primitive types
  51  * {@code byte}, {@code short}, {@code int}, {@code long}, {@code float}, or
  52  * {@code double}).  The type variable {@code E} corresponds to the boxed
  53  * element type, specifically the class that wraps a value of {@code e} in an
  54  * object (such the {@code Integer} class that wraps a value of {@code int}}.
  55  * A Vector has a {@link #shape() shape} {@code S}, extending type
  56  * {@link Shape}, that governs the total {@link #bitSize() size} in bits
  57  * of the sequence of values.


 886      *     order(ByteOrder.nativeOrder()).position(i).
 887      *     asEBuffer();
 888      * e[] es = ((EVector<S>)this).toArray();
 889      * for (int n = 0; n < t.length; n++) {
 890      *     if (m.isSet(n)) {
 891      *         eb.put(n, es[n]);
 892      *     }
 893      * }
 894      * }</pre>
 895      *
 896      * @param b the byte buffer
 897      * @param i the offset into the byte buffer
 898      * @param m the mask
 899      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 900      * or {@code > b.limit()},
 901      * for any vector lane index {@code N} where the mask at lane {@code N}
 902      * is set
 903      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} bytes
 904      */
 905     public abstract void intoByteBuffer(ByteBuffer b, int i, Mask<E> m);



































































































































































































































































































































































































































































































































































































































































 906 
 907     /**
 908      * Find bit size based on element type and number of elements.
 909      *
 910      * @param c the element type
 911      * @param numElem number of lanes in the vector
 912      * @return size in bits for vector
 913      */
 914     public static int bitSizeForVectorLength(Class<?> c, int numElem) {
 915         if (c == float.class) {
 916             return Float.SIZE * numElem;
 917         }
 918         else if (c == double.class) {
 919             return Double.SIZE * numElem;
 920         }
 921         else if (c == byte.class) {
 922             return Byte.SIZE * numElem;
 923         }
 924         else if (c == short.class) {
 925             return Short.SIZE * numElem;
< prev index next >