How does the C++ API work (and is there a mistake in the example?)

cpp_deploy_pack works, but I get the error attached at the bottom for cpp_deploy_normal.

Also, I’m not sure I understand why the program needs both a system-lib, and a .so file. They both get produced from the same lib object in prepoare_test_lib.py, so why are they both needed?

g++ -std=c++11 -O2 -fPIC -I/home/asamara/tvm/include -I/home/asamara/tvm/3rdparty/dmlc-core/include -I/home/asamara/tvm/3rdparty/dlpack/include -o lib/cpp_deploy_normal -ltvm_runtime cpp_deploy.cc lib/test_addone_sys.o -L/home/asamara/tvm/build -lpthread -ldl
/tmp/cc5Tz5aW.o: In function Verify(tvm::runtime::Module, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)': cpp_deploy.cc:(.text+0x195): undefined reference to TVMArrayAlloc’ cpp_deploy.cc:(.text+0x1c6): undefined reference to TVMArrayAlloc' cpp_deploy.cc:(.text+0x2ee): undefined reference to tvm::runtime::ExtTypeVTable::Get(int)’ /tmp/cc5Tz5aW.o: In function tvm::runtime::TVMRetValue::Clear()': cpp_deploy.cc:(.text._ZN3tvm7runtime11TVMRetValue5ClearEv[_ZN3tvm7runtime11TVMRetValue5ClearEv]+0x73): undefined reference to tvm::runtime::ExtTypeVTable::Get(int)’ /tmp/cc5Tz5aW.o: In function main': cpp_deploy.cc:(.text.startup+0x5a): undefined reference to tvm::runtime::Module::LoadFromFile(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&)’ cpp_deploy.cc:(.text.startup+0x171): undefined reference to tvm::runtime::Registry::Get(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' lib/test_addone_sys.o: In function addonesys’: addonesys:(.text+0x12f): undefined reference to TVMAPISetLastError' lib/test_addone_sys.o: In function __tvm_module_startup’: addonesys:(.text+0x240): undefined reference to TVMBackendRegisterSystemLibSymbol' addonesys:(.text+0x254): undefined reference to TVMBackendRegisterSystemLibSymbol’ collect2: error: ld returned 1 exit status Makefile:33: recipe for target ‘lib/cpp_deploy_normal’ failed make: *** [lib/cpp_deploy_normal] Error 1

No, @KenArrari as per my understanding one of them will be needed at runtime. The .so file will be used by the application at runtime.

Yeah the .so file is loaded in in the C code. What I don’t understand is why they’re both needed.

I’m trying to figure that out because I wanted to compile this for RISCV. I tried doing it from inside of TVM by adding these lines to the prepare_test_libs.py script:

    target = 'llvm -target=riscv64-unknown-linux -mtriple=riscv64 -mcpu=generic-rv64 -mattr=+64bit,a,c,d,f,m'    
    target_sys = 'llvm --system-lib -mtriple=riscv64 -target=riscv64-unknown-linux -mcpu=generic-rv64 -mattr=+64bit,a,c,d,f,m'

But got some errors. So instead I just had it print the LLVM code and tried to manually produce the .so and .o files, which still doesn’t work and I’m trying to understand why.

Should using the g++ default compiler be fine?
I would suggest you do the following

cd /opt/android-ndk/build/tools/
./make-standalone-toolchain.sh --platform=android-24 --use-llvm --arch=arm64 --install-dir=/opt/android-toolchain-arm64
well that is a command for arm target, change it according to the requirement, generate a toolchain and use it, by setting the TVM_NDK_CC path to the generate toolchain. Use the same toolchain for building the application.

I tried this with a couple different permutations of replacing --arch=arm64 wth --arch=riscv64 (and also trying the 32 bit version) and it didn’t work.

I tried going into the make_standalone_toolchain.py script to add in the riscv options:


def get_triple(arch):
    """Return the triple for the given architecture."""
    return {
        'arm': 'arm-linux-androideabi',
        'arm64': 'aarch64-linux-android',
        'x86': 'i686-linux-android',
        'x86_64': 'x86_64-linux-android',
        'rv': 'riscv64'
    }[arch]

Also did not help.

But honestly all of this is a workaround for the llc issue. The target argument in the prepare_test_libs.py script is supposed to directly correspond to llc arguments but I get these errors when I try:

 # target = 'llvm -target=riscv64-unknown-linux -mtriple=riscv64 -mcpu=generic-rv64 -mattr=+64bit,a,c,d,f,m'    
    # target_sys = 'llvm --system-lib -mtriple=riscv64 -target=riscv64-unknown-linux -mcpu=generic-rv64 -mattr=+64bit,a,c,d,f,m'
'generic' is not a recognized processor for this target (ignoring processor)
'generic' is not a recognized processor for this target (ignoring processor)
'generic' is not a recognized processor for this target (ignoring processor)
'generic' is not a recognized processor for this target (ignoring processor)
'generic' is not a recognized processor for this target (ignoring processor)
'generic' is not a recognized processor for this target (ignoring processor)
[15:35:11] /home/asamara/tvm/src/codegen/llvm/codegen_llvm.cc:75: Set native vector bits to be 128 for riscv64
LLVM ERROR: Cannot select: 0x22c7228: ch = brcond 0x22a3438, 0x22c6e18, BasicBlock:ch<assert_end 0x22bc260>
  0x22c6e18: i64 = setcc 0x22c7430, Constant:i64<2>, seteq:ch
    0x22c7430: i64 = and 0x22c6fb8, Constant:i64<4294967295>
      0x22c6fb8: i64,ch = CopyFromReg 0x22a3438, Register:i64 %14
        0x22c6f50: i64 = Register %14
      0x22c73c8: i64 = Constant<4294967295>
    0x22c6db0: i64 = Constant<2>
In function: addone

If I could at least solve that initial one, which looks like an LLVM error, I guess I wouldn’t need this workaround.