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

threading building block graph example from reference manual not compiling

gajendra_g_
Beginner
504 Views

This is yet another example from the reference manual  of that i am trying to compile but it spawns error that I cannot understand.

Here's the code:

#include <cstdio>
#include <iostream>
#include "tbb/flow_graph.h"

using namespace tbb::flow;

struct  square
{
    int operator()(int v) {return v*v;}
};

struct cube
{
    int operator()(int v) {return v*v*v;}
};

class sum
{
    private:
        int &m_sum;

    public:
        sum(int &usrSum) : m_sum(usrSum) {}

        int operator()(std::tuple<int, int> v)
        {
            m_sum += std::get<0>(v) + std::get<1>(v);
            return m_sum;
        }
};

int main()
{
    int result = 0;
    graph g;

    broadcast_node<int> input(g);
    function_node<int,int> squarer(g, unlimited, square());
    function_node<int,int> cuber(g, unlimited, cube());
    join_node<std::tuple<int,int>, queueing> join(g);
    function_node<std::tuple<int, int>,int> summer(g, serial, sum(result));

    make_edge( input, squarer );
    make_edge( input, cuber );
    make_edge(squarer, std::get<0>(join.inputs() ) );
    make_edge(cuber, std::get<1>(join.inputs() ) );
    make_edge(join, summer);

    for(int i=1; i<=10; ++i);
    {
        input.try_put(i);
    }

    g.wait_for_all();

    std::cout << "Final result is: " << result <<"\n";

    return 0;
}

 

The error spawned is :

/2_summer.cpp: In function ‘int main()’:
./2_summer.cpp:45:41: error: ‘class tbb::flow::interface8::join_node<std::tuple<int, int>, tbb::flow::interface8::internal::graph_policy_namespace::queueing>’ has no member named ‘inputs’
     make_edge(squarer, std::get<0>(join.inputs() ) );
                                         ^
./2_summer.cpp:46:39: error: ‘class tbb::flow::interface8::join_node<std::tuple<int, int>, tbb::flow::interface8::internal::graph_policy_namespace::queueing>’ has no member named ‘inputs’
     make_edge(cuber, std::get<1>(join.inputs() ) );
                                       ^
./2_summer.cpp:51:23: error: ‘i’ was not declared in this scope
         input.try_put(i);
                       ^

 

especially very confounding is the last error : "i was not declared in this scope", when i is the loop iteration index which has been clearly declared.

 

Thanks in advance

0 Kudos
5 Replies
gajendra_g_
Beginner
504 Views

I made a modification to the code (line 45 and line 46) above by calling join.input_ports() instead of join.inputs() (which according to the compiler is not defined)

This code compiles but when i try to run it with a trivial value of i = 1 it gives me a wrong answer. The summer sums i2 + i3 and prints the value. for i = 1 the sum should be 2 but i get result 12.

I am not entirely sure if input_ports() is the right function to be called here on the object join_node. Would be great to have a clarification

#include <cstdio>
#include <iostream>
#include "tbb/flow_graph.h"

using namespace tbb::flow;

struct  square
{
    int operator()(int v) {return v*v;}
};

struct cube
{
    int operator()(int v) {return v*v*v;}
};

class sum
{
    private:
        int &m_sum;

    public:
        sum(int &usrSum) : m_sum(usrSum) {}

        int operator()(std::tuple<int, int> v)
        {
            m_sum += std::get<0>(v) + std::get<1>(v);
            return m_sum;
        }
};

int main()
{
    int result = 0;
    graph g;

    broadcast_node<int> input(g);
    function_node<int,int> squarer(g, unlimited, square());
    function_node<int,int> cuber(g, unlimited, cube());
    join_node<std::tuple<int,int>, queueing> join(g);
    function_node<std::tuple<int, int>,int> summer(g, serial, sum(result));

    make_edge( input, squarer );
    make_edge( input, cuber );
    make_edge(squarer, std::get<0>(join.input_ports() ) ); //changed
    make_edge(cuber, std::get<1>(join.input_ports() ) ); //changed
    make_edge(join, summer);
    
    int end;
    int j=1;
    std::cout << "Enter the number of terms for the graph: ";
    std::cin >> end;
    
    for(j; j<=end; j++);
    {
        input.try_put(j);
    }

    g.wait_for_all();

    std::cout << "Final result is: " << result <<"\n";

    return 0;
}

Thanks in advance

Gajendra

0 Kudos
Alexei_K_Intel
Employee
504 Views

Hi Gajendra,

Where is the example taken from? The latest documentation contains a correct version.

As for 12, I suppose it is caused by a surplus semi-column on line 54. I.e. try_put on line 56 is called out of the loop scope. It means that the initial value of j is incremented until it exceeds the value of end. If the input value for end is 1 then the loop finishes when j==2. And the graph is called with 2, i.e. result = 22+23 = 4 + 8 = 12.

Regards,
Alex

0 Kudos
gajendra_g_
Beginner
504 Views

Hi Alex,

Thanks for pointing out the mistake. I took the example from an older version of tbb reference manual and was of the impression that input_ports( ) might be causing the issue.. haha

Best

Gajendra

0 Kudos
gajendra_g_
Beginner
504 Views

Hi Alex, Can you please tell me your full name?

I am actually doing a presentation on TBB for my seminar at the University and would like to give you the credits for the support :)

 

Best

Gajendra

0 Kudos
Alexei_K_Intel
Employee
504 Views

I suppose the product support forum is not appropriate place for your question. If possible, please, contact us by e-mail: TBBDevelopers@intel.com.

Regards,
Alex
 

0 Kudos
Reply