Permalink
Browse files

Removed the sends/recvs compiler error FAQ entry

Now that we support sends/recvs!
  • Loading branch information...
mhong committed Aug 16, 2018
1 parent c9bf192 commit 7dc7f2f9e6475a08340baa50869c43074401e79e
Showing with 0 additions and 89 deletions.
  1. +0 −89 FAQ.md
View
89 FAQ.md
@@ -6,7 +6,6 @@ encountered and prefer not to get new issues filed in our bug tracker.
* [Why Swift?](#why-swift)
* [Why do I get "error: array input is not a constant array of tensors"?](#why-do-i-get-error-array-input-is-not-a-constant-array-of-tensors)
* [Why do I get "error: internal error generating TensorFlow graph: GraphGen cannot lower a 'send/receive' to the host yet"](#why-do-i-get-error-internal-error-generating-tensorflow-graph-graphgen-cannot-lower-a-sendreceive-to-the-host-yet)
* [How can I use Python 3 with the Python module?](#how-can-i-use-python-3-with-the-python-module)
* [\[Mac\] I wrote some code in an Xcode Playground. Why is it frozen/hanging?](https://github.com/tensorflow/swift/blob/master/FAQ.md#mac-i-wrote-some-code-in-a-xcode-playground-why-is-it-frozenhanging)
@@ -37,94 +36,6 @@ Here's how to enable optimizations in different environments:
* You may also need to add `libtensorflow.so` and `libtensorflow_framework.so` to `Linked Frameworks and Libraries` and change `Runtime Search Paths`.
See [this comment](https://github.com/tensorflow/swift/issues/10#issuecomment-385167803) for specific instructions with screenshots.
## Why do I get ["error: internal error generating TensorFlow graph: GraphGen cannot lower a 'send/receive' to the host yet"](https://github.com/tensorflow/swift/issues/8)?
### Context
In Swift for Tensorflow, a Swift program is executed between the "host" (Swift binary) and the "device" (TensorFlow).
During program compilation, the compiler finds all of the `Tensor`-related code, extracts it and builds a TensorFlow graph to be run on the device.
The compiler tries to inline as much tensor related code into one "unit of Graph Program Extraction (GPE)" as possible. This is for performance reason -- a larger TensorFlow graph is expected to be more efficient for execution.
In some cases, the extracted tensor computation has some interleaving host logic, in which case the compiler adds "send" or "receive" nodes in the TensorFlow graph for tensor communication between host and device.
Send/receive aren't fully implemented, which explains why you got your error. The core team is working on it as a high-priority feature. Once send/receive are done, this error should go away!
For more context, please read about the [graph program extraction algorithm](https://github.com/tensorflow/swift/blob/master/docs/GraphProgramExtraction.md),
in particular about [host-graph communication](https://github.com/tensorflow/swift/blob/master/docs/GraphProgramExtraction.md#adding-hostgraph-communication).
### Example 1
```swift
import TensorFlow
var x = Tensor<Float>([[1, 2], [3, 4]])
print(x)
x = x + 1
```
In this case, the `Tensor` code to-be-extracted are lines 2 and 4 (the calculations and assign/update to `x`).
However, notice line 3: it's a call to the `print` function (which must be run on the host), and it requires the value of `x` (which is computed on the device). It's also not the last computation run in the graph (which is line 4).
As such, the compiler adds a "send" node in the TensorFlow graph to send a copy of the initial `x` to the host for printing.
To work around the generated "send" for this particular example, you can reorder the code:
```swift
import TensorFlow
var x = Tensor<Float>([[1, 2], [3, 4]])
x = x + 1
print(x)
```
The `Tensor` code is no longer "interrupted" by host code so "send" is not
generated.
### Example 2
Say you have the following top-level code, where `foo` and `bar` are functions
that return some `Tensor` value:
```swift
print(foo())
print(bar())
```
The code is equivalent to:
```swift
let x = foo()
print(x)
let y = bar()
print(y)
```
The `print(x)` above interrupts the `Tensor` code (calls to `foo()` and
`bar()`), causing a "send" to be generated.
One workaround (as mentioned above) is to refactor the code and bring the
`Tensor` code together (e.g. move `print(x)` downward).
Another workaround is to mark `foo()` and `bar()` as `@inline(never)`, e.g.
```swift
@inline(never)
public func bar() -> Tensor<Double> {
return ... // returns some `Tensor` value
}
```
This will prevent the body of `bar()` from being inlined into the body of
`main()` when compiler processes `main()`. This will cause compiler to generate
separate TF graphs for `foo()` and `bar()`.
**Note**: Given that our implementation will change a lot in the coming months,
marking functions with `@inline(never)` is the most pragmatic and reliable
workaround.
We recommend separating functions that do tensor computation from host code in
your programs. Those functions should be marked as `@inline(never)` (and have
`public` access, to be safe). Within those functions, tensor computation should
not be interrupted by host code. This ensures that the arguments and results of
the extracted tensor program will be values on the host, as expected.
## How can I use Python 3 with the `Python` module?
Currently, Swift is hard-coded to use Python 2.7.

1 comment on commit 7dc7f2f

@rxwei

This comment has been minimized.

Show comment
Hide comment
@rxwei

rxwei Aug 16, 2018

Member

Yay!

Member

rxwei commented on 7dc7f2f Aug 16, 2018

Yay!

Please sign in to comment.