DenseElementAttr is convenient but exposes a very complex C++ API. A lot of it stems from the fact that it supports splat, which was motivated by the desire to handle large constant.
Also it is hard to subclass: an op that just want an array of
i64 (for example any attribute that refers to the dimensions, like in a
transpose operation) will still expose and API based on the generic
DenseElementAttr: this leads to a lot of inefficiency where people iterate through it using APInt/APFloat.
This new attribute is similar to
DenseElementsAttr but does not support
splat. As such it has a much simpler API and does not need any smart
iterator: it exposes direct ArrayRef access.
A new syntax is introduced so that the generic printing/parsing looks
[:i16 1, -2, 3]
It opens on a square bracket like the ArrayAttr, but is followed by a colon to distinguish the two. The colon is followed by the element type
(supported are I8, I16, I32, I64, F32, F64) and then the comma-separated list for the data as usual.
This is particularly convenient for attributes intended to be small,
like those referring to shapes.
For example a
transpose operation with a
dims attribute could be
defined as such:
let arguments = (ins AnyTensor:$input, DenseI64ArrayAttr:$dims); let assemblyFormat = "$input `dims` `=` $dims attr-dict : type($input)";
And printed this way (we elide the element type here):
transpose %input dims = [0, 2, 1] : tensor<2x3x4xf32>
The attribute is directly parsed/printed as data in between square brackets without any other type indication.
Also and more importantly, the C++ API for
TransposeOps::getDims() would just directly return an
Revision: ⚙ D123774 Introduce a new Dense Array attribute (~400 lines)
I had updated TOSA with an earlier revision of this patch in December, in case you want to see the actual effect on the C++ API that motivated this work: ⚙ D116394 Adopt DimensionListAttr in TOSA op definition (NFC)