Add channel design document (#9463)
* Add channel design document * Update channel send/recv state diagramhelinwang-patch-1
parent
f5da16e51b
commit
241f3c988f
@ -0,0 +1,139 @@
|
||||
# Channel Design
|
||||
|
||||
## Introduction
|
||||
|
||||
A Channel is a data structure that allows for synchronous interprocess
|
||||
communication via message passing. It is a fundemental component of CSP
|
||||
(communicating sequential processes), and allows for users to pass data
|
||||
between threads without having to worry about synchronization.
|
||||
|
||||
## How to use it
|
||||
|
||||
Paddle offers python APIs to open and close channels, along with sending
|
||||
and receiving data to/from a channel.
|
||||
|
||||
### Create a channel
|
||||
|
||||
Creates a new channel that takes in variables of a specific dtype.
|
||||
|
||||
- **fluid.make_channel(dtype, capacity=0)**
|
||||
- **dtype**: The data type of variables being sent/received through channel
|
||||
- **capacity**: The capacity of the channel. A capacity of 0 represents
|
||||
an unbuffered channel. Capacity > 0 represents a buffered channel
|
||||
|
||||
```
|
||||
ch = fluid.make_channel(dtype=core.VarDesc.VarType.LOD_TENSOR, 10)
|
||||
```
|
||||
|
||||
### Close a channel
|
||||
|
||||
Closes a channel. Any pending senders and receivers will be awoken during
|
||||
this time. Receivers can still receive from a closed channel, but senders
|
||||
are not allowed to send any additional data to the channel (Paddle will
|
||||
raise an exception if users try to send to a closed channel.)
|
||||
|
||||
- **fluid.channel_close(channel)**
|
||||
|
||||
```
|
||||
fluid.channel_close(ch)
|
||||
```
|
||||
|
||||
### Send data to a channel
|
||||
|
||||
Sends a variable to a channel. Currently, variables of dtype `LoDTensor`,
|
||||
`LoDRankTable`, `LoDTensorArray`, `SelectedRows`, `ReaderHolder`, and
|
||||
`ChannelHolder` are supported.
|
||||
|
||||
By default, the data of the Variable is moved from the sender to the receiver,
|
||||
however the user can optionally copy the data before performing the send.
|
||||
|
||||
- **channel_send(channel, variable, is_copy=False)**
|
||||
- **channel**: The channel to send the variable to
|
||||
- **variable**: The variable to send to the channel
|
||||
- **is_copy**: If set to True, channel_send will perform a variable assign
|
||||
to copy the source variable to a new variable to be sent.
|
||||
|
||||
```
|
||||
ch = fluid.make_channel(dtype=core.VarDesc.VarType.LOD_TENSOR)
|
||||
var = fill_constant(shape=[1],dtype=core.VarDesc.VarType.INT32, value=100)
|
||||
fluid.channel_send(ch, var, True)
|
||||
```
|
||||
|
||||
### Receive data from a channel
|
||||
|
||||
Receives a variable from a channel. The data of the variable is moved to the
|
||||
receiving variable.
|
||||
|
||||
- **channel_recv(channel, return_variable)**
|
||||
- **channel**: The channel to receive the variable from
|
||||
- **return_variable**: The destination variable used to store the data of the
|
||||
variable received from the channel
|
||||
|
||||
```
|
||||
ch = fluid.make_channel(dtype=core.VarDesc.VarType.LOD_TENSOR)
|
||||
var = fill_constant(shape=[1],dtype=core.VarDesc.VarType.INT32, value=-1)
|
||||
fluid.channel_recv(ch, var)
|
||||
```
|
||||
|
||||
## How it Works
|
||||
|
||||
Channels provides a simple interface for different threads to share data.
|
||||
To support the synchronization requirements, channels utilizes a series of
|
||||
internal queues, locks, and conditional variables.
|
||||
|
||||
### QueueMessage
|
||||
|
||||
QueueMessage encapsulates the state of the channel send/receive operation to be
|
||||
put in the **sendq/recvq**. It contains a condition variable used to lock the
|
||||
thread (when there are no available sends/receives). In addition, it contains
|
||||
a callback function to notify a thread when the QueueMessage is being
|
||||
processed by the channel.
|
||||
|
||||
### Queues
|
||||
|
||||
- **buff_**: This queue holds the data buffer in a buffered channel. The
|
||||
capacity is set to the capacity of the channel. This data buffer is not
|
||||
used in an unbuffered channel.
|
||||
|
||||
- **sendq**: This queue holds the QueueMessage of any pending senders of a
|
||||
channel. When a thread performs a channel_send operation on the channel, the
|
||||
channel_send operation will put a new QueueMessage on the sendq and block the
|
||||
current thread under two conditions:
|
||||
1. The channel is buffered and is full
|
||||
2. The channel is unbuffered and does not have a receiver
|
||||
|
||||
- **recvq**: This queue holds the QueueMessage of any pending receivers of a
|
||||
channel. When a thread performs a channel_recv operation on the channel, the
|
||||
channel_recv operation will put a new QueueMessage on the recvq and block the
|
||||
current thread under two conditions:
|
||||
1. The channel is buffered and there is no data on the buff_
|
||||
2. The channel is unbuffered and does not have a sender
|
||||
|
||||
### State diagram
|
||||
|
||||
#### Channel Send
|
||||
|
||||
<p align="center">
|
||||
<img src="./images/channel_send.png"/><br/>
|
||||
</p>
|
||||
|
||||
#### Channel Receive
|
||||
|
||||
<p align="center">
|
||||
<img src="./images/channel_recv.png"/><br/>
|
||||
</p>
|
||||
|
||||
## Limitations and Considerations
|
||||
|
||||
### Variable Copy
|
||||
|
||||
In golang, variables in channels are copied from the sender to the receiver.
|
||||
In Paddle, the data from our variables are **moved** from sender to receiver.
|
||||
As a result, these variables should not be used after they are sent. We
|
||||
provide a flag in channel_send method to allow users to copy the variable to
|
||||
be sent before it is sent.
|
||||
|
||||
Please note that this is acheived by adding an **assign** operator and creating
|
||||
a temporary variable that is sent in place of the original variable. Please
|
||||
note that **assign** operator has limited support for only certain variables
|
||||
datatypes.
|
After Width: | Height: | Size: 133 KiB |
After Width: | Height: | Size: 84 KiB |
Loading…
Reference in new issue