< prev index next >

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

Print this page
rev 55891 : 8222897: [vector] Renaming of shift, rotate operations. Few other api changes.
Summary: Renaming of shift, rotate operations. Few other api changes.
Reviewed-by: jrose, briangoetz
rev 55894 : 8222897: [vector] Renaming of shift, rotate operations. Few other api changes.
Summary: Renaming of shift, rotate operations. Few other api changes.
Reviewed-by: jrose, briangoetz


  95     interface FUnCon {
  96         void apply(int i, double a);
  97     }
  98 
  99     abstract void forEach(FUnCon f);
 100 
 101     abstract void forEach(VectorMask<Double> m, FUnCon f);
 102 
 103     // Static factories
 104 
 105     /**
 106      * Returns a vector where all lane elements are set to the default
 107      * primitive value.
 108      *
 109      * @param species species of desired vector
 110      * @return a zero vector of given species
 111      */
 112     @ForceInline
 113     @SuppressWarnings("unchecked")
 114     public static DoubleVector zero(VectorSpecies<Double> species) {
 115         return VectorIntrinsics.broadcastCoerced((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 116                                                  Double.doubleToLongBits(0.0f), species,
 117                                                  ((bits, s) -> ((DoubleSpecies)s).op(i -> Double.longBitsToDouble((long)bits))));
 118     }
 119 
 120     /**
 121      * Loads a vector from a byte array starting at an offset.
 122      * <p>
 123      * Bytes are composed into primitive lane elements according to the
 124      * native byte order of the underlying platform
 125      * <p>
 126      * This method behaves as if it returns the result of calling the
 127      * byte buffer, offset, and mask accepting
 128      * {@link #fromByteBuffer(VectorSpecies, ByteBuffer, int, VectorMask) method} as follows:
 129      * <pre>{@code
 130      * return fromByteBuffer(species, ByteBuffer.wrap(a), offset, VectorMask.allTrue());
 131      * }</pre>
 132      *
 133      * @param species species of desired vector
 134      * @param a the byte array
 135      * @param offset the offset into the array
 136      * @return a vector loaded from a byte array
 137      * @throws IndexOutOfBoundsException if {@code i < 0} or
 138      * {@code offset > a.length - (species.length() * species.elementSize() / Byte.SIZE)}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static DoubleVector fromByteArray(VectorSpecies<Double> species, byte[] a, int offset) {
 143         Objects.requireNonNull(a);
 144         offset = VectorIntrinsics.checkIndex(offset, a.length, species.bitSize() / Byte.SIZE);
 145         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 146                                      a, ((long) offset) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 147                                      a, offset, species,
 148                                      (c, idx, s) -> {
 149                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 150                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 151                                          return ((DoubleSpecies)s).op(i -> tb.get());
 152                                      });
 153     }
 154 
 155     /**
 156      * Loads a vector from a byte array starting at an offset and using a
 157      * mask.
 158      * <p>
 159      * Bytes are composed into primitive lane elements according to the
 160      * native byte order of the underlying platform.
 161      * <p>
 162      * This method behaves as if it returns the result of calling the
 163      * byte buffer, offset, and mask accepting
 164      * {@link #fromByteBuffer(VectorSpecies, ByteBuffer, int, VectorMask) method} as follows:
 165      * <pre>{@code


 183 
 184     /**
 185      * Loads a vector from an array starting at offset.
 186      * <p>
 187      * For each vector lane, where {@code N} is the vector lane index, the
 188      * array element at index {@code offset + N} is placed into the
 189      * resulting vector at lane index {@code N}.
 190      *
 191      * @param species species of desired vector
 192      * @param a the array
 193      * @param offset the offset into the array
 194      * @return the vector loaded from an array
 195      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
 196      * {@code offset > a.length - species.length()}
 197      */
 198     @ForceInline
 199     @SuppressWarnings("unchecked")
 200     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int offset){
 201         Objects.requireNonNull(a);
 202         offset = VectorIntrinsics.checkIndex(offset, a.length, species.length());
 203         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 204                                      a, (((long) offset) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 205                                      a, offset, species,
 206                                      (c, idx, s) -> ((DoubleSpecies)s).op(n -> c[idx + n]));
 207     }
 208 
 209 
 210     /**
 211      * Loads a vector from an array starting at offset and using a mask.
 212      * <p>
 213      * For each vector lane, where {@code N} is the vector lane index,
 214      * if the mask lane at index {@code N} is set then the array element at
 215      * index {@code offset + N} is placed into the resulting vector at lane index
 216      * {@code N}, otherwise the default element value is placed into the
 217      * resulting vector at lane index {@code N}.
 218      *
 219      * @param species species of desired vector
 220      * @param a the array
 221      * @param offset the offset into the array
 222      * @param m the mask
 223      * @return the vector loaded from an array


 249      * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or
 250      * {@code i_offset > indexMap.length - species.length()},
 251      * or for any vector lane index {@code N} the result of
 252      * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length}
 253      */
 254     @ForceInline
 255     @SuppressWarnings("unchecked")
 256     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int a_offset, int[] indexMap, int i_offset) {
 257         Objects.requireNonNull(a);
 258         Objects.requireNonNull(indexMap);
 259 
 260         if (species.length() == 1) {
 261           return DoubleVector.fromArray(species, a, a_offset + indexMap[i_offset]);
 262         }
 263 
 264         // Index vector: vix[0:n] = k -> a_offset + indexMap[i_offset + k]
 265         IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, i_offset).add(a_offset);
 266 
 267         vix = VectorIntrinsics.checkIndex(vix, a.length);
 268 
 269         return VectorIntrinsics.loadWithMap((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 270                                             IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_DOUBLE_BASE_OFFSET, vix,
 271                                             a, a_offset, indexMap, i_offset, species,
 272                                             (double[] c, int idx, int[] iMap, int idy, VectorSpecies<Double> s) ->
 273                                                 ((DoubleSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 274         }
 275 
 276     /**
 277      * Loads a vector from an array using indexes obtained from an index
 278      * map and using a mask.
 279      * <p>
 280      * For each vector lane, where {@code N} is the vector lane index,
 281      * if the mask lane at index {@code N} is set then the array element at
 282      * index {@code a_offset + indexMap[i_offset + N]} is placed into the resulting vector
 283      * at lane index {@code N}.
 284      *
 285      * @param species species of desired vector
 286      * @param a the array
 287      * @param a_offset the offset into the array, may be negative if relative
 288      * indexes in the index map compensate to produce a value within the
 289      * array bounds
 290      * @param m the mask


 319      *   return fromByteBuffer(b, offset, VectorMask.allTrue())
 320      * }</pre>
 321      *
 322      * @param species species of desired vector
 323      * @param bb the byte buffer
 324      * @param offset the offset into the byte buffer
 325      * @return a vector loaded from a byte buffer
 326      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 327      * or {@code > b.limit()},
 328      * or if there are fewer than
 329      * {@code species.length() * species.elementSize() / Byte.SIZE} bytes
 330      * remaining in the byte buffer from the given offset
 331      */
 332     @ForceInline
 333     @SuppressWarnings("unchecked")
 334     public static DoubleVector fromByteBuffer(VectorSpecies<Double> species, ByteBuffer bb, int offset) {
 335         if (bb.order() != ByteOrder.nativeOrder()) {
 336             throw new IllegalArgumentException();
 337         }
 338         offset = VectorIntrinsics.checkIndex(offset, bb.limit(), species.bitSize() / Byte.SIZE);
 339         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 340                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + offset,
 341                                      bb, offset, species,
 342                                      (c, idx, s) -> {
 343                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 344                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 345                                          return ((DoubleSpecies)s).op(i -> tb.get());
 346                                      });
 347     }
 348 
 349     /**
 350      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 351      * offset into the byte buffer and using a mask.
 352      * <p>
 353      * This method behaves as if the byte buffer is viewed as a primitive
 354      * {@link java.nio.Buffer buffer} for the primitive element type,
 355      * according to the native byte order of the underlying platform, and
 356      * the returned vector is loaded with a mask from a primitive array
 357      * obtained from the primitive buffer.
 358      * The following pseudocode expresses the behaviour, where
 359      * {@code EBuffer} is the primitive buffer type, {@code e} is the


 375      * @param bb the byte buffer
 376      * @param offset the offset into the byte buffer
 377      * @param m the mask
 378      * @return a vector loaded from a byte buffer
 379      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 380      * or {@code > b.limit()},
 381      * for any vector lane index {@code N} where the mask at lane {@code N}
 382      * is set
 383      * {@code offset >= b.limit() - (N * species.elementSize() / Byte.SIZE)}
 384      */
 385     @ForceInline
 386     public static DoubleVector fromByteBuffer(VectorSpecies<Double> species, ByteBuffer bb, int offset, VectorMask<Double> m) {
 387         return zero(species).blend(fromByteBuffer(species, bb, offset), m);
 388     }
 389 
 390     /**
 391      * Returns a vector where all lane elements are set to the primitive
 392      * value {@code e}.
 393      *
 394      * @param species species of the desired vector
 395      * @param e the value
 396      * @return a vector of vector where all lane elements are set to
 397      * the primitive value {@code e}
 398      */
 399     @ForceInline
 400     @SuppressWarnings("unchecked")
 401     public static DoubleVector broadcast(VectorSpecies<Double> species, double e) {
 402         return VectorIntrinsics.broadcastCoerced(
 403             (Class<DoubleVector>) species.boxType(), double.class, species.length(),
 404             Double.doubleToLongBits(e), species,
 405             ((bits, sp) -> ((DoubleSpecies)sp).op(i -> Double.longBitsToDouble((long)bits))));
 406     }
 407 
 408     /**
 409      * Returns a vector where each lane element is set to given
 410      * primitive values.
 411      * <p>
 412      * For each vector lane, where {@code N} is the vector lane index, the
 413      * the primitive value at index {@code N} is placed into the resulting
 414      * vector at lane index {@code N}.
 415      *
 416      * @param species species of the desired vector
 417      * @param es the given primitive values
 418      * @return a vector where each lane element is set to given primitive
 419      * values
 420      * @throws IndexOutOfBoundsException if {@code es.length < species.length()}
 421      */
 422     @ForceInline
 423     @SuppressWarnings("unchecked")
 424     public static DoubleVector scalars(VectorSpecies<Double> species, double... es) {
 425         Objects.requireNonNull(es);
 426         int ix = VectorIntrinsics.checkIndex(0, es.length, species.length());
 427         return VectorIntrinsics.load((Class<DoubleVector>) species.boxType(), double.class, species.length(),
 428                                      es, Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 429                                      es, ix, species,
 430                                      (c, idx, sp) -> ((DoubleSpecies)sp).op(n -> c[idx + n]));
 431     }
 432 
 433     /**
 434      * Returns a vector where the first lane element is set to the primtive
 435      * value {@code e}, all other lane elements are set to the default
 436      * value.
 437      *
 438      * @param species species of the desired vector
 439      * @param e the value
 440      * @return a vector where the first lane element is set to the primitive
 441      * value {@code e}
 442      */
 443     @ForceInline
 444     public static final DoubleVector single(VectorSpecies<Double> species, double e) {
 445         return zero(species).with(0, e);
 446     }
 447 


 785     @Override
 786     public abstract DoubleVector rearrange(Vector<Double> v,
 787                                                       VectorShuffle<Double> s, VectorMask<Double> m);
 788 
 789     /**
 790      * {@inheritDoc}
 791      */
 792     @Override
 793     public abstract DoubleVector rearrange(VectorShuffle<Double> m);
 794 
 795     /**
 796      * {@inheritDoc}
 797      */
 798     @Override
 799     public abstract DoubleVector reshape(VectorSpecies<Double> s);
 800 
 801     /**
 802      * {@inheritDoc}
 803      */
 804     @Override
 805     public abstract DoubleVector rotateEL(int i);
 806 
 807     /**
 808      * {@inheritDoc}
 809      */
 810     @Override
 811     public abstract DoubleVector rotateER(int i);
 812 
 813     /**
 814      * {@inheritDoc}
 815      */
 816     @Override
 817     public abstract DoubleVector shiftEL(int i);
 818 
 819     /**
 820      * {@inheritDoc}
 821      */
 822     @Override
 823     public abstract DoubleVector shiftER(int i);
 824 
 825     /**
 826      * Divides this vector by an input vector.
 827      * <p>
 828      * This is a lane-wise binary operation which applies the primitive division
 829      * operation ({@code /}) to each lane.
 830      *
 831      * @param v the input vector
 832      * @return the result of dividing this vector by the input vector
 833      */
 834     public abstract DoubleVector div(Vector<Double> v);
 835 
 836     /**
 837      * Divides this vector by the broadcast of an input scalar.
 838      * <p>
 839      * This is a lane-wise binary operation which applies the primitive division
 840      * operation ({@code /}) to each lane.
 841      *
 842      * @param s the input scalar
 843      * @return the result of dividing this vector by the broadcast of an input


1705 
1706     // Type specific horizontal reductions
1707     /**
1708      * Adds all lane elements of this vector.
1709      * <p>
1710      * This is a cross-lane reduction operation which applies the addition
1711      * operation ({@code +}) to lane elements,
1712      * and the identity value is {@code 0.0}.
1713      *
1714      * <p>The value of a floating-point sum is a function both of the input values as well
1715      * as the order of addition operations. The order of addition operations of this method
1716      * is intentionally not defined to allow for JVM to generate optimal machine
1717      * code for the underlying platform at runtime. If the platform supports a vector
1718      * instruction to add all values in the vector, or if there is some other efficient machine
1719      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1720      * the default implementation of adding vectors sequentially from left to right is used.
1721      * For this reason, the output of this method may vary for the same input values.
1722      *
1723      * @return the addition of all the lane elements of this vector
1724      */
1725     public abstract double addAll();
1726 
1727     /**
1728      * Adds all lane elements of this vector, selecting lane elements
1729      * controlled by a mask.
1730      * <p>
1731      * This is a cross-lane reduction operation which applies the addition
1732      * operation ({@code +}) to lane elements,
1733      * and the identity value is {@code 0.0}.
1734      *
1735      * <p>The value of a floating-point sum is a function both of the input values as well
1736      * as the order of addition operations. The order of addition operations of this method
1737      * is intentionally not defined to allow for JVM to generate optimal machine
1738      * code for the underlying platform at runtime. If the platform supports a vector
1739      * instruction to add all values in the vector, or if there is some other efficient machine
1740      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1741      * the default implementation of adding vectors sequentially from left to right is used.
1742      * For this reason, the output of this method may vary on the same input values.
1743      *
1744      * @param m the mask controlling lane selection
1745      * @return the addition of the selected lane elements of this vector
1746      */
1747     public abstract double addAll(VectorMask<Double> m);
1748 
1749     /**
1750      * Multiplies all lane elements of this vector.
1751      * <p>
1752      * This is a cross-lane reduction operation which applies the
1753      * multiplication operation ({@code *}) to lane elements,
1754      * and the identity value is {@code 1.0}.
1755      *
1756      * <p>The order of multiplication operations of this method
1757      * is intentionally not defined to allow for JVM to generate optimal machine
1758      * code for the underlying platform at runtime. If the platform supports a vector
1759      * instruction to multiply all values in the vector, or if there is some other efficient machine
1760      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1761      * the default implementation of multiplying vectors sequentially from left to right is used.
1762      * For this reason, the output of this method may vary on the same input values.
1763      *
1764      * @return the multiplication of all the lane elements of this vector
1765      */
1766     public abstract double mulAll();
1767 
1768     /**
1769      * Multiplies all lane elements of this vector, selecting lane elements
1770      * controlled by a mask.
1771      * <p>
1772      * This is a cross-lane reduction operation which applies the
1773      * multiplication operation ({@code *}) to lane elements,
1774      * and the identity value is {@code 1.0}.
1775      *
1776      * <p>The order of multiplication operations of this method
1777      * is intentionally not defined to allow for JVM to generate optimal machine
1778      * code for the underlying platform at runtime. If the platform supports a vector
1779      * instruction to multiply all values in the vector, or if there is some other efficient machine
1780      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1781      * the default implementation of multiplying vectors sequentially from left to right is used.
1782      * For this reason, the output of this method may vary on the same input values.
1783      *
1784      * @param m the mask controlling lane selection
1785      * @return the multiplication of all the lane elements of this vector
1786      */
1787     public abstract double mulAll(VectorMask<Double> m);
1788 
1789     /**
1790      * Returns the minimum lane element of this vector.
1791      * <p>
1792      * This is an associative cross-lane reduction operation which applies the operation
1793      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1794      * and the identity value is
1795      * {@link Double#POSITIVE_INFINITY}.
1796      *
1797      * @return the minimum lane element of this vector
1798      */
1799     public abstract double minAll();
1800 
1801     /**
1802      * Returns the minimum lane element of this vector, selecting lane elements
1803      * controlled by a mask.
1804      * <p>
1805      * This is an associative cross-lane reduction operation which applies the operation
1806      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1807      * and the identity value is
1808      * {@link Double#POSITIVE_INFINITY}.
1809      *
1810      * @param m the mask controlling lane selection
1811      * @return the minimum lane element of this vector
1812      */
1813     public abstract double minAll(VectorMask<Double> m);
1814 
1815     /**
1816      * Returns the maximum lane element of this vector.
1817      * <p>
1818      * This is an associative cross-lane reduction operation which applies the operation
1819      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1820      * and the identity value is
1821      * {@link Double#NEGATIVE_INFINITY}.
1822      *
1823      * @return the maximum lane element of this vector
1824      */
1825     public abstract double maxAll();
1826 
1827     /**
1828      * Returns the maximum lane element of this vector, selecting lane elements
1829      * controlled by a mask.
1830      * <p>
1831      * This is an associative cross-lane reduction operation which applies the operation
1832      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1833      * and the identity value is
1834      * {@link Double#NEGATIVE_INFINITY}.
1835      *
1836      * @param m the mask controlling lane selection
1837      * @return the maximum lane element of this vector
1838      */
1839     public abstract double maxAll(VectorMask<Double> m);
1840 
1841 
1842     // Type specific accessors
1843 
1844     /**
1845      * Gets the lane element at lane index {@code i}
1846      *
1847      * @param i the lane index
1848      * @return the lane element at lane index {@code i}
1849      * @throws IllegalArgumentException if the index is is out of range
1850      * ({@code < 0 || >= length()})
1851      */
1852     public abstract double lane(int i);
1853 
1854     /**
1855      * Replaces the lane element of this vector at lane index {@code i} with
1856      * value {@code e}.
1857      * <p>
1858      * This is a cross-lane operation and behaves as if it returns the result
1859      * of blending this vector with an input vector that is the result of


1963      * or for any vector lane index {@code N} where the mask at lane
1964      * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is
1965      * {@code < 0} or {@code >= a.length}
1966      */
1967     public abstract void intoArray(double[] a, int a_offset, VectorMask<Double> m, int[] indexMap, int i_offset);
1968     // Species
1969 
1970     /**
1971      * {@inheritDoc}
1972      */
1973     @Override
1974     public abstract VectorSpecies<Double> species();
1975 
1976     /**
1977      * Class representing {@link DoubleVector}'s of the same {@link VectorShape VectorShape}.
1978      */
1979     static final class DoubleSpecies extends AbstractSpecies<Double> {
1980         final Function<double[], DoubleVector> vectorFactory;
1981 
1982         private DoubleSpecies(VectorShape shape,
1983                           Class<?> boxType,
1984                           Class<?> maskType,
1985                           Function<double[], DoubleVector> vectorFactory,
1986                           Function<boolean[], VectorMask<Double>> maskFactory,
1987                           Function<IntUnaryOperator, VectorShuffle<Double>> shuffleFromArrayFactory,
1988                           fShuffleFromArray<Double> shuffleFromOpFactory) {
1989             super(shape, double.class, Double.SIZE, boxType, maskType, maskFactory,
1990                   shuffleFromArrayFactory, shuffleFromOpFactory);
1991             this.vectorFactory = vectorFactory;
1992         }
1993 
1994         interface FOp {
1995             double apply(int i);
1996         }
1997 
1998         DoubleVector op(FOp f) {
1999             double[] res = new double[length()];
2000             for (int i = 0; i < length(); i++) {
2001                 res[i] = f.apply(i);
2002             }
2003             return vectorFactory.apply(res);
2004         }
2005 
2006         DoubleVector op(VectorMask<Double> o, FOp f) {
2007             double[] res = new double[length()];
2008             boolean[] mbits = ((AbstractMask<Double>)o).getBits();
2009             for (int i = 0; i < length(); i++) {




  95     interface FUnCon {
  96         void apply(int i, double a);
  97     }
  98 
  99     abstract void forEach(FUnCon f);
 100 
 101     abstract void forEach(VectorMask<Double> m, FUnCon f);
 102 
 103     // Static factories
 104 
 105     /**
 106      * Returns a vector where all lane elements are set to the default
 107      * primitive value.
 108      *
 109      * @param species species of desired vector
 110      * @return a zero vector of given species
 111      */
 112     @ForceInline
 113     @SuppressWarnings("unchecked")
 114     public static DoubleVector zero(VectorSpecies<Double> species) {
 115         return VectorIntrinsics.broadcastCoerced((Class<DoubleVector>) species.vectorType(), double.class, species.length(),
 116                                                  Double.doubleToLongBits(0.0f), species,
 117                                                  ((bits, s) -> ((DoubleSpecies)s).op(i -> Double.longBitsToDouble((long)bits))));
 118     }
 119 
 120     /**
 121      * Loads a vector from a byte array starting at an offset.
 122      * <p>
 123      * Bytes are composed into primitive lane elements according to the
 124      * native byte order of the underlying platform
 125      * <p>
 126      * This method behaves as if it returns the result of calling the
 127      * byte buffer, offset, and mask accepting
 128      * {@link #fromByteBuffer(VectorSpecies, ByteBuffer, int, VectorMask) method} as follows:
 129      * <pre>{@code
 130      * return fromByteBuffer(species, ByteBuffer.wrap(a), offset, VectorMask.allTrue());
 131      * }</pre>
 132      *
 133      * @param species species of desired vector
 134      * @param a the byte array
 135      * @param offset the offset into the array
 136      * @return a vector loaded from a byte array
 137      * @throws IndexOutOfBoundsException if {@code i < 0} or
 138      * {@code offset > a.length - (species.length() * species.elementSize() / Byte.SIZE)}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static DoubleVector fromByteArray(VectorSpecies<Double> species, byte[] a, int offset) {
 143         Objects.requireNonNull(a);
 144         offset = VectorIntrinsics.checkIndex(offset, a.length, species.bitSize() / Byte.SIZE);
 145         return VectorIntrinsics.load((Class<DoubleVector>) species.vectorType(), double.class, species.length(),
 146                                      a, ((long) offset) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 147                                      a, offset, species,
 148                                      (c, idx, s) -> {
 149                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 150                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 151                                          return ((DoubleSpecies)s).op(i -> tb.get());
 152                                      });
 153     }
 154 
 155     /**
 156      * Loads a vector from a byte array starting at an offset and using a
 157      * mask.
 158      * <p>
 159      * Bytes are composed into primitive lane elements according to the
 160      * native byte order of the underlying platform.
 161      * <p>
 162      * This method behaves as if it returns the result of calling the
 163      * byte buffer, offset, and mask accepting
 164      * {@link #fromByteBuffer(VectorSpecies, ByteBuffer, int, VectorMask) method} as follows:
 165      * <pre>{@code


 183 
 184     /**
 185      * Loads a vector from an array starting at offset.
 186      * <p>
 187      * For each vector lane, where {@code N} is the vector lane index, the
 188      * array element at index {@code offset + N} is placed into the
 189      * resulting vector at lane index {@code N}.
 190      *
 191      * @param species species of desired vector
 192      * @param a the array
 193      * @param offset the offset into the array
 194      * @return the vector loaded from an array
 195      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
 196      * {@code offset > a.length - species.length()}
 197      */
 198     @ForceInline
 199     @SuppressWarnings("unchecked")
 200     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int offset){
 201         Objects.requireNonNull(a);
 202         offset = VectorIntrinsics.checkIndex(offset, a.length, species.length());
 203         return VectorIntrinsics.load((Class<DoubleVector>) species.vectorType(), double.class, species.length(),
 204                                      a, (((long) offset) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 205                                      a, offset, species,
 206                                      (c, idx, s) -> ((DoubleSpecies)s).op(n -> c[idx + n]));
 207     }
 208 
 209 
 210     /**
 211      * Loads a vector from an array starting at offset and using a mask.
 212      * <p>
 213      * For each vector lane, where {@code N} is the vector lane index,
 214      * if the mask lane at index {@code N} is set then the array element at
 215      * index {@code offset + N} is placed into the resulting vector at lane index
 216      * {@code N}, otherwise the default element value is placed into the
 217      * resulting vector at lane index {@code N}.
 218      *
 219      * @param species species of desired vector
 220      * @param a the array
 221      * @param offset the offset into the array
 222      * @param m the mask
 223      * @return the vector loaded from an array


 249      * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or
 250      * {@code i_offset > indexMap.length - species.length()},
 251      * or for any vector lane index {@code N} the result of
 252      * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length}
 253      */
 254     @ForceInline
 255     @SuppressWarnings("unchecked")
 256     public static DoubleVector fromArray(VectorSpecies<Double> species, double[] a, int a_offset, int[] indexMap, int i_offset) {
 257         Objects.requireNonNull(a);
 258         Objects.requireNonNull(indexMap);
 259 
 260         if (species.length() == 1) {
 261           return DoubleVector.fromArray(species, a, a_offset + indexMap[i_offset]);
 262         }
 263 
 264         // Index vector: vix[0:n] = k -> a_offset + indexMap[i_offset + k]
 265         IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, i_offset).add(a_offset);
 266 
 267         vix = VectorIntrinsics.checkIndex(vix, a.length);
 268 
 269         return VectorIntrinsics.loadWithMap((Class<DoubleVector>) species.vectorType(), double.class, species.length(),
 270                                             IntVector.species(species.indexShape()).vectorType(), a, Unsafe.ARRAY_DOUBLE_BASE_OFFSET, vix,
 271                                             a, a_offset, indexMap, i_offset, species,
 272                                             (double[] c, int idx, int[] iMap, int idy, VectorSpecies<Double> s) ->
 273                                                 ((DoubleSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 274         }
 275 
 276     /**
 277      * Loads a vector from an array using indexes obtained from an index
 278      * map and using a mask.
 279      * <p>
 280      * For each vector lane, where {@code N} is the vector lane index,
 281      * if the mask lane at index {@code N} is set then the array element at
 282      * index {@code a_offset + indexMap[i_offset + N]} is placed into the resulting vector
 283      * at lane index {@code N}.
 284      *
 285      * @param species species of desired vector
 286      * @param a the array
 287      * @param a_offset the offset into the array, may be negative if relative
 288      * indexes in the index map compensate to produce a value within the
 289      * array bounds
 290      * @param m the mask


 319      *   return fromByteBuffer(b, offset, VectorMask.allTrue())
 320      * }</pre>
 321      *
 322      * @param species species of desired vector
 323      * @param bb the byte buffer
 324      * @param offset the offset into the byte buffer
 325      * @return a vector loaded from a byte buffer
 326      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 327      * or {@code > b.limit()},
 328      * or if there are fewer than
 329      * {@code species.length() * species.elementSize() / Byte.SIZE} bytes
 330      * remaining in the byte buffer from the given offset
 331      */
 332     @ForceInline
 333     @SuppressWarnings("unchecked")
 334     public static DoubleVector fromByteBuffer(VectorSpecies<Double> species, ByteBuffer bb, int offset) {
 335         if (bb.order() != ByteOrder.nativeOrder()) {
 336             throw new IllegalArgumentException();
 337         }
 338         offset = VectorIntrinsics.checkIndex(offset, bb.limit(), species.bitSize() / Byte.SIZE);
 339         return VectorIntrinsics.load((Class<DoubleVector>) species.vectorType(), double.class, species.length(),
 340                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + offset,
 341                                      bb, offset, species,
 342                                      (c, idx, s) -> {
 343                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 344                                          DoubleBuffer tb = bbc.asDoubleBuffer();
 345                                          return ((DoubleSpecies)s).op(i -> tb.get());
 346                                      });
 347     }
 348 
 349     /**
 350      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 351      * offset into the byte buffer and using a mask.
 352      * <p>
 353      * This method behaves as if the byte buffer is viewed as a primitive
 354      * {@link java.nio.Buffer buffer} for the primitive element type,
 355      * according to the native byte order of the underlying platform, and
 356      * the returned vector is loaded with a mask from a primitive array
 357      * obtained from the primitive buffer.
 358      * The following pseudocode expresses the behaviour, where
 359      * {@code EBuffer} is the primitive buffer type, {@code e} is the


 375      * @param bb the byte buffer
 376      * @param offset the offset into the byte buffer
 377      * @param m the mask
 378      * @return a vector loaded from a byte buffer
 379      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 380      * or {@code > b.limit()},
 381      * for any vector lane index {@code N} where the mask at lane {@code N}
 382      * is set
 383      * {@code offset >= b.limit() - (N * species.elementSize() / Byte.SIZE)}
 384      */
 385     @ForceInline
 386     public static DoubleVector fromByteBuffer(VectorSpecies<Double> species, ByteBuffer bb, int offset, VectorMask<Double> m) {
 387         return zero(species).blend(fromByteBuffer(species, bb, offset), m);
 388     }
 389 
 390     /**
 391      * Returns a vector where all lane elements are set to the primitive
 392      * value {@code e}.
 393      *
 394      * @param species species of the desired vector
 395      * @param e the value to be broadcasted
 396      * @return a vector of vector where all lane elements are set to
 397      * the primitive value {@code e}
 398      */
 399     @ForceInline
 400     @SuppressWarnings("unchecked")
 401     public static DoubleVector broadcast(VectorSpecies<Double> species, double e) {
 402         return VectorIntrinsics.broadcastCoerced(
 403             (Class<DoubleVector>) species.vectorType(), double.class, species.length(),
 404             Double.doubleToLongBits(e), species,
 405             ((bits, sp) -> ((DoubleSpecies)sp).op(i -> Double.longBitsToDouble((long)bits))));
 406     }
 407 
 408     /**
 409      * Returns a vector where each lane element is set to given
 410      * primitive values.
 411      * <p>
 412      * For each vector lane, where {@code N} is the vector lane index, the
 413      * the primitive value at index {@code N} is placed into the resulting
 414      * vector at lane index {@code N}.
 415      *
 416      * @param species species of the desired vector
 417      * @param es the given primitive values
 418      * @return a vector where each lane element is set to given primitive
 419      * values
 420      * @throws IndexOutOfBoundsException if {@code es.length < species.length()}
 421      */
 422     @ForceInline
 423     @SuppressWarnings("unchecked")
 424     public static DoubleVector scalars(VectorSpecies<Double> species, double... es) {
 425         Objects.requireNonNull(es);
 426         int ix = VectorIntrinsics.checkIndex(0, es.length, species.length());
 427         return VectorIntrinsics.load((Class<DoubleVector>) species.vectorType(), double.class, species.length(),
 428                                      es, Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 429                                      es, ix, species,
 430                                      (c, idx, sp) -> ((DoubleSpecies)sp).op(n -> c[idx + n]));
 431     }
 432 
 433     /**
 434      * Returns a vector where the first lane element is set to the primtive
 435      * value {@code e}, all other lane elements are set to the default
 436      * value.
 437      *
 438      * @param species species of the desired vector
 439      * @param e the value
 440      * @return a vector where the first lane element is set to the primitive
 441      * value {@code e}
 442      */
 443     @ForceInline
 444     public static final DoubleVector single(VectorSpecies<Double> species, double e) {
 445         return zero(species).with(0, e);
 446     }
 447 


 785     @Override
 786     public abstract DoubleVector rearrange(Vector<Double> v,
 787                                                       VectorShuffle<Double> s, VectorMask<Double> m);
 788 
 789     /**
 790      * {@inheritDoc}
 791      */
 792     @Override
 793     public abstract DoubleVector rearrange(VectorShuffle<Double> m);
 794 
 795     /**
 796      * {@inheritDoc}
 797      */
 798     @Override
 799     public abstract DoubleVector reshape(VectorSpecies<Double> s);
 800 
 801     /**
 802      * {@inheritDoc}
 803      */
 804     @Override
 805     public abstract DoubleVector rotateLanesLeft(int i);
 806 
 807     /**
 808      * {@inheritDoc}
 809      */
 810     @Override
 811     public abstract DoubleVector rotateLanesRight(int i);
 812 
 813     /**
 814      * {@inheritDoc}
 815      */
 816     @Override
 817     public abstract DoubleVector shiftLanesLeft(int i);
 818 
 819     /**
 820      * {@inheritDoc}
 821      */
 822     @Override
 823     public abstract DoubleVector shiftLanesRight(int i);
 824 
 825     /**
 826      * Divides this vector by an input vector.
 827      * <p>
 828      * This is a lane-wise binary operation which applies the primitive division
 829      * operation ({@code /}) to each lane.
 830      *
 831      * @param v the input vector
 832      * @return the result of dividing this vector by the input vector
 833      */
 834     public abstract DoubleVector div(Vector<Double> v);
 835 
 836     /**
 837      * Divides this vector by the broadcast of an input scalar.
 838      * <p>
 839      * This is a lane-wise binary operation which applies the primitive division
 840      * operation ({@code /}) to each lane.
 841      *
 842      * @param s the input scalar
 843      * @return the result of dividing this vector by the broadcast of an input


1705 
1706     // Type specific horizontal reductions
1707     /**
1708      * Adds all lane elements of this vector.
1709      * <p>
1710      * This is a cross-lane reduction operation which applies the addition
1711      * operation ({@code +}) to lane elements,
1712      * and the identity value is {@code 0.0}.
1713      *
1714      * <p>The value of a floating-point sum is a function both of the input values as well
1715      * as the order of addition operations. The order of addition operations of this method
1716      * is intentionally not defined to allow for JVM to generate optimal machine
1717      * code for the underlying platform at runtime. If the platform supports a vector
1718      * instruction to add all values in the vector, or if there is some other efficient machine
1719      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1720      * the default implementation of adding vectors sequentially from left to right is used.
1721      * For this reason, the output of this method may vary for the same input values.
1722      *
1723      * @return the addition of all the lane elements of this vector
1724      */
1725     public abstract double addLanes();
1726 
1727     /**
1728      * Adds all lane elements of this vector, selecting lane elements
1729      * controlled by a mask.
1730      * <p>
1731      * This is a cross-lane reduction operation which applies the addition
1732      * operation ({@code +}) to lane elements,
1733      * and the identity value is {@code 0.0}.
1734      *
1735      * <p>The value of a floating-point sum is a function both of the input values as well
1736      * as the order of addition operations. The order of addition operations of this method
1737      * is intentionally not defined to allow for JVM to generate optimal machine
1738      * code for the underlying platform at runtime. If the platform supports a vector
1739      * instruction to add all values in the vector, or if there is some other efficient machine
1740      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1741      * the default implementation of adding vectors sequentially from left to right is used.
1742      * For this reason, the output of this method may vary on the same input values.
1743      *
1744      * @param m the mask controlling lane selection
1745      * @return the addition of the selected lane elements of this vector
1746      */
1747     public abstract double addLanes(VectorMask<Double> m);
1748 
1749     /**
1750      * Multiplies all lane elements of this vector.
1751      * <p>
1752      * This is a cross-lane reduction operation which applies the
1753      * multiplication operation ({@code *}) to lane elements,
1754      * and the identity value is {@code 1.0}.
1755      *
1756      * <p>The order of multiplication operations of this method
1757      * is intentionally not defined to allow for JVM to generate optimal machine
1758      * code for the underlying platform at runtime. If the platform supports a vector
1759      * instruction to multiply all values in the vector, or if there is some other efficient machine
1760      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1761      * the default implementation of multiplying vectors sequentially from left to right is used.
1762      * For this reason, the output of this method may vary on the same input values.
1763      *
1764      * @return the multiplication of all the lane elements of this vector
1765      */
1766     public abstract double mulLanes();
1767 
1768     /**
1769      * Multiplies all lane elements of this vector, selecting lane elements
1770      * controlled by a mask.
1771      * <p>
1772      * This is a cross-lane reduction operation which applies the
1773      * multiplication operation ({@code *}) to lane elements,
1774      * and the identity value is {@code 1.0}.
1775      *
1776      * <p>The order of multiplication operations of this method
1777      * is intentionally not defined to allow for JVM to generate optimal machine
1778      * code for the underlying platform at runtime. If the platform supports a vector
1779      * instruction to multiply all values in the vector, or if there is some other efficient machine
1780      * code sequence, then the JVM has the option of generating this machine code. Otherwise,
1781      * the default implementation of multiplying vectors sequentially from left to right is used.
1782      * For this reason, the output of this method may vary on the same input values.
1783      *
1784      * @param m the mask controlling lane selection
1785      * @return the multiplication of all the lane elements of this vector
1786      */
1787     public abstract double mulLanes(VectorMask<Double> m);
1788 
1789     /**
1790      * Returns the minimum lane element of this vector.
1791      * <p>
1792      * This is an associative cross-lane reduction operation which applies the operation
1793      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1794      * and the identity value is
1795      * {@link Double#POSITIVE_INFINITY}.
1796      *
1797      * @return the minimum lane element of this vector
1798      */
1799     public abstract double minLanes();
1800 
1801     /**
1802      * Returns the minimum lane element of this vector, selecting lane elements
1803      * controlled by a mask.
1804      * <p>
1805      * This is an associative cross-lane reduction operation which applies the operation
1806      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1807      * and the identity value is
1808      * {@link Double#POSITIVE_INFINITY}.
1809      *
1810      * @param m the mask controlling lane selection
1811      * @return the minimum lane element of this vector
1812      */
1813     public abstract double minLanes(VectorMask<Double> m);
1814 
1815     /**
1816      * Returns the maximum lane element of this vector.
1817      * <p>
1818      * This is an associative cross-lane reduction operation which applies the operation
1819      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1820      * and the identity value is
1821      * {@link Double#NEGATIVE_INFINITY}.
1822      *
1823      * @return the maximum lane element of this vector
1824      */
1825     public abstract double maxLanes();
1826 
1827     /**
1828      * Returns the maximum lane element of this vector, selecting lane elements
1829      * controlled by a mask.
1830      * <p>
1831      * This is an associative cross-lane reduction operation which applies the operation
1832      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1833      * and the identity value is
1834      * {@link Double#NEGATIVE_INFINITY}.
1835      *
1836      * @param m the mask controlling lane selection
1837      * @return the maximum lane element of this vector
1838      */
1839     public abstract double maxLanes(VectorMask<Double> m);
1840 
1841 
1842     // Type specific accessors
1843 
1844     /**
1845      * Gets the lane element at lane index {@code i}
1846      *
1847      * @param i the lane index
1848      * @return the lane element at lane index {@code i}
1849      * @throws IllegalArgumentException if the index is is out of range
1850      * ({@code < 0 || >= length()})
1851      */
1852     public abstract double lane(int i);
1853 
1854     /**
1855      * Replaces the lane element of this vector at lane index {@code i} with
1856      * value {@code e}.
1857      * <p>
1858      * This is a cross-lane operation and behaves as if it returns the result
1859      * of blending this vector with an input vector that is the result of


1963      * or for any vector lane index {@code N} where the mask at lane
1964      * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is
1965      * {@code < 0} or {@code >= a.length}
1966      */
1967     public abstract void intoArray(double[] a, int a_offset, VectorMask<Double> m, int[] indexMap, int i_offset);
1968     // Species
1969 
1970     /**
1971      * {@inheritDoc}
1972      */
1973     @Override
1974     public abstract VectorSpecies<Double> species();
1975 
1976     /**
1977      * Class representing {@link DoubleVector}'s of the same {@link VectorShape VectorShape}.
1978      */
1979     static final class DoubleSpecies extends AbstractSpecies<Double> {
1980         final Function<double[], DoubleVector> vectorFactory;
1981 
1982         private DoubleSpecies(VectorShape shape,
1983                           Class<?> vectorType,
1984                           Class<?> maskType,
1985                           Function<double[], DoubleVector> vectorFactory,
1986                           Function<boolean[], VectorMask<Double>> maskFactory,
1987                           Function<IntUnaryOperator, VectorShuffle<Double>> shuffleFromArrayFactory,
1988                           fShuffleFromArray<Double> shuffleFromOpFactory) {
1989             super(shape, double.class, Double.SIZE, vectorType, maskType, maskFactory,
1990                   shuffleFromArrayFactory, shuffleFromOpFactory);
1991             this.vectorFactory = vectorFactory;
1992         }
1993 
1994         interface FOp {
1995             double apply(int i);
1996         }
1997 
1998         DoubleVector op(FOp f) {
1999             double[] res = new double[length()];
2000             for (int i = 0; i < length(); i++) {
2001                 res[i] = f.apply(i);
2002             }
2003             return vectorFactory.apply(res);
2004         }
2005 
2006         DoubleVector op(VectorMask<Double> o, FOp f) {
2007             double[] res = new double[length()];
2008             boolean[] mbits = ((AbstractMask<Double>)o).getBits();
2009             for (int i = 0; i < length(); i++) {


< prev index next >