(
inputs: NamedTensorMap, outputs: Node[], weightMap: NamedTensorsMap,
initNodes?: Node[])
| 39 | * - Alternative inputs in order to avoid async (dynamic op) execution. |
| 40 | */ |
| 41 | export function getExecutionSubgraph( |
| 42 | inputs: NamedTensorMap, outputs: Node[], weightMap: NamedTensorsMap, |
| 43 | initNodes?: Node[]): ExecutionInfo { |
| 44 | const usedNodes = new Set<string>(); |
| 45 | const missingInputs: string[] = []; |
| 46 | let dynamicNode: Node = null; |
| 47 | let syncInputs: string[] = null; |
| 48 | |
| 49 | // Start with the outputs, going backwards and find all the nodes that are |
| 50 | // needed to compute those outputs. |
| 51 | const seen = new Set<string>(); |
| 52 | const inputNodeNames = |
| 53 | new Set(Object.keys(inputs).map((name) => parseNodeName(name)[0])); |
| 54 | |
| 55 | initNodes = initNodes || []; |
| 56 | const initNodeNames = |
| 57 | new Set(initNodes.map((node) => parseNodeName(node.name)[0])); |
| 58 | |
| 59 | const frontier = [...outputs]; |
| 60 | while (frontier.length > 0) { |
| 61 | const node = frontier.pop(); |
| 62 | if (isControlFlow(node) || isDynamicShape(node) || isHashTable(node)) { |
| 63 | if (dynamicNode == null) { |
| 64 | dynamicNode = node; |
| 65 | syncInputs = dynamicNode.children.map(child => child.name) |
| 66 | .filter(name => usedNodes.has(name)); |
| 67 | } |
| 68 | } |
| 69 | usedNodes.add(node.name); |
| 70 | |
| 71 | // Weights are dead end since we already have their values. |
| 72 | if (weightMap[node.name] != null) { |
| 73 | continue; |
| 74 | } |
| 75 | // This node is a dead end since it's one of the user-provided inputs. |
| 76 | if (inputNodeNames.has(node.name)) { |
| 77 | continue; |
| 78 | } |
| 79 | // This node is a dead end since it doesn't have any inputs. |
| 80 | if (initNodeNames.has(node.name)) { |
| 81 | continue; |
| 82 | } |
| 83 | if (node.inputs.length === 0) { |
| 84 | missingInputs.push(node.name); |
| 85 | continue; |
| 86 | } |
| 87 | node.inputs.forEach(input => { |
| 88 | // Don't add to the frontier if it is already there. |
| 89 | if (seen.has(input.name)) { |
| 90 | return; |
| 91 | } |
| 92 | seen.add(input.name); |
| 93 | frontier.push(input); |
| 94 | }); |
| 95 | } |
| 96 | return {inputs, outputs, usedNodes, missingInputs, dynamicNode, syncInputs}; |
| 97 | } |
| 98 |
no test coverage detected
searching dependent graphs…