Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
Announcements
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.
2448 Discussions

threading building block graph example from reference manual not compiling

gajendra_g_
Beginner
314 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
314 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

Alexei_K_Intel
Employee
314 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

gajendra_g_
Beginner
314 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

gajendra_g_
Beginner
314 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

Alexei_K_Intel
Employee
314 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
 

Reply