Skip to content

Commit a25fdaf

Browse files
committed
NNAdapter support Intel OpenVINO
1 parent 61cc1e0 commit a25fdaf

File tree

24 files changed

+1371
-22
lines changed

24 files changed

+1371
-22
lines changed

cmake/configure.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ if (LITE_WITH_NNADAPTER)
244244
if (NNADAPTER_WITH_ANDROID_NNAPI)
245245
add_definitions("-DNNADAPTER_WITH_ANDROID_NNAPI")
246246
endif()
247+
if (NNADAPTER_WITH_INTEL_OPENVINO)
248+
add_definitions("-DNNADAPTER_WITH_INTEL_OPENVINO")
249+
endif()
247250
endif()
248251
endif()
249252

lite/backends/nnadapter/nnadapter/src/driver/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ endif()
5757
if(NNADAPTER_WITH_ANDROID_NNAPI)
5858
add_subdirectory(android_nnapi)
5959
endif()
60+
61+
if(NNADAPTER_WITH_INTEL_OPENVINO)
62+
add_subdirectory(intel_openvino)
63+
endif()

lite/backends/nnadapter/nnadapter/src/driver/huawei_ascend_npu/engine.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ class Program {
6060
uint32_t output_count,
6161
core::Argument* output_arguments);
6262

