| 33 | namespace grappler { |
| 34 | |
| 35 | struct NodeState { |
| 36 | // A node (i.e., an op) takes a set of input:port pairs and produces |
| 37 | // a set of output ports. |
| 38 | |
| 39 | // Cross references to input and output nodes from graphdef. |
| 40 | std::vector<std::pair<const NodeDef*, int>> inputs; // Input, port pairs. |
| 41 | // List of output nodes (a list of nodes that takes this output port as input) |
| 42 | // keyed by port_num. Note that port_num -1 is used for control dependency. |
| 43 | std::unordered_map<int, std::vector<const NodeDef*>> outputs; |
| 44 | |
| 45 | // Info from GraphProperties. |
| 46 | std::vector<OpInfo::TensorProperties> input_properties; |
| 47 | std::vector<OpInfo::TensorProperties> output_properties; |
| 48 | |
| 49 | // Canonical device name used within VirtualScheduler. |
| 50 | string device_name; |
| 51 | |
| 52 | // States updated as scheduling nodes. |
| 53 | int num_inputs_ready; |
| 54 | std::unordered_map<int, int> num_outputs_executed; |
| 55 | Costs::Duration time_ready; |
| 56 | Costs::Duration time_scheduled; |
| 57 | Costs::Duration time_finished; |
| 58 | // Time that all the consumers are executed (hence, no need to keep this |
| 59 | // output in memory), keyed by port_num. |
| 60 | std::unordered_map<int, Costs::Duration> time_no_references; |
| 61 | |
| 62 | // Note that a node may have multiple output ports. The length of outputs, |
| 63 | // num_outputs_executed, and time_no_references should be |
| 64 | // identical when a NodeState is fully initialized. |
| 65 | // They should be 1 + output_properties.size() as we add [-1] for control |
| 66 | // dependency. |
| 67 | |
| 68 | // Node will be ready to be executed at time_ready, scheduled at |
| 69 | // time_scheduled, and finishes execution at time_finished. |
| 70 | // Each output port uses up memory space from time_scheduled to its |
| 71 | // time_no_references. |
| 72 | |
| 73 | // How many times this node has been executed, e.g. in a while loop. |
| 74 | int execution_count; |
| 75 | |
| 76 | // Output shape incompatible between shape annotation and shape inference. |
| 77 | bool shape_incompatible; |
| 78 | |
| 79 | NodeState() { |
| 80 | num_inputs_ready = 0; |
| 81 | time_ready = Costs::Duration::max(); |
| 82 | time_scheduled = Costs::Duration::max(); |
| 83 | time_finished = Costs::Duration::max(); |
| 84 | execution_count = 0; |
| 85 | shape_incompatible = false; |
| 86 | // Note that num_outputs_executed and time_no_references are not initialized |
| 87 | // here, since we don't know the size (i.e., # outputs for this node). |
| 88 | } |
| 89 | }; |
| 90 | |
| 91 | struct DeviceState { |
| 92 | // Nodes executed on this device in execution order. |
no outgoing calls