Disable NNAPI support for dynamic input shape, add warning logs (#7439)

* disable nnapi for graph with dynamic input shape

* Add warning for multiple paritions

* minor update

* update the message logging

* Fix coreml ci failure
This commit is contained in:
Guoyu Wang 2021-05-04 11:09:23 -07:00 committed by GitHub
parent c3c4db2c1b
commit 71ff6ff2ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 20 deletions

View file

@ -69,7 +69,7 @@ bool IsInputSupported(const NodeArg& input, const std::string& parent_name, cons
for (const auto& dim : shape_proto->dim()) {
// For now we do not support dynamic shape
if (!dim.has_dim_value()) {
LOGS(logger, WARNING) << "Dynamic shape is not supported yet, for input:" << input_name;
LOGS(logger, WARNING) << "Dynamic shape is not supported for now, for input:" << input_name;
return false;
}
@ -87,19 +87,19 @@ bool IsInputSupported(const NodeArg& input, const std::string& parent_name, cons
}
std::vector<std::vector<NodeIndex>> GetSupportedNodes(const GraphViewer& graph_viewer, const logging::Logger& logger) {
std::vector<std::vector<size_t>> supported_node_vecs;
std::vector<std::vector<size_t>> supported_node_groups;
if (!util::HasRequiredBaseOS()) {
LOGS(logger, WARNING) << "All ops will fallback to CPU EP, because we do not have supported OS";
return supported_node_vecs;
return supported_node_groups;
}
for (const auto* input : graph_viewer.GetInputs()) {
if (!IsInputSupported(*input, "graph", logger)) {
return supported_node_vecs;
return supported_node_groups;
}
}
std::vector<size_t> supported_node_vec;
std::vector<size_t> supported_node_group;
const auto& node_indices = graph_viewer.GetNodesInTopologicalOrder();
for (size_t i = 0; i < node_indices.size(); i++) {
auto node_idx = node_indices[i];
@ -111,20 +111,20 @@ std::vector<std::vector<NodeIndex>> GetSupportedNodes(const GraphViewer& graph_v
<< "] supported: [" << supported
<< "]";
if (supported) {
supported_node_vec.push_back(node_idx);
supported_node_group.push_back(node_idx);
} else {
if (!supported_node_vec.empty()) {
supported_node_vecs.push_back(supported_node_vec);
supported_node_vec.clear();
if (!supported_node_group.empty()) {
supported_node_groups.push_back(supported_node_group);
supported_node_group.clear();
}
}
}
if (!supported_node_vec.empty()) {
supported_node_vecs.push_back(supported_node_vec);
if (!supported_node_group.empty()) {
supported_node_groups.push_back(supported_node_group);
}
return supported_node_vecs;
return supported_node_groups;
}
bool HasNeuralEngine(const logging::Logger& logger) {

View file

@ -163,10 +163,19 @@ CoreMLExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_vie
result.push_back(std::make_unique<ComputeCapability>(std::move(sub_graph)));
}
LOGS(logger, INFO) << "CoreMLExecutionProvider::GetCapability,"
<< " number of partitions supported by CoreML: " << result.size()
<< " number of nodes in the graph: " << graph_viewer.NumberOfNodes()
<< " number of nodes supported by CoreML: " << num_of_supported_nodes;
auto num_of_partitions = result.size();
const auto summary_msg = MakeString(
"CoreMLExecutionProvider::GetCapability,",
" number of partitions supported by CoreML: ", num_of_partitions,
" number of nodes in the graph: ", graph_viewer.NumberOfNodes(),
" number of nodes supported by CoreML: ", num_of_supported_nodes);
// If the graph is partitioned in multiple subgraphs, and this may impact performance,
// we want to give users a summary message at warning level.
if (num_of_partitions > 1)
LOGS_DEFAULT(WARNING) << summary_msg;
else
LOGS_DEFAULT(INFO) << summary_msg;
return result;
}

View file

@ -483,6 +483,27 @@ bool IsNodeSupportedInternal(const Node& node, const GraphViewer& graph_viewer,
return true;
}
bool IsInputSupported(const NodeArg& input, const std::string& parent_name) {
const auto& input_name = input.Name();
const auto* shape_proto = input.Shape();
// We do not support input with no shape
if (!shape_proto) {
LOGS_DEFAULT(VERBOSE) << "Input [" << input_name << "] of [" << parent_name
<< "] has not shape";
return false;
}
for (const auto& dim : shape_proto->dim()) {
// For now we do not support dynamic shape
if (!dim.has_dim_value()) {
LOGS_DEFAULT(WARNING) << "Dynamic shape is not supported for now, for input:" << input_name;
return false;
}
}
return true;
}
std::vector<std::vector<size_t>> GetSupportedNodes(const GraphViewer& graph_viewer, const OpSupportCheckParams& params) {
std::vector<std::vector<size_t>> supported_node_groups;
if (params.android_sdk_ver < ORT_NNAPI_MIN_API_LEVEL) {
@ -492,6 +513,13 @@ std::vector<std::vector<size_t>> GetSupportedNodes(const GraphViewer& graph_view
return supported_node_groups;
}
// Disable NNAPI if the graph has input with dynamic shape
for (const auto* input : graph_viewer.GetInputs()) {
if (!IsInputSupported(*input, "graph")) {
return supported_node_groups;
}
}
// This holds the supported node's topological index
std::vector<size_t> supported_node_group;
// This holds the NodeIndex of the nodes in the above group

View file

@ -196,10 +196,19 @@ NnapiExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_view
result.push_back(std::make_unique<ComputeCapability>(std::move(sub_graph)));
}
LOGS_DEFAULT(INFO) << "NnapiExecutionProvider::GetCapability,"
<< " number of partitions supported by NNAPI: " << result.size()
<< " number of nodes in the graph: " << graph_view.NumberOfNodes()
<< " number of nodes supported by NNAPI: " << num_of_supported_nodes;
auto num_of_partitions = result.size();
const auto summary_msg = MakeString(
"NnapiExecutionProvider::GetCapability,",
" number of partitions supported by NNAPI: ", num_of_partitions,
" number of nodes in the graph: ", graph_view.NumberOfNodes(),
" number of nodes supported by NNAPI: ", num_of_supported_nodes);
// If the graph is partitioned in multiple subgraphs, and this may impact performance,
// we want to give users a summary message at warning level.
if (num_of_partitions > 1)
LOGS_DEFAULT(WARNING) << summary_msg;
else
LOGS_DEFAULT(INFO) << summary_msg;
return result;
}