[Mlir-commits] [mlir] [mlir][spirv] Tighten SPIR-V TOSA convolution verification (PR #194592)

Igor Wodiany llvmlistbot at llvm.org
Tue Apr 28 08:53:08 PDT 2026


================
@@ -111,18 +111,212 @@ LogicalResult verifyPool2DOp(Operation *op, DenseIntElementsAttr kernel,
   return success();
 }
 
+LogicalResult verifyConvolutionOutputDim(
+    Operation *op, int64_t inputSize, int64_t kernelSize, int64_t outputSize,
+    int64_t padBefore, int64_t padAfter, int64_t strideSize,
+    int64_t dilationSize, StringRef dimName, StringRef dimAxis,
+    StringRef padBeforeName, StringRef padAfterName, StringRef errorMessage) {
+  if (ShapedType::isDynamic(inputSize) || ShapedType::isDynamic(kernelSize))
+    return success();
+
+  const int64_t numerator =
+      inputSize - 1 + padBefore + padAfter - (kernelSize - 1) * dilationSize;
+  if (numerator % strideSize != 0)
+    return op->emitOpError("expected input_")
+           << dimName << " - 1 + pad_" << padBeforeName << " + pad_"
+           << padAfterName << " - (kernel_" << dimName << " - 1) * dilation_"
+           << dimAxis << " to be wholly divisible by stride_" << dimAxis
+           << ", got (" << inputSize << " - 1 + " << padBefore << " + "
+           << padAfter << " - (" << kernelSize << " - 1) * " << dilationSize
+           << ") / " << strideSize;
+
+  const int64_t calculatedOutput = numerator / strideSize + 1;
+  if (!ShapedType::isDynamic(outputSize) && outputSize != calculatedOutput)
+    return op->emitOpError(errorMessage);
+
+  return success();
+}
+
+LogicalResult verifyTransposeConvolutionOutputDim(
+    Operation *op, int64_t inputSize, int64_t kernelSize, int64_t outputSize,
+    int64_t padBefore, int64_t padAfter, int64_t strideSize,
+    StringRef errorMessage) {
+  if (ShapedType::isDynamic(inputSize) || ShapedType::isDynamic(kernelSize))
+    return success();
+
+  const int64_t calculatedOutput =
+      (inputSize - 1) * strideSize + padBefore + padAfter + kernelSize;
+  if (!ShapedType::isDynamic(outputSize) && outputSize != calculatedOutput)
+    return op->emitOpError(errorMessage);
+
+  return success();
+}
+
+LogicalResult verifyConv2DOutputShape(Operation *op, DenseIntElementsAttr pad,
+                                      DenseIntElementsAttr stride,
+                                      DenseIntElementsAttr dilation,
+                                      TensorArmType inputType,
+                                      TensorArmType weightType,
+                                      TensorArmType outputType) {
+  constexpr StringLiteral errorMessage =
+      "failed to verify that shapes of input, weight, and output must satisfy "
+      "[N,IH,IW,*], [*,KH,KW,*], [N,OH,OW,*], with OH = ((IH - 1 + pad_top + "
+      "pad_bottom - (KH - 1) * dilation_y) / stride_y) + 1 and OW = ((IW - 1 "
+      "+ pad_left + pad_right - (KW - 1) * dilation_x) / stride_x) + 1";
+  if (!inputType.hasRank() || !weightType.hasRank() || !outputType.hasRank())
+    return success();
+
+  if (failed(verifyConvolutionOutputDim(
+          op, inputType.getDimSize(1), weightType.getDimSize(1),
+          outputType.getDimSize(1), getIntValue(pad, 0), getIntValue(pad, 1),
+          getIntValue(stride, 0), getIntValue(dilation, 0), "height", "y",
+          "top", "bottom", errorMessage)))
+    return failure();
----------------
IgWod wrote:

Instead of passing `errorMessage` why not return failure from the other function and have `return op->emitOpError(errorMessage)` here?

https://github.com/llvm/llvm-project/pull/194592


More information about the Mlir-commits mailing list