I need to register some models to a global static registry for serving, but meet a segment fault error. Here is a minimal reproducible example:
#include <fstream>
#include <string>
#include <iostream>
#include <dlpack/dlpack.h>
#include <tvm/runtime/module.h>
#include <tvm/runtime/packed_func.h>
#include <tvm/runtime/registry.h>
tvm::runtime::Module load_model(const std::string &modelFolder,
const int deviceType, const int deviceID)
{
// load graph structure
std::ifstream graphStream(modelFolder + "/deploy_graph.json", std::ios::in);
std::string graph((std::istreambuf_iterator<char>(graphStream)),
std::istreambuf_iterator<char>());
graphStream.close();
// load module op library
tvm::runtime::Module lib =
tvm::runtime::Module::LoadFromFile(modelFolder + "/deploy_lib.so");
// create graph runtime
tvm::runtime::Module model =
(*tvm::runtime::Registry::Get("tvm.graph_runtime.create"))(
graph, lib, deviceType, deviceID);
// load parameters
std::ifstream paramsStream(modelFolder + "/deploy_param.params",
std::ios::binary);
std::string paramsData((std::istreambuf_iterator<char>(paramsStream)),
std::istreambuf_iterator<char>());
paramsStream.close();
// parameters need to be TVMByteArray type to indicate the binary data
TVMByteArray paramsArr;
paramsArr.data = paramsData.c_str();
paramsArr.size = paramsData.length();
// get the function from the module(load patameters)
tvm::runtime::PackedFunc load_params_func =
model.GetFunction("load_params");
load_params_func(paramsArr);
return model;
}
class A
{
public:
A(const std::string &modelFolder, const int deviceType, const int deviceID)
{
model_ = load_model(modelFolder, deviceType, deviceID);
}
private:
tvm::runtime::Module model_;
};
A *pA = nullptr;
int main(int argc, char **argv)
{
pA = new A(argv[1], (int)kDLCPU, 0);
return 0;
}
__attribute__((destructor)) void after_main()
{
if (nullptr != pA)
{
std::cout << "delete pA" << std::endl;
delete pA;
std::cout << "done" << std::endl;
}
}
I can release all models at the end of main() to work around this. But I am interested in the reason, because it is ok to do the same thing with libtorch and tensorflow.
Appreciate to any feedback.