Handler for structured fetches. Given a graph, a user-provided structure for fetches, and a feed dict, this class takes care of generating a list of tensor names to fetch and op names to run for a low level `run()` call. Given the results of the low level run call, this class can also rebu
| 449 | |
| 450 | |
| 451 | class _FetchHandler(object): |
| 452 | """Handler for structured fetches. |
| 453 | |
| 454 | Given a graph, a user-provided structure for fetches, and a feed dict, this |
| 455 | class takes care of generating a list of tensor names to fetch and op names |
| 456 | to run for a low level `run()` call. |
| 457 | |
| 458 | Given the results of the low level run call, this class can also rebuild a |
| 459 | result structure matching the user-provided structure for fetches, but |
| 460 | containing the corresponding results. |
| 461 | """ |
| 462 | |
| 463 | # TODO(touts): Make this class also take care of destructuring the feed |
| 464 | # dict instead of doing it in the callers. |
| 465 | |
| 466 | def __init__(self, graph, fetches, feeds, feed_handles=None): |
| 467 | """Creates a fetch handler. |
| 468 | |
| 469 | Args: |
| 470 | graph: Graph of the fetches. Used to check for fetchability and to |
| 471 | convert all fetches to tensors or ops as needed. |
| 472 | fetches: An arbitrary fetch structure: singleton, list, tuple, namedtuple, |
| 473 | or dict. |
| 474 | feeds: A feed dict where keys are Tensors. |
| 475 | feed_handles: A dict from feed Tensors to TensorHandle objects used as |
| 476 | direct feeds. |
| 477 | """ |
| 478 | with graph.as_default(): |
| 479 | self._fetch_mapper = _FetchMapper.for_fetch(fetches) |
| 480 | self._fetches = [] |
| 481 | self._targets = [] |
| 482 | self._feeds = feeds |
| 483 | self._feed_handles = ( |
| 484 | feed_handles or object_identity.ObjectIdentityDictionary()) |
| 485 | self._ops = [] |
| 486 | self._fetch_handles = object_identity.ObjectIdentityDictionary() |
| 487 | for fetch in self._fetch_mapper.unique_fetches(): |
| 488 | if isinstance(fetch, ops.Operation): |
| 489 | self._assert_fetchable(graph, fetch) |
| 490 | self._targets.append(fetch) |
| 491 | self._ops.append(True) |
| 492 | else: |
| 493 | self._assert_fetchable(graph, fetch.op) |
| 494 | self._fetches.append(fetch) |
| 495 | self._ops.append(False) |
| 496 | # Remember the fetch if it is for a tensor handle. |
| 497 | if (isinstance(fetch, ops.Tensor) and |
| 498 | (fetch.op.type == 'GetSessionHandle' or |
| 499 | fetch.op.type == 'GetSessionHandleV2')): |
| 500 | self._fetch_handles[fetch] = fetch.op.inputs[0].dtype |
| 501 | self._final_fetches = [x for x in self._fetches if x not in feeds] |
| 502 | |
| 503 | def _assert_fetchable(self, graph, op): |
| 504 | if not graph.is_fetchable(op): |
| 505 | raise errors.InaccessibleTensorError( |
| 506 | 'Operation %r has been marked as not fetchable. Typically this' |
| 507 | ' happens when it is defined in another function or code block.' |
| 508 | ' Use return values,explicit Python locals or TensorFlow collections' |
no outgoing calls
no test coverage detected