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 java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
29 import java.nio.DoubleBuffer;
30 import java.nio.ReadOnlyBufferException;
31 import java.util.Arrays;
32 import java.util.Objects;
33 import java.util.function.IntUnaryOperator;
34
35 import jdk.internal.misc.Unsafe;
36 import jdk.internal.vm.annotation.ForceInline;
37 import static jdk.incubator.vector.VectorIntrinsics.*;
38
39 @SuppressWarnings("cast")
40 final class DoubleMaxVector extends DoubleVector {
41 static final DoubleMaxSpecies SPECIES = new DoubleMaxSpecies();
42
43 static final DoubleMaxVector ZERO = new DoubleMaxVector();
44
45 static final int LENGTH = SPECIES.length();
46
47 // Index vector species
48 private static final IntVector.IntSpecies INDEX_SPEC;
49 static {
50 int bitSize = Vector.bitSizeForVectorLength(int.class, LENGTH);
51 Vector.Shape shape = Shape.forBitSize(bitSize);
52 INDEX_SPEC = (IntVector.IntSpecies) Species.of(int.class, shape);
53 }
54 private final double[] vec; // Don't access directly, use getElements() instead.
55
56 private double[] getElements() {
57 return VectorIntrinsics.maybeRebox(this).vec;
58 }
59
60 DoubleMaxVector() {
61 vec = new double[SPECIES.length()];
62 }
63
64 DoubleMaxVector(double[] v) {
65 vec = v;
66 }
67
68 @Override
69 public int length() { return LENGTH; }
70
71 // Unary operator
72
73 @Override
145
146 @Override
147 double rOp(double v, FBinOp f) {
148 double[] vec = getElements();
149 for (int i = 0; i < length(); i++) {
150 v = f.apply(i, v, vec[i]);
151 }
152 return v;
153 }
154
155 @Override
156 @ForceInline
157 public <F> Vector<F> cast(Species<F> s) {
158 Objects.requireNonNull(s);
159 if (s.length() != LENGTH)
160 throw new IllegalArgumentException("Vector length this species length differ");
161
162 return VectorIntrinsics.cast(
163 DoubleMaxVector.class,
164 double.class, LENGTH,
165 s.vectorType(),
166 s.elementType(), LENGTH,
167 this, s,
168 (species, vector) -> vector.castDefault(species)
169 );
170 }
171
172 @SuppressWarnings("unchecked")
173 @ForceInline
174 private <F> Vector<F> castDefault(Species<F> s) {
175 int limit = s.length();
176
177 Class<?> stype = s.elementType();
178 if (stype == byte.class) {
179 byte[] a = new byte[limit];
180 for (int i = 0; i < limit; i++) {
181 a[i] = (byte) this.get(i);
182 }
183 return (Vector) ByteVector.fromArray((ByteVector.ByteSpecies) s, a, 0);
184 } else if (stype == short.class) {
185 short[] a = new short[limit];
186 for (int i = 0; i < limit; i++) {
187 a[i] = (short) this.get(i);
188 }
189 return (Vector) ShortVector.fromArray((ShortVector.ShortSpecies) s, a, 0);
190 } else if (stype == int.class) {
191 int[] a = new int[limit];
192 for (int i = 0; i < limit; i++) {
193 a[i] = (int) this.get(i);
194 }
195 return (Vector) IntVector.fromArray((IntVector.IntSpecies) s, a, 0);
196 } else if (stype == long.class) {
197 long[] a = new long[limit];
198 for (int i = 0; i < limit; i++) {
199 a[i] = (long) this.get(i);
200 }
201 return (Vector) LongVector.fromArray((LongVector.LongSpecies) s, a, 0);
202 } else if (stype == float.class) {
203 float[] a = new float[limit];
204 for (int i = 0; i < limit; i++) {
205 a[i] = (float) this.get(i);
206 }
207 return (Vector) FloatVector.fromArray((FloatVector.FloatSpecies) s, a, 0);
208 } else if (stype == double.class) {
209 double[] a = new double[limit];
210 for (int i = 0; i < limit; i++) {
211 a[i] = (double) this.get(i);
212 }
213 return (Vector) DoubleVector.fromArray((DoubleVector.DoubleSpecies) s, a, 0);
214 } else {
215 throw new UnsupportedOperationException("Bad lane type for casting.");
216 }
217 }
218
219 @Override
220 @ForceInline
221 @SuppressWarnings("unchecked")
222 public <F> Vector<F> reinterpret(Species<F> s) {
223 Objects.requireNonNull(s);
224
225 if(s.elementType().equals(double.class)) {
226 return (Vector<F>) reshape((Species<Double>)s);
227 }
228 if(s.bitSize() == bitSize()) {
229 return reinterpretType(s);
230 }
231
232 return defaultReinterpret(s);
233 }
283 (species, vector) -> vector.defaultReinterpret(species)
284 );
285 } else if (stype == double.class) {
286 return VectorIntrinsics.reinterpret(
287 DoubleMaxVector.class,
288 double.class, LENGTH,
289 DoubleMaxVector.class,
290 double.class, DoubleMaxVector.LENGTH,
291 this, s,
292 (species, vector) -> vector.defaultReinterpret(species)
293 );
294 } else {
295 throw new UnsupportedOperationException("Bad lane type for casting.");
296 }
297 }
298
299 @Override
300 @ForceInline
301 public DoubleVector reshape(Species<Double> s) {
302 Objects.requireNonNull(s);
303 if (s.bitSize() == 64 && (s instanceof Double64Vector.Double64Species)) {
304 Double64Vector.Double64Species ts = (Double64Vector.Double64Species)s;
305 return VectorIntrinsics.reinterpret(
306 DoubleMaxVector.class,
307 double.class, LENGTH,
308 Double64Vector.class,
309 double.class, Double64Vector.LENGTH,
310 this, ts,
311 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
312 );
313 } else if (s.bitSize() == 128 && (s instanceof Double128Vector.Double128Species)) {
314 Double128Vector.Double128Species ts = (Double128Vector.Double128Species)s;
315 return VectorIntrinsics.reinterpret(
316 DoubleMaxVector.class,
317 double.class, LENGTH,
318 Double128Vector.class,
319 double.class, Double128Vector.LENGTH,
320 this, ts,
321 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
322 );
323 } else if (s.bitSize() == 256 && (s instanceof Double256Vector.Double256Species)) {
324 Double256Vector.Double256Species ts = (Double256Vector.Double256Species)s;
325 return VectorIntrinsics.reinterpret(
326 DoubleMaxVector.class,
327 double.class, LENGTH,
328 Double256Vector.class,
329 double.class, Double256Vector.LENGTH,
330 this, ts,
331 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
332 );
333 } else if (s.bitSize() == 512 && (s instanceof Double512Vector.Double512Species)) {
334 Double512Vector.Double512Species ts = (Double512Vector.Double512Species)s;
335 return VectorIntrinsics.reinterpret(
336 DoubleMaxVector.class,
337 double.class, LENGTH,
338 Double512Vector.class,
339 double.class, Double512Vector.LENGTH,
340 this, ts,
341 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
342 );
343 } else if ((s.bitSize() > 0) && (s.bitSize() <= 2048)
344 && (s.bitSize() % 128 == 0) && (s instanceof DoubleMaxVector.DoubleMaxSpecies)) {
345 DoubleMaxVector.DoubleMaxSpecies ts = (DoubleMaxVector.DoubleMaxSpecies)s;
346 return VectorIntrinsics.reinterpret(
347 DoubleMaxVector.class,
348 double.class, LENGTH,
349 DoubleMaxVector.class,
350 double.class, DoubleMaxVector.LENGTH,
351 this, ts,
352 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
353 );
354 } else {
355 throw new InternalError("Unimplemented size");
356 }
357 }
358
359 // Binary operations with scalars
360
361 @Override
362 @ForceInline
363 public DoubleVector add(double o) {
364 return add(SPECIES.broadcast(o));
365 }
366
367 @Override
368 @ForceInline
369 public DoubleVector add(double o, Mask<Double> m) {
370 return add(SPECIES.broadcast(o), m);
371 }
372
373 @Override
374 @ForceInline
375 public DoubleVector sub(double o) {
376 return sub(SPECIES.broadcast(o));
377 }
378
379 @Override
380 @ForceInline
381 public DoubleVector sub(double o, Mask<Double> m) {
382 return sub(SPECIES.broadcast(o), m);
383 }
384
385 @Override
386 @ForceInline
387 public DoubleVector mul(double o) {
388 return mul(SPECIES.broadcast(o));
389 }
390
391 @Override
392 @ForceInline
393 public DoubleVector mul(double o, Mask<Double> m) {
394 return mul(SPECIES.broadcast(o), m);
395 }
396
397 @Override
398 @ForceInline
399 public DoubleVector min(double o) {
400 return min(SPECIES.broadcast(o));
401 }
402
403 @Override
404 @ForceInline
405 public DoubleVector max(double o) {
406 return max(SPECIES.broadcast(o));
407 }
408
409 @Override
410 @ForceInline
411 public Mask<Double> equal(double o) {
412 return equal(SPECIES.broadcast(o));
413 }
414
415 @Override
416 @ForceInline
417 public Mask<Double> notEqual(double o) {
418 return notEqual(SPECIES.broadcast(o));
419 }
420
421 @Override
422 @ForceInline
423 public Mask<Double> lessThan(double o) {
424 return lessThan(SPECIES.broadcast(o));
425 }
426
427 @Override
428 @ForceInline
429 public Mask<Double> lessThanEq(double o) {
430 return lessThanEq(SPECIES.broadcast(o));
431 }
432
433 @Override
434 @ForceInline
435 public Mask<Double> greaterThan(double o) {
436 return greaterThan(SPECIES.broadcast(o));
437 }
438
439 @Override
440 @ForceInline
441 public Mask<Double> greaterThanEq(double o) {
442 return greaterThanEq(SPECIES.broadcast(o));
443 }
444
445 @Override
446 @ForceInline
447 public DoubleVector blend(double o, Mask<Double> m) {
448 return blend(SPECIES.broadcast(o), m);
449 }
450
451 @Override
452 @ForceInline
453 public DoubleVector div(double o) {
454 return div(SPECIES.broadcast(o));
455 }
456
457 @Override
458 @ForceInline
459 public DoubleVector div(double o, Mask<Double> m) {
460 return div(SPECIES.broadcast(o), m);
461 }
462
463 @Override
464 @ForceInline
465 public DoubleMaxVector div(Vector<Double> v, Mask<Double> m) {
466 return blend(div(v), m);
467 }
468
469 @Override
470 @ForceInline
471 public DoubleVector atan2(double o) {
472 return atan2(SPECIES.broadcast(o));
473 }
474
475 @Override
476 @ForceInline
477 public DoubleVector atan2(double o, Mask<Double> m) {
478 return atan2(SPECIES.broadcast(o), m);
479 }
480
481 @Override
482 @ForceInline
483 public DoubleVector pow(double o) {
484 return pow(SPECIES.broadcast(o));
485 }
486
487 @Override
488 @ForceInline
489 public DoubleVector pow(double o, Mask<Double> m) {
490 return pow(SPECIES.broadcast(o), m);
491 }
492
493 @Override
494 @ForceInline
495 public DoubleVector fma(double o1, double o2) {
496 return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2));
497 }
498
499 @Override
500 @ForceInline
501 public DoubleVector fma(double o1, double o2, Mask<Double> m) {
502 return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2), m);
503 }
504
505 @Override
506 @ForceInline
507 public DoubleVector hypot(double o) {
508 return hypot(SPECIES.broadcast(o));
509 }
510
511 @Override
512 @ForceInline
513 public DoubleVector hypot(double o, Mask<Double> m) {
514 return hypot(SPECIES.broadcast(o), m);
515 }
516
517
518 // Unary operations
519
520 @ForceInline
521 @Override
522 public DoubleMaxVector neg(Mask<Double> m) {
523 return blend(neg(), m);
524 }
525
526 @Override
527 @ForceInline
528 public DoubleMaxVector abs() {
529 return VectorIntrinsics.unaryOp(
530 VECTOR_OP_ABS, DoubleMaxVector.class, double.class, LENGTH,
531 this,
532 v1 -> v1.uOp((i, a) -> (double) Math.abs(a)));
533 }
534
880 return Double.longBitsToDouble(bits);
881 }
882
883 @Override
884 @ForceInline
885 public double maxAll() {
886 long bits = (long) VectorIntrinsics.reductionCoerced(
887 VECTOR_OP_MAX, DoubleMaxVector.class, double.class, LENGTH,
888 this,
889 v -> {
890 double r = v.rOp(Double.MIN_VALUE , (i, a, b) -> (double) Math.max(a, b));
891 return (long)Double.doubleToLongBits(r);
892 });
893 return Double.longBitsToDouble(bits);
894 }
895
896
897 @Override
898 @ForceInline
899 public double addAll(Mask<Double> m) {
900 return SPECIES.broadcast((double) 0).blend(this, m).addAll();
901 }
902
903
904 @Override
905 @ForceInline
906 public double mulAll(Mask<Double> m) {
907 return SPECIES.broadcast((double) 1).blend(this, m).mulAll();
908 }
909
910 @Override
911 @ForceInline
912 public double minAll(Mask<Double> m) {
913 return SPECIES.broadcast(Double.MAX_VALUE).blend(this, m).minAll();
914 }
915
916 @Override
917 @ForceInline
918 public double maxAll(Mask<Double> m) {
919 return SPECIES.broadcast(Double.MIN_VALUE).blend(this, m).maxAll();
920 }
921
922 @Override
923 @ForceInline
924 public Shuffle<Double> toShuffle() {
925 double[] a = toArray();
926 int[] sa = new int[a.length];
927 for (int i = 0; i < a.length; i++) {
928 sa[i] = (int) a[i];
929 }
930 return DoubleVector.shuffleFromArray(SPECIES, sa, 0);
931 }
932
933 // Memory operations
934
935 private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
936 private static final int BOOLEAN_ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
937
938 @Override
939 @ForceInline
944 a, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
945 this,
946 a, ix,
947 (arr, idx, v) -> v.forEach((i, e) -> arr[idx + i] = e));
948 }
949
950 @Override
951 @ForceInline
952 public final void intoArray(double[] a, int ax, Mask<Double> m) {
953 DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax);
954 DoubleVector newVal = oldVal.blend(this, m);
955 newVal.intoArray(a, ax);
956 }
957 @Override
958 @ForceInline
959 public void intoArray(double[] a, int ix, int[] b, int iy) {
960 Objects.requireNonNull(a);
961 Objects.requireNonNull(b);
962
963 // Index vector: vix[0:n] = i -> ix + indexMap[iy + i]
964 IntVector vix = IntVector.fromArray(INDEX_SPEC, b, iy).add(ix);
965
966 vix = VectorIntrinsics.checkIndex(vix, a.length);
967
968 VectorIntrinsics.storeWithMap(DoubleMaxVector.class, double.class, LENGTH, vix.getClass(),
969 a, Unsafe.ARRAY_DOUBLE_BASE_OFFSET, vix,
970 this,
971 a, ix, b, iy,
972 (arr, idx, v, indexMap, idy) -> v.forEach((i, e) -> arr[idx+indexMap[idy+i]] = e));
973 }
974
975 @Override
976 @ForceInline
977 public final void intoArray(double[] a, int ax, Mask<Double> m, int[] b, int iy) {
978 // @@@ This can result in out of bounds errors for unset mask lanes
979 DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax, b, iy);
980 DoubleVector newVal = oldVal.blend(this, m);
981 newVal.intoArray(a, ax, b, iy);
982 }
983
984 @Override
1318 boolean[] res = new boolean[species().length()];
1319 boolean[] bits = getBits();
1320 for (int i = 0; i < species().length(); i++) {
1321 res[i] = f.apply(i, bits[i]);
1322 }
1323 return new DoubleMaxMask(res);
1324 }
1325
1326 @Override
1327 DoubleMaxMask bOp(Mask<Double> o, MBinOp f) {
1328 boolean[] res = new boolean[species().length()];
1329 boolean[] bits = getBits();
1330 boolean[] mbits = ((DoubleMaxMask)o).getBits();
1331 for (int i = 0; i < species().length(); i++) {
1332 res[i] = f.apply(i, bits[i], mbits[i]);
1333 }
1334 return new DoubleMaxMask(res);
1335 }
1336
1337 @Override
1338 public DoubleMaxSpecies species() {
1339 return SPECIES;
1340 }
1341
1342 @Override
1343 public DoubleMaxVector toVector() {
1344 double[] res = new double[species().length()];
1345 boolean[] bits = getBits();
1346 for (int i = 0; i < species().length(); i++) {
1347 // -1 will result in the most significant bit being set in
1348 // addition to some or all other bits
1349 res[i] = (double) (bits[i] ? -1 : 0);
1350 }
1351 return new DoubleMaxVector(res);
1352 }
1353
1354 // Unary operations
1355
1356 @Override
1357 @ForceInline
1358 public DoubleMaxMask not() {
1359 return (DoubleMaxMask) VectorIntrinsics.unaryOp(
1360 VECTOR_OP_NOT, DoubleMaxMask.class, long.class, LENGTH,
1361 this,
1362 (m1) -> m1.uOp((i, a) -> !a));
1363 }
1364
1365 // Binary operations
1366
1367 @Override
1368 @ForceInline
1369 public DoubleMaxMask and(Mask<Double> o) {
1370 Objects.requireNonNull(o);
1371 DoubleMaxMask m = (DoubleMaxMask)o;
1372 return VectorIntrinsics.binaryOp(VECTOR_OP_AND, DoubleMaxMask.class, long.class, LENGTH,
1373 this, m,
1406 // Shuffle
1407
1408 static final class DoubleMaxShuffle extends AbstractShuffle<Double> {
1409 DoubleMaxShuffle(byte[] reorder) {
1410 super(reorder);
1411 }
1412
1413 public DoubleMaxShuffle(int[] reorder) {
1414 super(reorder);
1415 }
1416
1417 public DoubleMaxShuffle(int[] reorder, int i) {
1418 super(reorder, i);
1419 }
1420
1421 public DoubleMaxShuffle(IntUnaryOperator f) {
1422 super(f);
1423 }
1424
1425 @Override
1426 public DoubleMaxSpecies species() {
1427 return SPECIES;
1428 }
1429
1430 @Override
1431 public DoubleVector toVector() {
1432 double[] va = new double[SPECIES.length()];
1433 for (int i = 0; i < va.length; i++) {
1434 va[i] = (double) getElement(i);
1435 }
1436 return DoubleVector.fromArray(SPECIES, va, 0);
1437 }
1438
1439 @Override
1440 public DoubleMaxShuffle rearrange(Vector.Shuffle<Double> o) {
1441 DoubleMaxShuffle s = (DoubleMaxShuffle) o;
1442 byte[] r = new byte[reorder.length];
1443 for (int i = 0; i < reorder.length; i++) {
1444 r[i] = reorder[s.reorder[i]];
1445 }
1446 return new DoubleMaxShuffle(r);
1447 }
1448 }
1449
1450 // Species
1451
1452 @Override
1453 public DoubleMaxSpecies species() {
1454 return SPECIES;
1455 }
1456
1457 static final class DoubleMaxSpecies extends DoubleSpecies {
1458 static final int BIT_SIZE = Shape.S_Max_BIT.bitSize();
1459
1460 static final int LENGTH = BIT_SIZE / Double.SIZE;
1461
1462 @Override
1463 public String toString() {
1464 StringBuilder sb = new StringBuilder("Shape[");
1465 sb.append(bitSize()).append(" bits, ");
1466 sb.append(length()).append(" ").append(double.class.getSimpleName()).append("s x ");
1467 sb.append(elementSize()).append(" bits");
1468 sb.append("]");
1469 return sb.toString();
1470 }
1471
1472 @Override
1473 @ForceInline
1474 public int bitSize() {
1475 return BIT_SIZE;
1476 }
1477
1478 @Override
1479 @ForceInline
1480 public int length() {
1481 return LENGTH;
1482 }
1483
1484 @Override
1485 @ForceInline
1486 public Class<Double> elementType() {
1487 return double.class;
1488 }
1489
1490 @Override
1491 @ForceInline
1492 public Class<?> boxType() {
1493 return DoubleMaxVector.class;
1494 }
1495
1496 @Override
1497 @ForceInline
1498 public Class<?> maskType() {
1499 return DoubleMaxMask.class;
1500 }
1501
1502 @Override
1503 @ForceInline
1504 public int elementSize() {
1505 return Double.SIZE;
1506 }
1507
1508 @Override
1509 @ForceInline
1510 @SuppressWarnings("unchecked")
1511 Class<?> vectorType() {
1512 return DoubleMaxVector.class;
1513 }
1514
1515 @Override
1516 @ForceInline
1517 public Shape shape() {
1518 return Shape.S_Max_BIT;
1519 }
1520
1521 @Override
1522 IntVector.IntSpecies indexSpecies() {
1523 return INDEX_SPEC;
1524 }
1525
1526 @Override
1527 DoubleMaxVector op(FOp f) {
1528 double[] res = new double[length()];
1529 for (int i = 0; i < length(); i++) {
1530 res[i] = f.apply(i);
1531 }
1532 return new DoubleMaxVector(res);
1533 }
1534
1535 @Override
1536 DoubleMaxVector op(Mask<Double> o, FOp f) {
1537 double[] res = new double[length()];
1538 boolean[] mbits = ((DoubleMaxMask)o).getBits();
1539 for (int i = 0; i < length(); i++) {
1540 if (mbits[i]) {
1541 res[i] = f.apply(i);
1542 }
1543 }
1544 return new DoubleMaxVector(res);
1545 }
1546
1547 @Override
1548 DoubleMaxMask opm(FOpm f) {
1549 boolean[] res = new boolean[length()];
1550 for (int i = 0; i < length(); i++) {
1551 res[i] = (boolean)f.apply(i);
1552 }
1553 return new DoubleMaxMask(res);
1554 }
1555
1556 // Factories
1557
1558 @Override
1559 @ForceInline
1560 public DoubleMaxVector zero() {
1561 return VectorIntrinsics.broadcastCoerced(DoubleMaxVector.class, double.class, LENGTH,
1562 Double.doubleToLongBits(0.0f), SPECIES,
1563 ((bits, s) -> ((DoubleMaxSpecies)s).op(i -> Double.longBitsToDouble((long)bits))));
1564 }
1565
1566 @Override
1567 @ForceInline
1568 public DoubleMaxVector broadcast(double e) {
1569 return VectorIntrinsics.broadcastCoerced(
1570 DoubleMaxVector.class, double.class, LENGTH,
1571 Double.doubleToLongBits(e), SPECIES,
1572 ((bits, s) -> ((DoubleMaxSpecies)s).op(i -> Double.longBitsToDouble((long)bits))));
1573 }
1574
1575 @Override
1576 @ForceInline
1577 public DoubleMaxVector scalars(double... es) {
1578 Objects.requireNonNull(es);
1579 int ix = VectorIntrinsics.checkIndex(0, es.length, LENGTH);
1580 return VectorIntrinsics.load(DoubleMaxVector.class, double.class, LENGTH,
1581 es, Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
1582 es, ix, SPECIES,
1583 (c, idx, s) -> ((DoubleMaxSpecies)s).op(n -> c[idx + n]));
1584 }
1585
1586 @Override
1587 @ForceInline
1588 public <E> DoubleMaxMask cast(Mask<E> m) {
1589 if (m.length() != LENGTH)
1590 throw new IllegalArgumentException("Mask length this species length differ");
1591 return new DoubleMaxMask(m.toArray());
1592 }
1593
1594 @Override
1595 @ForceInline
1596 public <E> DoubleMaxShuffle cast(Shuffle<E> s) {
1597 if (s.length() != LENGTH)
1598 throw new IllegalArgumentException("Shuffle length this species length differ");
1599 return new DoubleMaxShuffle(s.toArray());
1600 }
1601 }
1602 }
|
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 java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
29 import java.nio.DoubleBuffer;
30 import java.nio.ReadOnlyBufferException;
31 import java.util.Arrays;
32 import java.util.Objects;
33 import java.util.function.IntUnaryOperator;
34
35 import jdk.internal.misc.Unsafe;
36 import jdk.internal.vm.annotation.ForceInline;
37 import static jdk.incubator.vector.VectorIntrinsics.*;
38
39 @SuppressWarnings("cast")
40 final class DoubleMaxVector extends DoubleVector {
41 private static final Species<Double> SPECIES = DoubleVector.SPECIES_MAX;
42
43 static final DoubleMaxVector ZERO = new DoubleMaxVector();
44
45 static final int LENGTH = SPECIES.length();
46
47 // Index vector species
48 private static final IntVector.IntSpecies INDEX_SPECIES;
49
50 static {
51 int bitSize = Vector.bitSizeForVectorLength(int.class, LENGTH);
52 INDEX_SPECIES = (IntVector.IntSpecies) IntVector.species(Shape.forBitSize(bitSize));
53 }
54
55 private final double[] vec; // Don't access directly, use getElements() instead.
56
57 private double[] getElements() {
58 return VectorIntrinsics.maybeRebox(this).vec;
59 }
60
61 DoubleMaxVector() {
62 vec = new double[SPECIES.length()];
63 }
64
65 DoubleMaxVector(double[] v) {
66 vec = v;
67 }
68
69 @Override
70 public int length() { return LENGTH; }
71
72 // Unary operator
73
74 @Override
146
147 @Override
148 double rOp(double v, FBinOp f) {
149 double[] vec = getElements();
150 for (int i = 0; i < length(); i++) {
151 v = f.apply(i, v, vec[i]);
152 }
153 return v;
154 }
155
156 @Override
157 @ForceInline
158 public <F> Vector<F> cast(Species<F> s) {
159 Objects.requireNonNull(s);
160 if (s.length() != LENGTH)
161 throw new IllegalArgumentException("Vector length this species length differ");
162
163 return VectorIntrinsics.cast(
164 DoubleMaxVector.class,
165 double.class, LENGTH,
166 s.boxType(),
167 s.elementType(), LENGTH,
168 this, s,
169 (species, vector) -> vector.castDefault(species)
170 );
171 }
172
173 @SuppressWarnings("unchecked")
174 @ForceInline
175 private <F> Vector<F> castDefault(Species<F> s) {
176 int limit = s.length();
177
178 Class<?> stype = s.elementType();
179 if (stype == byte.class) {
180 byte[] a = new byte[limit];
181 for (int i = 0; i < limit; i++) {
182 a[i] = (byte) this.get(i);
183 }
184 return (Vector) ByteVector.fromArray((Species<Byte>) s, a, 0);
185 } else if (stype == short.class) {
186 short[] a = new short[limit];
187 for (int i = 0; i < limit; i++) {
188 a[i] = (short) this.get(i);
189 }
190 return (Vector) ShortVector.fromArray((Species<Short>) s, a, 0);
191 } else if (stype == int.class) {
192 int[] a = new int[limit];
193 for (int i = 0; i < limit; i++) {
194 a[i] = (int) this.get(i);
195 }
196 return (Vector) IntVector.fromArray((Species<Integer>) s, a, 0);
197 } else if (stype == long.class) {
198 long[] a = new long[limit];
199 for (int i = 0; i < limit; i++) {
200 a[i] = (long) this.get(i);
201 }
202 return (Vector) LongVector.fromArray((Species<Long>) s, a, 0);
203 } else if (stype == float.class) {
204 float[] a = new float[limit];
205 for (int i = 0; i < limit; i++) {
206 a[i] = (float) this.get(i);
207 }
208 return (Vector) FloatVector.fromArray((Species<Float>) s, a, 0);
209 } else if (stype == double.class) {
210 double[] a = new double[limit];
211 for (int i = 0; i < limit; i++) {
212 a[i] = (double) this.get(i);
213 }
214 return (Vector) DoubleVector.fromArray((Species<Double>) s, a, 0);
215 } else {
216 throw new UnsupportedOperationException("Bad lane type for casting.");
217 }
218 }
219
220 @Override
221 @ForceInline
222 @SuppressWarnings("unchecked")
223 public <F> Vector<F> reinterpret(Species<F> s) {
224 Objects.requireNonNull(s);
225
226 if(s.elementType().equals(double.class)) {
227 return (Vector<F>) reshape((Species<Double>)s);
228 }
229 if(s.bitSize() == bitSize()) {
230 return reinterpretType(s);
231 }
232
233 return defaultReinterpret(s);
234 }
284 (species, vector) -> vector.defaultReinterpret(species)
285 );
286 } else if (stype == double.class) {
287 return VectorIntrinsics.reinterpret(
288 DoubleMaxVector.class,
289 double.class, LENGTH,
290 DoubleMaxVector.class,
291 double.class, DoubleMaxVector.LENGTH,
292 this, s,
293 (species, vector) -> vector.defaultReinterpret(species)
294 );
295 } else {
296 throw new UnsupportedOperationException("Bad lane type for casting.");
297 }
298 }
299
300 @Override
301 @ForceInline
302 public DoubleVector reshape(Species<Double> s) {
303 Objects.requireNonNull(s);
304 if (s.bitSize() == 64 && (s.boxType() == Double64Vector.class)) {
305 return VectorIntrinsics.reinterpret(
306 DoubleMaxVector.class,
307 double.class, LENGTH,
308 Double64Vector.class,
309 double.class, Double64Vector.LENGTH,
310 this, s,
311 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
312 );
313 } else if (s.bitSize() == 128 && (s.boxType() == Double128Vector.class)) {
314 return VectorIntrinsics.reinterpret(
315 DoubleMaxVector.class,
316 double.class, LENGTH,
317 Double128Vector.class,
318 double.class, Double128Vector.LENGTH,
319 this, s,
320 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
321 );
322 } else if (s.bitSize() == 256 && (s.boxType() == Double256Vector.class)) {
323 return VectorIntrinsics.reinterpret(
324 DoubleMaxVector.class,
325 double.class, LENGTH,
326 Double256Vector.class,
327 double.class, Double256Vector.LENGTH,
328 this, s,
329 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
330 );
331 } else if (s.bitSize() == 512 && (s.boxType() == Double512Vector.class)) {
332 return VectorIntrinsics.reinterpret(
333 DoubleMaxVector.class,
334 double.class, LENGTH,
335 Double512Vector.class,
336 double.class, Double512Vector.LENGTH,
337 this, s,
338 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
339 );
340 } else if ((s.bitSize() > 0) && (s.bitSize() <= 2048)
341 && (s.bitSize() % 128 == 0) && (s.boxType() == DoubleMaxVector.class)) {
342 return VectorIntrinsics.reinterpret(
343 DoubleMaxVector.class,
344 double.class, LENGTH,
345 DoubleMaxVector.class,
346 double.class, DoubleMaxVector.LENGTH,
347 this, s,
348 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
349 );
350 } else {
351 throw new InternalError("Unimplemented size");
352 }
353 }
354
355 // Binary operations with scalars
356
357 @Override
358 @ForceInline
359 public DoubleVector add(double o) {
360 return add((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
361 }
362
363 @Override
364 @ForceInline
365 public DoubleVector add(double o, Mask<Double> m) {
366 return add((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
367 }
368
369 @Override
370 @ForceInline
371 public DoubleVector sub(double o) {
372 return sub((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
373 }
374
375 @Override
376 @ForceInline
377 public DoubleVector sub(double o, Mask<Double> m) {
378 return sub((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
379 }
380
381 @Override
382 @ForceInline
383 public DoubleVector mul(double o) {
384 return mul((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
385 }
386
387 @Override
388 @ForceInline
389 public DoubleVector mul(double o, Mask<Double> m) {
390 return mul((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
391 }
392
393 @Override
394 @ForceInline
395 public DoubleVector min(double o) {
396 return min((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
397 }
398
399 @Override
400 @ForceInline
401 public DoubleVector max(double o) {
402 return max((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
403 }
404
405 @Override
406 @ForceInline
407 public Mask<Double> equal(double o) {
408 return equal((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
409 }
410
411 @Override
412 @ForceInline
413 public Mask<Double> notEqual(double o) {
414 return notEqual((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
415 }
416
417 @Override
418 @ForceInline
419 public Mask<Double> lessThan(double o) {
420 return lessThan((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
421 }
422
423 @Override
424 @ForceInline
425 public Mask<Double> lessThanEq(double o) {
426 return lessThanEq((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
427 }
428
429 @Override
430 @ForceInline
431 public Mask<Double> greaterThan(double o) {
432 return greaterThan((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
433 }
434
435 @Override
436 @ForceInline
437 public Mask<Double> greaterThanEq(double o) {
438 return greaterThanEq((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
439 }
440
441 @Override
442 @ForceInline
443 public DoubleVector blend(double o, Mask<Double> m) {
444 return blend((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
445 }
446
447 @Override
448 @ForceInline
449 public DoubleVector div(double o) {
450 return div((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
451 }
452
453 @Override
454 @ForceInline
455 public DoubleVector div(double o, Mask<Double> m) {
456 return div((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
457 }
458
459 @Override
460 @ForceInline
461 public DoubleMaxVector div(Vector<Double> v, Mask<Double> m) {
462 return blend(div(v), m);
463 }
464
465 @Override
466 @ForceInline
467 public DoubleVector atan2(double o) {
468 return atan2((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
469 }
470
471 @Override
472 @ForceInline
473 public DoubleVector atan2(double o, Mask<Double> m) {
474 return atan2((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
475 }
476
477 @Override
478 @ForceInline
479 public DoubleVector pow(double o) {
480 return pow((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
481 }
482
483 @Override
484 @ForceInline
485 public DoubleVector pow(double o, Mask<Double> m) {
486 return pow((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
487 }
488
489 @Override
490 @ForceInline
491 public DoubleVector fma(double o1, double o2) {
492 return fma((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o1), (DoubleMaxVector)DoubleVector.broadcast(SPECIES, o2));
493 }
494
495 @Override
496 @ForceInline
497 public DoubleVector fma(double o1, double o2, Mask<Double> m) {
498 return fma((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o1), (DoubleMaxVector)DoubleVector.broadcast(SPECIES, o2), m);
499 }
500
501 @Override
502 @ForceInline
503 public DoubleVector hypot(double o) {
504 return hypot((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o));
505 }
506
507 @Override
508 @ForceInline
509 public DoubleVector hypot(double o, Mask<Double> m) {
510 return hypot((DoubleMaxVector)DoubleVector.broadcast(SPECIES, o), m);
511 }
512
513
514 // Unary operations
515
516 @ForceInline
517 @Override
518 public DoubleMaxVector neg(Mask<Double> m) {
519 return blend(neg(), m);
520 }
521
522 @Override
523 @ForceInline
524 public DoubleMaxVector abs() {
525 return VectorIntrinsics.unaryOp(
526 VECTOR_OP_ABS, DoubleMaxVector.class, double.class, LENGTH,
527 this,
528 v1 -> v1.uOp((i, a) -> (double) Math.abs(a)));
529 }
530
876 return Double.longBitsToDouble(bits);
877 }
878
879 @Override
880 @ForceInline
881 public double maxAll() {
882 long bits = (long) VectorIntrinsics.reductionCoerced(
883 VECTOR_OP_MAX, DoubleMaxVector.class, double.class, LENGTH,
884 this,
885 v -> {
886 double r = v.rOp(Double.MIN_VALUE , (i, a, b) -> (double) Math.max(a, b));
887 return (long)Double.doubleToLongBits(r);
888 });
889 return Double.longBitsToDouble(bits);
890 }
891
892
893 @Override
894 @ForceInline
895 public double addAll(Mask<Double> m) {
896 return blend((DoubleMaxVector)DoubleVector.broadcast(SPECIES, (double) 0), m).addAll();
897 }
898
899
900 @Override
901 @ForceInline
902 public double mulAll(Mask<Double> m) {
903 return blend((DoubleMaxVector)DoubleVector.broadcast(SPECIES, (double) 1), m).mulAll();
904 }
905
906 @Override
907 @ForceInline
908 public double minAll(Mask<Double> m) {
909 return blend((DoubleMaxVector)DoubleVector.broadcast(SPECIES, Double.MAX_VALUE), m).minAll();
910 }
911
912 @Override
913 @ForceInline
914 public double maxAll(Mask<Double> m) {
915 return blend((DoubleMaxVector)DoubleVector.broadcast(SPECIES, Double.MIN_VALUE), m).maxAll();
916 }
917
918 @Override
919 @ForceInline
920 public Shuffle<Double> toShuffle() {
921 double[] a = toArray();
922 int[] sa = new int[a.length];
923 for (int i = 0; i < a.length; i++) {
924 sa[i] = (int) a[i];
925 }
926 return DoubleVector.shuffleFromArray(SPECIES, sa, 0);
927 }
928
929 // Memory operations
930
931 private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
932 private static final int BOOLEAN_ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
933
934 @Override
935 @ForceInline
940 a, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
941 this,
942 a, ix,
943 (arr, idx, v) -> v.forEach((i, e) -> arr[idx + i] = e));
944 }
945
946 @Override
947 @ForceInline
948 public final void intoArray(double[] a, int ax, Mask<Double> m) {
949 DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax);
950 DoubleVector newVal = oldVal.blend(this, m);
951 newVal.intoArray(a, ax);
952 }
953 @Override
954 @ForceInline
955 public void intoArray(double[] a, int ix, int[] b, int iy) {
956 Objects.requireNonNull(a);
957 Objects.requireNonNull(b);
958
959 // Index vector: vix[0:n] = i -> ix + indexMap[iy + i]
960 IntVector vix = IntVector.fromArray(INDEX_SPECIES, b, iy).add(ix);
961
962 vix = VectorIntrinsics.checkIndex(vix, a.length);
963
964 VectorIntrinsics.storeWithMap(DoubleMaxVector.class, double.class, LENGTH, vix.getClass(),
965 a, Unsafe.ARRAY_DOUBLE_BASE_OFFSET, vix,
966 this,
967 a, ix, b, iy,
968 (arr, idx, v, indexMap, idy) -> v.forEach((i, e) -> arr[idx+indexMap[idy+i]] = e));
969 }
970
971 @Override
972 @ForceInline
973 public final void intoArray(double[] a, int ax, Mask<Double> m, int[] b, int iy) {
974 // @@@ This can result in out of bounds errors for unset mask lanes
975 DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax, b, iy);
976 DoubleVector newVal = oldVal.blend(this, m);
977 newVal.intoArray(a, ax, b, iy);
978 }
979
980 @Override
1314 boolean[] res = new boolean[species().length()];
1315 boolean[] bits = getBits();
1316 for (int i = 0; i < species().length(); i++) {
1317 res[i] = f.apply(i, bits[i]);
1318 }
1319 return new DoubleMaxMask(res);
1320 }
1321
1322 @Override
1323 DoubleMaxMask bOp(Mask<Double> o, MBinOp f) {
1324 boolean[] res = new boolean[species().length()];
1325 boolean[] bits = getBits();
1326 boolean[] mbits = ((DoubleMaxMask)o).getBits();
1327 for (int i = 0; i < species().length(); i++) {
1328 res[i] = f.apply(i, bits[i], mbits[i]);
1329 }
1330 return new DoubleMaxMask(res);
1331 }
1332
1333 @Override
1334 public Species<Double> species() {
1335 return SPECIES;
1336 }
1337
1338 @Override
1339 public DoubleMaxVector toVector() {
1340 double[] res = new double[species().length()];
1341 boolean[] bits = getBits();
1342 for (int i = 0; i < species().length(); i++) {
1343 // -1 will result in the most significant bit being set in
1344 // addition to some or all other bits
1345 res[i] = (double) (bits[i] ? -1 : 0);
1346 }
1347 return new DoubleMaxVector(res);
1348 }
1349
1350 @Override
1351 @ForceInline
1352 @SuppressWarnings("unchecked")
1353 public <E> Mask<E> cast(Species<E> species) {
1354 if (length() != species.length())
1355 throw new IllegalArgumentException("Mask length and species length differ");
1356 Class<?> stype = species.elementType();
1357 boolean [] maskArray = toArray();
1358 if (stype == byte.class) {
1359 return (Mask <E>) new ByteMaxVector.ByteMaxMask(maskArray);
1360 } else if (stype == short.class) {
1361 return (Mask <E>) new ShortMaxVector.ShortMaxMask(maskArray);
1362 } else if (stype == int.class) {
1363 return (Mask <E>) new IntMaxVector.IntMaxMask(maskArray);
1364 } else if (stype == long.class) {
1365 return (Mask <E>) new LongMaxVector.LongMaxMask(maskArray);
1366 } else if (stype == float.class) {
1367 return (Mask <E>) new FloatMaxVector.FloatMaxMask(maskArray);
1368 } else if (stype == double.class) {
1369 return (Mask <E>) new DoubleMaxVector.DoubleMaxMask(maskArray);
1370 } else {
1371 throw new UnsupportedOperationException("Bad lane type for casting.");
1372 }
1373 }
1374
1375 // Unary operations
1376
1377 @Override
1378 @ForceInline
1379 public DoubleMaxMask not() {
1380 return (DoubleMaxMask) VectorIntrinsics.unaryOp(
1381 VECTOR_OP_NOT, DoubleMaxMask.class, long.class, LENGTH,
1382 this,
1383 (m1) -> m1.uOp((i, a) -> !a));
1384 }
1385
1386 // Binary operations
1387
1388 @Override
1389 @ForceInline
1390 public DoubleMaxMask and(Mask<Double> o) {
1391 Objects.requireNonNull(o);
1392 DoubleMaxMask m = (DoubleMaxMask)o;
1393 return VectorIntrinsics.binaryOp(VECTOR_OP_AND, DoubleMaxMask.class, long.class, LENGTH,
1394 this, m,
1427 // Shuffle
1428
1429 static final class DoubleMaxShuffle extends AbstractShuffle<Double> {
1430 DoubleMaxShuffle(byte[] reorder) {
1431 super(reorder);
1432 }
1433
1434 public DoubleMaxShuffle(int[] reorder) {
1435 super(reorder);
1436 }
1437
1438 public DoubleMaxShuffle(int[] reorder, int i) {
1439 super(reorder, i);
1440 }
1441
1442 public DoubleMaxShuffle(IntUnaryOperator f) {
1443 super(f);
1444 }
1445
1446 @Override
1447 public Species<Double> species() {
1448 return SPECIES;
1449 }
1450
1451 @Override
1452 public DoubleVector toVector() {
1453 double[] va = new double[SPECIES.length()];
1454 for (int i = 0; i < va.length; i++) {
1455 va[i] = (double) getElement(i);
1456 }
1457 return DoubleVector.fromArray(SPECIES, va, 0);
1458 }
1459
1460 @Override
1461 @ForceInline
1462 @SuppressWarnings("unchecked")
1463 public <F> Shuffle<F> cast(Species<F> species) {
1464 if (length() != species.length())
1465 throw new IllegalArgumentException("Shuffle length and species length differ");
1466 Class<?> stype = species.elementType();
1467 int [] shuffleArray = toArray();
1468 if (stype == byte.class) {
1469 return (Shuffle<F>) new ByteMaxVector.ByteMaxShuffle(shuffleArray);
1470 } else if (stype == short.class) {
1471 return (Shuffle<F>) new ShortMaxVector.ShortMaxShuffle(shuffleArray);
1472 } else if (stype == int.class) {
1473 return (Shuffle<F>) new IntMaxVector.IntMaxShuffle(shuffleArray);
1474 } else if (stype == long.class) {
1475 return (Shuffle<F>) new LongMaxVector.LongMaxShuffle(shuffleArray);
1476 } else if (stype == float.class) {
1477 return (Shuffle<F>) new FloatMaxVector.FloatMaxShuffle(shuffleArray);
1478 } else if (stype == double.class) {
1479 return (Shuffle<F>) new DoubleMaxVector.DoubleMaxShuffle(shuffleArray);
1480 } else {
1481 throw new UnsupportedOperationException("Bad lane type for casting.");
1482 }
1483 }
1484
1485 @Override
1486 public DoubleMaxShuffle rearrange(Vector.Shuffle<Double> o) {
1487 DoubleMaxShuffle s = (DoubleMaxShuffle) o;
1488 byte[] r = new byte[reorder.length];
1489 for (int i = 0; i < reorder.length; i++) {
1490 r[i] = reorder[s.reorder[i]];
1491 }
1492 return new DoubleMaxShuffle(r);
1493 }
1494 }
1495
1496 // Species
1497
1498 @Override
1499 public Species<Double> species() {
1500 return SPECIES;
1501 }
1502 }
|