JDK-8223348 : Vector API (Incubator)
  • Type: CSR
  • Component: hotspot
  • Sub-Component: compiler
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2019-05-04
  • Updated: 2020-10-12
  • Resolved: 2020-10-12
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Provide an initial iteration of an [incubator module], jdk.incubator.vector, to express vector computations
that reliably compile at runtime to optimal vector hardware instructions on supported CPU architectures
and thus achieve superior performance to equivalent scalar computations.

Problem
-------

Vector computations consist of a sequence of operations on vectors.  A vector
comprises a (usually) fixed sequence of scalar values, where the scalar
values correspond to the number of hardware-defined vector lanes.   A binary operation applied
to two vectors with the same number of lanes would, for each lane, apply the
equivalent scalar operation on the corresponding two scalar values from each
vector.  This is commonly referred to as
[Single Instruction Multiple Data][SIMD] (SIMD).

[SIMD]:https://en.wikipedia.org/wiki/SIMD

Vector operations express a degree of parallelism that enables more work to be
performed in a single CPU cycle and thus can result in significant performance
gains.  For example, given two vectors each covering a sequence of eight
integers (eight lanes), then the two vectors can be added together using a
single hardware instruction.  The vector addition hardware instruction operates
on sixteen integers, performing eight integer additions, in the time it would
ordinarily take to operate on two integers, performing one integer addition.

HotSpot supports [auto-vectorization] where scalar operations are transformed into
superword operations, which are then mapped to vector hardware instructions.
The set of transformable scalar operations are limited and fragile to changes in
the code shape.  Furthermore, only a subset of available vector hardware
instructions might be utilized limiting the performance of generated code.

[auto-vectorization]:http://cr.openjdk.java.net/~vlivanov/talks/2017_Vectorization_in_HotSpot_JVM.pdf

A developer wishing to write scalar operations that are reliably transformed
into superword operations needs to understand HotSpot's auto-vectorization
support and its limitations to achieve reliable and sustainable performance.

In some cases it may not be possible for the developer to write scalar
operations that are transformable.  For example, HotSpot does not transform the
simple scalar operations for calculating the hash code of an array (see the
`Arrays.hashCode` method implementations in the JDK source code), nor can it
auto-vectorize code to lexicographically compare two arrays (which why an
intrinsic was added to perform  lexicographical comparison, see
[JDK-8033148][JDK-8033148]).

[JDK-8033148]:https://bugs.openjdk.java.net/browse/JDK-8033148

Solution
--------

The Vector API aims to address these issues by providing a mechanism to write
complex vector algorithms in Java, using pre-existing support in HotSpot
for vectorization, but with a user model which makes vectorization far more
predictable and robust.  Hand-coded vector loops can express high-performance
algorithms (such as vectorized `hashCode` or specialized array comparison)
which an auto-vectorizer may never optimize.
There are numerous domains where this explicitly vectorizing
API may be applicable such as machine learning, linear algebra, cryptography,
finance, and usages within the JDK itself.

Specification
-------------

The implementation of Vector API exports the following interfaces in the package `jdk.incubator.vector`, defined in module `jdk.incubator.vector`.

```
Interfaces
VectorOperators.Associative	       Binary associative lane-wise operations that are applicable to vector lane values of some or all lane types.
VectorOperators.Binary	           Binary lane-wise operations that are applicable to vector lane values of some or all lane types.
VectorOperators.Comparison	       Binary lane-wise comparisons that are applicable to vector lane values of all lane types.
VectorOperators.Conversion<E,���F>    Conversion operations that are applicable to vector lane values of specific lane types.
VectorOperators.Operator	       Lane-wise operations that are applicable to vector lane values of some or all lane types.
VectorOperators.Ternary	           Ternary lane-wise operations that are applicable to vector lane values of some or all lane types.
VectorOperators.Unary	           Unary lane-wise operations that are applicable to vector lane values of some or all lane types.
VectorSpecies<E>                   Interface for managing all vectors of the same combination of element type (ETYPE) and shape.

Classes
ByteVector                         A specialized Vector representing an ordered immutable sequence of byte values.
DoubleVector                       A specialized Vector representing an ordered immutable sequence of double values.
FloatVector                        A specialized Vector representing an ordered immutable sequence of float values.
IntVector                          A specialized Vector representing an ordered immutable sequence of int values.
LongVector                         A specialized Vector representing an ordered immutable sequence of long values.
ShortVector                        A specialized Vector representing an ordered immutable sequence of short values.
Vector<E>                          A sequence of a fixed number of lanes, all of some fixed element type such as byte, long, or float.
VectorMask<E>                      A VectorMask represents an ordered immutable sequence of boolean values.
VectorOperators                    This class consists solely of static constants that describe lane-wise vector operations,
                                   plus nested interfaces which classify them.
VectorShuffle<E>                   A VectorShuffle represents an ordered immutable sequence of int values called source indexes, 
                                   where each source index numerically selects a source lane from a Vector of a compatible vector species.

Enum
VectorShape                        A VectorShape selects a particular implementation of Vectors.
```

