diff --git a/onnxruntime/core/framework/fallback_cpu_capability.cc b/onnxruntime/core/framework/fallback_cpu_capability.cc index 8ee958fdbc..ab8266cf93 100644 --- a/onnxruntime/core/framework/fallback_cpu_capability.cc +++ b/onnxruntime/core/framework/fallback_cpu_capability.cc @@ -40,8 +40,7 @@ static bool IsSmallInitializer(const onnxruntime::GraphViewer& graph, const Node std::unordered_set GetCpuPreferredNodes(const onnxruntime::GraphViewer& graph, const IExecutionProvider::IKernelLookup& kernel_lookup, - gsl::span tentative_nodes, - bool requires_matching_kernel) { + gsl::span tentative_nodes) { // automatic conversion from const std::vector& const auto& ordered_nodes = graph.GetNodesInTopologicalOrder(); InlinedVector node_id_to_order_map(graph.MaxNodeIndex()); @@ -70,18 +69,15 @@ std::unordered_set GetCpuPreferredNodes(const onnxruntime::GraphViewe const Node* node = graph.GetNode(node_id); const KernelCreateInfo* kernel_info = kernel_lookup.LookUpKernel(*node); - - if (requires_matching_kernel) { - // at least one registry has a target provider's kernel for this node - ORT_ENFORCE(kernel_info != nullptr); - node_to_kernel.insert({node_id, kernel_info}); - } + // at least one registry has a target provider's kernel for this node + ORT_ENFORCE(kernel_info != nullptr); + node_to_kernel.insert({node_id, kernel_info}); // first, find all the direct consumer of cpu tensors. ORT_THROW_IF_ERROR(node->ForEachWithIndex( node->OutputDefs(), [&](const NodeArg& node_arg, size_t out_index) { - if ((!requires_matching_kernel && kernel_info == nullptr) || kernel_info->kernel_def->IsOutputOnCpu(out_index)) { + if (kernel_info->kernel_def->IsOutputOnCpu(out_index)) { cpu_output_args.insert(&node_arg); auto consumer_nodes = graph.GetConsumerNodes(node_arg.Name()); for (auto& consumer_node : consumer_nodes) { @@ -139,7 +135,7 @@ std::unordered_set GetCpuPreferredNodes(const onnxruntime::GraphViewe } // input is a CPU tensor, but it's intended to be consumed as CPU input by the target EP - if (requires_matching_kernel && node_to_kernel[cur]->kernel_def->IsInputOnCpu(i)) { + if (node_to_kernel[cur]->kernel_def->IsInputOnCpu(i)) { place_in_cpu = false; break; } diff --git a/onnxruntime/core/framework/fallback_cpu_capability.h b/onnxruntime/core/framework/fallback_cpu_capability.h index f8e8fdc359..afc518d28a 100644 --- a/onnxruntime/core/framework/fallback_cpu_capability.h +++ b/onnxruntime/core/framework/fallback_cpu_capability.h @@ -16,11 +16,9 @@ namespace onnxruntime { @param graph Graph viewer @param kernel_lookup The kernel lookup for the target execution provider @param tentative_nodes Nodes that are tentative to be placed on on target EP - @param requires_matching_kernel If no matching kernels are found, assumes that the kernel should be on the CPU */ std::unordered_set GetCpuPreferredNodes(const GraphViewer& graph, const IExecutionProvider::IKernelLookup& kernel_lookup, - gsl::span tentative_nodes, - bool requires_matching_kernel = true); + gsl::span tentative_nodes); } // namespace onnxruntime diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ExecutionProvider.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ExecutionProvider.cpp index b2681cd82f..09314c4db3 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ExecutionProvider.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/ExecutionProvider.cpp @@ -668,8 +668,21 @@ namespace Dml // downstream nodes consuming them. const std::vector& toplogicalOrder = graph.GetNodesInTopologicalOrder(); + std::vector tentativeNodes; + tentativeNodes.reserve(toplogicalOrder.size()); + + for (onnxruntime::NodeIndex nodeIndex : toplogicalOrder) + { + const onnxruntime::Node& node = *graph.GetNode(nodeIndex); + const auto* kernelInfo = kernel_lookup.LookUpKernel(node); + if (kernelInfo != nullptr) + { + tentativeNodes.push_back(nodeIndex); + } + } + // Get the list of nodes that should stay on the CPU - auto cpuPreferredNodes = GetCpuPreferredNodes(graph, kernel_lookup, toplogicalOrder, false); + auto cpuPreferredNodes = GetCpuPreferredNodes(graph, kernel_lookup, tentativeNodes); for (size_t nodeIndex : toplogicalOrder) {