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


#1

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 toTVMArrayAlloc’
cpp_deploy.cc:(.text+0x1c6): undefined reference to TVMArrayAlloc' cpp_deploy.cc:(.text+0x2ee): undefined reference totvm::runtime::ExtTypeVTable::Get(int)’
/tmp/cc5Tz5aW.o: In function tvm::runtime::TVMRetValue::Clear()': cpp_deploy.cc:(.text._ZN3tvm7runtime11TVMRetValue5ClearEv[_ZN3tvm7runtime11TVMRetValue5ClearEv]+0x73): undefined reference totvm::runtime::ExtTypeVTable::Get(int)’
/tmp/cc5Tz5aW.o: In function main': cpp_deploy.cc:(.text.startup+0x5a): undefined reference totvm::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 functionaddonesys’:
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 toTVMBackendRegisterSystemLibSymbol’
collect2: error: ld returned 1 exit status
Makefile:33: recipe for target ‘lib/cpp_deploy_normal’ failed
make: *** [lib/cpp_deploy_normal] Error 1


#2

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.


#3

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.


#4

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.


#5

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.