A vector is represented by the abstract class `Vector<E>`, where type variable E corresponds to the boxed type of scalar primitive integral or floating point element types covered by the vector.
`Vector<E>` declares a set of methods for common vector operations supported by all element types. To reduce the surface of the api, instead of defining methods for each supported operation,
the api defines methods for each category of operations (such as lanewise(), reduceLanes(), compare(), etc). The operation to be performed is specified with an operator parameter.
The supported operators are defined in `VectorOperators` class as static final instances of `VectorOperators.Operator` interface and its sub-interfaces. The sub-interfaces correspond
to the classification of operators into groups such as unary (e.g. negation), binary (e.g. addition), comparison (e.g. lessThan), etc. Having said that, some common operations (such as add(), or())
are provided their own named methods.

The package has specialized implementations of `Vector<E>` for each `E` in the set {Byte, Short, Int, Long, Float, Double}. These classes export operations specific to an element type such as such as bitwise operations (e.g. logical or) which are specific to integral sub-types and mathematical operations (e.g. transcendental functions like pow()) for floating point sub-types.

A Vector has an element type which is represented by the type variable `E` and a shape which defines the size, in bits. Enum `VectorShape` is the enum of shapes supported by the api.
The element type and shape together form a species represented by `VectorSpecies<E>`. Species play a role in creation and type conversion of vectors, masks and shuffles.

To support control flow relevant vector operations will optionally accept masks, represented by the public abstract class `VectorMask<E>`. Each element
in a mask, a boolean value or bit, corresponds to a vector lane. When a mask is an input to an operation it governs whether the operation
is applied to a particular lane; the operation is applied for a lane(s) if the mask bit for that lane is set (is true). Alternative behavior occurs if the
mask bit is not set (is false). Comparison operations produce masks, which can then be input to other operations to selectively disable the
operation on certain lanes and thereby emulate flow control.

A VectorShuffle represents an ordered immutable sequence of int values. A VectorShuffle can be used with a shuffle accepting vector operation to
control the rearrangement of lane elements of input vectors.

The javadoc for the package with the implementation as of July 18, 2019 is at http://cr.openjdk.java.net/~kkharbas/vector-api/CSR/javadoc.02/jdk.incubator.vector/jdk/incubator/vector/package-summary.html and also attached here.

More details can be found in the JEP issue - https://bugs.openjdk.java.net/browse/JDK-8201271


Comments
[~psandoz], I filed JDK-8254622 for the javadoc issue. I recommend tightening up the build options for the module to catch any lingering missing javadoc cases, etc.
12-10-2020

[~darcy] thank you for the review effort, much appreciated. Re: Class Vector java.lang.Object jdk.internal.vm.vector.VectorSupport.VectorPayload jdk.internal.vm.vector.VectorSupport.Vector jdk.incubator.vector.Vector. I think this is a JavaDoc bug. The package of those internal types in java.base are exported only to the vector module, and therefore are not part of the public API. Re: In "Shapes and species", looks like an extra space after "vector shape "; likewise after " unique vector species "; however, these may be specdiff artifacts. These are specdiff artifacts. Re: No spec for DoubleVector.zero, FloatVector.zero -- javadoc issue? Well spotted, this static method lacks JavaDoc. A refactoring to a static method rendered the {@inheritDoc} useless.
12-10-2020

