[SOLVED] How to export model library to so file instead of tar for armv7 on x86 box

I’m compiling ResNet50 model for Raspberry Pi3 (armv7l) on x86 box and I’d like to export model library to “so” file instead of “tar” file.
If I just change file extension from “tar” to “so” then I got linker (/usr/bin/ld) error

path_lib = "model.so"
lib.export_library(path_lib)

Error:

# ./compile.py 
('model:', 'resnet50_v2', ', target:', llvm -device=arm_cpu -model=bcm2837 -target=armv7l-linux-gnueabihf -mattr=+neon, ', target_host:', None, ', opt_level:', 3, ', data_shape:', (1, 3, 224, 224))
Compiling...
No handlers could be found for logger "autotvm"
Compilation done
Saving files
Traceback (most recent call last):
  File "./compile.py", line 49, in <module>
    lib.export_library(path_lib)
  File "/root/tvm/python/tvm/module.py", line 121, in export_library
    fcompile(file_name, files, **kwargs)
  File "/root/tvm/python/tvm/contrib/cc.py", line 33, in create_shared
    _linux_shared(output, objects, options, cc)
  File "/root/tvm/python/tvm/contrib/cc.py", line 58, in _linux_shared
    raise RuntimeError(msg)
RuntimeError: Compilation error:
/usr/bin/ld: /tmp/tmpmj3yXZ/lib.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: /tmp/tmpmj3yXZ/lib.o: Relocations in generic ELF (EM: 40)
/tmp/tmpmj3yXZ/lib.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status

I do have /usr/arm-linux-gnueabi installed on x86 box. Is there a way to ask tvm compiler to use lib, include and bin from /usr/arm-linux-gnueabi to export model lib to “so” file?

1 Like

Having issue with linker - lib.o uses VFP register arguments, model.so does not

path_lib = "model.so"
lib.export_library(path_lib, tvm.contrib.cc.create_shared, cc="/usr/bin/arm-linux-gnueabi-g++")
$ ./compile.py 
('sys.getrecursionlimit()', 1031)
('model:', 'resnet50_v2', ', target:', llvm -device=arm_cpu -model=bcm2837 -target=armv7l-linux-gnueabihf -mattr=+neon, ', target_host:', None, ', opt_level:', 3, ', data_shape:', (1, 3, 224, 224))
Compiling...
No handlers could be found for logger "autotvm"
Compilation done
Saving files
Traceback (most recent call last):
  File "./compile.py", line 49, in <module>
    lib.export_library(path_lib, tvm.contrib.cc.create_shared, cc="/usr/bin/arm-linux-gnueabi-g++")
  File "/root/tvm/python/tvm/module.py", line 121, in export_library
    fcompile(file_name, files, **kwargs)
  File "/root/tvm/python/tvm/contrib/cc.py", line 33, in create_shared
    _linux_shared(output, objects, options, cc)
  File "/root/tvm/python/tvm/contrib/cc.py", line 58, in _linux_shared
    raise RuntimeError(msg)
RuntimeError: Compilation error:
/usr/lib/gcc-cross/arm-linux-gnueabi/5/../../../../arm-linux-gnueabi/bin/ld: error: /tmp/tmpxp7mqJ/lib.o uses VFP register arguments, model.so does not
/usr/lib/gcc-cross/arm-linux-gnueabi/5/../../../../arm-linux-gnueabi/bin/ld: failed to merge target specific data of file /tmp/tmpxp7mqJ/lib.o
collect2: error: ld returned 1 exit status


“Uses VFP register…” error message is directly caused from mixing mfloat-abi=soft and mfloat-abi=hard options within your build. This setting must be consistent for all objects that are to be linked.
Which flag should I use? soft or hard?
How to set the flag to CC and LD?

What float-abi and fpu should be used for Raspberry Pi ARMv7l?
I tried ["-mfloat-abi=hard","-mfpu=vfp"] - “so” file generation fails.

Sorry, I have no experience in doing this.

One of the easy thing you might be able to do, is to directly export a tar, and untar that and link on the board with gcc

Why we can not use cross compilation package g++-arm-linux-gnueabi on x86 box to generate “so” file for armv7l?

Yes, that is also a good alternative, but we have not tried this approach so there might be some glitch in linking.
Would be really nice if you can try to spend sometime to figure this out and document it :slight_smile:

I think you could. Maybe TVM_NDK_CC is you want to look for? We use it build for arm on x86, just .so not tar

1 Like

Found the solution!!!
export_library method should use “hf” HardFloat version of the cross-compiler and libs - arm-linux-gnueabihf-g++

Full code to compile and export model library for ARMv7 (Raspberry Pi 3B+) on x86 box

target = tvm.target.arm_cpu('rasp3b')
…
# Use hf HardFloat version of g++!!!
lib.export_library(“model.so”, cc="/usr/bin/arm-linux-gnueabihf-g++")

Nice, well done @apivovarov.

@apivovarov do you want to send a patch to tutorials to benefit other users?

Hi,

How is possible to achieve this in the current TVM state?, since the export_library call is now different.

Thanks

Try this

from tvm.contrib import cc
lib.export_library("model.so", cc.build_create_shared_func(compile_cmd="/usr/bin/arm-linux-gnueabihf-g++"))
2 Likes