From a86d439070c130cb40f049b69090fc3c72b4f146 Mon Sep 17 00:00:00 2001 From: Derek Murray Date: Fri, 7 Jul 2017 08:20:48 -0700 Subject: [PATCH] Edits to "Threading and Queues" section of programmers guide. PiperOrigin-RevId: 161203568 --- .../programmers_guide/threading_and_queues.md | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/tensorflow/docs_src/programmers_guide/threading_and_queues.md b/tensorflow/docs_src/programmers_guide/threading_and_queues.md index 7d3edb788e0..7f3e6f0da5e 100644 --- a/tensorflow/docs_src/programmers_guide/threading_and_queues.md +++ b/tensorflow/docs_src/programmers_guide/threading_and_queues.md @@ -1,28 +1,44 @@ # Threading and Queues -Queues are a powerful mechanism for asynchronous computation using TensorFlow. +Note: In versions of TensorFlow before 1.2, we recommended using multi-threaded, +queue-based input pipelines for performance. Beginning with TensorFlow 1.2, +however, we recommend using the `tf.contrib.data` module instead. (See +[Datasets](datasets) for details.) The `tf.contrib.data` module offers an +easier-to-use interface for constructing efficient input pipelines. Furthermore, +we've stopped developing the old multi-threaded, queue-based input pipelines. +We've retained the documentation in this file to help developers who are still +maintaining older code. -Like everything in TensorFlow, a queue is a node in a TensorFlow graph. It's a -stateful node, like a variable: other nodes can modify its content. In -particular, nodes can enqueue new items in to the queue, or dequeue existing -items from the queue. +Multithreaded queues are a powerful and widely used mechanism supporting +asynchronous computation. -To get a feel for queues, let's consider a simple example. We will create a -"first in, first out" queue (`FIFOQueue`) and fill it with zeros. -Then we'll construct a graph -that takes an item off the queue, adds one to that item, and puts it back on the -end of the queue. Slowly, the numbers on the queue increase. +Following the [dataflow programming model](graphs.md), TensorFlow's queues are +implemented using nodes in the computation graph. A queue is a stateful node, +like a variable: other nodes can modify its content. In particular, nodes can +enqueue new items in to the queue, or dequeue existing items from the +queue. TensorFlow's queues provide a way to coordinate multiple steps of a +computation: a queue will **block** any step that attempts to dequeue from it +when it is empty, or enqueue to it when it is full. When that condition no +longer holds, the queue will unblock the step and allow execution to proceed. + +TensorFlow implements several classes of queue. The principal difference between +these classes is the order that items are removed from the queue. To get a feel +for queues, let's consider a simple example. We will create a "first in, first +out" queue (@{tf.FIFOQueue}) and fill it with zeros. Then we'll construct a +graph that takes an item off the queue, adds one to that item, and puts it back +on the end of the queue. Slowly, the numbers on the queue increase.
`Enqueue`, `EnqueueMany`, and `Dequeue` are special nodes. They take a pointer -to the queue instead of a normal value, allowing them to change it. We recommend -you think of these as being like methods of the queue. In fact, in the Python -API, they are methods of the queue object (e.g. `q.enqueue(...)`). +to the queue instead of a normal value, allowing them to mutate its state. We +recommend that you think of these operations as being like methods of the queue +in an object-oriented sense. In fact, in the Python API, these operations are +created by calling methods on a queue object (e.g. `q.enqueue(...)`). -**N.B.** Queue methods (such as `q.enqueue(...)`) *must* run on the same device +Note: Queue methods (such as `q.enqueue(...)`) *must* run on the same device as the queue. Incompatible device placement directives will be ignored when creating these operations. @@ -32,13 +48,13 @@ Now that you have a bit of a feel for queues, let's dive into the details... Queues, such as @{tf.FIFOQueue} and @{tf.RandomShuffleQueue}, -are important TensorFlow objects for computing tensors asynchronously in a -graph. +are important TensorFlow objects that aid in computing tensors asynchronously +in a graph. -For example, a typical input architecture is to use a `RandomShuffleQueue` to +For example, a typical input pipeline uses a `RandomShuffleQueue` to prepare inputs for training a model: -* Multiple threads prepare training examples and push them in the queue. +* Multiple threads prepare training examples and enqueue them in the queue. * A training thread executes a training op that dequeues mini-batches from the queue @@ -46,7 +62,8 @@ This architecture has many benefits, as highlighted in the @{$reading_data$Reading data how to}, which also gives an overview of functions that simplify the construction of input pipelines. -The TensorFlow `Session` object is multithreaded, so multiple threads can +The TensorFlow `Session` object is multithreaded and thread-safe, so multiple +threads can easily use the same session and run ops in parallel. However, it is not always easy to implement a Python program that drives threads as described above. All threads must be able to stop together, exceptions must be caught and @@ -62,11 +79,12 @@ enqueue tensors in the same queue. ## Coordinator -The `Coordinator` class helps multiple threads stop together. +The @{tf.train.Coordinator} class manages background threads in a TensorFlow +program and helps multiple threads stop together. Its key methods are: -* @{tf.train.Coordinator.should_stop}: returns True if the threads should stop. +* @{tf.train.Coordinator.should_stop}: returns `True` if the threads should stop. * @{tf.train.Coordinator.request_stop}: requests that threads should stop. * @{tf.train.Coordinator.join}: waits until the specified threads have stopped. @@ -105,10 +123,10 @@ also has support to capture and report exceptions. See the @{tf.train.Coordinat ## QueueRunner -The `QueueRunner` class creates a number of threads that repeatedly run an -enqueue op. These threads can use a coordinator to stop together. In -addition, a queue runner runs a *closer thread* that automatically closes the -queue if an exception is reported to the coordinator. +The @{tf.train.QueueRunner} class creates a number of threads that repeatedly +run an enqueue op. These threads can use a coordinator to stop together. In +addition, a queue runner will run a *closer operation* that closes the queue if +an exception is reported to the coordinator. You can use a queue runner to implement the architecture described above.