Moving to Approved with the commends below for follow-up work: In Vector, the start of the page displays as: Class Vector<E> java.lang.Object jdk.internal.vm.vector.VectorSupport.VectorPayload jdk.internal.vm.vector.VectorSupport.Vector<E> jdk.incubator.vector.Vector<E> I don't know if the jdk.internal.* classes are a specdiff artifact; it would be strongly preferable if they were not in the eventual javadoc output. " unary lane-wise operation," should be linkplain rather than link "The type E in Vector<E> is the boxed version of ETYPE. For example, in the type Vector<Integer>, the E parameter is Integer and the ETYPE is int. In such a vector, each lane carries a primitive int value. This pattern continues for the other primitive types as well. " Please supplement with @jls to 5.1.7. Boxing Conversion and 5.1.8. Unboxing Conversion. In "Shapes and species", looks like an extra space after "vector shape "; likewise after " unique vector species "; however, these may be specdiff artifacts. Garbled end of sentence: "Each possible VSHAPE is represented by a member of the VectorShape enumeration, and represents an implementation format shared in common by all vectors of a of that shape." In "Vector subtypes", missing comma "IntVectorLongVector" Code review comment -- DRY -- refer to Vector.java text from package-info.java. Not sure if using <em></em> inside a linkplain is supported, suggest checking with [~jjg]. For elementType, elementSize, sahpe, bitSize, byteSize, etc. I'd recommend making "This is the same value as this.species().foo()." as implSpec VectorOperators.Binary "Type for all lane-wise binary operators, usable in expressions like w = v0. lanewise(ADD, v1) " Please add "binary" meaning "two-argument" with analogous text in the Unary and Ternary cases. VectorShape.S_MAX_BIT -- recommend being a method. Not necessarily matching one of the built-in values? No spec for DoubleVector.zero, FloatVector.zero -- javadoc issue? SPECIES_MAX, SPECIES_PREFERRED might be better as methods.
12-10-2020

Restarting my review; prior round of comments all look well-addressed.
11-10-2020

I finalized the CSR. The API has not changed since the last update to resolve feedback (see [comment][1]). The development has successfully switched to git, if you want direct access it can be found at the following link: https://github.com/openjdk/panama-vector/tree/vector-unstable Hopefully we can resolve any further comments as follow-up issues. [1]: https://bugs.openjdk.java.net/browse/JDK-8223348?focusedCommentId=14361286&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14361286
21-09-2020

I have addressed the latest CSR comments here: http://cr.openjdk.java.net/~psandoz/panama/vector-csr-round-2-review/webrev/ Once it makes it's way into the right repo (after merges) i will send an specdiff (total + incremental). The latest specdiff is attached and is accessible here: http://cr.openjdk.java.net/~psandoz/panama/vector-api-review/specdiff-jdk-2020-08-06-0c1d7953debe/overview-summary.html The incremental specdiff is also attached and is accessible here: http://cr.openjdk.java.net/~psandoz/panama/vector-api-review/specdiff-2020-05-15-88a83f7238d8-2020-08-06-0c1d7953debe/jdk.incubator.vector/jdk/incubator/vector/package-summary.html
07-08-2020

Thanks for the update [~psandoz] and the discussion earlier this week. Before the CSR is approved, I'll take at least one more pass over the entire API. It is likely I'll have additional items of feedback; those can either be dealt with before pushing or possibly as follow-up issues depending on what we agree to.
06-08-2020

