Error while running tflite model with vulkan backend on android

@masahi @csullivan @Lunderberg @tqchen @yzhliu Hi, I have a tflite model I’d like to run via TVM on Android using tvm_rpc with Vulkan Backend. My host tvm build is compiling with vulkan enabled but the target android runtime isn’t compiling with vulkan.

Using

mod, params = relay.frontend.from_tflite(
    tflite_model, shape_dict={input_tensor: input_shape}, dtype_dict={input_tensor: input_dtype}
)
test_target = "vulkan"
arch = "arm64"
target = tvm.target.Target("llvm -mtriple=arm64-linux-android")
target = tvm.target.Target(test_target, host=target)
with tvm.transform.PassContext(opt_level=3):
        lib = relay.build(mod, target=target, params=params)
fcompile = ndk.create_shared if run_on_device else None
lib.export_library(lib_fname, fcompile)

The relay is built but when running using:

import tvm
import numpy as np
from tvm import te
from tvm.contrib import graph_executor as runtime

# ctx = remote.cl(0)
#ctx = remote.cpu(0)
ctx = remote.vulkan(0)
print("ctx:", ctx)
# Transfer the model lib to remote device
remote.upload(lib_fname)
# Load the remote module
rlib = remote.load_module(lib_fname)

# Create a runtime executor module
module = runtime.GraphModule(rlib["default"](ctx))

# Run
module.run()

# Benchmark the performance

ftime = module.module.time_evaluator("run", ctx, number=1, repeat=10)
prof_res = np.array(ftime().results) * 1000
print("Mean inference time (std dev): %.2f ms (%.2f ms)" % (np.mean(prof_res), np.std(prof_res)))

I’m getting this error:

RPCError: Error caught from RPC call: [15:58:19] /home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/src/runtime/library_module.cc:122: Binary was created using {vulkan} but a loader of that name is not registered. Available loaders are const_loader, GraphExecutorFactory, static_library, relax.Executable, AotExecutorFactory, opencl, metadata_module, VMExecutable, metadata, GraphRuntimeFactory. Perhaps you need to recompile with this runtime enabled.

Below is the configuration for host and target build. Host Build:

mkdir -p build
cd build
cp ../cmake/config.cmake .

echo set\(USE_RPC ON\) >> config.cmake
echo set\(USE_GRAPH_EXECUTOR ON\) >> config.cmake
echo set\(USE_LIBBACKTRACE AUTO\) >> config.cmake
echo set\(USE_LLVM llvm-config-10\) >> config.cmake
echo set\(USE_VULKAN ON\) >> config.cmake

cmake ..
make 

Got these logs in output:

-- Vulkan_INCLUDE_DIRS=/usr/include/usr/include/spirv-tools/usr/include/spirv/unified1/usr/include/spirv/unified1
-- Vulkan_LIBRARY=/usr/lib/x86_64-linux-gnu/libvulkan.so
-- Vulkan_SPIRV_TOOLS_LIBRARY=/usr/lib/x86_64-linux-gnu/libSPIRV-Tools.a

So the host build is finding vulkan libraries and tools from root and is building with vulkan enabled.

Android Target Build:

Env Variables:

export TVM_ROOT=/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/
export TVM_HOME=/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/
export ANDROID_NDK_ROOT=/home/tvm-code/Android/Ndk/android-ndk-r25c/
export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT
export NDK_ROOT=$ANDROID_NDK_ROOT
export ANDROID_NDK=$ANDROID_NDK_ROOT
export PYTHONPATH=$TVM_ROOT/python:$PYTHONPATH
export TVM_NDK_CC=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang++
export Vulkan_LIBRARY=/home/tvm-code/Android/Ndk/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/28/libvulkan.so
mkdir -p build-test
cd build-test
cp ../cmake/config.cmake .

echo set\(USE_OPENCL ON\) >> config.cmake
echo set\(USE_LLVM llvm-config-10\) >> config.cmake
echo set\(USE_RPC ON\) >> config.cmake
echo set\(USE_CPP_RPC ON\) >> config.cmake
echo set\(USE_CPP_RTVM ON\) >> config.cmake
echo set\(USE_SORT ON\) >> config.cmake
echo set\(USE_VULKAN ON\) >> config.cmake
echo set\(USE_GRAPH_EXECUTOR ON\) >> config.cmake
echo set\(USE_LIBBACKTRACE AUTO\) >> config.cmake
echo set\(USE_KALLOC_ALIGNMENT 32\) >> config.cmake
echo set\(ANDROID_ABI arm64-v8a\) >> config.cmake
echo set\(ANDROID_PLATFORM android-28\) >> config.cmake
echo set\(MACHINE_NAME aarch64-linux-gnu\) >> config.cmake

cmake -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake" \
   -DANDROID_ABI=arm64-v8a \
   -DANDROID_PLATFORM=android-28 \
   -DUSE_VULKAN=ON \
   -DANDROID_NATIVE_API_LEVEL=23 ..

