Find one path from `from_op` to `tensor`, ignoring `sources`. Args: from_op: A `tf.Operation`. tensor: A `tf.Operation` or `tf.Tensor`. sources: A list of `tf.Tensor`. Returns: A python string containing the path, or "??" if none is found.
(from_op, tensor, sources)
| 326 | |
| 327 | |
| 328 | def _path_from(from_op, tensor, sources): |
| 329 | """Find one path from `from_op` to `tensor`, ignoring `sources`. |
| 330 | |
| 331 | Args: |
| 332 | from_op: A `tf.Operation`. |
| 333 | tensor: A `tf.Operation` or `tf.Tensor`. |
| 334 | sources: A list of `tf.Tensor`. |
| 335 | |
| 336 | Returns: |
| 337 | A python string containing the path, or "??" if none is found. |
| 338 | """ |
| 339 | if isinstance(from_op, ops.Tensor): |
| 340 | from_op = from_op.op |
| 341 | |
| 342 | visited_ops = set([x.op for x in sources]) |
| 343 | ops_to_visit = [_as_operation(tensor)] |
| 344 | some_op_output = {} |
| 345 | while ops_to_visit: |
| 346 | op = ops_to_visit.pop() |
| 347 | if op in visited_ops: |
| 348 | continue |
| 349 | visited_ops.add(op) |
| 350 | if op == from_op: |
| 351 | path_op = op |
| 352 | path = [path_op] |
| 353 | final_op = _as_operation(tensor) |
| 354 | while path_op != final_op: |
| 355 | path_op = some_op_output[path_op] |
| 356 | path.append(path_op) |
| 357 | return " <- ".join(["%s (%s)" % (x.name, x.type) for x in reversed(path)]) |
| 358 | else: |
| 359 | for inp in graph_inputs(op): |
| 360 | if inp not in visited_ops and inp not in sources: |
| 361 | some_op_output[inp] = op |
| 362 | ops_to_visit.append(inp) |
| 363 | return "??" |
| 364 | |
| 365 | |
| 366 | # TODO(jmenick) - there is considerable duplication of functionality between |
no test coverage detected