Moving to Provisional (not Approved). A JEP may go proposed to target once all its constitute CSRs are in Provisional or Approved state. Several comments to be addressed before this work is Finalized: In the package-info discussion: For the code sampels, I strongly recommend leading with the best-practice code for programmers, which is presumably using SPECIES_PREFERRED rather than a fixed species. ------ > "Unless specified otherwise, any method arguments of reference type > must not be null, and any null argument will elicit a > NullPointerException. This fact is not individually documented for > methods in this package." is given as a performance note and stand-alone. Only the stand-alone one should remain. ------ In Vector: > "The element type of a vector, sometimes called ETYPE, is one of the > primitive types byte, short, int, long, float , or double. > > The type E in Vector<E> is a generic type argument that corresponds to > the element type. In fact, it is the boxed version of the primitive > element type. For example, in the type Vector<Integer>, the E > parameter is Integer but the ETYPE is int. In such a vector, each lane > carries a primitive int value. This pattern continues for the other > primitive types as well." This text is rather wordy and not entirely consistent with the type parameter docs for E. Please simplify and clarify. For example, the with the type parameter consider something like: E - The boxed version of ETYPE, the element type of the vector ------ > "Vector shape, VLENGTH, and ETYPE are all mutually constrained, so > that VLENGTH times the bit-size of each lane must always match the > bit-size of the vector's shape. Thus, reinterpreting a vector via a > cast may double its length if and only if it either halves the lane > size, or else changes the shape. Likewise, reinterpreting a vector may > double the lane size if and only if it either halves the length, or > else changes the shape of the vector." The operation in question is *not* a Java language cast. This wording is at best confusing and at least "cast" should be a link to the conversion method in question. Please consider different phrasing to describe this operation in text, writing out the method name, calling it "recast", etc. ------ In the following section: > Memory Operations: > > As was already mentioned, vectors can be loaded from memory and stored > back. An optional mask can control which individual memory locations > are read from or written to. The shape of a vector determines how much > memory it will occupy. In the absence of masking, the lanes are stored > as a dense sequence of back-to-back values in memory, the same as a > dense (gap-free) series of single scalar values in an array of the > scalar type. Memory order corresponds exactly to lane order. The first > vector lane value occupies the first position in memory, and so on, up > to the length of the vector. Although memory order is not directly > defined by Java as a separate concept, the memory order of stored > vector lanes always corresponds to increasing index values in a Java > array or in a ByteBuffer. I find this over-specified. It should be downgraded to *informative* rather than *normative* text. "An implementation typically has these properties..." ------ > "With Vector, identity-sensitive operations such as == may yield > unpredictable results, or reduced performance. Oddly enough, > v.equals(w) is likely to be faster than v==w, since equals is not an > identity sensitive method. It is also reasonable to use, on vectors, > the toString and hashCode methods of Object. Also, these objects can > be stored in locals and parameters and as static final constants, but > storing them in other Java fields or in array elements, while > semantically valid, may incur performance penalties." What do the toString and hashCode comments here mean? It appears they should be as the methods are overridden as appropriate in the types. ------ In DoubleVector and FloatVector, I recommend replacing wording like: "This is a lane-wise binary operation which applies the method Math.pow() to each pair of corresponding lane values." with "This is a lane-wise binary operation which applies an operation conforming to the specification of Math.pow() to each pair of corresponding lane values." (And Math.pow should be a link to Math.pow.) This allow a future vector-optimized version of the pow that could differ from Math.pow. The float version of the operations should make some mention of the float -> double widening of argument and narrowing of results as many Java math library methods only exist for double argument.
02-08-2020

[~darcy] yes links and files with "2020-05-15-88a83f7238d8" (the last bit is the change-set id).
21-07-2020

Planning to take another look at the API in the near future; is the 2020-05-15 iteration the most recent one? Thanks.
21-07-2020

The latest specdiff is attached and is accessible here: http://cr.openjdk.java.net/~psandoz/panama/vector-api-review/specdiff-jdk-2020-05-15-88a83f7238d8/overview-summary.html The incremental specdiff is also attached and is accessible here: http://cr.openjdk.java.net/~psandoz/panama/vector-api-review/specdiff-2020-05-11-38dd763d023e-2020-05-15-88a83f7238d8/overview-summary.html The latest JavaDoc can be found here: http://cr.openjdk.java.net/~psandoz/panama/vector-api-review/docs-2020-05-15-88a83f7238d8/api/jdk.incubator.vector/jdk/incubator/vector/package-summary.html The updates address some but not all comments. We would prefer to keep the species consistent as static final fields for all cases (and feel the distinction between a fixed constant and runtime constant is not important for a user of the API). Changing Vector.test to Vector.filter, as in Stream.filter, would be misleading as no filtering (reducing) is occurring. However, Stream.filter, does require a test before performing the reducing action (as in Predicate.test), and that part is similar. The categorization of lane-wise operations has been specified in the shared documentation of the Vector class and package. Current limitations are briefly described in the Vector class doc in the @implNote The fromValues method has been removed. Feedback indicated this was a confusing distraction. The byte array and ByteBuffer load/store methods were simplified to be uniform in their signature pattern and always accept a ByteOrder argument. The variable type names and their constraints have been clarified for all cases. The terms ETYPE and ELENGTH have been linked to the corresponding methods on Vector (cannot be observed in specdiff). Those terms are also linked to from the VectorMask, VectorShuffle, VectorSpecies class doc, and the package doc. For now we consider the floating point reduction challenges (accuracy/reproducibility) as work in progress. more time is required to determine the best approach. So at the moment the accuracy and reproducibility is unfortunately specified to be unspecified.
18-05-2020