make tvm_runtime tvm_rpc rtvm

After this I tried

readelf -a libtvm_runtime.so | grep vulkan

and it outputs nothing.

Hi Abhinav,

As a functionality, I enabled Vulkan for Android a while back and it worked. Didn’t try recent times though.

Probably you may look into cmake console log (Vulkan related enables) and build log (to make sure Vulkan runtime files are compiled).

Siva

@srkreddy1238 As you can see from the below logs there aren’t any vulkan related enables in the build logs though its including given directories in shown in cmake log. It is setting these variables according to FindVulkan.cmake. Also tried building only tvm_runtime but got same output.

  if(CMAKE_SYSTEM_NAME STREQUAL "Android")
    set(VULKAN_NDK_SRC ${CMAKE_ANDROID_NDK}/sources/third_party/vulkan/src)
    set(Vulkan_INCLUDE_DIRS ${VULKAN_NDK_SRC}/include)
    set(Vulkan_FOUND TRUE)
    message(STATUS "Android Vulkan_INCLUDE_DIRS=" ${Vulkan_INCLUDE_DIRS})
    message(STATUS "Skip finding SPIRV in Android, make sure you only build tvm runtime.")
    return()
  endif()
-- Android Vulkan_INCLUDE_DIRS=/home/tvm-code/Android/Ndk/android-ndk-r25c/sources/third_party/vulkan/src/include
-- Skip finding SPIRV in Android, make sure you only build tvm runtime.

CMake logs:

-- The C compiler identification is Clang 14.0.7
-- The CXX compiler identification is Clang 14.0.7
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /home/tvm-code/Android/Ndk/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /home/tvm-code/Android/Ndk/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Forbidding undefined symbols in shared library, using -Wl,--no-undefined on platform Android
-- Building for Android
-- Build with RPC support...
-- Build with Graph Executor support...
-- Build with profiler...
-- Build with AOT Executor support...
-- Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
-- Build Alloc alignment set to 32
-- Didn't find the path to CCACHE, disabling ccache
-- Performing Test SUPPORT_CXX17
-- Performing Test SUPPORT_CXX17 - Success
-- VTA build with VTA_HW_PATH=/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/vta-hw
-- Build VTA runtime with target: sim
-- Enabled runtime search for OpenCL library location
-- Using gtest from Android NDK
-- Building OpenCL-Gtests
-- Android Vulkan_INCLUDE_DIRS=/home/tvm-code/Android/Ndk/android-ndk-r25c/sources/third_party/vulkan/src/include
-- Skip finding SPIRV in Android, make sure you only build tvm runtime.
-- Use llvm-config=llvm-config-10
-- LLVM libdir: /usr/lib/llvm-10/lib
-- LLVM cmakedir: /usr/lib/llvm-10/lib/cmake/llvm
-- Found LLVM_INCLUDE_DIRS=/usr/lib/llvm-10/include
-- Found LLVM_DEFINITIONS=-D_GNU_SOURCE;-D__STDC_CONSTANT_MACROS;-D__STDC_FORMAT_MACROS;-D__STDC_LIMIT_MACROS
-- Found LLVM_LIBS=/usr/lib/llvm-10/lib/libLLVM-10.so
-- Found TVM_LLVM_VERSION=100
-- Build with LLVM
-- Set TVM_LLVM_VERSION=100
-- Build with contrib.random
-- Build with contrib.sort
-- Build with contrib.hybriddump
-- Git found: /usr/bin/git
-- Found TVM_GIT_COMMIT_HASH=daa37e7e954f77006da4f2994bf544a1e9c62fce
-- Found TVM_GIT_COMMIT_TIME=2024-02-15 14:10:10 -0500
-- Could NOT find LIBBACKTRACE (missing: LIBBACKTRACE_STATIC_LIBRARY LIBBACKTRACE_INCLUDE_DIR)
-- Building with TVM Map...
-- Build with thread support...
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE
-- CLANG_VERSION 14.0
-- Setting enhanced clang warning flags
-- Performing Test FILE_PREFIX_MAP_SUPPORTED
-- Performing Test FILE_PREFIX_MAP_SUPPORTED - Success
-- Added "-fuse-ld=lld" to linker flags -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments
-- Build without FlashInfer
-- Configuring done (2.9s)
-- Generating done (0.2s)
-- Build files have been written to: /home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/build-test

Build logs:

