Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions doc/design/csp.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,55 @@ The point here is that we need a consistent way to compose types, like in C++ we

### Select

In Go, the `select` statement lets a goroutine wait on multiple communication operations. A `select` blocks untill one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.

```go

ch1 := make(chan int)
ch2 := make(chan int, 100)

x := 0

for {
select {
case ch1 <- x:
x := x + 1
case y <- ch2:
fmt.Println("Received on channel")
default:
fmt.Println("Default")
}
}

```

In Fluid, we should be able to do the same:

```python
ch1 = fluid.make_chan(dtype=INT)
ch2 = fluid.make_chan(dtype=INT, 100)

sel = fluid.select()

with sel.case(ch1, 'w', X):
fluid.layers.increment(X)

with sel.case(ch2, 'r', Y):
fluid.print("Received on Channel")

with sel.default():
fluid.print("Default")

```

In the above code snippet, `X` and `Y` are variables. Now let us look at each of these statements one by one.

- `sel.case(ch1, 'w', X)` : This specifies that we are writing to `ch1` and we want to write the integer in variable `X` to the channel. The character `w` is used here to make the syntax familar to write syntax in Python I/O.

- `sel.case(ch2, 'r', Y)` : This specifies that we would like to read the result from `ch2` into variable `Y`. The character `r` is used here to make the syntax familar to read syntax in Python I/O.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative to consider: sel.case(ch1.recv(x)) and sel.case(ch2.send(Y)).

Copy link

@kavyasrinet kavyasrinet Jan 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My proposal is similar -- Defining the send and recv (write/read) for the Channel as @helinwang proposed above, or writing out send and recv as separate methods:

x = sel.case(fluid.recv(ch1)) sel.case(fluid.send(ch2, Y))

The methods can have the definition like:

void send(Channel* channel, Element* val) Element* recv(Channel* channel)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the C++ syntax should look like the one that you mentioned above. I am not sure how we would be able to implement sel.case(ch1.recv(x)) in python. This is because ch1.recv(x) can also be called in a standalone fashion, outside of select. I think this might depend on how we design the select operator in Paddle.

Copy link
Contributor

@helinwang helinwang Feb 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late reply!

I have not find recv design in this doc, but I think ch1.recv(x) should return a var, so it could work both in standalone and in select.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @helinwang 's proposal as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @helinwang as well. I am approving this PR so we could merge it, together with @kavyasrinet 's PR on send/recv syntax. Then, let us rethink about them.


- `sel.default()` : This is equivalent to the default in Go `select`. If none of the channels are ready for read or write, then the fluid code in the default block will be executed.

## Example Programs

### 1. RPC between Trainers and Parameter Servers
Expand Down