The overview summary of the specdiff only appears to show all the files as newly added as opposed to changes within each file. To refamiliarize myself with the API, I've review the new version of it. I'm moving the CSR to Provisional, but have various comments / questions as detailed below to be addressed or discussed before the request if Finalized for the second phase of CSR review. -=-==- I think the flow the docs would be helped if the package-level (or module-level) docs included a summary of terms used in this API such as Lane / Vector length, Species, and Shape. These definition are given in the class-level comments in jdk.incubator.vector.Vector, not unreasonable for a vector API, but a conceptual road map to the package in the package level docs would aid new readers. Terms such as "full service named operation" would be appropriate to define at the package level too. I will repeat the feedback that "Vector" is more of a "VectorRegister" and I would prefer if that was expressed in at least the root type in some fashion (even as VecReg with a IntVector subclass). This also avoids a name class with java.util.Vector. Vector has multiple methods that duplicate information on the species such as vector.elementType() being equivalent to vector.species().elementType(). In an API with an abundance of methods, do these convenience methods pull their weight? Would Vector.test be better as Vector.filter as used in streams? Please add an @see link from Vector.eq to Vector.equals. What is the rationale for VectorMask being generic as opposed to just "an ordered immutable sequence of boolean values"? In VectorMask.toLong ,throwing IllegalArgumentException doesn't seem to be the best exception since there is no explicit argument. Perhaps ArithmeticException would be better. Should there be a VectorMask.toBigInteger to guarantee an non-exceptional result? The signature of this method public abstract VectorMask<E> equal(VectorMask<E> m) is likely to be confused with equals. The collections of DoubleVector.SPECIES_*, IntVector.SPECIES_*, etc. fields look like they should be enums to me. A nested enum DoubleVector.Species can implement the VectorSpecies<Double> interface. However, I think MAX and PREFERRED should be methods and *not* (pseudo) constants as static final fields. On max, same feedback for VectorShape, "max" should be returned by a method and not be a constant. It is odd for VectorShape.preferredShape to throw an IllegalArgumentException when it takes no arguments, not even this. Please consider returning an Optional<VectorShape> or some alternative idiom. What alternative structures were considered for VectorOperators? Having the operator objects not have any methods to provide useful information could be a bit hard to use. I may have overlooked it, but I didn't see any "add up all these numbers and in some not-exactly-specified way so that the total error isn't that bad."
05-05-2020

I have attached JavaDoc and specdiff for the latest API. It has not changed significantly and we have attempted to address all the comments so far. An online version can be accessed here: http://cr.openjdk.java.net/~psandoz/panama/vector-api-review/
19-03-2020

I have attached a [specdiff][1] from revision d78d3d6098ab to revision 43bc39c09590 (tip of the vectorIntrinsics branch as of writing), that shows the changes made from the last specdiff by Kishor. [1]: https://bugs.openjdk.java.net/secure/attachment/85468/specdiff-vectorIntrinsics-d78d3d6098ab-43bc39c09590.zip
07-11-2019

Working my way back to do another review pass on the new iteration.
06-11-2019

@Joe Here is the link to the specdiff - http://cr.openjdk.java.net/~kkharbas/8223348/spec-diff_03_to_02/overview-summary.html Link to webrev - http://cr.openjdk.java.net/~kkharbas/8223348/webrev.00/
17-10-2019

Please find the link to webrev from Kishor attached: http://cr.openjdk.java.net/~kkharbas/8223348/webrev.00/
10-10-2019

