Skip to content

Commit 56b36a5

Browse files
Initial PR for VSINPU execution provider (microsoft#20903)
### Description <!-- Describe your changes. --> -It is an initial PR for VSINPU execution provider ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> - For support VeriSilicon hardware - TIM-VX(Tensor Interface Module) (https://github.com/VeriSilicon/TIM-VX) is an integrated software solution by Verisilicon for our hardware(A311D/i.MX 8M Plus etc.) design, it is easy to use Verisilicon’s hardware by simply connecting onnxruntime with the TIM-VX API by this VSINPU execution provider.
1 parent 9007ede commit 56b36a5

File tree

65 files changed

+5096
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+5096
-3
lines changed

cmake/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ option(onnxruntime_BUILD_OBJC "Build Objective-C library" OFF)
101101
option(onnxruntime_USE_PREINSTALLED_EIGEN "Use pre-installed EIGEN. Need to provide eigen_SOURCE_PATH if turn this on." OFF)
102102
option(onnxruntime_BUILD_BENCHMARKS "Build ONNXRuntime micro-benchmarks" OFF)
103103
option(onnxruntime_USE_LLVM "Build TVM with LLVM" OFF)
104+
option(onnxruntime_USE_VSINPU "Build with VSINPU support" OFF)
104105

105106
cmake_dependent_option(onnxruntime_USE_FLASH_ATTENTION "Build flash attention kernel for scaled dot product attention" ON "onnxruntime_USE_CUDA" OFF)
106107
option(onnxruntime_USE_MEMORY_EFFICIENT_ATTENTION "Build memory efficient attention kernel for scaled dot product attention" ON)
@@ -797,6 +798,11 @@ if (onnxruntime_USE_RKNPU)
797798
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_RKNPU=1)
798799
list(APPEND ONNXRUNTIME_PROVIDER_NAMES rknpu)
799800
endif()
801+
if (onnxruntime_USE_VSINPU)
802+
list(APPEND ORT_PROVIDER_FLAGS -DUSE_VSINPU=1)
803+
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_VSINPU=1)
804+
list(APPEND ONNXRUNTIME_PROVIDER_NAMES vsinpu)
805+
endif()
800806
if (onnxruntime_USE_NNAPI_BUILTIN)
801807
list(APPEND ORT_PROVIDER_FLAGS -DUSE_NNAPI=1)
802808
list(APPEND ORT_PROVIDER_CMAKE_FLAGS -Donnxruntime_USE_NNAPI_BUILTIN=1)

cmake/onnxruntime.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ set(onnxruntime_INTERNAL_LIBRARIES
189189
${PROVIDERS_SNPE}
190190
${PROVIDERS_TVM}
191191
${PROVIDERS_RKNPU}
192+
${PROVIDERS_VSINPU}
192193
${PROVIDERS_XNNPACK}
193194
${PROVIDERS_WEBNN}
194195
${PROVIDERS_AZURE}

cmake/onnxruntime_providers.cmake

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ endif()
8080
if(onnxruntime_USE_RKNPU)
8181
set(PROVIDERS_RKNPU onnxruntime_providers_rknpu)
8282
endif()
83+
if(onnxruntime_USE_VSINPU)
84+
set(PROVIDERS_VSINPU onnxruntime_providers_vsinpu)
85+
endif()
8386
if(onnxruntime_USE_DML)
8487
set(PROVIDERS_DML onnxruntime_providers_dml)
8588
endif()
@@ -188,6 +191,35 @@ if (onnxruntime_USE_TVM)
188191
include(onnxruntime_providers_tvm.cmake)
189192
endif()
190193

194+
if (onnxruntime_USE_VSINPU)
195+
add_definitions(-DUSE_VSINPU=1)
196+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
197+
file(GLOB_RECURSE onnxruntime_providers_vsinpu_srcs
198+
"${ONNXRUNTIME_ROOT}/core/providers/vsinpu/builders/*.h"
199+
"${ONNXRUNTIME_ROOT}/core/providers/vsinpu/builders/*.cc"
200+
"${ONNXRUNTIME_ROOT}/core/providers/vsinpu/*.h"
201+
"${ONNXRUNTIME_ROOT}/core/providers/vsinpu/*.cc"
202+
"${ONNXRUNTIME_ROOT}/core/providers/shared/utils/utils.h"
203+
"${ONNXRUNTIME_ROOT}/core/providers/shared/utils/utils.cc"
204+
)
205+
source_group(TREE ${ONNXRUNTIME_ROOT}/core FILES ${onnxruntime_providers_vsinpu_srcs})
206+
add_library(onnxruntime_providers_vsinpu ${onnxruntime_providers_vsinpu_srcs})
207+
onnxruntime_add_include_to_target(onnxruntime_providers_vsinpu
208+
onnxruntime_common onnxruntime_framework onnx onnx_proto protobuf::libprotobuf-lite flatbuffers Boost::mp11
209+
safeint_interface nsync::nsync_cpp)
210+
add_dependencies(onnxruntime_providers_vsinpu ${onnxruntime_EXTERNAL_DEPENDENCIES})
211+
set_target_properties(onnxruntime_providers_vsinpu PROPERTIES FOLDER "ONNXRuntime" LINKER_LANGUAGE CXX)
212+
target_include_directories(onnxruntime_providers_vsinpu PRIVATE ${ONNXRUNTIME_ROOT} $ENV{TIM_VX_INSTALL}/include)
213+
214+
find_library(TIMVX_LIBRARY NAMES tim-vx PATHS $ENV{TIM_VX_INSTALL}/lib NO_DEFAULT_PATH)
215+
if(TIMVX_LIBRARY)
216+
target_link_libraries(onnxruntime_providers_vsinpu PRIVATE ${TIMVX_LIBRARY})
217+
else()
218+
message(FATAL_ERROR "Cannot find TIM-VX library!")
219+
endif()
220+
221+
endif()
222+
191223
if (onnxruntime_USE_XNNPACK)
192224
include(onnxruntime_providers_xnnpack.cmake)
193225
endif()

cmake/onnxruntime_unittests.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,10 @@ if(onnxruntime_USE_NNAPI_BUILTIN)
546546
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_nnapi)
547547
endif()
548548

