delldu commented on a change in pull request #8443:
URL: https://github.com/apache/tvm/pull/8443#discussion_r670288455



##########
File path: src/relay/op/nn/pad.cc
##########
@@ -272,5 +272,86 @@ RELAY_REGISTER_OP("nn.mirror_pad")
     .add_type_rel("MirrorPad", MirrorPadRel)
     .set_attr<TOpPattern>("TOpPattern", kInjective);
 
+Array<te::Tensor> Im2colCompute(const Attrs& attrs, const Array<te::Tensor>& 
inputs,
+                                const Type& out_type) {
+  const auto* param = attrs.as<Im2colAttrs>();
+  ICHECK(param != nullptr);
+
+  return Array<te::Tensor>{
+      topi::im2col(inputs[0], param->kernel_size, param->dilation, 
param->padding, param->stride)};
+}
+
+bool Im2colRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
+               const TypeReporter& reporter) {
+  // types: [input, output]
+  ICHECK_EQ(types.size(), 2) << "Expects two types, one for the input and 
another for the output";
+
+  const auto* input = types[0].as<TensorTypeNode>();
+  if (input == nullptr) return false;
+
+  if (input->shape.size() != 4) {
+    reporter->GetDiagCtx().EmitFatal(Diagnostic::Error(reporter->GetSpan())
+                                     << "Im2lossRel: input data should be 4 
dimensions, NxCxHxW.");
+    return false;
+  }
+
+  const Im2colAttrs* param = attrs.as<Im2colAttrs>();
+  if (param == nullptr) return false;
+
+  // Calculate output shape
+  auto kernel_h = tvm::cast(tvm::DataType::Int(32), param->kernel_size[0]);
+  auto kernel_w = tvm::cast(tvm::DataType::Int(32), param->kernel_size[1]);
+  auto dilation_h = tvm::cast(tvm::DataType::Int(32), param->dilation[0]);
+  auto dilation_w = tvm::cast(tvm::DataType::Int(32), param->dilation[1]);
+  auto padding_h = tvm::cast(tvm::DataType::Int(32), param->padding[0]);
+  auto padding_w = tvm::cast(tvm::DataType::Int(32), param->padding[1]);
+  auto stride_h = tvm::cast(tvm::DataType::Int(32), param->stride[0]);
+  auto stride_w = tvm::cast(tvm::DataType::Int(32), param->stride[1]);

Review comment:
       Sorry, let me paste the source code.
   ```
   bool Im2colRel(const Array<Type>& types, int num_inputs, const Attrs& attrs,
                  const TypeReporter& reporter) {
     // types: [input, output]
     ICHECK_EQ(types.size(), 2) << "Expects two types, one for the input and 
another for the output";
   
     const auto* input = types[0].as<TensorTypeNode>();
     if (input == nullptr) return false;
   
     if (input->shape.size() != 4) {
       reporter->GetDiagCtx().EmitFatal(Diagnostic::Error(reporter->GetSpan())
                                        << "Im2lossRel: input data should be 4 
dimensions, NxCxHxW.");
       return false;
     }
   
     const Im2colAttrs* param = attrs.as<Im2colAttrs>();
     if (param == nullptr) return false;
   
     ICHECK_EQ(param->kernel_size.size(), 2) << "Expects two parameters for 
kernel height and width";
     ICHECK_EQ(param->dilation.size(), 2) << "Expects two parameters for 
dilation height and width";
     ICHECK_EQ(param->padding.size(), 2) << "Expects two parameters for padding 
height and width";
     ICHECK_EQ(param->stride.size(), 2) << "Expects two parameters for stride 
height and width";
   
     // Calculate output shape
     auto kernel_h = tvm::cast(tvm::DataType::Int(32), param->kernel_size[0]);
     auto kernel_w = tvm::cast(tvm::DataType::Int(32), param->kernel_size[1]);
     auto dilation_h = tvm::cast(tvm::DataType::Int(32), param->dilation[0]);
     auto dilation_w = tvm::cast(tvm::DataType::Int(32), param->dilation[1]);
     auto padding_h = tvm::cast(tvm::DataType::Int(32), param->padding[0]);
     auto padding_w = tvm::cast(tvm::DataType::Int(32), param->padding[1]);
     auto stride_h = tvm::cast(tvm::DataType::Int(32), param->stride[0]);
     auto stride_w = tvm::cast(tvm::DataType::Int(32), param->stride[1]);
     auto dilated_kernel_h = (kernel_h - 1) * dilation_h + 1;
     auto dilated_kernel_w = (kernel_w - 1) * dilation_w + 1;
     // Output size after padding
     auto output_h = (input->shape[2] + 2 * padding_h - dilated_kernel_h) / 
stride_h + 1;
     auto output_w = (input->shape[3] + 2 * padding_w - dilated_kernel_w) / 
stride_w + 1;
   
     tvm::Array<tvm::PrimExpr> output_shape;
     output_shape.push_back(input->shape[0]);                        // N
     output_shape.push_back(input->shape[1] * kernel_h * kernel_w);  // K
     output_shape.push_back(output_h * output_w);                    // L
   
     // assign output type
     reporter->Assign(types[1], TensorType(output_shape, input->dtype));
   
     return true;
   }
   ```
   1) RELAY_REGISTER_OP need Im2col with interface: bool Im2colRel(const 
Array<Type>& **types**, int num_inputs, const Attrs& **attrs**, const 
TypeReporter& **reporter**);
   2) We must parse attrs for checking they are valid or not;
   3) We must calculate output shape depend on parse results.
   Unfortunately, **attrs** are not integer, so we have to do such stupid 
things.
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to