Hi [~kkharbas], thanks for the update. Please also send a pointer to a webrev, specdiff, or repository state. (To review the changes, I'll want some way to do a diff of the current version compared to what was previously reviewed in the CSR.) Cheers.
09-10-2019

Thank you Joe for the feedback. I have an pushed an update, the latest Javadoc is at http://cr.openjdk.java.net/~kkharbas/vector-api/CSR/javadoc.03/jdk.incubator.vector/module-summary.html. The update addresses following feedback points: 1. Describe the accuracy, monotonicity specification and associativity of Floating point operations. 2. Divide by zero @inheritdoc issue. 3. REINTERPRET_${I}2${J}entries should reference Float.floatTo[Raw]IntBits. 4. "Please reference Math.min/max rather than less-than or greater-than as those methods are specified to properly handle the zero cases of interest" 5. Replace "default double zero" with "positive zero." 6. Minor corrections pointed above.
05-10-2019

PS JEP describing semantics and usage of apiNote, implSpec, and implNote: http://openjdk.java.net/jeps/8068562
26-09-2019

PS The classification of addition and multiplication as associative operations, including for floating-point, merits a disclaimer that for floating-point these operations are only "morally associative" and not mathematically associative.
10-09-2019

Administratively, I'm moving this CSR to Provisional. However, given the magnitude of the set of comments above, please resubmit the next iteration of the of the API through the full two-phase CSR process, operationally Back to Draft, then Propose.
10-09-2019

It seems a bit odd to have VectorShape.S_Max_BIT be a separate enum constant. In nearly all cases, won't S_Max_BIT to semantically equivalent to one of the other constants defined to have a particular statically known size? FWIW, when designing the javax.lang.model.SourceVersion enum (https://docs.oracle.com/en/java/javase/12/docs/api/java.compiler/javax/lang/model/SourceVersion.html), we included latest() and latestSupported() methods to return one of the other constants.
10-09-2019

In the VectorOperators class, presumably the REINTERPRET_${I}2${J}entries should reference Float.floatTo[Raw]IntBits���, Float.intBitsToFloat and analogous methods for double and long. Were one or more enum types considered to declare the set of operators?
10-09-2019

A note on the type relationship among the different classes. The base class Vector declares methods like: public abstract Vector<E> add���(Vector<E> v) and subclasses override these methods with specializations like public final DoubleVector add���(Vector<Double> v) In Java, the language supports covariant overrides where the return type can be more specific, a subtype, of the return type of the method in the parent class or interface. In this case, since DoubleVector, which is a Vector<Double>, is a subtype of Vector<E> so this works out. However, for parameters, method parameters in subtypes are naturally *contravariant* rather than *covariant*. That is, from a typing perspective a method in a subtype should accept parameters that are *supertypes* of the parameters of the overridden method, not *subtypes*. This is the opposite of return types. (For an overview see https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) ). At an implementation level, Java generics are erased so the overridden method at the VM level will be DoubleVector add(Vector) with a bridge method Vector add(Vector) However, this isn't really sound from a typing perspective without additional runtime checking that isn't supported on the platform. I don't know how these methods might interact with future changes to generics being considered.
09-09-2019

FYI, I've attached a patch file, vector-div-divide-by-zero.diff, showing the usage of apiNote I recommend to given more precise information about the ArithmeticException being thrown for division by zero and the div methods.
07-09-2019

Additional comments, more comments on this iteration expected in the future. The name clash with "java.util.Vector" is unfortunate, but I don't have a better same-length alternative name. ----- If I understand the API, The valid values of E in Vector<E> are all some subclass of Number. If that is the case, I recommend changing the declaration to include that information even though not all Number types are valid instantiations. ----- How do these two methods differ in their behavior: VectorSpecies.genericElementType() VectorSpecies.elementType() Typo in DoubleVector (and perhaps elsewhere) "appliesthe". ----- public final DoubleVector pow���(double n) Raises this vector to a scalar power. This is a lane-wise binary operation which applies the method Math.pow() to each pair of corresponding lane values. This method is also equivalent to the expression lanewise(POW, n). Does this mean "applies the method Math.pow()" or "applies a method meeting the quality implementation criteria of Math.pow()..." ---- I find the phrase "default double zero" to be awkward and recommend replacing with "positive zero." ---- public final <F> jdk.incubator.vector.AbstractVector<F> check���(VectorSpecies<F> species) Looks like "AbstractVector" isn't declared to be a public type but is used as the return type of a public method. ---- DoubleVector.min/max Please reference Math.min/max rather than less-than or greater-than as those methods are specified to properly handle the zero cases of interest. ---- It might be worthwhile to state that VectorSpecies.vectorBitSize() is "logical" size rather than a size that accounts for alignment + padding, etc. ---- There are ways in javadoc for the JDK to avoid inheriting misleading text as done in DoubleVector.div: DoubleVector.div "If the underlying scalar operator does not support division by zero, but is presented with a zero divisor, an ArithmeticException will be thrown. Because the underlying scalar operator is an IEEE floating point number, division by zero in fact will not throw an exception, but will yield a signed infinity or NaN." Clearly it would be better in DoubleVector.div to have text closer to "Note that since divide by zero in floating-point arithmetic returns a NaN or signed infinity, this method does not through ArithmeticException for division by zero." This can be done by replacing the text text Vector with a `@apiNote If the underlying scalar...` then in DoubleVector.div using `@inhertiDoc` and the DoubleVector.div disclaimer. Similar guidance for DoubleVector.toDoubleArray.
05-09-2019

