OpenCL target for 32-bit arm-linux-android broken after PR #4657

I have the script (at bottom of post) which I was using to compile a mobilenet model for an android target with a 32-bit ARM processor and a Mali gpu. Using a much older commit of TVM, I am able to compile the model using GPU (OpenCL) or CPU (llvm) targets. When I updated to a newer commit of TVM, the CPU target still works fine. However for OpenCL, I get this error during compilation :

RuntimeError: Compilation error:
Android (6317467 based on r365631c1) clang version 9.0.8 (https://android.googlesource.com/toolchain/llvm-project e0caee08e5f09b374a27a676d04978c81fcb1928) (based on LLVM 9.0.8svn)
Target: armv7a-unknown-linux-android27
Thread model: posix
InstalledDir: /data/standalone-ndk-r21b/bin
Found candidate GCC installation: /data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x
Selected GCC installation: /data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x
Candidate multilib: thumb;@mthumb
Candidate multilib: armv7-a;@march=armv7-a
Candidate multilib: armv7-a/thumb;@march=armv7-a@mthumb
Candidate multilib: .;
Selected multilib: armv7-a;@march=armv7-a
Found CUDA installation: /usr/local/cuda-10.0, version 10.0
 "/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld" --sysroot=/data/standalone-ndk-r21b/sysroot -z noexecstack -EL --warn-shared-textrel -z now -z relro -X --hash-style=gnu --enable-new-dtags --eh-frame-hdr -m armelf_linux_eabi -shared -o compiled.so /data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/27/crtbegin_so.o -L/data/standalone-ndk-r21b/lib64/clang/9.0.8/lib/linux/arm -L/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a -L/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/../lib/armv7-a -L/data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/27 -L/data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi -L/data/standalone-ndk-r21b/sysroot/usr/lib/../lib -L/data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/../../lib -L/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a -L/data/standalone-ndk-r21b/sysroot/usr/lib /tmp/tmp6x5vf9t2/lib0.o /tmp/tmp6x5vf9t2/devc.o -Bstatic -lc++ -Bdynamic -lm -lgcc -ldl -lc -lgcc -ldl /data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/27/crtend_so.o
/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: /tmp/tmp6x5vf9t2/devc.o uses VFP register arguments, output does not
clang90++: error: linker command failed with exit code 1 (use -v to see invocation)

I did a binary search on the TVM commits to find when this error was introduced, and I traced it down to the following PR. https://github.com/apache/incubator-tvm/pull/4657 Before this PR, my script worked fine. After this PR, I get the error above.

Question: Is there is a bug introduced by that PR? If not, how should my compilation script be updated? I have tried many, many combinations of compiler flags (-mfloat-abi=hard), usingndk.create_shared, etc and could not find a solution.

Also, this only happens with the OpenCL target. If I set the target to LLVM (same as target_host), compilation succeeds with and without #4657.

import tvm
from tvm import relay
import mxnet
from mxnet.gluon.model_zoo.vision import get_model
import gluoncv
import os

block = get_model('mobilenetv2_1.0', pretrained=True)
input_shape = (1, 3, 224, 224)
mod, params = relay.frontend.from_mxnet(block, shape={'data': input_shape}, dtype='float32')

# Compile
target = tvm.target.mali()
target_host = "llvm -target=arm-linux-android -mattr=+neon -mfloat-abi=soft"
with relay.build_config(opt_level=3):
    graph, lib, params = relay.build(mod, params=params, target=target, target_host=target_host)

# Save
with open('compiled.json', 'w') as f_graph_json:
    f_graph_json.write(graph)
with open('compiled.params', 'wb') as f_params:
    f_params.write(relay.save_param_dict(params))
cc = "/data/standalone-ndk-r21b/bin/armv7a-linux-androideabi27-clang++"
options = ["-v", "-static-libstdc++", "--sysroot", "/data/standalone-ndk-r21b/sysroot"]
lib.export_library('compiled.so', cc=cc, options=options)

Hi, I can not use -mfloat-abi=soft(AttributeError: Invalid config option, cannot recognize ‘mfloat-abi’. Candidates are:) in the newest version, and I also meet the error when I set the target to LLVM (same as target_host).

Even with https://github.com/apache/incubator-tvm/pull/6123 I still get the error. It seems like the arg isn’t getting passed to one of .o files.

Android (6317467 based on r365631c1) clang version 9.0.8 (https://android.googlesource.com/toolchain/llvm-project e0caee08e5f09b374a27a676d04978c81fcb1928) (based on LLVM 9.0.8svn)
Target: armv7a-unknown-linux-android27
Thread model: posix
InstalledDir: /data/standalone-ndk-r21b/bin
Found candidate GCC installation: /data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x
Selected GCC installation: /data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x
Candidate multilib: thumb;@mthumb
Candidate multilib: armv7-a;@march=armv7-a
Candidate multilib: armv7-a/thumb;@march=armv7-a@mthumb
Candidate multilib: .;
Selected multilib: armv7-a;@march=armv7-a
Found CUDA installation: /usr/local/cuda-10.0, version 10.0
 "/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld" --sysroot=/data/standalone-ndk-r21b/sysroot -z noexecstack -EL --warn-shared-textrel -z now -z relro -X --hash-style=gnu --enable-new-dtags --eh-frame-hdr -m armelf_linux_eabi -shared -o compiled.so /data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/27/crtbegin_so.o -L/data/standalone-ndk-r21b/lib64/clang/9.0.8/lib/linux/arm -L/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/armv7-a -L/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/../lib/armv7-a -L/data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/27 -L/data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi -L/data/standalone-ndk-r21b/sysroot/usr/lib/../lib -L/data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/../../lib -L/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/lib/armv7-a -L/data/standalone-ndk-r21b/sysroot/usr/lib /tmp/tmpofi5qtgn/lib0.o /tmp/tmpofi5qtgn/devc.o -lm -Bstatic -lc++ -Bdynamic -lm -lgcc -ldl -lc -lgcc -ldl /data/standalone-ndk-r21b/sysroot/usr/lib/arm-linux-androideabi/27/crtend_so.o
/data/standalone-ndk-r21b/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: /tmp/tmpofi5qtgn/devc.o uses VFP register arguments, output does not
clang90++: error: linker command failed with exit code 1 (use -v to see invocation)

I did some digging and I believe I found the source of this issue. I’m not sure what is the best way to fix it.

The target string reconstructed here is missing the “-mfloat-abi=soft” flag:

Interesting…Not sure if I understand correctly, is it because this line only produces mtriple, but we need an extra argument “-mfloat-abi=soft”?

Yes, that is correct.

Looks like we do have some snippets dealing with mfloat-abi in llvm codegen: https://github.com/apache/incubator-tvm/blob/67a7497ad304d128f2b0d32a16718f432e33044b/src/target/llvm/llvm_common.cc#L94. But it doesn’t work because it doesnt exist in target_str…I am not sure about the right fix either…

1 Like

I think that does work correctly, the problems I am experiencing only happens where there are imported modules and ModulePackImportsToLLVM is used (for example when using OpenCL as the target).

1 Like

hello,do you solve this problem,I have the same problem,need you help ,thanks,thanks.

I have replaced codegen_blob.cc and llvm_module.cc ,but it don’t work,only modify the two file?

@wwwxxxhhh could you post the stack trace of the error?

raise get_last_ffi_error()

AttributeError: Traceback (most recent call last): [bt] (5) /home/wuxiaohua/tvm/build/libtvm.so(TVMFuncCall+0x65) [0x7f771bd9b3e5] [bt] (4) /home/wuxiaohua/tvm/build/libtvm.so(+0x8fb24b) [0x7f771b7cc24b] [bt] (3) /home/wuxiaohua/tvm/build/libtvm.so(tvm::Target::Create(tvm::runtime::String const&)+0x388) [0x7f771b7cbdf8] [bt] (2) /home/wuxiaohua/tvm/build/libtvm.so(tvm::Target::CreateTarget(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&)+0x336) [0x7f771b7c96c6] [bt] (1) /home/wuxiaohua/tvm/build/libtvm.so(tvm::TargetIdNode::ParseAttrsFromRaw(std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&) const+0xe36) [0x7f771b7d1cd6] [bt] (0) /home/wuxiaohua/tvm/build/libtvm.so(+0x8fecd2) [0x7f771b7cfcd2] system-lib model mcpu device keys libs mattr mtriple File “/home/wuxiaohua/tvm/src/target/target_id.cc”, line 271 AttributeError: Invalid config option, cannot recognize ‘mfloat-abi’. Candidates are:

@wwwxxxhhh what is your git commit hash? and what is the target string you gave?

although I use the other device,but produce the same problem

target = tvm.target.arm_cpu()

target_host = “llvm -device=arm_cpu -mtriple=arm-linux-uclibceabi -mattr=+neon -mfloat-abi=soft”

with tvm.transform.PassContext(opt_level=3):

    graph, lib, params = relay.build_module.build(mod, target=target,target_host = target_host,params=params)

I believe the fix has been merged into the mainline via this pull request: https://github.com/apache/incubator-tvm/pull/6123

Could you compile with the latest mainline branch of TVM?

I compiled mainline branch of TVM last week。

Could you confirm if the following snippet works?

import tvm
target = tvm.target.create("llvm -device=arm_cpu -mtriple=arm-linux-uclibceabi -mattr=+neon -mfloat-abi=soft")
print(target)