MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / BuildLoopBody

Function BuildLoopBody

tensorflow/compiler/tf2xla/functionalize_while.cc:157–211  ·  view source on GitHub ↗

Builds a graph for the loop body.

Source from the content-addressed store, hash-verified

155
156// Builds a graph for the loop body.
157Status BuildLoopBody(const Graph& graph, WhileLoopFrame* frame,
158 DataTypeVector* arg_types,
159 std::unique_ptr<Graph>* body_output) {
160 VLOG(2) << "Building loop body for " << frame->name;
161 *body_output = absl::make_unique<Graph>(graph.op_registry());
162 Graph* output = body_output->get();
163
164 // Map from nodes in the original graph to the condition graph.
165 std::vector<Node*> node_map(graph.num_node_ids(), nullptr);
166 std::vector<bool> squash_src_outputs(graph.num_node_ids(), false);
167
168 // Build one _Arg node for each Enter node.
169 std::vector<Node*> next_iterations;
170 next_iterations.reserve(frame->args.size());
171 arg_types->reserve(frame->args.size());
172 for (int i = 0; i < frame->args.size(); ++i) {
173 const WhileLoopArg& arg = frame->args[i];
174
175 DataType dtype = arg.enter->input_type(0);
176 arg_types->push_back(dtype);
177
178 TF_ASSIGN_OR_RETURN(Node * arg_node, BuildArgNode(output, dtype, i));
179 TF_ASSIGN_OR_RETURN(Node * retval_node, BuildRetvalNode(output, dtype, i));
180 if (arg.is_loop_invariant) {
181 // Argument is loop-invariant. Forward it from the Arg to the Retval.
182 node_map[arg.enter->id()] = arg_node;
183 output->AddEdge(arg_node, 0, retval_node, 0);
184 } else {
185 // Argument is loop-varying.
186 if (dtype == DT_RESOURCE) {
187 // DT_RESOURCE arguments should always be loop-invariant in the graphs
188 // generated from TF.
189 return errors::Unimplemented("Loop-varying DT_RESOURCE Enter node ",
190 arg.enter->name(), " is currently not",
191 " supported.");
192 }
193 node_map[arg.switch_node->id()] = arg_node;
194 // The Switch node has two outputs, but _Arg only has one. This tells
195 // the CopySubgraph function to rewrite the output number of edges from
196 // the _Arg node to be 0 rather than copying the output number from the
197 // Switch node.
198 squash_src_outputs[arg.switch_node->id()] = true;
199 node_map[arg.next_iteration->id()] = retval_node;
200 next_iterations.push_back(arg.next_iteration);
201 }
202 }
203
204 // Performs a reverse DFS, copying nodes and edges to the output graph.
205 // The _Arg and _Retval nodes were added unconditionally above, so we are
206 // guaranteed to get the correct function signature.
207 TF_RETURN_IF_ERROR(CopySubgraph(graph, frame, std::move(next_iterations),
208 squash_src_outputs, &node_map, output));
209
210 return Status::OK();
211}
212
213// Copy the FunctionDef of given function from lookup_library to library, if
214// it can be found in lookup_library but is missing from library.

Callers 1

FunctionalizeLoopFunction · 0.85

Calls 15

BuildArgNodeFunction · 0.85
BuildRetvalNodeFunction · 0.85
UnimplementedFunction · 0.85
CopySubgraphFunction · 0.85
nameMethod · 0.65
TF_ASSIGN_OR_RETURNFunction · 0.50
op_registryMethod · 0.45
getMethod · 0.45
num_node_idsMethod · 0.45
reserveMethod · 0.45
sizeMethod · 0.45
input_typeMethod · 0.45

Tested by

no test coverage detected