I am new to TVM. I tried a toy example, where I wrote a two layer LinearNet, compiled it using TVM, and run in C++. Below is my python script:
import tvm
from tvm import relay
import torch
class LinearNet(torch.nn.Module):
def __init__(self,dim_in, hidden_dim, dim_out):
super(LinearNet, self).__init__()
self.fc1 = torch.nn.Linear(dim_in, hidden_dim)
self.fc2 = torch.nn.Linear(hidden_dim, dim_out)
def forward(self, x):
x = self.fc1(x)
x = self.fc2(x)
return x
# Load your PyTorch model
model = LinearNet(1,1,1)
input_shape = [1,1] # Adjust with your actual input shape (as a list of integers)
# random input
x = torch.ones(input_shape)
y = model(x)
print(x)
print(y)
# Convert PyTorch model to a ScriptModule
scripted_model = torch.jit.script(model)
# Define input information as a list of tuples
# Each tuple contains the input name and its shape
input_info = [("input", input_shape)]
# Convert PyTorch ScriptModule to Relay IR
relay_model, params = relay.frontend.from_pytorch(scripted_model, input_info)
# Compile Relay IR
target = "llvm"
with tvm.transform.PassContext(opt_level=3):
lib = relay.build(relay_model, target, params=params)
# Save the compiled library
lib.export_library("compiled_model.so")
and the C++ file:
#include <tvm/runtime/module.h>
#include <tvm/runtime/packed_func.h>
#include <tvm/runtime/registry.h>
#include <dlpack/dlpack.h>
#include <tvm/runtime/container/shape_tuple.h>
#include <tvm/runtime/device_api.h>
#include <iostream>
int main() {
// Load the compiled TVM module
tvm::runtime::Module mod = tvm::runtime::Module::LoadFromFile("compiled_model.so");
// Obtain the global functions from the module
tvm::runtime::PackedFunc set_input = mod.GetFunction("set_input");
tvm::runtime::PackedFunc run = mod.GetFunction("run");
tvm::runtime::PackedFunc get_output = mod.GetFunction("get_output");
DLDevice dev = {static_cast<DLDeviceType>(kDLCPU), 0};
// Create an input tensor
tvm::runtime::NDArray x = tvm::runtime::NDArray::Empty({1, 1}, DLDataType{kDLFloat, 32, 1}, dev);
// Fill the input tensor with data
float* data = static_cast<float*>(x->data);
data[0] = 1.0;
// Set the input
std::cout << "1 Hello, World!" << std::endl;
set_input("input", x);
std::cout << "2 Hello, World!" << std::endl;
// Run the model
run();
// Get the output
tvm::runtime::NDArray y = get_output(0);
// Process the output as needed
float* output_data = static_cast<float*>(y->data);
// print output_data
for (int i = 0; i < 1; i++) {
std::cout << output_data[i] << std::endl;
}
return 0;
}
I successfully compiled the code and generated the executable uisng g++
. However, when I run the exectuable, I got the following information printed:
1 Hello, World!
[1] 44644 segmentation fault ./test
It seems to imply that the set_input
line fails. But the LinearNet model indeed takes in a tensor of shape (1,1). What am I missing?