Add Dos and Donts Section / Graph inputs

PiperOrigin-RevId: 509347658
This commit is contained in:
MediaPipe Team 2023-02-13 15:21:12 -08:00 committed by Copybara-Service
parent caa7d85141
commit ef9e5f881b

View File

@ -275,3 +275,69 @@ Tip: the same as for the `RunInference` function, extracting
`PassThroughNodeBuilder` and similar utility classes into dedicated modules
enables reuse in graph construction code and helps to automatically pull in the
corresponding calculator dependencies.
## Dos and Don'ts
### Define graph inputs at the very beginning if possible
```c++ {.bad}
Stream<D> RunSomething(Stream<A> a, Stream<B> b, Graph& graph) {
Stream<C> c = graph.In(2).SetName("c").Cast<C>(); // Bad.
// ...
}
CalculatorGraphConfig BuildGraph() {
Graph graph;
Stream<A> a = graph.In(0).SetName("a").Cast<A>();
// 10/100/N lines of code.
Stream<B> b = graph.In(1).SetName("b").Cast<B>() // Bad.
Stream<D> d = RunSomething(a, b, graph);
// ...
}
```
In the above code:
* It can be hard to guess how many inputs you have in the graph.
* Can be error prone overall and hard to maintain in future (e.g. is it a
correct index? name? what if some inputs are removed or made optional?
etc.).
Instead, simply define your graph inputs at the very beginning of your graph
builder:
```c++ {.good}
Stream<int> RunSomething(Stream<A> a, Stream<B> b, Stream<C> c, Graph& graph) {
// ...
}
CalculatorGraphConfig BuildGraph() {
Graph graph;
Stream<A> a = graph.In(0).SetName("a").Cast<A>();
Stream<B> b = graph.In(1).SetName("b").Cast<B>();
Stream<C> c = graph.In(2).SetName("c").Cast<C>();
// 10/100/N lines of code.
Stream<D> d = RunSomething(a, b, c, graph);
// ...
}
```
And if you have an input stream or side packet that is not always defined -
simply use `std::optional` and put it at the very beginning as well:
```c++ {.good}
std::optional<Stream<A>> a;
if (needs_a) {
a = graph.In(0).SetName(a).Cast<A>();
}
```
Note: of course, there can be exceptions - for example, there can be a use case
where calling `RunSomething1(..., graph)`, ..., `RunSomethingN(..., graph)` is
**intended to add new inputs**, so afterwards you can iterate over them and feed
only added inputs into the graph. However, in any case, try to make it easy for
readers to find out what graph inputs it has or may have.