549+
if(onnxruntime_USE_VSINPU)
550+
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_vsinpu)
551+
endif()
552+
549553
if(onnxruntime_USE_JSEP)
550554
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_js)
551555
endif()
@@ -589,6 +593,7 @@ set(ONNXRUNTIME_TEST_LIBS
589593
${onnxruntime_libs}
590594
# CUDA, ROCM, TENSORRT, MIGRAPHX, DNNL, and OpenVINO are dynamically loaded at runtime
591595
${PROVIDERS_NNAPI}
596+
${PROVIDERS_VSINPU}
592597
${PROVIDERS_JS}
593598
${PROVIDERS_QNN}
594599
${PROVIDERS_SNPE}

include/onnxruntime/core/graph/constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ constexpr const char* kXnnpackExecutionProvider = "XnnpackExecutionProvider";
5252
constexpr const char* kWebNNExecutionProvider = "WebNNExecutionProvider";
5353
constexpr const char* kCannExecutionProvider = "CANNExecutionProvider";
5454
constexpr const char* kAzureExecutionProvider = "AzureExecutionProvider";
55+
constexpr const char* kVSINPUExecutionProvider = "VSINPUExecutionProvider";
5556

5657
constexpr const char* kExecutionProviderSharedLibraryPath = "shared_lib_path";
5758
constexpr const char* kExecutionProviderSharedLibraryEntry = "provider_factory_entry_point";
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (c) 2023 Vivante Corporation
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a
6+
* copy of this software and associated documentation files (the "Software"),
7+
* to deal in the Software without restriction, including without limitation
8+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+
* and/or sell copies of the Software, and to permit persons to whom the
10+
* Software is furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
*****************************************************************************/
24+
#include "onnxruntime_c_api.h"
25+
26+
#ifdef __cplusplus
27+
extern "C" {
28+
#endif
29+
30+
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_VSINPU, _In_ OrtSessionOptions* options);
31+
32+
#ifdef __cplusplus
33+
}
34+
#endif

