Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Pipeline filter: Style

Sensei_S_
Beginner
369 Views

Dear all,

I have a simple pipeline that should be constructed invoking some class methods. This is done because I'm using those methods serially for debugging purposes, but the style I'm using is horrible: having lambda wrappers:

    auto readerfn = [&](tbb::flow_control &flow)
    {
        return reader(flow);
    };
    
    auto correctorfn = [&](std::string s)
    {
        return corrector(s);
    };
    
    auto writerfn = [&](bool b)
    {
        writer(b);
    };
    
    // Start the pipeline
    tbb::parallel_pipeline(tokens,
                           tbb::make_filter<void, std::string>(tbb::filter::serial, readerfn) &
                           tbb::make_filter<std::string, bool>(tbb::filter::parallel, correctorfn) &
                           tbb::make_filter<bool, void>(tbb::filter::serial, writerfn));

Can you suggest a more acceptable way of making this thing work serially (not using the pipeline), and in parallel?

Thanks & Cheers!

0 Kudos
5 Replies
RafSchietekat
Valued Contributor III
369 Views

This seems even more complicated than the example in the Reference Manual, which doesn't use separate variables for the lambdas, so I'm not sure what you mean...

0 Kudos
Sensei_S_
Beginner
369 Views

Well, I'd like to avoid using those lambdas in that way: it's ugly :)

I already developed the serial code (methods in a class), and using the code in a pipeline isn't that cute.

0 Kudos
MLema2
New Contributor I
369 Views

Personnally, I like my pipelines to look this way:

 
// Start the pipeline
tbb::parallel_pipeline(
    tokens,
    tbb::make_filter<void, std::string>(
        tbb::filter::serial,
        [&](tbb::flow_control &flow) {
            return reader(flow);
        }) &
    tbb::make_filter<std::string, bool>(
        tbb::filter::parallel,
        [&](std::string s) {
            return corrector(s);
        }) &
    tbb::make_filter<bool, void>(
        tbb::filter::serial,
        [&](bool b) {
            writer(b);
        })
    );

 

0 Kudos
RafSchietekat
Valued Contributor III
369 Views

You could whip up a macro to factor out the commonalities.

You could use "std::bind(&MyClass::reader, this, _1)" if you like that better than "[&] (tbb::flow_control &flow) { return reader(flow); }".

You could write a function template make_filter_from_functor() that determines the argument and result types of the functor and do "make_filter_from_functor(tbb::filter::serial, [&] (tbb::flow_control &flow) { return reader(flow); })". Have a look at boost::function_traits or somesuch. I wouldn't mind if TBB emulated that.

You could write a function template make_filter_from_memfn() combining ideas from the previous two and do "make_filter_from_memfn(tbb::filter::serial, &MyClass::reader, this)".

(2014-07-06 Edited) Replaced (non-technical) uses of "capture"(s) with "factor out" and "determines" to avoid confusion with lambda captures.

0 Kudos
Sensei_S_
Beginner
369 Views

Thanks for all your comments!

0 Kudos
Reply