Skip to content

[mlir][tosa] Support DenseResourceElementsAttr in TOSA transpose folders #124532

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions mlir/lib/Dialect/Tosa/Transforms/TosaFolders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "mlir/Dialect/Utils/IndexingUtils.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectResourceBlobManager.h"
#include "mlir/IR/Matchers.h"
#include "mlir/Pass/Pass.h"
#include "llvm/ADT/APFloat.h"
Expand Down Expand Up @@ -176,13 +177,36 @@ DenseElementsAttr transposeType(const RangeType &data, ShapedType inputType,
llvm::ArrayRef<ElementType>(outputValues));
}

// Try to get the values of a DenseResourceElementsAttr construct
template <typename T>
std::optional<ArrayRef<T>> tryGetDenseResourceValues(ElementsAttr attr) {
if (auto denseResource = dyn_cast<DenseResourceElementsAttr>(attr)) {
// Check that the resource memory blob exists
AsmResourceBlob *blob = denseResource.getRawHandle().getBlob();
if (!blob)
return std::nullopt;

// Check that the data are in a valid form
bool isSplat = false;
if (!DenseElementsAttr::isValidRawBuffer(attr.getShapedType(),
blob->getData(), isSplat)) {
return std::nullopt;
}

return blob->template getDataAs<T>();
}

return std::nullopt;
}

// A type specialized transposition of an ElementsAttr.
// This implementation tries to operate on the underlying data in its raw
// representation when possible to avoid allocating a large number of Attribute
// objects.
DenseElementsAttr transpose(ElementsAttr attr, ShapedType inputType,
ShapedType outputType,
llvm::ArrayRef<int64_t> permValues) {
// Handle generic ElementsAttr
if (auto data = attr.tryGetValues<bool>())
return transposeType(*data, inputType, outputType, permValues);

Expand All @@ -204,6 +228,35 @@ DenseElementsAttr transpose(ElementsAttr attr, ShapedType inputType,
if (auto data = attr.tryGetValues<APFloat>())
return transposeType(*data, inputType, outputType, permValues);

// Handle DenseResourceElementsAttr
if (isa<DenseResourceElementsAttr>(attr)) {
auto elementTy = attr.getElementType();

if (auto data = tryGetDenseResourceValues<bool>(attr);
data && elementTy.isInteger(1))
return transposeType(*data, inputType, outputType, permValues);

if (auto data = tryGetDenseResourceValues<int8_t>(attr);
data && elementTy.isInteger(8))
return transposeType(*data, inputType, outputType, permValues);

if (auto data = tryGetDenseResourceValues<int16_t>(attr);
data && elementTy.isInteger(16))
return transposeType(*data, inputType, outputType, permValues);

if (auto data = tryGetDenseResourceValues<int32_t>(attr);
data && elementTy.isInteger(32))
return transposeType(*data, inputType, outputType, permValues);

if (auto data = tryGetDenseResourceValues<int64_t>(attr);
data && elementTy.isInteger(64))
return transposeType(*data, inputType, outputType, permValues);

if (auto data = tryGetDenseResourceValues<float>(attr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we missing other floating point types like FP16 per spec?

Copy link
Contributor Author

@GeorgeARM GeorgeARM Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs handling through APFloat I presume. Need to look into this. Happy to do this as part of this patch if you want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So had a look at this and is not as simple. I think this requires more effort to layer cleanly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth adding this as a TODO below?

data && elementTy.isF32())
return transposeType(*data, inputType, outputType, permValues);
}

return nullptr;
}

Expand Down
8 changes: 4 additions & 4 deletions mlir/test/Dialect/Tosa/constant-op-fold.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,18 @@ func.func @transpose_nofold_quantized_types() -> tensor<1x1x2x2x!quant.uniform<i
return %0: tensor<1x1x2x2x!quant.uniform<i8<-127:127>:f32:3, {1.000000e-01,1.000000e-01}>>
}

// CHECK-LABEL: @transpose_nofold_dense_resource
func.func @transpose_nofold_dense_resource() -> tensor<2x2xf32> {
// CHECK-LABEL: @transpose_fold_dense_resource
func.func @transpose_fold_dense_resource() -> tensor<2x2xf32> {
%0 = "tosa.const"() <{values = dense_resource<resource> : tensor<2x2xf32>}> : () -> tensor<2x2xf32>

// CHECK: tosa.transpose
// CHECK-NOT: tosa.transpose
%2 = tosa.transpose %0 { perms = array<i32: 1, 0> }: (tensor<2x2xf32>) -> tensor<2x2xf32>
return %2 : tensor<2x2xf32>
}
{-#
dialect_resources: {
builtin: {
resource: "0x08000000010000000000000002000000000000000300000000000000"
resource: "0x040000003f800000400000004040000040800000"
}
}
#-}
Expand Down