I'm trying to modify this example from https://software.intel.com/content/www/us/en/develop/blogs/a-feature-detection-example-using-the-intel-threading-building-blocks-flow-graph.html
The idea is I have a "preprocess" function that is applied to each input, and a "process" function that is applied to every pair of preprocessed inputs, scanning the stream. In my example we simply end up calculating the differences between successive square numbers.
My example below does not work. I believe it's because the buffer is empty at the start. In the blog example they fill the buffer at some point. Calling buffer.try_put(0)
does not seem to solve it for me. What am I missing? And what is a better way to allow the process to work naturally, simply ignoring the first elements that cannot be fully processed because the buffer is empty?
#include <cstring>
#include <iostream>
#include "tbb/flow_graph.h"
using namespace tbb;
using namespace tbb::flow;
const int N = 13;
template<typename T>
class source_body {
unsigned my_count;
int *ninvocations;
public:
source_body() : ninvocations(NULL) { my_count = 0; }
source_body(int &_inv) : ninvocations(&_inv) { my_count = 0; }
bool operator()(T &v) {
v = (T) my_count++;
if (ninvocations) ++(*ninvocations);
if ((int) v < N)
return true;
else
return false;
}
};
int main() {
graph g;
typedef std::tuple<int32_t, int32_t> resource_tuple;
queue_node<int> buffer(g);
join_node<resource_tuple, reserving> resource_join(g);
tbb::flow::source_node<int> src3(g, source_body<int>());
src3.activate();
function_node<int, int>
preprocess_function(g, unlimited,
[](const int &a) -> int {
return a * a;
}
);
make_edge(src3, preprocess_function);
make_edge(preprocess_function, input_port<1>(resource_join));
make_edge(preprocess_function, buffer);
make_edge(buffer, input_port<0>(resource_join));
function_node<resource_tuple, int>
process_function(g, unlimited,
[](const resource_tuple &a) -> int {
return std::get<1>(a) - std::get<0>(a);
}
);
make_edge(resource_join, process_function);
function_node<int> printint(g, serial,
[](const int &t) -> void {
std::cout << t << '\n';
}
);
make_edge(process_function, printint);
buffer.try_put(0);
g.wait_for_all();
return 0;
}