terminated called after throuwing an instance of ‘dmlc::Error’
what(): 00:54:19 ../../src/runtime/graph/graph_runtime.cc::541: Check failed pf != nullptr no such function in module: fuse_pad
note:
no only fuse_pad is missing, all the operations in the JSON file are missing
Am I missing something when generating the library or loading the module?
terminated called after throuwing an instance of ‘dmlc::Error’
what(): 00:54:19 …/…/src/runtime/graph/graph_runtime.cc::541: Check failed pf != nullptr no such function in module: fuse_pad
I used “nm” and the fuse_pad is in the application, am I missing a build or function call step?
After you load dso module mod_syslib by the line above, you can get actual runtime module by
tvm::runtime::Module mod = (*tvm::runtime::Registry::Get("tvm.graph_runtime.create"))(json_data, mod_syslib, device_type, device_id);
And LoadFromFile can only load shared libs, because it uses dlopen (unix) or LoadLibrary (win). If you are trying to load static lib dynamically at runtime, you are doing it wrong.
In this question, I am not extracting shared library .so file, I build with extracted .o file, I do this in python with this line
lib_path = os.path.join(project_root, 'unet_deploy_arm.tar')
lib.export_library(lib_path,fcompile=False)
graph_json_path = os.path.join(project_root, 'unet.json')
with open(graph_json_path, 'w') as fo:
fo.write(graph.json())
param_path = os.path.join(project_root, 'unet.params')
with open(param_path, 'wb') as fo:
fo.write(nnvm.compiler.save_param_dict(params))
Then in a C++ application I do this:
tvm::runtime::Module mod_syslib = (*tvm::runtime::Registry::Get("module._GetSystemLib"))();
// json graph
std::ifstream json_in("unet.json", std::ios::in);
std::string json_data((std::istreambuf_iterator<char>(json_in)), std::istreambuf_iterator<char>());
json_in.close();
// parameters in binary
std::ifstream params_in("unet.params", std::ios::binary);
std::string params_data((std::istreambuf_iterator<char>(params_in)), std::istreambuf_iterator<char>());
params_in.close();
// parameters need to be TVMByteArray type to indicate the binary data
TVMByteArray params_arr;
params_arr.data = params_data.c_str();
params_arr.size = params_data.length();
int dtype_code = kDLFloat;
int dtype_bits = 32;
int dtype_lanes = 1;
int device_type = kDLCPU;
int device_id = 0;
// get global function module for graph runtime
tvm::runtime::Module mod = (*tvm::runtime::Registry::Get("tvm.graph_runtime.create"))(json_data, mod_syslib, device_type, device_id);
std::cout << "Graph created"<<std::endl;
I cross-compile the source code above, and link it with the lib.o in the .tar file.
I get the error by calling tvm.graph_runtime.create, I suppose, loading the module was not done correctly, any idea how to debug this?
I’ve generated a compiled.o with target llvm --system-lib,
linked it into the test app under apps/howto_deploy, and got a tvm module with *tvm::runtime::Registry::Get("module._GetSystemLib").
However I can only get the packedFuncs from the module on MacOS, where I have brew installed llvm 6.0.1 and clang. On Ubuntu (16.04, GCC 5.4.0, LLVM 6.0.1) I just got the same “empty pf” assert.
It seems that on MacOS, system_lib_module.cc:TVMBackendRegisterSystemLibSymbol() gets invoked multiple times to register the symbols in compiled.o, which is then used to populate tbl_. On Ubuntu the runtime doesn’t enter this function at all, and tbl_ remains empty.
I’m unable to find an entrypoint to TVMBackendRegisterSystemLibSymbol() that can explain this different behavior, Thoughts?