From 3a45ee5de885b3847d1084383b32e21272b8b269 Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Wed, 23 Feb 2022 07:40:39 -0800 Subject: [PATCH] Remove explicit verifier usage as it is about to be obsolete (#1195) Several properties (such as verifier, printer & parser) are going to be obsolete in main mlir soon. This change removes the explicit usage of verifier and instead uses the hasVerifier option instead. Also, some minor whitespace cleanup. Signed-off-by: Stella Stamenova stilis@microsoft.com --- src/Dialect/Krnl/Krnl.td | 104 ++++++++++++-------------- src/Dialect/Krnl/KrnlOps.cpp | 59 ++++++++------- src/Dialect/ONNX/AdditionalONNXOps.td | 16 ++-- src/Dialect/ONNX/ONNX.td | 47 +++++++----- src/Dialect/ONNX/ONNXOps.cpp | 28 +++---- 5 files changed, 128 insertions(+), 126 deletions(-) diff --git a/src/Dialect/Krnl/Krnl.td b/src/Dialect/Krnl/Krnl.td index 463f5d43f38..8cfe4c84068 100644 --- a/src/Dialect/Krnl/Krnl.td +++ b/src/Dialect/Krnl/Krnl.td @@ -19,6 +19,7 @@ include "mlir/IR/OpBase.td" include "mlir/Dialect/Shape/IR/ShapeBase.td" +include "mlir/Interfaces/CastInterfaces.td" include "mlir/Interfaces/LoopLikeInterface.td" include "mlir/Interfaces/SideEffectInterfaces.td" include "mlir/Interfaces/ViewLikeInterface.td" @@ -42,8 +43,8 @@ def KrnlDefineLoopsOp : Op { intend to optimize. }]; - let arguments = (ins); let results = (outs Variadic); + let skipDefaultBuilders = 1; let builders = [ OpBuilder<(ins "int64_t":$num_loops)> ]; @@ -53,14 +54,14 @@ def KrnlDefineLoopsOp : Op { let extraClassDeclaration = [{ static StringRef getNumLoopsAttrName() { return "num_loops"; } - // Helper function to extract the number of loops being defined. - int64_t getNumLoops() { - auto num_loops = (*this)->getAttrOfType(getNumLoopsAttrName()) - .getValue() - .getSExtValue(); - return num_loops; - } -}]; + // Helper function to extract the number of loops being defined. + int64_t getNumLoops() { + auto num_loops = (*this)->getAttrOfType(getNumLoopsAttrName()) + .getValue() + .getSExtValue(); + return num_loops; + } + }]; } def KrnlIterateOp : Op); + let regions = (region SizedRegion<1>:$bodyRegion); + let skipDefaultBuilders = 1; let builders = [ // Main builder. @@ -106,7 +109,12 @@ def KrnlIterateOp : Op">:$lbs, CArg<"ArrayRef">:$ubs, CArg<"ValueRange">:$iterArgs, CArg<"function_ref">:$bodyBuilderFn)> - ]; + ]; + + let printer = [{ return ::print(p, *this); }]; + let parser = [{ return ::parse$cppClass(parser, result); }]; + + let hasVerifier = 1; let extraClassDeclaration = [{ // In krnl.iterate operation, operands are stored as such @@ -127,11 +135,7 @@ def KrnlIterateOp : Op { @@ -148,9 +152,6 @@ def KrnlTerminatorOp : Op { // No custom parsing/printing form. let parser = ?; let printer = ?; - - // Fully specified by traits. - let verifier = ?; } def KrnlEntryPointOp : Op { @@ -223,6 +224,9 @@ def KrnlGetRefOp : Op { }]>, ]; + let parser = ?; + let printer = ?; + let extraClassDeclaration = [{ /// Returns the symbolic operands (the ones in square brackets), which bind /// to the symbols of the memref's layout map. @@ -230,9 +234,6 @@ def KrnlGetRefOp : Op { return {operand_begin() + 2, operand_end()}; } }]; - - let parser = ?; - let printer = ?; } def KrnlBlockOp : Op { @@ -243,9 +244,9 @@ def KrnlBlockOp : Op { means to block the for loop referred to by %i using a tile size of 4. }]; - let arguments = (ins - AnyType:$loop, I64Attr:$tile_size); + let arguments = (ins AnyType:$loop, I64Attr:$tile_size); let results = (outs AnyType:$loop_block, AnyType:$loop_local); + let builders = [ OpBuilder<(ins "Value": $loop, "int64_t":$tile_size)> ]; let assemblyFormat = [{ $loop $tile_size attr-dict `:` functional-type($loop, results) @@ -312,7 +313,7 @@ def KrnlPermuteOp : Op { }]; let arguments = (ins Variadic:$loops, I64ArrayAttr:$map); - let results = (outs); + let builders = [ OpBuilder<(ins "ValueRange": $loops, "ArrayRef":$map)> ]; let assemblyFormat = [{ `(` $loops `)` $map attr-dict `:` type($loops) @@ -330,7 +331,7 @@ def KrnlUnrollOp : Op { }]; let arguments = (ins AnyType:$loop); - let results = (outs); + let assemblyFormat = [{ $loop attr-dict `:` type($loop) }]; @@ -507,6 +508,8 @@ def KrnlLoadOp : Op]; + let assemblyFormat = [{$memref `[` $indices `]` attr-dict `:` type($memref)}]; + let extraClassDeclaration = [{ Value getMemRef() { return getOperand(0); } void setMemRef(Value value) { setOperand(0, value); } @@ -516,8 +519,6 @@ def KrnlLoadOp : Op]; + let assemblyFormat = [{ + $value `,` $memref `[` $indices `]` attr-dict `:` type($memref) + }]; + let extraClassDeclaration = [{ Value getValueToStore() { return getOperand(0); } @@ -557,10 +562,6 @@ def KrnlStoreOp : Op { @@ -576,8 +577,6 @@ def KrnlMovableOp : Op { are nested imperfectly between an "eager" and a "lazy" loop. }]; - let arguments = (ins ); - let regions = (region AnyRegion:$region); let assemblyFormat = [{ @@ -600,6 +599,7 @@ def KrnlGetInductionVariableValueOp : Op : $loops); let results = (outs Variadic : $ind_var_vals); + let builders = [ OpBuilder<(ins "ValueRange": $loops)>]; let assemblyFormat = [{ @@ -611,7 +611,7 @@ def KrnlGetInductionVariableValueOp : Op { + MemRefsNormalizable, DeclareOpInterfaceMethods, ViewLikeOpInterface]> { let summary = "vector type cast operation"; let description = [{ The "vector_type_cast" operation converts a memref from an non-vector @@ -627,30 +627,20 @@ def KrnlVectorTypeCastOp : Op ]; - let verifier = [{ return impl::verifyCastOp(*this, areCastCompatible); }]; + let assemblyFormat = [{ + $source attr-dict `:` type($source) `to` type($result) + }]; let extraClassDeclaration = [{ - /// Return true if `a` and `b` are valid operand and result pairs for - /// the operation. - static bool areCastCompatible(Type a, Type b); - /// The result of a vector_type_cast is always a memref. MemRefType getType() { return getResult().getType().cast(); } /// Return the view source. Value getViewSource() { return source(); } }]; - - let hasFolder = 1; - let builders = [ OpBuilder<(ins "Value": $source, "int64_t": $vectorLen)> ]; - - let assemblyFormat = [{ - $source attr-dict `:` type($source) `to` type($result) - }]; - } // ============================================================================= @@ -663,7 +653,6 @@ def KrnlSpecializedKernel : Op : $loops); - let results = (outs ); let assemblyFormat = [{ `(` $loops `)` attr-dict `:` type($loops) @@ -841,7 +830,7 @@ def KrnlMatMulOp : Op ]; - let verifier = [{ return ::verify(*this); }]; + let hasVerifier = 1; let assemblyFormat = [{ $A `[` $aMemStart `]` `,` @@ -922,8 +911,9 @@ def KrnlCopyToBufferOp : Op ]; - let verifier = [{ return ::verify(*this); }]; - let assemblyFormat = [{ + let hasVerifier = 1; + + let assemblyFormat = [{ $buffer `,` $source `[` $starts `]` `,` $padValue attr-dict `:` type($buffer) `,` type($source) }]; @@ -955,8 +945,9 @@ def KrnlCopyFromBufferOp : Op ]; - let verifier = [{ return ::verify(*this); }]; - let assemblyFormat = [{ + let hasVerifier = 1; + + let assemblyFormat = [{ $buffer `,` $dest `[` $starts `]` attr-dict `:` type($buffer) `,` type($dest) }]; } @@ -984,6 +975,7 @@ def KrnlMemsetOp : Op(); auto bT = b.dyn_cast(); @@ -617,8 +622,8 @@ void KrnlMatMulOp::build(::mlir::OpBuilder &odsBuilder, odsSimdize, odsUnroll, odsOvercompute); } -static LogicalResult verify(KrnlMatMulOp op) { - KrnlMatMulOpAdaptor operandAdaptor = KrnlMatMulOpAdaptor(op); +LogicalResult KrnlMatMulOp::verify() { + KrnlMatMulOpAdaptor operandAdaptor = KrnlMatMulOpAdaptor(*this); uint64_t aRank = operandAdaptor.A().getType().cast().getShape().size(); uint64_t bRank = @@ -626,35 +631,35 @@ static LogicalResult verify(KrnlMatMulOp op) { uint64_t cRank = operandAdaptor.C().getType().cast().getShape().size(); if (!(aRank >= 2 && bRank >= 2 && cRank >= 2)) - return op.emitOpError("currently only support ranks >=2"); + return emitOpError("currently only support ranks >=2"); if (operandAdaptor.aMemStart().size() != aRank) - return op.emitOpError("aMemStart should have same rank as memref A"); + return emitOpError("aMemStart should have same rank as memref A"); if (operandAdaptor.bMemStart().size() != bRank) - return op.emitOpError("bMemStart should have same rank as memref A"); + return emitOpError("bMemStart should have same rank as memref A"); if (operandAdaptor.cMemStart().size() != cRank) - return op.emitOpError("cMemStart should have same rank as memref A"); + return emitOpError("cMemStart should have same rank as memref A"); if (operandAdaptor.loops().size() != 3) - return op.emitOpError("loops rank should be 3 (i,j,k)"); + return emitOpError("loops rank should be 3 (i,j,k)"); if (operandAdaptor.computeTileSize().hasValue()) { ArrayAttr computeAttr = operandAdaptor.computeTileSize().getValue(); if (!(computeAttr.size() == 0 || computeAttr.size() == 3)) - return op.emitOpError("computeTileSize rank should be 0 or 3"); + return emitOpError("computeTileSize rank should be 0 or 3"); } if (operandAdaptor.aTileSize().hasValue()) { ArrayAttr aTileAttr = operandAdaptor.aTileSize().getValue(); if (!(aTileAttr.size() == 0 || aTileAttr.size() == 2)) - return op.emitOpError("aTileSize rank should be 0 or 2"); + return emitOpError("aTileSize rank should be 0 or 2"); } if (operandAdaptor.bTileSize().hasValue()) { ArrayAttr bTileAttr = operandAdaptor.bTileSize().getValue(); if (!(bTileAttr.size() == 0 || bTileAttr.size() == 2)) - return op.emitOpError("bTileSize rank should be 0 or 2"); + return emitOpError("bTileSize rank should be 0 or 2"); } if (operandAdaptor.cTileSize().hasValue()) { ArrayAttr cTileAttr = operandAdaptor.cTileSize().getValue(); if (!(cTileAttr.size() == 0 || cTileAttr.size() == 2)) - return op.emitOpError("cTileSize rank should be 0 or 2"); + return emitOpError("cTileSize rank should be 0 or 2"); } return success(); } @@ -687,32 +692,32 @@ void KrnlCopyToBufferOp::build(::mlir::OpBuilder &odsBuilder, odsPadValue, empty, empty, odsTranspose); } -static LogicalResult verify(KrnlCopyToBufferOp op) { - KrnlCopyToBufferOpAdaptor opAdaptor = KrnlCopyToBufferOpAdaptor(op); +LogicalResult KrnlCopyToBufferOp::verify() { + KrnlCopyToBufferOpAdaptor opAdaptor = KrnlCopyToBufferOpAdaptor(*this); MemRefBoundsIndexCapture buffCapture(opAdaptor.buffer()); MemRefBoundsIndexCapture srcCapture(opAdaptor.source()); int64_t bufferRank = buffCapture.getRank(); int64_t srcRank = srcCapture.getRank(); int64_t startRank = opAdaptor.starts().size(); if (!buffCapture.areAllLiteral()) - return op.emitOpError("buffer expect constant dimensions"); + return emitOpError("buffer expect constant dimensions"); if (srcRank < bufferRank) - return op.emitOpError("Rank of memref cannot be smaller than buffer"); + return emitOpError("Rank of memref cannot be smaller than buffer"); if (startRank != srcRank) - return op.emitOpError("Rank of starts and memrefs must be identical"); + return emitOpError("Rank of starts and memrefs must be identical"); if (opAdaptor.tileSize()) { int64_t tRank = opAdaptor.tileSize().getValue().size(); if (!(tRank == 0 || tRank == bufferRank)) - return op.emitOpError("Rank of tileSize must be identical to buffer"); + return emitOpError("Rank of tileSize must be identical to buffer"); } if (opAdaptor.padToNext()) { int64_t padRank = opAdaptor.padToNext().getValue().size(); if (!(padRank == 0 || padRank == bufferRank)) - return op.emitOpError("Rank of padToNext must be identical to buffer"); + return emitOpError("Rank of padToNext must be identical to buffer"); } if (opAdaptor.transpose()) { if (bufferRank < 2) - return op.emitOpError( + return emitOpError( "To transpose buffer, its rank must be greater than 1"); } @@ -742,23 +747,23 @@ void KrnlCopyFromBufferOp::build(::mlir::OpBuilder &odsBuilder, build(odsBuilder, odsState, odsBufferMemref, odsMemref, startsRange, empty); } -static LogicalResult verify(KrnlCopyFromBufferOp op) { - KrnlCopyFromBufferOpAdaptor opAdaptor = KrnlCopyFromBufferOpAdaptor(op); +LogicalResult KrnlCopyFromBufferOp::verify() { + KrnlCopyFromBufferOpAdaptor opAdaptor = KrnlCopyFromBufferOpAdaptor(*this); MemRefBoundsIndexCapture buffCapture(opAdaptor.buffer()); int64_t bufferRank = buffCapture.getRank(); int64_t destRank = opAdaptor.dest().getType().cast().getShape().size(); int64_t startRank = opAdaptor.starts().size(); if (!buffCapture.areAllLiteral()) - return op.emitOpError("buffer expect constant dimensions"); + return emitOpError("buffer expect constant dimensions"); if (destRank < bufferRank) - return op.emitOpError("Rank of memref cannot be smaller than buffer"); + return emitOpError("Rank of memref cannot be smaller than buffer"); if (startRank != destRank) - return op.emitOpError("Rank of starts and memrefs must be identical"); + return emitOpError("Rank of starts and memrefs must be identical"); if (opAdaptor.tileSize()) { int64_t tRank = opAdaptor.tileSize().getValue().size(); if (!(tRank == 0 || tRank == bufferRank)) - return op.emitOpError("Rank of tileSize must be identical to buffer"); + return emitOpError("Rank of tileSize must be identical to buffer"); } return success(); } diff --git a/src/Dialect/ONNX/AdditionalONNXOps.td b/src/Dialect/ONNX/AdditionalONNXOps.td index ddcae7b31d4..4a65613184e 100644 --- a/src/Dialect/ONNX/AdditionalONNXOps.td +++ b/src/Dialect/ONNX/AdditionalONNXOps.td @@ -4,7 +4,7 @@ include "mlir/Interfaces/CallInterfaces.td" include "mlir/IR/SymbolInterfaces.td" def ONNXCustomOp:ONNX_Op<"Custom", - [NoSideEffect, DeclareOpInterfaceMethods]> { + [NoSideEffect, DeclareOpInterfaceMethods]> { let summary = "ONNX Custom operation"; let description = [{ "Allow call-out to a user defined operation. A single attribute" @@ -12,8 +12,10 @@ def ONNXCustomOp:ONNX_Op<"Custom", "passed to the user operation." "The number of inputs and outputs can vary." }]; + let arguments = (ins Variadic>:$input, StrAttr:$function_name); let results = (outs Variadic>:$outputs); + let extraClassDeclaration = [{ static int getNumberOfOperands() { return -1; @@ -49,10 +51,8 @@ def ONNXCallOp : ONNX_Op<"ONNX_Call", // TODO I would rather have > here, but the testcase for CustomOps supplies an empty parameter which fails that test -- //will try to figure out why and revert, leaving this old style as a reminder //let results = (outs Variadic); - let results = (outs Variadic>); - let builders = [ OpBuilder<(ins "FuncOp":$callee, CArg<"ValueRange", "{}">:$operands), [{ $_state.addOperands(operands); @@ -75,6 +75,10 @@ def ONNXCallOp : ONNX_Op<"ONNX_Call", results, operands); }]>]; + let assemblyFormat = [{ + $callee `(` $operands `)` attr-dict `:` functional-type($operands, results) + }]; + let extraClassDeclaration = [{ StringRef getCallee() { return callee(); } StringAttr getCalleeAttr() { return calleeAttr().getAttr(); } @@ -93,10 +97,4 @@ def ONNXCallOp : ONNX_Op<"ONNX_Call", return (*this)->getAttrOfType("callee"); } }]; - - let assemblyFormat = [{ - $callee `(` $operands `)` attr-dict `:` functional-type($operands, results) - }]; - let verifier = ?; } - diff --git a/src/Dialect/ONNX/ONNX.td b/src/Dialect/ONNX/ONNX.td index 05dca92ca65..dd3ef7d82b4 100644 --- a/src/Dialect/ONNX/ONNX.td +++ b/src/Dialect/ONNX/ONNX.td @@ -51,7 +51,7 @@ def ONNX_Dialect : Dialect { // * The mnemonic for the operation, or the name without the dialect prefix. // * A list of traits for the operation. class ONNX_Op traits = []> : - Op ; + Op ; //===----------------------------------------------------------------------===// // ONNX Operations @@ -84,10 +84,11 @@ def ONNXEntryPointOp: ONNX_Op<"EntryPoint"> { let description = [{ The "onnx.EntryPoint" function indicates the main entry point of ONNX model. }]; + let arguments = (ins SymbolRefAttr:$func, - I32Attr:$numInputs, - I32Attr:$numOutputs, - StrAttr:$signature); + I32Attr:$numInputs, + I32Attr:$numOutputs, + StrAttr:$signature); let builders = [OpBuilder<(ins "FuncOp":$function, "int":$numInputs, "int":$numOutputs, "std::string":$signature)>]; @@ -142,27 +143,29 @@ def ONNXMaxPoolSingleOutOp: ONNX_Op<"MaxPoolSingleOut", "ONNX MaxPool operation with a single output." "See ONNXMaxPoolOp for a full description of the MaxPool semantics." }]; + let arguments = (ins AnyTypeOf<[AnyMemRef, AnyTensor]>:$X, - DefaultValuedStrAttr:$auto_pad, - DefaultValuedAttr:$ceil_mode, - OptionalAttr:$dilations, - DefaultValuedAttr:$kernel_shape, - OptionalAttr:$pads, - DefaultValuedAttr:$storage_order, - OptionalAttr:$strides); + DefaultValuedStrAttr:$auto_pad, + DefaultValuedAttr:$ceil_mode, + OptionalAttr:$dilations, + DefaultValuedAttr:$kernel_shape, + OptionalAttr:$pads, + DefaultValuedAttr:$storage_order, + OptionalAttr:$strides); let results = (outs AnyTypeOf<[AnyMemRef, AnyTensor]>:$o_Y); + + let hasVerifier = 1; + let extraClassDeclaration = [{ static int getNumberOfOperands() { return 1; } static int getNumberOfResults() { return 1; } static std::vector getTypeMap() { return {20}; } }]; - let verifier = [{ return ::verify(*this); }]; } def ONNXBatchNormalizationInferenceModeOp: ONNX_Op<"BatchNormalizationInferenceMode", [NoSideEffect, DeclareOpInterfaceMethods]> { let summary = "ONNX BatchNormalization operation in test mode"; - let hasCanonicalizer = 1; let description = [{ "Carries out batch normalization as described in the paper" "https://arxiv.org/abs/1502.03167. Depending on the mode it is being run," @@ -175,14 +178,18 @@ def ONNXBatchNormalizationInferenceModeOp: ONNX_Op<"BatchNormalizationInferenceM "to flatten the input shape to (N x C*D1*D2 ..*Dn) before a BatchNormalization Op." "This operator has **optional** inputs/outputs. See [the doc](IR.md) for more details about the representation of optional arguments. An empty string may be used in the place of an actual argument's name to indicate a missing argument. Trailing optional arguments (those not followed by an argument that is present) may also be simply omitted." }]; + let arguments = (ins AnyTypeOf<[AnyMemRef, AnyTensor]>:$X, - AnyTypeOf<[AnyMemRef, AnyTensor]>:$scale, - AnyTypeOf<[AnyMemRef, AnyTensor]>:$B, - AnyTypeOf<[AnyMemRef, AnyTensor]>:$mean, - AnyTypeOf<[AnyMemRef, AnyTensor]>:$var, - DefaultValuedAttr:$epsilon, - DefaultValuedAttr:$momentum); + AnyTypeOf<[AnyMemRef, AnyTensor]>:$scale, + AnyTypeOf<[AnyMemRef, AnyTensor]>:$B, + AnyTypeOf<[AnyMemRef, AnyTensor]>:$mean, + AnyTypeOf<[AnyMemRef, AnyTensor]>:$var, + DefaultValuedAttr:$epsilon, + DefaultValuedAttr:$momentum); let results = (outs AnyTypeOf<[AnyMemRef, AnyTensor]>:$o_Y); + + let hasCanonicalizer = 1; + let extraClassDeclaration = [{ static int getNumberOfOperands() { return 5; } static int getNumberOfResults() { return 1; } @@ -202,6 +209,7 @@ def ONNXNoneOp : ONNX_Op<"NoValue", [ConstantLike, NoSideEffect]> { let arguments = (ins UnitAttr:$value); let results = (outs NoneType:$none_val); + let hasFolder = 1; let builders = [ OpBuilder<(ins),[{ @@ -227,6 +235,7 @@ def ONNX_SeqType : ONNX_Type<"Seq", "Seq"> { let description = [{ An list of tensors which may have different shape }]; + let parameters = (ins "::mlir::ShapedType":$ElementType, "int64_t":$Length); // Previous implementation did not print/parse the length field diff --git a/src/Dialect/ONNX/ONNXOps.cpp b/src/Dialect/ONNX/ONNXOps.cpp index 17ac99c1779..3c8cf95d13e 100644 --- a/src/Dialect/ONNX/ONNXOps.cpp +++ b/src/Dialect/ONNX/ONNXOps.cpp @@ -2273,38 +2273,38 @@ LogicalResult ONNXAveragePoolOp::inferShapes( // MaxPoolSingleOut //===----------------------------------------------------------------------===// -static LogicalResult verify(ONNXMaxPoolSingleOutOp op) { +LogicalResult ONNXMaxPoolSingleOutOp::verify() { ONNXMaxPoolSingleOutOpAdaptor operandAdaptor = - ONNXMaxPoolSingleOutOpAdaptor(op); + ONNXMaxPoolSingleOutOpAdaptor(*this); // Mandatory and unsupported parameters. - if (!op.kernel_shape()) - return op.emitError("kernel_shape is a mandatory attribute"); + if (!kernel_shape()) + return emitOpError("kernel_shape is a mandatory attribute"); // Get spatial rank from mandatory kernel_shape parameter. - int64_t spatialRank = op.kernel_shape().size(); + int64_t spatialRank = kernel_shape().size(); if (spatialRank < 1) - return op.emitError("Spatial rank must be strictly positive"); + return emitOpError("Spatial rank must be strictly positive"); // Not supported for storage order in column major mode. - if (op.storage_order() != 0) - return op.emitError("Column major storage order not implemented yet"); + if (storage_order() != 0) + return emitOpError("Column major storage order not implemented yet"); // Get operands. auto X = operandAdaptor.X(); if (hasShapeAndRank(X)) { auto xShape = X.getType().cast().getShape(); - if ((int64_t)xShape.size() - 2 != spatialRank) - return op->emitError("Input and kernel shape rank mismatch"); + if (static_cast(xShape.size()) - 2 != spatialRank) + return (*this)->emitError("Input and kernel shape rank mismatch"); } // Verify parameters. if (failed(verifyKernelShape( - &op, nullptr, op.kernel_shape(), spatialRank))) + this, nullptr, kernel_shape(), spatialRank))) return failure(); - if (failed(verifyStrides(&op, spatialRank))) + if (failed(verifyStrides(this, spatialRank))) return failure(); - if (failed(verifyDilations(&op, spatialRank))) + if (failed(verifyDilations(this, spatialRank))) return failure(); - if (failed(verifyPadding(&op, spatialRank))) + if (failed(verifyPadding(this, spatialRank))) return failure(); return success(); }