mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-06-19 02:03:52 +00:00
[TVM EP] support build on Windows (#11851)
* add description of build ORT+TVM EP on Windows * fix cmake error related to symlink creation on Windows * add llvm config path to build flags for correct build on Windows * update TVM_EP.md for llvm_config build arg * fix warnings skipping during build on Windows * fix using string or wstring for model path to correct build on Windows (MSVC error) * fix error in custom logger for correct build on Windows * implement glob algorithm for Windows * additional build fixes * update TVM with export of VM symbols for dll * description of nasm issue and workaround * update TVM with export of Executable from VM symbols for dll * description of installation of ipp-crypto dependencies on Windows * cmake key for ipp-crypto build * fix wstring for TVMso EP * fix ipp-crypto build * cmake key onnxruntime_TVM_USE_HASH switch off not specific methods, but full hash functionality * fix absolute path to compiled lib * update TVM_EP.md, fix lint warnings * update TVM_EP.md * small fixes after review * switch on handshake functionality for Linux workflow Co-authored-by: Valery Chernov <valery.chernov@deelvin.com> Co-authored-by: KJlaccHoeUM9l <wotpricol@mail.ru>
This commit is contained in:
parent
75cf5dc2c9
commit
3b0aaa9e0e
14 changed files with 240 additions and 51 deletions
4
.github/workflows/linux.yml
vendored
4
.github/workflows/linux.yml
vendored
|
|
@ -19,10 +19,10 @@ jobs:
|
|||
architecture: 'x64'
|
||||
- name: 'Setup TVM EP requirements'
|
||||
run: |
|
||||
set -e -x
|
||||
set -e -x
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libtinfo-dev zlib1g-dev build-essential libedit-dev libxml2-dev nasm
|
||||
python3 -m pip install -r ${{ github.workspace }}/tools/ci_build/github/linux/tvm/requirements.txt
|
||||
- name: 'Build and Test'
|
||||
run: |
|
||||
python3 ${{ github.workspace }}/tools/ci_build/build.py --build_dir build --config Release --skip_submodule_sync --parallel --enable_pybind --disable_contrib_ops --disable_ml_ops --skip_onnx_tests --use_tvm --ctest_path ""
|
||||
python3 ${{ github.workspace }}/tools/ci_build/build.py --build_dir build --config Release --skip_submodule_sync --parallel --enable_pybind --disable_contrib_ops --disable_ml_ops --skip_onnx_tests --use_tvm --use_tvm_hash --ctest_path ""
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
"component": {
|
||||
"type": "git",
|
||||
"git": {
|
||||
"commitHash": "bc492acd7677dd7875b14f9ee46beef658955441",
|
||||
"commitHash": "3425ed846308a456f98404c79f6df1693bed6377",
|
||||
"repositoryUrl": "https://github.com/apache/tvm.git"
|
||||
},
|
||||
"comments": "needed for TVM EP"
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ option(onnxruntime_PREFER_SYSTEM_LIB "Experimental: Build with the preinstalled
|
|||
option(onnxruntime_USE_ROCM "Build with AMD GPU support" OFF)
|
||||
option(onnxruntime_USE_TVM "Build with TVM support" OFF)
|
||||
option(onnxruntime_TVM_CUDA_RUNTIME "Build TVM with CUDA support" OFF)
|
||||
option(onnxruntime_TVM_USE_LLVM "Build TVM with LLVM. Set customized path to llvm-config.exe here if need" OFF)
|
||||
option(onnxruntime_TVM_USE_HASH "Build ipp-crypto library for support has algorithm. It is defined for TVM only")
|
||||
option(onnxruntime_USE_XNNPACK "Build with XNNPACK support. Provides an alternative math library on ARM, WebAssembly and x86." OFF)
|
||||
|
||||
# Options related to reducing the binary size produced by the build
|
||||
|
|
@ -1437,11 +1439,9 @@ if (onnxruntime_USE_NUPHAR_TVM)
|
|||
add_definitions(-DUSE_NUPHAR_TVM_WITH_LLVM)
|
||||
endif()
|
||||
|
||||
message(STATUS "TVM BEFORE USE_LLVM=${USE_LLVM} USE_OPENMP=${USE_OPENMP} CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} USE_CUDA=${USE_CUDA} USE_GTEST=${USE_GTEST} CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
|
||||
message(STATUS "tvm_SOURCE_DIR=${tvm_SOURCE_DIR}")
|
||||
message(STATUS "tvm_BINARY_DIR=${tvm_BINARY_DIR}")
|
||||
add_subdirectory(${tvm_SOURCE_DIR} ${tvm_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
message(STATUS "TVM AFTER USE_LLVM=${USE_LLVM} USE_OPENMP=${USE_OPENMP} CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} USE_CUDA=${USE_CUDA} USE_GTEST=${USE_GTEST} CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
|
||||
|
||||
set_target_properties(tvm PROPERTIES FOLDER ${tvm_SOURCE_DIR})
|
||||
set_target_properties(tvm_topi PROPERTIES FOLDER ${tvm_SOURCE_DIR})
|
||||
|
|
@ -1491,18 +1491,24 @@ if (onnxruntime_USE_TVM)
|
|||
if (NOT TARGET tvm)
|
||||
message(STATUS "Include TVM(*).")
|
||||
include(tvm)
|
||||
message(STATUS "Include ipp-crypto(*).")
|
||||
include(ipp-crypto)
|
||||
if (onnxruntime_TVM_USE_HASH)
|
||||
message(STATUS "Include ipp-crypto(*).")
|
||||
include(ipp-crypto)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ipp-crypto
|
||||
set(ARCH intel64 CACHE STRING "Only defined for TVM")
|
||||
add_subdirectory(${ipp_crypto_SOURCE_DIR} ${ipp_crypto_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
set_target_properties(ippcp_s PROPERTIES FOLDER ${ipp_crypto_SOURCE_DIR})
|
||||
set(IPP_CRYPTO_INCLUDES ${ipp_crypto_INCLUDE_DIRS})
|
||||
if (onnxruntime_TVM_USE_HASH)
|
||||
set(ARCH intel64 CACHE STRING "Only defined for TVM")
|
||||
add_subdirectory(${ipp_crypto_SOURCE_DIR} ${ipp_crypto_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
set_target_properties(ippcp_s PROPERTIES FOLDER ${ipp_crypto_SOURCE_DIR})
|
||||
set(IPP_CRYPTO_INCLUDES ${ipp_crypto_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# TVM
|
||||
if (onnxruntime_USE_LLVM)
|
||||
if (onnxruntime_TVM_USE_LLVM)
|
||||
set(USE_LLVM "${onnxruntime_TVM_USE_LLVM}" CACHE STRING "Path to LLVM for correct TVM build")
|
||||
elseif(onnxruntime_USE_LLVM)
|
||||
set(USE_LLVM ON CACHE BOOL "Only defined for TVM")
|
||||
endif()
|
||||
|
||||
|
|
@ -1533,8 +1539,12 @@ if (onnxruntime_USE_TVM)
|
|||
set(FS_STDLIB stdc++fs)
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND onnxruntime_EXTERNAL_LIBRARIES tvm ippcp_s ${FS_STDLIB})
|
||||
list(APPEND onnxruntime_EXTERNAL_DEPENDENCIES tvm ippcp_s)
|
||||
list(APPEND onnxruntime_EXTERNAL_LIBRARIES tvm ${FS_STDLIB})
|
||||
list(APPEND onnxruntime_EXTERNAL_DEPENDENCIES tvm)
|
||||
if (onnxruntime_TVM_USE_HASH)
|
||||
list(APPEND onnxruntime_EXTERNAL_LIBRARIES ippcp_s)
|
||||
list(APPEND onnxruntime_EXTERNAL_DEPENDENCIES ippcp_s)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# XNNPACK EP
|
||||
|
|
|
|||
10
cmake/external/tvm.cmake
vendored
10
cmake/external/tvm.cmake
vendored
|
|
@ -4,13 +4,19 @@ if (onnxruntime_USE_TVM)
|
|||
FetchContent_Declare(
|
||||
tvm
|
||||
GIT_REPOSITORY https://github.com/apache/tvm.git
|
||||
GIT_TAG bc492acd7677dd7875b14f9ee46beef658955441
|
||||
GIT_TAG 3425ed846308a456f98404c79f6df1693bed6377
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(tvm)
|
||||
if(NOT tvm_POPULATED)
|
||||
FetchContent_Populate(tvm)
|
||||
file(CREATE_LINK ${tvm_BINARY_DIR} ${tvm_SOURCE_DIR}/build SYMBOLIC)
|
||||
if (WIN32)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${tvm_BINARY_DIR}/${CMAKE_BUILD_TYPE} ${tvm_SOURCE_DIR}/build
|
||||
)
|
||||
else()
|
||||
file(CREATE_LINK ${tvm_BINARY_DIR} ${tvm_SOURCE_DIR}/build SYMBOLIC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(tvm_INCLUDE_DIRS ${tvm_SOURCE_DIR}/include)
|
||||
|
|
|
|||
|
|
@ -1457,11 +1457,22 @@ endif()
|
|||
|
||||
if (onnxruntime_USE_TVM)
|
||||
add_definitions(-DUSE_TVM=1)
|
||||
if (onnxruntime_TVM_USE_HASH)
|
||||
add_definitions(-DUSE_TVM_HASH=1)
|
||||
endif()
|
||||
|
||||
file (GLOB_RECURSE onnxruntime_providers_tvm_cc_srcs CONFIGURE_DEPENDS
|
||||
"${ONNXRUNTIME_ROOT}/core/providers/tvm/*.h"
|
||||
"${ONNXRUNTIME_ROOT}/core/providers/tvm/*.cc"
|
||||
if (onnxruntime_TVM_USE_HASH)
|
||||
file (GLOB_RECURSE onnxruntime_providers_tvm_cc_srcs CONFIGURE_DEPENDS
|
||||
"${ONNXRUNTIME_ROOT}/core/providers/tvm/*.h"
|
||||
"${ONNXRUNTIME_ROOT}/core/providers/tvm/*.cc"
|
||||
)
|
||||
else()
|
||||
file (GLOB onnxruntime_providers_tvm_cc_srcs CONFIGURE_DEPENDS
|
||||
"${ONNXRUNTIME_ROOT}/core/providers/tvm/*.h"
|
||||
"${ONNXRUNTIME_ROOT}/core/providers/tvm/*.cc"
|
||||
)
|
||||
endif()
|
||||
|
||||
source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_tvm_cc_srcs})
|
||||
onnxruntime_add_static_library(onnxruntime_providers_tvm ${onnxruntime_providers_tvm_cc_srcs})
|
||||
|
||||
|
|
@ -1473,22 +1484,36 @@ if (onnxruntime_USE_TVM)
|
|||
${TVM_INCLUDES}
|
||||
${IPP_CRYPTO_INCLUDES}
|
||||
${PYTHON_INLCUDE_DIRS})
|
||||
onnxruntime_add_include_to_target(onnxruntime_providers_tvm onnxruntime_common onnx tvm ippcp_s)
|
||||
onnxruntime_add_include_to_target(onnxruntime_providers_tvm onnxruntime_common onnx tvm)
|
||||
if (onnxruntime_TVM_USE_HASH)
|
||||
onnxruntime_add_include_to_target(onnxruntime_providers_tvm ippcp_s)
|
||||
endif()
|
||||
|
||||
add_dependencies(onnxruntime_providers_tvm ${onnxruntime_EXTERNAL_DEPENDENCIES})
|
||||
|
||||
target_link_libraries(onnxruntime_providers_tvm PRIVATE
|
||||
onnx
|
||||
tvm
|
||||
ippcp_s
|
||||
onnxruntime_common
|
||||
onnxruntime_framework
|
||||
)
|
||||
if (onnxruntime_TVM_USE_HASH)
|
||||
target_link_libraries(onnxruntime_providers_tvm PRIVATE
|
||||
ippcp_s
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(onnxruntime_providers_tvm PROPERTIES FOLDER "ONNXRuntime")
|
||||
set_target_properties(onnxruntime_providers_tvm PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
target_compile_options(onnxruntime_providers_tvm PRIVATE -Wno-error=type-limits)
|
||||
if (WIN32 AND MSVC)
|
||||
# wd4100: identifier' : unreferenced formal parameter
|
||||
# wd4127: conditional expression is constant
|
||||
# wd4244: conversion from 'int' to 'char', possible loss of data
|
||||
target_compile_options(onnxruntime_providers_tvm PRIVATE "/wd4100" "/wd4127" "/wd4244")
|
||||
else()
|
||||
target_compile_options(onnxruntime_providers_tvm PRIVATE "-Wno-error=type-limits")
|
||||
endif()
|
||||
target_compile_definitions(onnxruntime_providers_tvm PUBLIC DMLC_USE_LOGGING_LIBRARY=<tvm/runtime/logging.h>)
|
||||
|
||||
install(DIRECTORY ${PROJECT_SOURCE_DIR}/../include/onnxruntime/core/providers/tvm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/onnxruntime/core/providers)
|
||||
|
|
|
|||
106
docs/TVM_EP.md
106
docs/TVM_EP.md
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
- [Introduction](#introduction)
|
||||
- [Build](#build-onnx-runtime-with-the-tvm-execution-provider)
|
||||
- [Linux](#linux)
|
||||
- [Windows](#windows)
|
||||
- [Configuration options](#configuration-options)
|
||||
- [Performance Tuning](#performance-tuning)
|
||||
- [Using precompiled model](#using-precompiled-model)
|
||||
|
|
@ -14,15 +16,17 @@
|
|||
## Introduction
|
||||
|
||||
TVM is an execution provider for ONNX Runtime that is built on top of Apache TVM. It enables ONNX Runtime users to leverage Apache TVM model optimizations.
|
||||
TVM EP is currently in "Preview". It's been tested to work on a handful of models on Linux, but not on Windows or MacOS.
|
||||
TVM EP is currently in "Preview". It's been tested to work on a handful of models on Linux or Windows, but not on MacOS.
|
||||
|
||||
## Build ONNX Runtime with the TVM Execution Provider
|
||||
|
||||
### **Linux**
|
||||
Install the minimal pre-requisites on Ubuntu/Debian like linux operating systems:
|
||||
```bash
|
||||
apt-get install -y python3 python3-dev python3-pip python3-setuptools gcc libtinfo-dev zlib1g-dev build-essential cmake libedit-dev libxml2-dev llvm-12
|
||||
pip3 install numpy decorator attrs
|
||||
pip3 install numpy decorator attrs nasm
|
||||
```
|
||||
Note: since ONNX Runtime with TVM EP is built with Intel ipp-crypto library there are new requirements. Compiler gcc (and g++) version should be equal to or higher than 8.2. nasm version should be 2.14.02 or higher. Problem with small nasm version can be seen [here](https://github.com/intel/ipp-crypto/issues/9) or [here](https://bugzilla.nasm.us/show_bug.cgi?id=3392205). For ubuntu LTS 18 `apt-get install nasm` is not enough due to it has version 2.13.02, see how to install from sources instruction [here](https://stackoverflow.com/questions/36144930/steps-to-install-nasm-offline-on-ubuntu).
|
||||
|
||||
Also, the current implementation has `NVidia GPU` support for TVM EP. For now, you can use only `NVidia GPU` with CUDA Toolkit support.
|
||||
To do this, make sure you have installed the NVidia driver and CUDA Toolkit.
|
||||
|
|
@ -81,6 +85,92 @@ export PYTHONPATH=<path_to_onnx_runtime>/build/<OS_NAME>/Release:${PYTHONPATH}
|
|||
export PYTHONPATH=<path_to_onnx_runtime>/build/<OS_NAME>/Release/_deps/tvm-src/python:${PYTHONPATH}
|
||||
```
|
||||
|
||||
### **Windows**
|
||||
Install the minimal prerequisites on Windows: Git, CMake, Visual Studio, Python, LLVM
|
||||
- Git: Download Git for Windows from [here](https://git-scm.com/download/win) and install it. Please make sure that the git.exe path is included in the environment variable. By default, it should be added. To check git after the installation use `git --version` in command line (cmd).
|
||||
- CMake: use [the link](https://cmake.org/download/) to download and install CMake. msi-file is recommended for it. To verify CMake installation use `cmake --version` in cmd.
|
||||
- Visual Studio: Download from [here](https://visualstudio.microsoft.com/ru/downloads/) and install Visual Studio 20** Community & Visual Studio Build Tools respectively. It is recommended not to change the default installation path. Chose "Desktop development with C++" workload and make sure that both options of “MSVC [contemporary version] C++ build tools” and “Windows 10 SDK” are selected.
|
||||
- Python: Download Python 3.* from [here](https://www.python.org/downloads/windows/) and install it. Please have a check on the option of “Add Python to PATH”, so the installer will include the Python directory into the environment variable directly. To check python after the installation use `python` from cmd. The expected output is similar to the following:
|
||||
```cmd
|
||||
Python 3.10.5 (tags/v3.10.5:f377153, Jun 6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>>
|
||||
```
|
||||
Use `quit()` to exit from python interface.
|
||||
- LLVM: the compiler is not necessary for pure ONNX Runtime installation but it is needed for TVM EP by default.
|
||||
```cmd
|
||||
git clone --depth 1 --branch release/11.x https://github.com/llvm/llvm-project.git
|
||||
cmake -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi" -DLLVM_TARGETS_TO_BUILD=X86 -Thost=x64 -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022"
|
||||
cmake --build ./build --config Release
|
||||
```
|
||||
- Dependencies of ipp-crypto:<br>
|
||||
1. install asm compiler (nasm) on windows by line:
|
||||
```cmd
|
||||
winget install nasm -i
|
||||
```
|
||||
|
||||
Add it to PATH (instruction for Windows GUI can be seen [here](https://www.computerhope.com/issues/ch000549.htm#dospath)) or by cmd:
|
||||
```
|
||||
set PATH="%PATH%;C:\Program Files\NASM"
|
||||
```
|
||||
|
||||
Check by `nasm --version` in prompt command line.<br>
|
||||
|
||||
2. install openssl on windows by msi-file from [here](https://slproweb.com/products/Win32OpenSSL.html)
|
||||
Add path to directory (e.g. "C:\Program Files\OpenSSL-Win64\bin") with executable file to PATH (see instructions above).<br>
|
||||
|
||||
Check by `openssl version` in prompt command line.
|
||||
<br>
|
||||
<br>
|
||||
|
||||
For using NVIDIA GPU (optional) CUDA and cuDNN should be installed.
|
||||
- CUDA: Install CUDA by the [link](https://developer.nvidia.com/cuda-11.0-download-archive).
|
||||
- cuDNN: download cuDNN installer from [here](https://developer.nvidia.com/rdp/cudnn-archive). Choose v8.* for corresponding CUDA v11.*, unzip it, and move cuDNN files as following:
|
||||
1. [unzipped dir]\bin\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin
|
||||
2. [unzipped dir]\include\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\include
|
||||
3. [unzipped dir]\lib\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\lib
|
||||
|
||||
To verify the CUDA installation use `nvcc --version` in cmd.
|
||||
<br>
|
||||
<br>
|
||||
|
||||
Build ONNX Runtime with TVM Execution Provider from source:
|
||||
- Use command line and clone sources from github:
|
||||
```cmd
|
||||
git clone --recursive https://github.com/Microsoft/onnxruntime
|
||||
cd onnxruntime
|
||||
```
|
||||
- CPU build:
|
||||
```
|
||||
build.bat --config Release --enable_pybind --build_wheel --skip_tests --parallel --use_tvm --skip_onnx_tests --cmake_generator "Visual Studio 17 2022" --llvm_config <path_to_llvm_root>/build/Release/bin/llvm-config.exe
|
||||
```
|
||||
- GPU build:
|
||||
```
|
||||
build.bat --config Release --enable_pybind --build_wheel --skip_tests --parallel --use_tvm --skip_onnx_tests --cmake_generator "Visual Studio 17 2022" --llvm_config <path_to_llvm_root>/build/Release/bin/llvm-config.exe --use_cuda --cudnn_home “C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.*” --cuda_home “C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.*”
|
||||
```
|
||||
In both cases (CPU, GPU) there are the following options for cmake generator: "Visual Studio 15 2017", "Visual Studio 16 2019", "Visual Studio 17 2022" and "Ninja"
|
||||
- Install python wheel package for ONNX Runtime:<br>
|
||||
Default path to the package is `<path_to_onnxruntime_root>/build/Windows/Release/Release/dist`. Note that it is different in comparison with path to the package on Linux. Before installation check names of wheel packages and use corresponding one. It can be looked like the following:
|
||||
```cmd
|
||||
python -m pip install .\onnxruntime\build\Windows\Release\Release\dist\onnxruntime_tvm-1.6.0-cp37-cp37m-win_amd64.whl
|
||||
```
|
||||
- Install python wheel package for TVM due to its python API is used inside TVM EP:<br>
|
||||
It can be looked like the following:
|
||||
```cmd
|
||||
python -m pip install .\onnxruntime\build\Windows\Release\_deps\tvm-src\python\dist\tvm-0.9.dev1728+g3425ed846-cp39-cp39-win_amd64.whl
|
||||
```
|
||||
- Verify result by python script. Note: python should not be launched from directory containing 'onnxruntime' directory for correct result:
|
||||
```python
|
||||
import onnxruntime
|
||||
print(onnxruntime.__version__)
|
||||
print(onnxruntime.get_device())
|
||||
print(onnxruntime.get_available_providers())
|
||||
```
|
||||
- Uninstall procedure:
|
||||
```cmd
|
||||
pip uninstall onnxruntime-tvm
|
||||
```
|
||||
|
||||
## Configuration options
|
||||
TVM Executor Provider can be configured with the following provider options:
|
||||
```python
|
||||
|
|
@ -102,7 +192,7 @@ tvm_session = onnxruntime.InferenceSession(model_path, providers=["TvmExecutionP
|
|||
<br>
|
||||
|
||||
- `executor` is executor type used by TVM. There is choice between two types: GraphExecutor and VirtualMachine which are corresponded to "graph" and "vm" tags. VirtualMachine is used by default.
|
||||
- `so_folder` is path to folder with set of files (.ro-, .so-files and weights) obtained after model tuning. It uses these files for executor compilation instead of onnx-model. But the latter is still needed for ONNX Runtime.
|
||||
- `so_folder` is path to folder with set of files (.ro-, .so/.dll-files and weights) obtained after model tuning. It uses these files for executor compilation instead of onnx-model. But the latter is still needed for ONNX Runtime.
|
||||
- `check_hash` means that it is necessary to perform a HASH check for the model obtained in the `so_folder` parameter. It is `False` by default.
|
||||
- `hash_file_path` is path to file that contains the pre-computed HASH for the ONNX model which result of tuning locates in the path passed by `so_folder` parameter.
|
||||
If an empty string was passed as this value, then the file will be searched in the folder that was passed in the `so_folder` parameter.
|
||||
|
|
@ -138,18 +228,18 @@ so.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_DISABLE_ALL
|
|||
tvm_session = onnxruntime.InferenceSession(model_path, sess_options=so, providers=["TvmExecutionProvider"], provider_options=po)
|
||||
```
|
||||
|
||||
### Using precompiled model
|
||||
### **Using precompiled model**
|
||||
It is also possible to use a precompiled model.
|
||||
|
||||
The compiled model can be obtained using the [OctoML platform](https://onnx.octoml.ai)
|
||||
The compiled model can be obtained using the [OctoML platform](https://onnx.octoml.ai)
|
||||
or compiled directly (see **Support precompiled model** section in
|
||||
[Sample notebook for ResNet50 inference with TVM EP](https://github.com/microsoft/onnxruntime/blob/master/docs/python/inference/notebooks/onnxruntime-tvm-tutorial.ipynb)
|
||||
for more information on model compilation).
|
||||
|
||||
In order to use the precompiled model, only need to pass two options:
|
||||
* **executor** - `vm` (`VirtualMachine`) must be used as a value
|
||||
* **executor** - `vm` (`VirtualMachine`) must be used as a value
|
||||
(this functionality is not supported for `GraphExecutor`);
|
||||
* **so_folder** - as a value, you must pass the path to the directory where
|
||||
* **so_folder** - as a value, you must pass the path to the directory where
|
||||
the files of the precompiled model are located.
|
||||
* **check_hash** - (optional) if you want to check hash, you must pass `True` as the value.
|
||||
* **hash_file_path** - (optional) by default, the file containing the hash for the tuned model will be searched in the directory that is passed in the `so_folder` parameter.
|
||||
|
|
@ -162,7 +252,7 @@ You can read more about these options in section [Configuration options](#config
|
|||
- [Sample notebook for ResNet50 inference with TVM EP](https://github.com/microsoft/onnxruntime/blob/master/docs/python/inference/notebooks/onnxruntime-tvm-tutorial.ipynb)
|
||||
|
||||
## Known issues
|
||||
- At this moment, the TVM EP has only been verified on UNIX/Linux systems.
|
||||
- At this moment, the TVM EP has only been verified on UNIX/Linux and Windows systems.
|
||||
- Some compatibility issues have been found between ONNX and Google protobuf. `AttributeError: module 'google.protobuf.internal.containers' has no attribute 'MutableMapping'`. This usually occurss during `import onnx` in any python scripts for protobuf version >= 3.19.0 and ONNX version <= 1.8.1. To resolve the issue Google protobuf and ONNX can be reinstalled separately or together using:
|
||||
```
|
||||
pip3 uninstall onnx -y
|
||||
|
|
|
|||
|
|
@ -13,12 +13,6 @@ namespace {
|
|||
constexpr auto k_dot = ORT_TSTR(".");
|
||||
constexpr auto k_dotdot = ORT_TSTR("..");
|
||||
|
||||
#ifdef _WIN32
|
||||
constexpr PathChar k_preferred_path_separator = ORT_TSTR('\\');
|
||||
#else // POSIX
|
||||
constexpr PathChar k_preferred_path_separator = ORT_TSTR('/');
|
||||
#endif
|
||||
|
||||
constexpr std::array<PathChar, 2> k_valid_path_separators{
|
||||
ORT_TSTR('/'), ORT_TSTR('\\')};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@
|
|||
|
||||
namespace onnxruntime {
|
||||
|
||||
#ifdef _WIN32
|
||||
constexpr PathChar k_preferred_path_separator = ORT_TSTR('\\');
|
||||
#else // POSIX
|
||||
constexpr PathChar k_preferred_path_separator = ORT_TSTR('/');
|
||||
#endif
|
||||
|
||||
// Note: We should use the std::filesystem library after upgrading to C++17.
|
||||
|
||||
/** A filesystem path. */
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -22,7 +23,16 @@ std::string GetTimedLogMessage(const std::string& file, int lineno, const std::s
|
|||
std::stringstream sstream;
|
||||
std::string file_name = GetFileName(file);
|
||||
std::time_t t = std::time(nullptr);
|
||||
sstream << "[" << std::put_time(std::localtime(&t), "%H:%M:%S") << "][TVM] "
|
||||
sstream << "["
|
||||
#ifdef _WIN32
|
||||
// TODO(vvchernov): use #include <time.h> instead of <ctime> and localtime_s() approach for WIN32
|
||||
#pragma warning(disable : 4996) // _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
<< std::put_time(std::localtime(&t), "%H:%M:%S")
|
||||
#ifdef _WIN32
|
||||
#pragma warning(default : 4996)
|
||||
#endif
|
||||
<< "][TVM] "
|
||||
<< file_name << ":" << lineno << ": " + message;
|
||||
return sstream.str();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <glob.h> // glob(), globfree()
|
||||
#endif
|
||||
#include <string.h> // memset()
|
||||
#include <unordered_map>
|
||||
#include <fstream>
|
||||
|
|
@ -12,6 +16,7 @@
|
|||
#include <tvm/target/codegen.h>
|
||||
|
||||
#include "core/common/common.h"
|
||||
#include "core/common/path.h"
|
||||
|
||||
#include "tvm_api.h"
|
||||
|
||||
|
|
@ -59,30 +64,45 @@ TvmModule TVMCompile(const TvmEPOptions& options,
|
|||
return mod;
|
||||
}
|
||||
|
||||
std::vector<std::string> glob(const std::string& pattern) {
|
||||
std::vector<std::string> glob(const std::string& dir, const std::string& extension) {
|
||||
std::vector<std::string> filenames;
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string pattern = dir + "/*." + extension;
|
||||
WIN32_FIND_DATA fd;
|
||||
HANDLE hFind = ::FindFirstFile(pattern.c_str(), &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if ( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
|
||||
filenames.push_back(
|
||||
dir +
|
||||
ToUTF8String(PathString{k_preferred_path_separator}) +
|
||||
fd.cFileName);
|
||||
}
|
||||
} while (::FindNextFile(hFind, &fd));
|
||||
::FindClose(hFind);
|
||||
}
|
||||
#else
|
||||
glob_t glob_result;
|
||||
memset(&glob_result, 0, sizeof(glob_result));
|
||||
|
||||
std::string pattern = dir + "/*." + extension;
|
||||
int return_value = glob(pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
|
||||
ORT_ENFORCE(return_value == 0, "No results of glob for pattern: " + pattern);
|
||||
|
||||
for (size_t i = 0; i < glob_result.gl_pathc; ++i) {
|
||||
filenames.push_back(std::string(glob_result.gl_pathv[i]));
|
||||
}
|
||||
|
||||
globfree(&glob_result);
|
||||
|
||||
#endif
|
||||
return filenames;
|
||||
}
|
||||
|
||||
std::string filter_lib_paths(const std::vector<std::string>& lib_paths) {
|
||||
std::string filter_lib_paths(const std::vector<std::string>& lib_paths, const std::string& lib_ext) {
|
||||
std::string lib_path;
|
||||
size_t counter = 0;
|
||||
for (const auto& path : lib_paths) {
|
||||
if (path.find("libtvm_runtime.so") != std::string::npos ||
|
||||
path.find("liboctomized_model.so") != std::string::npos) {
|
||||
if (path.find("libtvm_runtime." + lib_ext) != std::string::npos ||
|
||||
path.find("liboctomized_model." + lib_ext) != std::string::npos) {
|
||||
++counter;
|
||||
} else {
|
||||
lib_path = path;
|
||||
|
|
@ -117,10 +137,17 @@ static std::unordered_map<std::string, uint64_t> str2dev_type = {
|
|||
};
|
||||
|
||||
TvmModule TVMSoCompile(const TvmEPOptions& options) {
|
||||
const std::string dir = options.so_folder;
|
||||
const std::string lib_path = filter_lib_paths(glob(dir + "/*.so"));
|
||||
const std::string consts_path = dir + "/consts";
|
||||
const auto& ro_paths = glob(dir + "/*.ro");
|
||||
const std::string& dir = options.so_folder;
|
||||
#ifdef _WIN32
|
||||
std::string lib_ext = "dll";
|
||||
#else
|
||||
std::string lib_ext = "so";
|
||||
#endif
|
||||
const std::string lib_path = filter_lib_paths(glob(dir, lib_ext), lib_ext);
|
||||
const std::string consts_path = dir +
|
||||
ToUTF8String(PathString{k_preferred_path_separator}) +
|
||||
"consts";
|
||||
const auto& ro_paths = glob(dir, "ro");
|
||||
ORT_ENFORCE(ro_paths.size() == 1, "It should be only one ro file in folder: " + dir);
|
||||
const std::string vm_exec_code_path = ro_paths[0];
|
||||
|
||||
|
|
@ -205,7 +232,7 @@ void TVM_VM_SetInputs(TvmModule& mod,
|
|||
|
||||
TvmPackedFunc set_input = mod.GetFunction("set_input", false);
|
||||
::tvm::runtime::TVMRetValue rv;
|
||||
set_input.CallPacked(::tvm::runtime::TVMArgs(tvm_values.data(), tvm_type_codes.data(), num_total_args), &rv);
|
||||
set_input.CallPacked(::tvm::runtime::TVMArgs(tvm_values.data(), tvm_type_codes.data(), int(num_total_args)), &rv);
|
||||
}
|
||||
|
||||
void TVMGetOutputs(TvmModule& mod,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "core/common/common.h"
|
||||
#include "core/framework/execution_provider.h"
|
||||
#include "core/framework/tensorprotoutils.h"
|
||||
#include "core/framework/kernel_registry.h"
|
||||
|
|
@ -123,7 +124,7 @@ common::Status TvmExecutionProvider::Compile(const std::vector<FusedNodeAndGraph
|
|||
std::string onnx_model_str;
|
||||
model_proto.SerializeToString(&onnx_model_str);
|
||||
compilers_[func_name] = std::make_shared<TVMCompiler>(std::move(onnx_model_str),
|
||||
fused_node.ModelPath().ToPathString(),
|
||||
ToUTF8String(fused_node.ModelPath().ToPathString()),
|
||||
int(opset->version()));
|
||||
InputsInfoMap all_input_shapes;
|
||||
auto mod = compileModel(func_name, graph_body_viewer, all_input_shapes);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
#include "tvm_allocator.h" // NOLINT(build/include_subdir)
|
||||
#include "tvm_utils.h" // NOLINT(build/include_subdir)
|
||||
#include "tvm_api.h" // NOLINT(build/include_subdir)
|
||||
#ifdef USE_TVM_HASH
|
||||
#include "hash_alg/hasher.h" // NOLINT(build/include_subdir)
|
||||
#endif
|
||||
|
||||
using ONNX_NAMESPACE::TensorShapeProto;
|
||||
|
||||
|
|
@ -107,10 +109,12 @@ common::Status TvmSoExecutionProvider::Compile(const std::vector<FusedNodeAndGra
|
|||
for (auto& fused_node_graph : fused_nodes_and_graphs) {
|
||||
const GraphViewer& graph_body_viewer = fused_node_graph.filtered_graph;
|
||||
const Node& fused_node = fused_node_graph.fused_node;
|
||||
#ifdef USE_TVM_HASH
|
||||
if (options_.check_hash) {
|
||||
ORT_ENFORCE(checkHash(fused_node.ModelPath().ToPathString()),
|
||||
ORT_ENFORCE(checkHash(ToUTF8String(fused_node.ModelPath().ToPathString())),
|
||||
"Hash check shows that used tuning files were not obtained for the given onnx-model");
|
||||
}
|
||||
#endif
|
||||
const std::string func_name = fused_node.Name();
|
||||
|
||||
compilers_[func_name] = std::make_shared<TVMSoCompiler>();
|
||||
|
|
@ -150,6 +154,7 @@ void TvmSoExecutionProvider::printOptions() {
|
|||
LOGS(*GetLogger(), INFO) << options_;
|
||||
}
|
||||
|
||||
#ifdef USE_TVM_HASH
|
||||
bool TvmSoExecutionProvider::checkHash(const std::string& onnx_path) const {
|
||||
auto hasher = Hasher("sha256");
|
||||
std::string onnx_str = readFromFile(onnx_path);
|
||||
|
|
@ -164,6 +169,7 @@ bool TvmSoExecutionProvider::checkHash(const std::string& onnx_path) const {
|
|||
}
|
||||
return onnx_hash == hash;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::shared_ptr<TvmModule> TvmSoExecutionProvider::compileModel(const std::string& func_name,
|
||||
const GraphViewer& graph_viewer,
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ class TvmSoExecutionProvider : public IExecutionProvider {
|
|||
|
||||
private:
|
||||
void printOptions();
|
||||
#ifdef USE_TVM_HASH
|
||||
bool checkHash(const std::string& onnx_path) const;
|
||||
#endif
|
||||
std::shared_ptr<TvmModule> compileModel(const std::string& func_name,
|
||||
const GraphViewer& graph_viewer,
|
||||
InputsInfoMap& inputs_info); // NOLINT
|
||||
|
|
|
|||
|
|
@ -476,6 +476,9 @@ def parse_arguments():
|
|||
parser.add_argument("--use_nuphar", action="store_true", help="Build with nuphar")
|
||||
parser.add_argument("--use_tvm", action="store_true", help="Build with TVM")
|
||||
parser.add_argument("--tvm_cuda_runtime", action="store_true", default=False, help="Build TVM with CUDA support")
|
||||
parser.add_argument(
|
||||
"--use_tvm_hash", action="store_true", help="Build ipp-crypto for hash generation. It is used by TVM EP only"
|
||||
)
|
||||
parser.add_argument("--use_tensorrt", action="store_true", help="Build with TensorRT")
|
||||
parser.add_argument(
|
||||
"--tensorrt_placeholder_builder", action="store_true", help="Instantiate Placeholder TensorRT Builder"
|
||||
|
|
@ -485,6 +488,12 @@ def parse_arguments():
|
|||
parser.add_argument("--migraphx_home", help="Path to MIGraphX installation dir")
|
||||
parser.add_argument("--use_full_protobuf", action="store_true", help="Use the full protobuf library")
|
||||
|
||||
parser.add_argument(
|
||||
"--llvm_config",
|
||||
type=str,
|
||||
default="",
|
||||
help="Path to llvm-config.exe for LLVM buit from sources. It is strongly needed for build on Windows",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip_onnx_tests",
|
||||
action="store_true",
|
||||
|
|
@ -833,6 +842,7 @@ def generate_build_tree(
|
|||
# set vars for TVM
|
||||
"-Donnxruntime_USE_TVM=" + ("ON" if args.use_tvm else "OFF"),
|
||||
"-Donnxruntime_TVM_CUDA_RUNTIME=" + ("ON" if args.use_tvm and args.tvm_cuda_runtime else "OFF"),
|
||||
"-Donnxruntime_TVM_USE_HASH=" + ("ON" if args.use_tvm_hash else "OFF"),
|
||||
# set vars for migraphx
|
||||
"-Donnxruntime_USE_MIGRAPHX=" + ("ON" if args.use_migraphx else "OFF"),
|
||||
# By default - we currently support only cross compiling for ARM/ARM64
|
||||
|
|
@ -915,6 +925,8 @@ def generate_build_tree(
|
|||
cmake_args.append("-Donnxruntime_ROCM_VERSION=" + args.rocm_version)
|
||||
if args.use_tensorrt:
|
||||
cmake_args.append("-Donnxruntime_TENSORRT_HOME=" + tensorrt_home)
|
||||
if args.llvm_config:
|
||||
cmake_args.append("-Donnxruntime_TVM_USE_LLVM=" + args.llvm_config)
|
||||
|
||||
# It should be default ON in CI build pipelines, and OFF in packaging pipelines.
|
||||
# And OFF for the people who are not actively developing onnx runtime.
|
||||
|
|
|
|||
Loading…
Reference in a new issue