AutoTVM error "RuntimeError: Could not find any input nodes with whose operator is one of [Op(nn.conv2d)]"

I wrote a small partition network with only four layers of conv2d, and randomly set the input, save the model, and put it into autotvm for tuning. However, I encountered the following errors:

Traceback (most recent call last): File “/home/PycharmProjects/vm_project/tune_relay_x86.py”, line 247, in tune_and_evaluate(tuning_option) File “/home/PycharmProjects/vm_project/tune_relay_x86.py”, line 212, in tune_and_evaluate tune_graph(mod[“main”], data_shape, log_file, graph_opt_sch_file) File “/home/PycharmProjects/vm_project/tune_relay_x86.py”, line 192, in tune_graph executor = Tuner(graph, {input_name: dshape}, records, target_op, target) File “/home/software/tvm/python/tvm/autotvm/graph_tuner/dynamic_programming_tuner.py”, line 44, in init super(DPTuner, self).init(*args, **kwargs) File “/home/software/tvm/python/tvm/autotvm/graph_tuner/base_graph_tuner.py”, line 179, in init “operator is one of %s” % self._target_ops RuntimeError: Could not find any input nodes with whose operator is one of [Op(nn.conv2d)]

The network I used is as follows:

class IB(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(IB, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1)
        self.bn = nn.BatchNorm2d(out_channels)
        self.act = nn.ReLU(inplace=True)
    def forward(self, input):
        out = self.act(self.bn(self.conv(input)))
        return out

class OB(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(OB, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.act1 = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=1)
        self.softmax = nn.Softmax(dim=1)

    def forward(self, input):
        out = self.act1(self.bn1(self.conv1(input)))
        out = self.conv2(out)
        out = self.softmax(out)
        return out

class SegNet(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(SegNet, self).__init__()
        self.in_block = IB(in_channels, 4)
        self.conv = nn.Conv2d(4, 4, kernel_size=3, stride=1, padding=1)
        self.out_block = OB(4, out_channels)

    def forward(self, input):
        out16 = self.in_block(input)
        out16 = self.conv(out16)
        out = self.out_block(out16)
        return out

Could you help me explain why?@kevinthesun thanks!

It can’t find the input node. Was the input_shapes setup correctly?

When I trained the network, I did it as follows:    
        data = torch.randn(1, 3, 48, 48)
        optimizer.zero_grad()
        out = net.forward(data)
        l = loss(out, label[i])
        l.backward()
        optimizer.step()
        if i == 9:
             torch.save(net.state_dict(), os.path.join(chk_path, 'tony_state_params.pth'))
             torch.save(net, os.path.join(chk_path, 'tony_params.pth'))
When I use autotvm, I load the model in this way:
    def get_my_network():
        input_shape = (1, 3, 48, 48)
        output_shape = (1, 2, 48, 48)
        for_model = torch.load('/home/tony_state_params.pth')
        with torch.no_grad():
            net = SegNet(3, 2)
            net.load_state_dict(for_model)
        input_data = torch.randn(input_shape)
        scripted_model = torch.jit.trace(net, input_data).eval()
        img = np.random.uniform(-1, 1, size=input_shape).astype("float32")
        input_name = 'input0'
        shape_list = [(input_name, img.shape)]
        mod, params = relay.frontend.from_pytorch(scripted_model, shape_list)
        return mod, params, input_shape, output_shape

Is that right in this way? thanks!

Does the problem come from graph tuning?

yes,it comes from the graph tuning

Any related code snippets?

The error occurred in:tvm/autotvm/graph_tuner/base_graph_tuner.py:

Generate workload and schedule dictionaries.`

    if isinstance(graph, tvm.IRModule):
        graph = graph["main"]

    if isinstance(graph, relay.function.Function):
        node_dict = {}
        graph = bind_inputs(graph, input_shapes, dtype)
        expr2graph(graph, self._target_ops, node_dict, self._node_list)
    else:
        raise RuntimeError("Unsupported graph type: %s" % str(type(graph)))

    self._graph = graph
    self._in_nodes_dict = get_in_nodes(self._node_list, self._target_ops, input_shapes.keys())
    if len(self._in_nodes_dict) == 0:
        raise RuntimeError(
            "Could not find any input nodes with whose "
            "operator is one of %s" % self._target_ops
        )
    self._out_nodes_dict = get_out_nodes(self._in_nodes_dict)

and the relevant code is in:tvm/autotvm/graph_tuner/utils/traverse_graph.py

def get_in_nodes(node_list, target_ops, input_names):
    visited_dict = {}
    in_node_dict = {}
    for i, node in enumerate(node_list):
        if is_boundary_node(node, input_names) or is_skipped_node(node):
            continue
        get_direct_ancestor(node_list, visited_dict, target_ops, i, input_names)
    for key, val in visited_dict.items():
        node = node_list[key]
        is_multiple_inputs = has_multiple_inputs(node_list, key, input_names, OPT_OUT_OP)
        if node["op"] in target_ops or is_multiple_inputs:
            in_node_dict[key] = val

    # Reduce boundary nodes
    out_node_dict = get_out_nodes(in_node_dict)
    has_reduced_node = True
    while has_reduced_node:
        boundary_nodes = []
        for key, val in in_node_dict.items():
            node = node_list[key]
            is_boundary = True
            # Target ops can't be boundary nodes
            if node["op"] not in target_ops:
                for input_idx in val:
                    in_node = node_list[input_idx]
                    if not is_boundary_node(in_node, input_names) and input_idx in in_node_dict:
                        is_boundary = False
                    else:
                        val.remove(input_idx)
                    if is_boundary:
                        boundary_nodes.append(key)
        if boundary_nodes:
            for idx in boundary_nodes:
                if idx in in_node_dict:
                    del in_node_dict[idx]
        else:
            has_reduced_node = False

    # Remove empty nodes to ignore pre-computed sub-graph
    has_empty_node = True
    while has_empty_node:
        empty_nodes = []
        for key, val in in_node_dict.items():
            if not val:
                empty_nodes.append(key)
        if empty_nodes:
            has_empty_node = True
            for node in empty_nodes:
                del in_node_dict[node]
                if node in out_node_dict:
                    for out_node in out_node_dict[node]:
                        in_node_dict[out_node].remove(node)
        else:
            has_empty_node = False

    return in_node_dict

This error was resolved because I set the wrong input_name, so it didn’t find the input, thanks very much ! Maybe I’ll ask you some questions about tune_graph later. Thank you in advance!

When I use the above network structure and replace conv2d with conv3d, I train a python model and save the parameters correctly. I use from_ pytorch.py on the official website. The tutorial runs the model correctly, and I saved it lib.so \ graph.json \ param.params. Then I wrote a test code to load my saved .so, the program can run normally and get the result. But when I increase the number of network layers, I also use the above steps, but I report an error Process finished with exit code 139 (interrupted by signal 11: SIGSEGV). Do you have any suggest for this error?Thanks!

data_shape = (1, 1, 96, 96, 96)
path_lib = '/home/deplo.so'
target = 'llvm'
ctx = tvm.context(str(target), 0)
loaded_json = open("/home/deploy.json").read()
loaded_lib = tvm.runtime.load_module(path_lib)
loaded_params = bytearray(open("/home/deploy.params", "rb").read())
image = np.random.uniform(-1, 1, size=data_shape).astype("float32")
input_data = tvm.nd.array(image.astype("float32"))
module = graph_runtime.create(loaded_json, loaded_lib, ctx)
module.load_params(loaded_params)
module.set_input("input0", input_data)

The error occurred in this statement:

module.run(input0=input_data)