63+
void Init() {
64+
static InferenceEngine::Core
65+
}
66+
67+
6368
private:
6469
void Clear();
6570
int CheckInputsAndOutputs(uint32_t input_count,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
set(DEVICE_NAME intel_openvino)
16+
add_definitions(-DNNADAPTER_DEVICE_NAME=${DEVICE_NAME})
17+
add_definitions(-DNNADAPTER_DEVICE_SYMBOL=${NNADAPTER_DEVICE_SYMBOL_PREFIX}${DEVICE_NAME})
18+
19+
include(dependencies.cmake)
20+
21+
aux_source_directory(converter CONVERTERS)
22+
set(SRCS engine.cc utility.cc driver.cc ${CONVERTERS})
23+
set(DEPS ${NNADAPTER_OPERATIONS} ${NNADAPTER_UTILITIES} ${${DEVICE_NAME}_deps})
24+
25+
add_library(${DEVICE_NAME} SHARED ${SRCS})
26+
target_link_libraries(${DEVICE_NAME} "-Wl,--start-group" ${DEPS} "-Wl,--end-group")
27+
set(NNADAPTER_DEVICES ${NNADAPTER_DEVICES} ${DEVICE_NAME} CACHE INTERNAL "")
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef __NNADAPTER_DRIVER_INTEL_OPENVINO_CONVERTER_ALL_H__ // NOLINT
16+
#define __NNADAPTER_DRIVER_INTEL_OPENVINO_CONVERTER_ALL_H__
17+
18+
REGISTER_CONVERTER(ABS, ConvertUnaryActivations)
19+
REGISTER_CONVERTER(ADD, ConvertElementwise)
20+
REGISTER_CONVERTER(AVERAGE_POOL_2D, ConvertPool2D)
21+
REGISTER_CONVERTER(BATCH_NORMALIZATION, ConvertBatchNormalization)
22+
REGISTER_CONVERTER(CONV_2D, ConvertConv2D)
23+
REGISTER_CONVERTER(DIV, ConvertElementwise)
24+
REGISTER_CONVERTER(EQUAL, ConvertElementwise)
25+
REGISTER_CONVERTER(EXP, ConvertUnaryActivations)
26+
REGISTER_CONVERTER(FLOOR, ConvertUnaryActivations)
27+
REGISTER_CONVERTER(GREATER_EQUAL, ConvertElementwise)
28+
REGISTER_CONVERTER(LOG, ConvertUnaryActivations)
29+
REGISTER_CONVERTER(MAT_MUL, ConvertMatMul)
30+
REGISTER_CONVERTER(MAX, ConvertElementwise)
31+
REGISTER_CONVERTER(MAX_POOL_2D, ConvertPool2D)
32+
REGISTER_CONVERTER(MIN, ConvertElementwise)
33+
REGISTER_CONVERTER(MUL, ConvertElementwise)
34+
REGISTER_CONVERTER(POW, ConvertElementwise)
35+
REGISTER_CONVERTER(RELU, ConvertUnaryActivations)
36+
REGISTER_CONVERTER(RESHAPE, ConvertReshape)
37+
REGISTER_CONVERTER(SOFTMAX, ConvertSoftmax)
38+
REGISTER_CONVERTER(SUB, ConvertElementwise)
39+
REGISTER_CONVERTER(TANH, ConvertUnaryActivations)
40+
41+
#endif
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "operation/batch_normalization.h"
16+
#include "driver/intel_openvino/converter/converter.h"
17+
#include "utility/debug.h"
18+
#include "utility/logging.h"
19+
20+
namespace nnadapter {
21+
namespace intel_openvino {
22+
23+
int ConvertBatchNormalization(Converter* converter, core::Operation* operation) {
24+
BATCH_NORMALIZATION_OPERATION_EXTRACT_INPUTS_OUTPUTS
25+
26+
// Convert operand to Intel OpenVINO's OutputNode
27+
auto input_node = converter->GetMappedOutputNode(input_operand);
28+
if (!input_node) {
29+
input_node = converter->ConvertToOutputNode(input_operand);
30+
}
31+
auto gamma_node = converter->ConvertToOutputNode(scale_operand);
32+
auto beta_node = converter->ConvertToOutputNode(bias_operand);
33+
auto mean_node = converter->ConvertToOutputNode(mean_operand);
34+
auto variance_node = converter->ConvertToOutputNode(variance_operand);
35+
// Create <BatchNormInference> Node for Intel OpenVINO
36+
std::shared_ptr<Node> node = std::make_shared<default_opset::BatchNormInference>
37+
(*input_node, *gamma_node, *beta_node, *mean_node, *variance_node, epsilon);
38+
auto output_node = std::make_shared<OutputNode>(node->output(0));
39+
converter->UpdateOutputNodeMap(output_operand, output_node);
40+
return NNADAPTER_NO_ERROR;
41+
}
42+
43+
} // namespace intel_openvino
44+
} // namespace nnadapter
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "operation/conv2d.h"
16+
#include "driver/intel_openvino/converter/converter.h"
17+
#include "utility/debug.h"
18+
#include "utility/logging.h"
19+
20+
namespace nnadapter {
21+
namespace intel_openvino {
22+
23+
int ConvertConv2D(Converter* converter, core::Operation* operation) {
24+
CONV_2D_OPERATION_EXTRACT_INPUTS_OUTPUTS
25+
if (auto_pad != NNADAPTER_AUTO_PAD_NONE) {
26+
operation::UpdateConv2DPadAndDilation(
27+
input_operand->type.dimensions.data[2],
28+
filter_height,
29+
auto_pad,
30+
&pad_height_top,
31+
&pad_height_bottom,
32+
stride_height,
33+
&dilation_height);
34+
operation::UpdateConv2DPadAndDilation(
35+
input_operand->type.dimensions.data[3],
36+
filter_width,
37+
auto_pad,
38+
&pad_width_left,
39+
&pad_width_right,
40+
stride_width,
41+
&dilation_width);
42+
}
43+
44+
// Convert operand to Intel OpenVINO's OutputNode
45+
auto input_node = converter->GetMappedOutputNode(input_operand);
46+
if (!input_node) {
47+
input_node = converter->ConvertToOutputNode(input_operand);
48+
}
49+
auto filter_node = converter->ConvertToOutputNode(filter_operand);
50+
auto ov_auto_pad = ConvertToOVPadType(auto_pad);
51+
auto ov_strides = ov::Strides({static_cast<size_t>(stride_height), static_cast<size_t>(stride_width)});
52+
auto ov_diliations = ov::Strides({static_cast<size_t>(dilation_height), static_cast<size_t>(dilation_width)});
53+
auto ov_pads_begin = ov::CoordinateDiff({static_cast<std::ptrdiff_t>(pad_height_top), static_cast<std::ptrdiff_t>(pad_width_left)});
54+
auto ov_pads_end = ov::CoordinateDiff({static_cast<std::ptrdiff_t>(pad_height_bottom), static_cast<std::ptrdiff_t>(pad_width_right)});
55+
// Create <Convolution> Node for Intel OpenVINO
56+
std::shared_ptr<OutputNode> output_node{nullptr};
57+
std::shared_ptr<Node> node = std::make_shared<default_opset::Convolution>(*input_node, *filter_node, ov_strides,
58+
ov_pads_begin, ov_pads_end, ov_diliations, ov_auto_pad);
59+
auto conv_output_node = std::make_shared<OutputNode>(node->output(0));
60+
converter->UpdateOutputNodeMap(output_operand, conv_output_node);
61+
output_node = conv_output_node;
62+
NNADAPTER_LOG(INFO) << "Convert conv2d success";
63+
// Bias
64+
auto unsqueeze_node = converter->AddUnsqueezeOutputNode(bias_operand, std::vector<size_t>({3}), std::vector<int64_t>({0,2,3}));
65+
std::shared_ptr<Node> add_node = std::make_shared<default_opset::Add>(*conv_output_node, *unsqueeze_node);
66+
auto add_output_node = std::make_shared<OutputNode>(add_node->output(0));
67+
converter->UpdateOutputNodeMap(output_operand, add_output_node);
68+
output_node = add_output_node;
69+
NNADAPTER_LOG(INFO) << " Convert conv2d-bias-add success";
70+
// Fuse activation
71+
switch (fuse_code) {
72+
#define CONVERT_UNARY_ACTIVATION(type, class_name) \
73+
case NNADAPTER_FUSED_##type: { \
74+
std::shared_ptr<Node> act_node = std::make_shared<default_opset::class_name>(*output_node); \
75+
auto act_output_node = std::make_shared<OutputNode>(act_node->output(0)); \
76+
converter->UpdateOutputNodeMap(output_operand, act_output_node); \
77+
} break;
78+
CONVERT_UNARY_ACTIVATION(RELU, Relu);
79+
NNADAPTER_LOG(INFO) << " Convert conv2d-relu success!";
80+
#undef CONVERT_UNARY_ACTIVATION
81+
case NNADAPTER_FUSED_NONE:
82+
break;
83+
default:
84+
NNADAPTER_LOG(FATAL) << "Unsupported fuse_code(" << fuse_code
85+
<< ") is found.";
86+
break;
87+
}
88+
return NNADAPTER_NO_ERROR;
89+
}
90+
91+
} // namespace intel_openvino
92+
} // namespace nnadapter
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "driver/intel_openvino/converter/converter.h"
16+
#include <unistd.h>
17+
#include <algorithm>
18+
#include <vector>
19+
#include "utility/debug.h"
20+
#include "utility/logging.h"
21+
#include "utility/modeling.h"
22+
#include "utility/string.h"
23+
#include "utility/utility.h"
24+
25+
namespace nnadapter {
26+
namespace intel_openvino {
27+
28+
#define REGISTER_CONVERTER(__op_type__, __func_name__) \
29+
extern int __func_name__(Converter* converter, core::Operation* operation);
30+
#include "driver/intel_openvino/converter/all.h" // NOLINT
31+
#undef __NNADAPTER_DRIVER_INTEL_OPENVINO_CONVERTER_ALL_H__
32+
#undef REGISTER_CONVERTER
33+
34+
int Converter::Apply(core::Model* model) {
35+
// Convert the NNAdapter operations to the aml operators
36+
std::vector<core::Operation*> operations =
37+
SortOperationsInTopologicalOrder(model);
38+
for (auto operation : operations) {
39+
NNADAPTER_VLOG(5) << "Converting " << OperationTypeToString(operation->type)
40+
<< " ...";
41+
switch (operation->type) {
42+
#define REGISTER_CONVERTER(__op_type__, __func_name__) \
43+
case NNADAPTER_##__op_type__: \
44+
__func_name__(this, operation); \
45+
break;
46+
#include "driver/intel_openvino/converter/all.h" // NOLINT
47+
#undef __NNADAPTER_DRIVER_INTEL_OPENVINO_CONVERTER_ALL_H__
48+
#undef REGISTER_CONVERTER
49+
default:
50+
NNADAPTER_LOG(FATAL) << "Unsupported operation("
51+
<< OperationTypeToString(operation->type)
52+
<< ") is found.";
53+
break;
54+
}
55+
}
56+
return NNADAPTER_NO_ERROR;
57+
}
58+
59+
std::shared_ptr<OutputNode> Converter::GetMappedOutputNode(
60+
core::Operand* operand) {
61+
auto it = output_nodes_->find(operand);
62+
if (it != output_nodes_->end()) {
63+
return it->second.back();
64+
}
65+
return nullptr;
66+
}
67+
68+
std::shared_ptr<OutputNode> Converter::UpdateOutputNodeMap(
69+
core::Operand* operand, std::shared_ptr<OutputNode> output_node) {
70+
auto it = output_nodes_->find(operand);
71+
if (it == output_nodes_->end()) {
72+
auto result = output_nodes_->insert(std::make_pair(
73+
operand, std::vector<std::shared_ptr<OutputNode>>()));
74+
NNADAPTER_CHECK(result.second);
75+
it = result.first;
76+
}
77+
output_node->set_names({OperandIdToString(operand)});
78+
it->second.push_back(output_node);
79+
return output_node;
80+
}
81+
82+
std::shared_ptr<OutputNode> Converter::ConvertToOutputNode(
83+
core::Operand* operand, std::vector<int32_t> dimensions) {
84+
if (dimensions.empty()) {
85+
for (uint32_t i = 0; i < operand->type.dimensions.count; i++) {
86+
dimensions.push_back(operand->type.dimensions.data[i]);
87+
}
88+
}
89+
if (IsConstantOperand(operand)) {
90+
auto constant_node = std::make_shared<default_opset::Constant>(ConvertToOVElementType(operand->type.precision),
91+
ConvertToOVShape(dimensions), operand->buffer);
92+
std::shared_ptr<OutputNode> output_node = std::make_shared<OutputNode>(constant_node->output(0));
93+
UpdateOutputNodeMap(operand, output_node);
94+
return output_node;
95+
} else if (IsModelInputOperand(operand)) {
96+
auto parameter_node = std::make_shared<default_opset::Parameter>(ConvertToOVElementType(operand->type.precision),
97+
ConvertToOVShape(dimensions));
98+
parameter_nodes_->push_back(parameter_node);
99+
std::shared_ptr<OutputNode> output_node = std::make_shared<OutputNode>(parameter_node->output(0));
100+
UpdateOutputNodeMap(operand, output_node);
101+
return output_node;
102+
}
103+
NNADAPTER_LOG(FATAL) << "Only constant and model input operands can be "
104+
"converted to Intel OpenVINO OutputNode!";
105+
return nullptr;
106+
}
107+
108+
} // namespace intel_openvino
109+
} // namespace nnadapter

0 commit comments

Comments
 (0)