We would like to add some lightweight wrappers for VectorType
(accessors and iterators), along with some new builders, to make it easier and safer to work with scalable dimensions.
Motivating example
Let’s say that you are trying to create a new VectorType
by “dropping” the leading n
dimensions of vType
:
VectorType::get(vType.getShape().drop_front(n),
vType.getElementType(),
vType.getScalableDims().drop_front(n));
This is problematic for a few reasons:
- Shape and scalability flags have to be updated separately
- It exposes an implementation detail that is often irrelevant (as in the example above)
- It is easy to forget about the scalability flags entirely
Another problematic example is when you check the size of a dimension:
- Usual thing - check for
1
(fixed width “1”):vType.getDimSize(0) == 1 && !vType.getScalableDims()[0]
- The code is quite verbose - checks for “scalability” even though we’re looking for plain fixed width “1”
- Unusual thing - check for
1
and[1]
(fixed width and scalable “1”):vType.getDimSize(0) == 1
- Seems normal, but matches
[1]
and1
- The semantics of
1
and[1]
are different and this is rarely what’s intended
Proposal
We would like to add new scalability-safe accessors and iterators to VectorType
, along with new builders that can make use of these:
/// Returns the value of the specified dimension (including scalability)
VectorDim VectorType::getDim(unsigned idx);
/// Returns the dimensions of this vector type (including scalability)
VectorDims VectorType::getDims();
With the proposed changes, the examples above would look like this:
// Drop leading n dims:
VectorType::get(vType.getElementType(), vType.getDims().dropFront(n));
// Check if the leading dim is a _fixed_ unit dim:
vType.getDims()[0] == VectorDim::getFixed(1);
In both cases:
- The intent is clear
- The code is more concise
- Scalability is checked and preserved (enforced by the new APIs)
The new accessors are backed by two new classes:
-
VectorDim
represents a single dimension ofVectorType
. It can be a fixed or scalable quantity. It cannot be implicitly converted to/from an integer, so you must specify the kind of quantity you expect in comparisons -
VectorDims
represents a non-owning list of vector dimensions, backed by separate size and scalability lists (matching the storage of VectorType). This class has an iterator, and a few common helper methods (similar to that of ArrayRef)
Importantly, this proposal does not change the storage of VectorType
.
Discussion
In our previous attempt to improve how scalable dimensions are treated, people suggested restricting the changes to VectorType
.
One option here was separating VectorType
from ShapedType
(switching solely to the new APIs), however:
- That would be a large non-incremental change
- Likely to cause major issues downstream
So as a compromise, this proposal only adds new APIs, that make:
- The task of improving support for scalable vectors much easier
- The codebase more concise and succinct
Also, those less interested in “scalability” won’t be exposed to the implementation details anymore. There is one disadvantage of this approach:
- It creates an alternative/additional mechanism to deal with dimensions of
VectorType
While we are happy to refactor the codebase to keep it uniform, there won’t be a mechanism to prevent people from using the accessors that we have today and to mix both approaches.
Feedback
Your feedback is much appreciate A complete implementation is available here:
To see the potential impact that this will have on the code-base:
- Demonstrate using the new APIs in scalable-aware code
- Statistics: 68 insertions(+), 123 deletions(-)
Thank you for taking a look
Andrzej & Ben