@@ -167,7 +167,7 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding",
167
167
- **soa** : only applicable to singleton levels, fuses the singleton
168
168
level in SoA (structure of arrays) scheme.
169
169
170
- In addition to the map, the following two fields are optional:
170
+ In addition to the map, the following fields are optional:
171
171
172
172
- The required bitwidth for position storage (integral offsets
173
173
into the sparse storage scheme). A narrow width reduces the memory
@@ -183,6 +183,23 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding",
183
183
coordinate over all levels). The choices are `8`, `16`, `32`,
184
184
`64`, or, the default, `0` to indicate a native bitwidth.
185
185
186
+ - The explicit value for the sparse tensor. If explicitVal is set,
187
+ then all the non-zero values in the tensor have the same explicit value.
188
+ The default value Attribute() indicates that it is not set. This
189
+ is useful for binary-valued sparse tensors whose values can either
190
+ be an implicit value (0 by default) or an explicit value (such as 1).
191
+ In this approach, we don't store explicit/implicit values, and metadata
192
+ (such as position and coordinate arrays) alone fully defines the original tensor.
193
+ This yields additional savings for the storage requirements,
194
+ as well as for the computational time, since we skip operating on
195
+ implicit values and can constant fold the explicit values where they are used.
196
+
197
+ - The implicit value for the sparse tensor. If implicitVal is set,
198
+ then the "zero" value in the tensor is equal to the implicit value.
199
+ For now, we only support `0` as the implicit value but it could be
200
+ extended in the future. The default value Attribute() indicates that
201
+ the implicit value is `0` (same type as the tensor element type).
202
+
186
203
Examples:
187
204
188
205
```mlir
@@ -226,6 +243,15 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding",
226
243
}>
227
244
... tensor<8x8xf64, #DCSC> ...
228
245
246
+ // Doubly compressed sparse column storage with specific
247
+ // explicit and implicit values.
248
+ #DCSC = #sparse_tensor.encoding<{
249
+ map = (i, j) -> (j : compressed, i : compressed),
250
+ explicitVal = 1 : i64,
251
+ implicitVal = 0 : i64
252
+ }>
253
+ ... tensor<8x8xi64, #DCSC> ...
254
+
229
255
// Block sparse row storage (2x3 blocks).
230
256
#BSR = #sparse_tensor.encoding<{
231
257
map = ( i, j ) ->
@@ -307,6 +333,12 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding",
307
333
// The required bitwidth for coordinate storage.
308
334
"unsigned":$crdWidth,
309
335
336
+ // The required explicit value.
337
+ "::mlir::Attribute":$explicitVal,
338
+
339
+ // The required implicit value.
340
+ "::mlir::Attribute":$implicitVal,
341
+
310
342
// A slice attribute for each dimension of the tensor type.
311
343
ArrayRefParameter<
312
344
"::mlir::sparse_tensor::SparseTensorDimSliceAttr",
@@ -319,14 +351,17 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding",
319
351
CArg<"AffineMap", "{}">:$dimToLvl,
320
352
CArg<"AffineMap", "{}">:$lvlToDim,
321
353
CArg<"unsigned", "0">:$posWidth,
322
- CArg<"unsigned", "0">:$crdWidth), [{
354
+ CArg<"unsigned", "0">:$crdWidth,
355
+ CArg<"::mlir::Attribute", "{}">:$explicitVal,
356
+ CArg<"::mlir::Attribute", "{}">:$implicitVal), [{
323
357
if (!dimToLvl) {
324
358
dimToLvl = ::mlir::AffineMap::getMultiDimIdentityMap(lvlTypes.size(), $_ctxt);
325
359
}
326
360
if (!lvlToDim) {
327
361
lvlToDim = ::mlir::sparse_tensor::inferLvlToDim(dimToLvl, $_ctxt);
328
362
}
329
363
return $_get($_ctxt, lvlTypes, dimToLvl, lvlToDim, posWidth, crdWidth,
364
+ explicitVal, implicitVal,
330
365
ArrayRef<::mlir::sparse_tensor::SparseTensorDimSliceAttr>{});
331
366
}]>
332
367
];
@@ -353,6 +388,22 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding",
353
388
/// reset to the default, and all other fields inherited from `this`.
354
389
SparseTensorEncodingAttr withoutBitWidths() const;
355
390
391
+ /// Constructs a new encoding with the given explicit value
392
+ /// and all other fields inherited from `this`.
393
+ SparseTensorEncodingAttr withExplicitVal(Attribute explicitVal) const;
394
+
395
+ /// Constructs a new encoding with the explicit value
396
+ /// reset to the default, and all other fields inherited from `this`.
397
+ SparseTensorEncodingAttr withoutExplicitVal() const;
398
+
399
+ /// Constructs a new encoding with the given implicit value
400
+ /// and all other fields inherited from `this`.
401
+ SparseTensorEncodingAttr withImplicitVal(Attribute implicitVal) const;
402
+
403
+ /// Constructs a new encoding with the implicit value
404
+ /// reset to the default, and all other fields inherited from `this`.
405
+ SparseTensorEncodingAttr withoutImplicitVal() const;
406
+
356
407
/// Constructs a new encoding with the given dimSlices, and all
357
408
/// other fields inherited from `this`.
358
409
SparseTensorEncodingAttr withDimSlices(ArrayRef<::mlir::sparse_tensor::SparseTensorDimSliceAttr> dimSlices) const;
0 commit comments