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 !!!