From 5216a43c9d0d07abf38ab9bd41c1bc81013afc09 Mon Sep 17 00:00:00 2001 From: stevenlix <38092805+stevenlix@users.noreply.github.com> Date: Thu, 14 Apr 2022 11:05:27 -0700 Subject: [PATCH] Consolidate TensorRT subgraphs to reduce inference overhead (#11211) * add trt node list consolidation * add more log * fix typo * seperate cycle detection and removal * update * change function name Co-authored-by: Ubuntu --- .../tensorrt/tensorrt_execution_provider.cc | 27 ++++++++++++++++--- .../tensorrt/tensorrt_execution_provider.h | 2 +- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc index 8cca6de041..1c42a58088 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc +++ b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.cc @@ -837,9 +837,9 @@ SubGraphCollection_t TensorrtExecutionProvider::GetSupportedList(SubGraphCollect } // Detect and remove cycles from supported node list -void TensorrtExecutionProvider::RemoveTensorRTGraphCycles(SubGraphCollection_t& supported_nodes_vector, const GraphViewer& graph) const { +bool TensorrtExecutionProvider::DetectTensorRTGraphCycles(SubGraphCollection_t& supported_nodes_vector, const GraphViewer& graph, bool remove_cycles) const { const std::vector& node_index = graph.GetNodesInTopologicalOrder(); - bool trt_cycle = true; + bool trt_cycle = true, cycle_detected = false; while (trt_cycle) { trt_cycle = false; std::unordered_map node_to_index_map; @@ -923,12 +923,13 @@ void TensorrtExecutionProvider::RemoveTensorRTGraphCycles(SubGraphCollection_t& for (size_t i = 0; i < graph_size; ++i) { if (FindCycleHelper(i, adjacency_map, visited, st, cycles)) { has_cycle = true; + cycle_detected = true; break; } } // Remove TensorRT subgraph from the supported node list if it's part of the cycle - if (has_cycle) { + if (has_cycle && remove_cycles) { for (size_t i = 0; i < cycles.size(); ++i) { auto loc = index_to_node_map.find(cycles[i]); if (loc != index_to_node_map.end() && loc->second.find("TRTKernel") != std::string::npos) { @@ -943,6 +944,7 @@ void TensorrtExecutionProvider::RemoveTensorRTGraphCycles(SubGraphCollection_t& delete[] visited; delete[] st; } + return cycle_detected; } std::vector> @@ -976,7 +978,24 @@ TensorrtExecutionProvider::GetCapability(const GraphViewer& graph, } // Detect and remove cycles from supported node list - RemoveTensorRTGraphCycles(supported_nodes_vector, graph); + DetectTensorRTGraphCycles(supported_nodes_vector, graph); + + // Consolidate supported node list + if (supported_nodes_vector.size() > 1) { + nodes_vector.clear(); + for (const auto& group : supported_nodes_vector) { + if (!group.first.empty()) { + nodes_vector.insert(nodes_vector.end(), group.first.begin(), group.first.end()); + } + } + SubGraphCollection_t consolidated_supported_nodes_vector = {{nodes_vector, true}}; + if (DetectTensorRTGraphCycles(consolidated_supported_nodes_vector, graph, false)) { + LOGS_DEFAULT(INFO) << "[TensorRT EP] TensorRT nodes are not consolidated because graph will have cycles after consolidation"; + } else { + LOGS_DEFAULT(INFO) << "[TensorRT EP] TensorRT nodes are consolidated into one subgraph"; + supported_nodes_vector = consolidated_supported_nodes_vector; + } + } // Construct subgraph capability from node list std::vector> result; diff --git a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h index 9aaec129c1..dcd25176de 100644 --- a/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h +++ b/onnxruntime/core/providers/tensorrt/tensorrt_execution_provider.h @@ -191,7 +191,7 @@ class TensorrtExecutionProvider : public IExecutionProvider { SubGraphCollection_t GetSupportedList(SubGraphCollection_t supported_nodes_list, int iterations, const int max_iterations, const GraphViewer& graph, bool* early_termination) const; - void RemoveTensorRTGraphCycles(SubGraphCollection_t& supported_nodes_vector, const GraphViewer& graph) const; + bool DetectTensorRTGraphCycles(SubGraphCollection_t& supported_nodes_vector, const GraphViewer& graph, bool remove_cycles = true) const; /** Get a unique_lock object to control the concurrency behavior.