onnxruntime/core/framework/node_unit.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ void NodeUnit::InitForSingleNode() {
285285
const auto& output_defs = target_node_.OutputDefs();
286286
const auto& node_attrs = target_node_.GetAttributes();
287287
auto qlinear_type = GetQLinearOpType(target_node_);
288-
if (qlinear_type == QLinearOpType::Unknown || IsVariadicQLinearOp(qlinear_type)) { // TODO, add variadic support
288+
if (qlinear_type == QLinearOpType::Unknown) {
289289
// Not a Qlinear op, add all inputs / outputs
290290
auto add_all_io = [](std::vector<NodeUnitIODef>& defs,
291291
const ConstPointerContainer<std::vector<NodeArg*>>& node_defs) {
@@ -351,6 +351,13 @@ void NodeUnit::InitForSingleNode() {
351351
NodeUnitIODef::QuantParam{*input_defs[1],
352352
input_defs.size() == 3 ? input_defs[2] : nullptr,
353353
axis}});
354+
} else if (IsVariadicQLinearOp(qlinear_type)) {
355+
size_t input_num = (input_defs.size() - 2) / 3;
356+
for (size_t i = 0; i < input_num; i++) {
357+
inputs_.push_back(NodeUnitIODef{*input_defs[3 * i + 2], NodeUnitIODef::QuantParam{*input_defs[3 * i + 3],
358+
input_defs[3 * i + 4]}});
359+
}
360+
outputs_.push_back(NodeUnitIODef{*output_defs[0], NodeUnitIODef::QuantParam{*input_defs[0], input_defs[1]}});
354361
} else {
355362
ORT_THROW("The QLinear op [", static_cast<uint8_t>(qlinear_type), "] is not supported");
356363
}

onnxruntime/core/framework/utils.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ bool ProviderIsCpuBased(const std::string& provider_type) {
6161
provider_type == onnxruntime::kVitisAIExecutionProvider ||
6262
provider_type == onnxruntime::kOpenVINOExecutionProvider ||
6363
provider_type == onnxruntime::kNnapiExecutionProvider ||
64+
provider_type == onnxruntime::kVSINPUExecutionProvider ||
6465
provider_type == onnxruntime::kAclExecutionProvider ||
6566
provider_type == onnxruntime::kArmNNExecutionProvider ||
6667
provider_type == onnxruntime::kRknpuExecutionProvider ||

onnxruntime/core/providers/get_execution_providers.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ constexpr ProviderInfo kProvidersInPriorityOrder[] =
9898
true,
9999
#else
100100
false,
101+
#endif
102+
},
103+
{
104+
kVSINPUExecutionProvider,
105+
#ifdef USE_VSINPU
106+
true,
107+
#else
108+
false,
101109
#endif
102110
},
103111
{

onnxruntime/core/providers/provider_factory_creators.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
#include "core/providers/nnapi/nnapi_provider_factory_creator.h"
4747
#endif
4848

49+
#if defined(USE_VSINPU)
50+
#include "core/providers/vsinpu/vsinpu_provider_factory_creator.h"
51+
#endif
52+
4953
#if defined(USE_JSEP)
5054
#include "core/providers/js/js_provider_factory_creator.h"
5155
#endif
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (c) 2023 Vivante Corporation
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a
6+
* copy of this software and associated documentation files (the "Software"),
7+
* to deal in the Software without restriction, including without limitation
8+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+
* and/or sell copies of the Software, and to permit persons to whom the
10+
* Software is furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
*****************************************************************************/
24+
#include <memory>
25+
#include <vector>
26+
#include <utility>
27+
#include "core/providers/shared/utils/utils.h"
28+
#include "core/providers/vsinpu/builders/impl/base_op_builder.h"
29+
30+
namespace onnxruntime {
31+
namespace vsi {
32+
namespace npu {
33+
class ReluOpBuilder : public BaseOpBuilder {
34+
public:
35+
bool HandleBuildOp(vsi::npu::GraphEP* graph_ep,
36+
std::vector<std::shared_ptr<tim::vx::Tensor>>& inputs,
37+
std::vector<std::shared_ptr<tim::vx::Tensor>>& outputs,
38+
const NodeUnit& node_unit) override {
39+
LOGS_DEFAULT(VERBOSE) << "Creating Relu Activation.";
40+
auto op = graph_ep->GetGraph()->CreateOperation<tim::vx::ops::Relu>();
41+
(*op).BindInputs(inputs).BindOutputs(outputs);
42+
graph_ep->GetOps().push_back(std::move(op));
43+
return true;
44+
}
45+
};
46+
class SigmoidOpBuilder : public BaseOpBuilder {
47+
public:
48+
bool HandleBuildOp(vsi::npu::GraphEP* graph_ep,
49+
std::vector<std::shared_ptr<tim::vx::Tensor>>& inputs,
50+
std::vector<std::shared_ptr<tim::vx::Tensor>>& outputs,
51+
const NodeUnit& node_unit) override {
52+
LOGS_DEFAULT(VERBOSE) << "Creating Sigmoid Activation.";
53+
auto op = graph_ep->GetGraph()->CreateOperation<tim::vx::ops::Sigmoid>();
54+
(*op).BindInputs(inputs).BindOutputs(outputs);
55+
graph_ep->GetOps().push_back(std::move(op));
56+
return true;
57+
}
58+
};
59+
class TanhOpBuilder : public BaseOpBuilder {
60+
public:
61+
bool HandleBuildOp(vsi::npu::GraphEP* graph_ep,
62+
std::vector<std::shared_ptr<tim::vx::Tensor>>& inputs,
63+
std::vector<std::shared_ptr<tim::vx::Tensor>>& outputs,
64+
const NodeUnit& node_unit) override {
65+
LOGS_DEFAULT(VERBOSE) << "Creating Tanh activation.";
66+
auto op = graph_ep->GetGraph()->CreateOperation<tim::vx::ops::Tanh>();
67+
(*op).BindInputs(inputs).BindOutputs(outputs);
68+
graph_ep->GetOps().push_back(std::move(op));
69+
return true;
70+
}
71+
};
72+
73+
class LeakyReluOpBuilder : public BaseOpBuilder {
74+
public:
75+
bool HandleBuildOp(vsi::npu::GraphEP* graph_ep,
76+
std::vector<std::shared_ptr<tim::vx::Tensor>>& inputs,
77+
std::vector<std::shared_ptr<tim::vx::Tensor>>& outputs,
78+
const NodeUnit& node_unit) override {
79+
LOGS_DEFAULT(VERBOSE) << "Creating LeakyRelu activation.";
80+
const auto& node = node_unit.GetNode();
81+
NodeAttrHelper helper(node);
82+
auto alpha = helper.Get("alpha", 1.0f);
83+
auto op =
84+
graph_ep->GetGraph()->CreateOperation<tim::vx::ops::LeakyRelu>(alpha);
85+
(*op).BindInputs(inputs).BindOutputs(outputs);
86+
graph_ep->GetOps().push_back(std::move(op));
87+
return true;
88+
}
89+
};
90+
91+
class EluOpBuilder : public BaseOpBuilder {
92+
public:
93+
bool HandleBuildOp(vsi::npu::GraphEP* graph_ep,
94+
std::vector<std::shared_ptr<tim::vx::Tensor>>& inputs,
95+
std::vector<std::shared_ptr<tim::vx::Tensor>>& outputs,
96+
const NodeUnit& node_unit) override {
97+
LOGS_DEFAULT(VERBOSE) << "Creating Elu activation.";
98+
const auto& node = node_unit.GetNode();
99+
NodeAttrHelper helper(node);
100+
auto alpha = helper.Get("alpha", 1.0f);
101+
auto op =
102+
graph_ep->GetGraph()->CreateOperation<tim::vx::ops::LeakyRelu>(alpha);
103+
(*op).BindInputs(inputs).BindOutputs(outputs);
104+
graph_ep->GetOps().push_back(std::move(op));
105+
return true;
106+
}
107+
};
108+
109+
class HardSigmoidOpBuilder : public BaseOpBuilder {
110+
public:
111+
bool HandleBuildOp(vsi::npu::GraphEP* graph_ep,
112+
std::vector<std::shared_ptr<tim::vx::Tensor>>& inputs,
113+
std::vector<std::shared_ptr<tim::vx::Tensor>>& outputs,
114+
const NodeUnit& node_unit) override {
115+
LOGS_DEFAULT(VERBOSE) << "Creating HardSigmoid activation.";
116+
const auto& node = node_unit.GetNode();
117+
NodeAttrHelper helper(node);
118+
auto alpha = helper.Get("alpha", 1.0f);
119+
auto beta = helper.Get("beta", 1.0f);
120+
auto op = graph_ep->GetGraph()->CreateOperation<tim::vx::ops::HardSigmoid>(
121+
alpha, beta);
122+
(*op).BindInputs(inputs).BindOutputs(outputs);
123+
graph_ep->GetOps().push_back(std::move(op));
124+
return true;
125+
}
126+
};
127+
} // namespace npu
128+
129+
} // namespace vsi
130+
} // namespace onnxruntime

0 commit comments

Comments
 (0)