I've started going through the proposed API in detail. This comment will contain some high-level impressions; subsequent comments will have finer-grained feedback. Conceptually, I think jdk.incubator.vector.Vector<E> would be more accurately named jdk.incubator.vector.VectorRegister<E>. For example, the package-level comments of jdk.incubator.vector describe what a user needs to do write a strip-mined loop in various ways, with and without masks, etc. There are certainly uses for a vector register level API where the structure of nodes in the IR would closely correspond to the structure of vector (register) API method calls. However, the are also uses for a *vector* API where the end-user would write something closer to FloatVector va = fromArray(a[]); FloatVector vb = fromArray(b[]); FloatVector vc = va.mul(vb); return vc.toFloatArray(); and the implementation of FloatVector.mul would be responsible for managing the strip-mining in a platform optimized way. This could be done by translating an API similar to the vector register API presented in this iteration. If the strongly recommended coding idiom is to write loops in terms of properties of the preferred species, then I'd recommend not exposing the full range of possible species for (most) end users.
05-09-2019

Thank you Joe for the initial feedback. We will address them in the next spec update.
24-07-2019

I may have overlooked in an initial look over the API, but if a "sum" operation is not present distinct from "add", there may be sufficient utility to add it. Merely adding up floating-point value reliably is surprisingly difficult. The straight-forward idiom of simply applying floating-point "+" to the element in some order is vulnerable to returning results far from the true sum. To guard against this, in the streams API DoubleStream.sum and DoubleSummaryStatistics are allowed to compensated summation or similar technique: "The value of a floating-point sum is a function both of the input values as well as the order of addition operations. The order of addition operations of this method is intentionally not defined to allow for implementation flexibility to improve the speed and accuracy of the computed result. In particular, this method may be implemented using compensated summation or other technique to reduce the error bound in the numerical sum compared to a simple summation of double values. Because of the unspecified order of operations and the possibility of using differing summation schemes, the output of this method may vary on the same input elements. Various conditions can result in a non-finite sum being computed. This can occur even if the all the elements being summed are finite. If any element is non-finite, the sum will be non-finite: If any element is a NaN, then the final sum will be NaN. If the elements contain one or more infinities, the sum will be infinite or NaN. If the elements contain infinities of opposite sign, the sum will be NaN. If the elements contain infinities of one sign and an intermediate sum overflows to an infinity of the opposite sign, the sum may be NaN. It is possible for intermediate sums of finite values to overflow into opposite-signed infinities; if that occurs, the final sum will be NaN even if the elements are all finite. If all the elements are zero, the sign of zero is not guaranteed to be preserved in the final sum. " https://download.java.net/java/early_access/jdk13/docs/api/java.base/java/util/stream/DoubleStream.html#sum() I'd advise a similar method be available in the vector API, even if it is not the default summation or summation method with the shortest name.
23-07-2019

The API in this JEP is nontrivial in size. With the JVMLS and OCW conferences coming up, it may be a week or more before I'll have comments on the entire API. In the mean time, I may have some partial comments. The first partial comments concerns the set of operators defined VectorOperators. What is the desired semantics for a constant like POW, specified as "Produce pow(a,b). Floating only." Use exactly the same algorithm as the possibly-optimized Math.pow uses? Allow use of *any* pow algorithm that meets the quality of implementation criteria of Math.pow, not necessarily the one used by Math.pow? Some other, presumably looser, definition? (As a point of comparison, I'm aware that Sun vector math library in some cases used different algorithms than the scalar math library.) It might be useful to define operators for the StrictMath method that can differ operationally from their Math counterparts, methods like sin, cos, pow but *not* method like floor, fma, sqrt, etc.
23-07-2019

As a procedural comment, to supplement the online webrev, please also attach a zip of the webrev (or some other free standing form of the proposed API). This supports the archival function of the CSR.
20-07-2019