plafer / Tissue.jl

Framework for building computational graphs that process any real time data source.
https://plafer.github.io/Tissue.jl/stable/
MIT License
2 stars 1 forks source link

Introduce a subgraph construct #11

Open plafer opened 3 years ago

plafer commented 3 years ago

It would be nice to be able to define a subgraph to be used as just another node in graphs, similar to how they do it in mediapipe. However, in mediapipe, a subgraph and a graph have the same interface. We'll need to make them different because we don't expose input and output streams coming in/out of graphs.

The idea would be that you can define a subgraph with a similar language to @graph, and be able to use it just as you'd use any other calculator. close(MySubgraph) calls close(calculator) on all the calculators in the subgraph. Similarly with open(calculator) (#10) when we have it.

Defining a subgraph would look like:

using Tissue

struct DinkyCalculator end
Tissue.process(c::DinkyCalculator, input_stream) = 42

struct MergerCalculator end
Tissue.process(c::MergerCalculator, in1, in2) = in1 + in2

@subgraph MySubgraph begin
    @inputstreams subgraph_input1, subgraph_input2

    @calculator c1 = DinkyCalculator()
    @calculator c2 = DinkyCalculator()
    @calculator c3 = MergerCalculator()

    @bindstreams c1 (input_stream = subgraph_input1)
    @bindstreams c2 (input_stream = subgraph_input2)
    @bindstreams c3 (in1 = c1) (in2 = c2)

    # Sets the output stream of MySubgraph as the output stream of c3
    @outputstream c3
end

Using that subgraph in a graph would look like:

using Tissue

struct SourceCalculator end
Tissue.process(c::SourceCalculator) = 42

struct PassthroughCalculator end
Tissue.process(c::PassthroughCalculator, input) = input

@graph MyGraph begin
    @calculator source = SourceCalculator()
    @calculator p1 = PassthroughCalculator()
    @calculator p2 = PassthroughCalculator()
    @calculator subgraph = MySubgraph()

    @bindstreams p1 (input = source)
    @bindstreams p2 (input = source)
    @bindstreams subgraph (subgraph_input1 = p1) (subgraph_input2 = p2)
end

After graphs are parameterized (#4), we can reuse that same idea with subgraphs to allow parameters to be passed down to internal calculators.