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++) {
|