[  0%] Building CXX object CMakeFiles/tvm_libinfo_objs.dir/src/support/libinfo.cc.o
[  0%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/builtin_fp16.cc.o
[  0%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/c_runtime_api.cc.o
[  0%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/const_loader_module.cc.o
[  0%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/container.cc.o
[  0%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/cpu_device_api.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/debug.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/disco/bcast_session.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/disco/builtin.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/disco/process_session.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/dso_library.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/disco/disco_worker.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/disco/loader.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/disco/session.cc.o
[ 12%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/disco/threaded_session.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/file_utils.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/library_module.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/logging.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/memory/memory_manager.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/metadata.cc.o
[ 25%] Built target tvm_libinfo_objs
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/minrpc/minrpc_logger.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/module.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/name_transforms.cc.o
[ 25%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/ndarray.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/nvtx.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/object.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/packed_func.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/profiling.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/registry.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/relax_vm/builtin.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/relax_vm/bytecode.cc.o
[ 37%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/relax_vm/executable.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/relax_vm/lm_support.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/relax_vm/ndarray_cache_support.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/relax_vm/paged_kv_cache.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/relax_vm/vm.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/source_utils.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/static_library.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/system_library.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/thread_pool.cc.o
[ 50%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/threading_backend.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/vm/bytecode.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/vm/executable.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/vm/vm.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/workspace_pool.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_channel.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_device_api.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_endpoint.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_event_impl.cc.o
[ 62%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_local_session.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_module.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_pipe_impl.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_server_env.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_session.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/rpc/rpc_socket_impl.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/graph_executor/graph_executor.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/graph_executor/graph_executor_factory.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/graph_executor/debug/graph_executor_debug.cc.o
[ 75%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/vm/profiler/vm.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/aot_executor/aot_executor.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/aot_executor/aot_executor_factory.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/opencl/opencl_device_api.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/opencl/opencl_module.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/opencl/opencl_module_spirv.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/opencl/texture_pool.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/opencl/opencl_wrapper/opencl_wrapper.cc.o
[ 87%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/contrib/random/random.cc.o
[100%] Building CXX object CMakeFiles/tvm_runtime_objs.dir/src/runtime/contrib/sort/sort.cc.o
[100%] Built target tvm_runtime_objs
[100%] Linking CXX shared library libtvm_runtime.so
[100%] Built target tvm_runtime
[  0%] Built target tvm_libinfo_objs
[100%] Built target tvm_runtime_objs
[100%] Built target tvm_runtime
[100%] Building CXX object apps/cpp_rpc/CMakeFiles/tvm_rpc.dir/main.cc.o
[100%] Building CXX object apps/cpp_rpc/CMakeFiles/tvm_rpc.dir/rpc_env.cc.o
[100%] Building CXX object apps/cpp_rpc/CMakeFiles/tvm_rpc.dir/rpc_server.cc.o
[100%] Linking CXX executable ../../tvm_rpc
[100%] Built target tvm_rpc
[  0%] Built target tvm_libinfo_objs
[100%] Built target tvm_runtime_objs
[100%] Built target tvm_runtime
[100%] Building CXX object apps/cpp_rtvm/CMakeFiles/rtvm.dir/main.cc.o
[100%] Building CXX object apps/cpp_rtvm/CMakeFiles/rtvm.dir/tvm_runner.cc.o
[100%] Building CXX object apps/cpp_rtvm/CMakeFiles/rtvm.dir/__/__/3rdparty/cnpy/cnpy.cpp.o
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:64:13: warning: unused variable 'major_version' [-Wunused-variable]
    uint8_t major_version = *reinterpret_cast<uint8_t*>(buffer+6);
            ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:93:10: warning: unused variable 'littleEndian' [-Wunused-variable]
    bool littleEndian = (header[loc1] == '<' || header[loc1] == '|' ? true : false);
         ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:65:13: warning: unused variable 'minor_version' [-Wunused-variable]
    uint8_t minor_version = *reinterpret_cast<uint8_t*>(buffer+7);
            ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:144:10: warning: unused variable 'littleEndian' [-Wunused-variable]
    bool littleEndian = (header[loc1] == '<' || header[loc1] == '|' ? true : false);
         ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:163:50: warning: variable 'comment_len' set but not used [-Wunused-but-set-variable]
    uint16_t disk_no, disk_start, nrecs_on_disk, comment_len;
                                                 ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:163:35: warning: variable 'nrecs_on_disk' set but not used [-Wunused-but-set-variable]
    uint16_t disk_no, disk_start, nrecs_on_disk, comment_len;
                                  ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:163:23: warning: variable 'disk_start' set but not used [-Wunused-but-set-variable]
    uint16_t disk_no, disk_start, nrecs_on_disk, comment_len;
                      ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:163:14: warning: variable 'disk_no' set but not used [-Wunused-but-set-variable]
    uint16_t disk_no, disk_start, nrecs_on_disk, comment_len;
             ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/3rdparty/cnpy/cnpy.cpp:199:9: warning: variable 'err' set but not used [-Wunused-but-set-variable]
    int err;
        ^
/home/tvm-code/abhinav/clones/open_src/vulkan_ostvm/tvm/apps/cpp_rtvm/main.cc:252:9: warning: unused variable 'total_time' [-Wunused-variable]
    int total_time = 0;
        ^
1 warning generated.
9 warnings generated.
[100%] Linking CXX executable ../../rtvm
[100%] Built target rtvm

Also I’ve read on the forum that https://github.com/apache/tvm/blob/main/src/runtime/vulkan/vulkan_device_api.cc this file should get included in the .so which isn’t there.