2463 Discussions

## Implementing a Synchronous DataFlow Graph using Intel Flow Graph

Beginner
258 Views

Hello,

I started investigating Intel TBB recently and was thinking of the possibility of implementing an application specified as a Synchronous DataFlow Graph using function and queue nodes. I seems to me doable in a straightforward manner. Could someone confirm? Any thoughts?

4 Replies
Employee
258 Views

Hi Salah,

It seems doable overall. In Flow Graph generally, for one message (set of tokens) that is produced, there is one message (same set of tokens) that is consumed, but it can be customized with nodes like queue and buffer node.
Could you, please, tell exactly what problem are you solving? Maybe we can help.

Thanks,

Nikita

Beginner
258 Views

Hello Nikita,

Thank you for your reply. I am working on a numerical simulation code. I have a physical system described by ODEs (Ordinary Differential Equations). These equations are provided in the form of DLLs and the source code is not available. Information about dependencies between the different functions of the DLLs is also provided. As such, I am able to construct the dependency graph of the code. I am now investigating different possible solutions to parallelize this code. I've already tried some approaches and currently am interested in using Intel TBB flow graph.

An important feature of this application is that for a pair of dependent functions, one function may execute several times against one execution of the other function. This is why I find it interesting to model such an application using Synchronous DataFlow Graphs, where such feature can be modeled by different amounts of produced and consumed tokens.

To give an example,  consider the following flow graph with two functional nodes and one queue node:

|f1(x)|---->||||||---->|f2(x)|

Here, f1(x) must be executed once to produce 5 pieces of data, than f2(x) is executed 5 times consuming one item at a time.

Salah

Employee
258 Views

You can use multifunction_node here, that acts as a splitter of your tokens producer:

```con int tokens_to_consume = 5;
tbb::flow::source_node< std::vector<int> > tokens_producer(g, [](std::vector<int>& tokens) -> bool {
if (!endOfTokensGenerator()) {
genereateTokens(tokens);
return true;
}
return false;
});

typedef multifunction_node < std::vector<int>, std::tuple< std::vector<int> > > multinode;
multinode tokens_splitter( g, tbb::flow::serial, [&tokens_to_consume]( const std::vector<int>& tokens, multinode::output_ports_type& op ) {
for (int i = 0; i < tokens_to_consume; )
std::get<0>( op ).try_put( tokens );
});

tbb::flow::function_node< std::vector<int> > tokens_consumer(g, tbb::flow::unlimited, [](const std::vector<int>& tokens) {
consume(tokens);
});

make_edge(tokens_producer, tokens_splitter);
make_edge(output_port<0>(tokens_splitter), tokens_consumer);```

Beginner
258 Views

Thank you Nikita. I have been trying to wrok around another solution using continue messages. Not working so far. I will give your suggestion a try.

Salah