How to fix the difference of deformable conv2d op between relay api and pytorch api?

Hi everyone:

I had some problems in struggling with deformable op in tvm. Currently I find that the pytorch version’s deformable conv2d has different result with tvm’s relay api output result. Here are my script to compare them:

import argparse, os, sys
import logging
from tvm.relay.op.contrib.tensorrt import partition_for_tensorrt
import time
import numpy as np
from tvm.contrib import graph_executor as runtime
from tvm import relay
from tvm.relay import testing
import tvm.testing
import math
import tvm.topi.testing
from tvm import relay, te, auto_scheduler, autotvm
from tvm.relay.testing import run_infer_type


import torch
from torch import nn
from torchvision.ops import DeformConv2d

def compare(v1, v2):
    return np.max(np.abs(v1 - v2))

logging.basicConfig(level=logging.DEBUG)


data_shape = (1, 3, 160, 160)
dtype = "float32"
data = relay.var("data", relay.TensorType(data_shape, "float32"))
(batch, in_channel, H, W) = tuple(data_shape)
print(str(batch) + " " + str(in_channel) + " " + str(H) + " " + str(W)) 
kernel_size = (3, 3)
out_channel = 8
groups = 1
deformable_groups = 1
kernel_shape = (out_channel, in_channel // groups, kernel_size[0], kernel_size[1])
out_shape = (batch, out_channel, H, W)
offset_shape = (
    batch,
    2 * kernel_size[0] * kernel_size[1] * deformable_groups,
    out_shape[2],
    out_shape[3],
)
name = "deformanle_op"
weight = relay.var(name + "_weight", relay.TensorType(kernel_shape, "float32"))
offset = relay.var(name +"_offset", relay.TensorType(offset_shape, "float32"))
net = tvm.relay.nn.deformable_conv2d(data, offset, weight, 
        strides=(1, 1), padding=(1, 1),  deformable_groups=deformable_groups, 
        groups=groups, channels=out_channel, kernel_size=kernel_size, data_layout='NCHW', kernel_layout='OIHW'
        )

func = relay.Function(relay.analysis.free_vars(net), net)
# func = relay.Function([data, offset, weight], net)

data = np.random.uniform(size=data_shape).astype(dtype)
offset = np.random.uniform(size=offset_shape).astype(dtype)
kernel = np.random.uniform(size=kernel_shape).astype(dtype)


target = "cuda"
dev = tvm.device(target, 0)
intrp1 = relay.create_executor("graph", device=dev, target=target)

op_res1 = intrp1.evaluate(func)(data, offset, kernel)
# op_res1 = intrp1.evaluate(func)(data, kernel, offset)
op_res1 = op_res1.asnumpy()
print(op_res1.shape)
print(op_res1)




print("start testing deform op of pytorch ......")
device = torch.device("cuda:0")
deform_op_object = DeformConv2d(in_channels = in_channel, out_channels = out_channel, kernel_size = 3,
                              padding = 1, bias = False)
deform_op_object.to(device)

with torch.no_grad():
    deform_op_object.weight = torch.nn.Parameter(torch.from_numpy(kernel).to(device))

torch_data = torch.from_numpy(data)
torch_offset = torch.from_numpy(offset)
torch_data = torch_data.to(device)
torch_offset = torch_offset.to(device)

torch_op_output = deform_op_object(input = torch_data, offset = torch_offset)
op_numpy_torch = torch_op_output.cpu().detach().numpy()
print(op_numpy_torch.shape)

print("largest difference: ")
print(compare(op_numpy_torch, op_res1))




Is there something wrong with my codes? I am wondering how to fix it so that I can get same result of pytorch api and relay api? Someone has same issue? Thank you very much !!!