Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[MLIR][TOSA] Fix validation for unsigned integer types in RescaleOp #137838

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

Closed

Conversation

swote-git
Copy link

@swote-git swote-git commented Apr 29, 2025

This patch fixes a bug in the TOSA RescaleOp verifier that incorrectly rejects unsigned integer types (ui8, ui16), even though they are supported by the TOSA specification.

The verifier now properly handles unsigned integer types when the corresponding input_unsigned or output_unsigned attribute is set to true.

Added tests for ui8<->i8 rescale operations.

Fixes #135699

This patch fixes a bug in the TOSA RescaleOp verifier that incorrectly rejects
unsigned integer types (ui8, ui16), even though they are supported by the TOSA
specification.

The verifier now properly handles unsigned integer types when the corresponding
input_unsigned or output_unsigned attribute is set to true.

Added tests for ui8<->i8 and ui16<->i16 rescale operations.

Fixes llvm#135699
Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Member

llvmbot commented Apr 29, 2025

@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-tosa

Author: NohHyeon Kwon (swote-git)

Changes

This patch fixes a bug in the TOSA RescaleOp verifier that incorrectly rejects unsigned integer types (ui8, ui16), even though they are supported by the TOSA specification.

The verifier now properly handles unsigned integer types when the corresponding input_unsigned or output_unsigned attribute is set to true.

Added tests for ui8<->i8 and ui16<->i16 rescale operations.

Fixes #135699


Full diff: https://github.com/llvm/llvm-project/pull/137838.diff

2 Files Affected:

  • (modified) mlir/lib/Dialect/Tosa/IR/TosaOps.cpp (+18-12)
  • (modified) mlir/test/Dialect/Tosa/availability.mlir (+22)
diff --git a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
index b2e471f2bba93..980ef18b975f9 100644
--- a/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
+++ b/mlir/lib/Dialect/Tosa/IR/TosaOps.cpp
@@ -2111,24 +2111,30 @@ static LogicalResult verifyZeroPoint(tosa::RescaleOp op, Value zpVal,
                                      const int64_t &zp,
                                      const std::string &operand) {
   bool isInputZp = (operand == "Input");
-
   bool tensorUnsigned =
-      isInputZp ? op.getInputUnsigned() : op.getOutputUnsigned();
+    isInputZp ? op.getInputUnsigned() : op.getOutputUnsigned();
   StringRef tensorName = isInputZp ? "input" : "output";
-
   Type zpElemType = getElementTypeOrSelf(zpVal);
 
   if (zp != 0) {
-    if (!zpElemType.isInteger(8) &&
-        !(zpElemType.isInteger(16) && tensorUnsigned)) {
-      return op.emitOpError()
-             << "expect " << tensorName << "_zp of 0, got " << zp;
+    bool validType = zpElemType.isInteger(8);
+
+    if (tensorUnsigned && zpElemType.isInteger(8)) {
+      validType = true;
     }
-    if (zpElemType.isInteger(16) && tensorUnsigned &&
-        zp != static_cast<int16_t>(32768)) {
-      return op.emitOpError() << "expect " << tensorName
-                              << "_zp of 0 or 32768 for unsigned int16 "
-                              << tensorName << ", got " << zp;
+
+    if (zpElemType.isInteger(16) && tensorUnsigned) {
+      validType = true;
+      if (zp != 32768) {
+        return op.emitOpError() << "expect " << tensorName
+                << "_zp of 0 or 32768 for unsigned int16 "
+                << tensorName << ", got " << zp;
+      }
+    }
+
+    if (!validType) {
+      return op.emitOpError() 
+              << "expect " << tensorName << "_zp of 0, got " << zp;
     }
   }
 
diff --git a/mlir/test/Dialect/Tosa/availability.mlir b/mlir/test/Dialect/Tosa/availability.mlir
index 75126a11ac504..08d2bd30cf971 100644
--- a/mlir/test/Dialect/Tosa/availability.mlir
+++ b/mlir/test/Dialect/Tosa/availability.mlir
@@ -622,6 +622,28 @@ func.func @test_rescale(%arg0: tensor<13x21x3x!quant.uniform<u8:f32, 0.015655439
   return %0 : tensor<13x21x3x!quant.uniform<i8:f32, 0.015655439347028732:-1>>
 }
 
+// -----
+// CHECK-LABEL: test_rescale
+func.func @test_rescale_unsigned_i8(%arg0: tensor<13x21x3x!quant.uniform<u8:f32, 0.015655439347028732:127>>, %multiplier : tensor<1xi32>, %shift : tensor<1xi8>) -> tensor<13x21x3x!quant.uniform<i8:f32, 0.015655439347028732:-1>> {
+  %input_zp = "tosa.const"() {values = dense<127> : tensor<1xi8>} : () -> tensor<1xi8>
+  %output_zp = "tosa.const"() {values = dense<-1> : tensor<1xi8>} : () -> tensor<1xi8>
+  // CHECK: tosa.rescale profiles: [ [pro_int] ]
+  // CHECK: tosa.rescale extensions: [ [int16] ]
+  %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp {rounding_mode = "SINGLE_ROUND", scale32 = true, per_channel = false, input_unsigned = true, output_unsigned = false} : (tensor<13x21x3x!quant.uniform<u8:f32, 0.015655439347028732:127>>, tensor<1xi32>, tensor<1xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<13x21x3x!quant.uniform<i8:f32, 0.015655439347028732:-1>>
+  return %0 : tensor<13x21x3x!quant.uniform<i8:f32, 0.015655439347028732:-1>>
+}
+
+// -----
+// CHECK-LABEL: test_rescale
+func.func @test_rescale_to_unsigned_i8(%arg0: tensor<13x21x3x!quant.uniform<i8:f32, 0.015655439347028732:-1>>, %multiplier : tensor<1xi32>, %shift : tensor<1xi8>) -> tensor<13x21x3x!quant.uniform<u8:f32, 0.015655439347028732:127>> {
+  %input_zp = "tosa.const"() {values = dense<-1> : tensor<1xi8>} : () -> tensor<1xi8>
+  %output_zp = "tosa.const"() {values = dense<127> : tensor<1xi8>} : () -> tensor<1xi8>
+  // CHECK: tosa.rescale profiles: [ [pro_int] ]
+  // CHECK: tosa.rescale extensions: [ [int16] ]
+  %0 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp {rounding_mode = "SINGLE_ROUND", scale32 = true, per_channel = false, input_unsigned = false, output_unsigned = true} : (tensor<13x21x3x!quant.uniform<i8:f32, 0.015655439347028732:-1>>, tensor<1xi32>, tensor<1xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<13x21x3x!quant.uniform<u8:f32, 0.015655439347028732:127>>
+  return %0 : tensor<13x21x3x!quant.uniform<u8:f32, 0.015655439347028732:127>>
+}
+
 // -----
 // CHECK-LABEL: test_const
 func.func @test_const(%arg0 : index) -> tensor<4xi32> {

@lhutton1
Copy link
Contributor

cc @psunn

@psunn
Copy link
Contributor

psunn commented May 2, 2025

Hi, thanks for looking into this issue.

The issue you mentioned above concerns whether the TOSA validation pass should allow ui8/16 inputs and outputs — we can continue the discussion from that perspective.

However, the changes in this PR modify the zero-point verification logic in the RescaleOp verifier, which seems unrelated to the issue above.

@@ -622,6 +622,28 @@ func.func @test_rescale(%arg0: tensor<13x21x3x!quant.uniform<u8:f32, 0.015655439
return %0 : tensor<13x21x3x!quant.uniform<i8:f32, 0.015655439347028732:-1>>
Copy link
Contributor

@lhutton1 lhutton1 May 2, 2025

Choose a reason for hiding this comment

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

A little unrelated to this PR - I feel this test case should be considered invalid since input_unsigned=false, but the provided input is u8. This is something we should check in the verifier.

@swote-git
Copy link
Author

Thank you for your passionate review.

I think I missed an important part of the issue because I misunderstood it.

Thank you again for your good comment.

Coming back to the topic, what should I do about the PR I patched?

@lhutton1
Copy link
Contributor

lhutton1 commented May 7, 2025

Thanks @swote-git, I think we can abandon this in favour of #138253

@swote-git swote-git closed this May 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[MLIR] tosa.rescale op validation incorrectly fails on unsigned integer type
4 participants