- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am unable to compile the following TBB program on DevCloud.
#include <cassert>
#include <chrono>
#include <iostream>
#include <tbb/task.h>
#include <tbb/tbb.h>
using std::cout;
using namespace std::chrono;
using namespace tbb;
using HR = high_resolution_clock;
using HRTimer = HR::time_point;
uint64_t CUTOFF = 16;
uint64_t SerialFib(uint64_t n) {
if (n < 2)
return n;
else
return SerialFib(n - 1) + SerialFib(n - 2);
}
class FibTask : public tbb::task {
public:
const uint64_t n;
uint64_t* const sum;
FibTask(uint64_t n_, uint64_t* sum_) : n(n_), sum(sum_) {}
// Overrides virtual function task::execute
task* execute() {
if (n < CUTOFF) {
*sum = SerialFib(n);
} else {
uint64_t x, y;
FibTask& a = *new (allocate_child()) FibTask(n - 1, &x);
FibTask& b = *new (allocate_child()) FibTask(n - 2, &y);
// Set ref_count to "two children plus one for the wait".
set_ref_count(3);
// Start b running.
spawn(b);
// Start a running and wait for all children (a and b).
spawn_and_wait_for_all(a);
// Do the sum
*sum = x + y;
}
return NULL;
}
};
uint64_t ParallelFib(uint64_t n) {
uint64_t sum;
FibTask& a = *new (task::allocate_root()) FibTask(n, &sum);
task::spawn_root_and_wait(a);
return sum;
}
int main() {
HRTimer start = HR::now();
uint64_t serialFib = SerialFib(50);
HRTimer end = HR::now();
auto duration = duration_cast<microseconds>(end - start).count();
cout << "Sequential Fibonacci in " << duration << " us\n";
start = HR::now();
uint64_t parFib = ParallelFib(50);
end = HR::now();
assert(serialFib == parFib);
duration = duration_cast<microseconds>(end - start).count();
cout << "Task-based Fibonacci in " << duration << " us\n";
return EXIT_SUCCESS;
}
I use the following: g++ -std=c++11 -fopenmp fibonacci-blocking.cpp -o fibonacci -ltbb.
Could someone please help what is the mistake in my setup here?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel DevCloud systems have the oneAPI bundle which contains a reworked TBB version (called oneTBB).
Some of the origin TBB interfaces were reworked in oneTBB. All changed interfaces are described here.
Regards the tbb::task interface, it was deprecated in TBB 2020 and removed in oneTBB. To find Fibonacci numbers, you can use other still actual oneTBB interfaces (e.g. parallel_reduce).
Example of Fibonacci numbers calculation using the tbb::parallel_reduce algorithm:
#include <cassert>
#include <chrono>
#include <iostream>
#include <tbb/tbb.h>
using std::cout;
using namespace std::chrono;
using namespace tbb;
using HR = high_resolution_clock;
using HRTimer = HR::time_point;
uint64_t CUTOFF = 16;
uint64_t SerialFib(uint64_t n) {
if (n < 2)
return n;
else
return SerialFib(n - 1) + SerialFib(n - 2);
}
typedef long long value;
//! Matrix 2x2 class
struct Matrix2x2
{
//! Array of values
value v[2][2];
Matrix2x2() {}
Matrix2x2(value v00, value v01, value v10, value v11) {
v[0][0] = v00; v[0][1] = v01; v[1][0] = v10; v[1][1] = v11;
}
Matrix2x2 operator * (const Matrix2x2 &to) const;
};
//! Identity matrix
static const Matrix2x2 MatrixIdentity(1, 0, 0, 1);
//! Default matrix to multiply
static const Matrix2x2 Matrix1110(1, 1, 1, 0);
//! Raw arrays matrices multiply
void Matrix2x2Multiply(const value a[2][2], const value b[2][2], value c[2][2])
{
for( int i = 0; i <= 1; i++)
for( int j = 0; j <= 1; j++)
c[i][j] = a[i][0]*b[0][j] + a[i][1]*b[1][j];
}
Matrix2x2 Matrix2x2::operator *(const Matrix2x2 &to) const
{
Matrix2x2 result;
Matrix2x2Multiply(v, to.v, result.v);
return result;
}
//! Functor for parallel_reduce
struct parallel_reduceFibBody {
Matrix2x2 sum;
int split_flag; //< flag to make one less operation for split bodies
//! Constructor fills sum with initial matrix
parallel_reduceFibBody() : sum( Matrix1110 ), split_flag(0) { }
//! Splitting constructor
parallel_reduceFibBody( parallel_reduceFibBody& other, split ) : sum( Matrix1110 ), split_flag(1/*note that it is split*/) {}
//! Join point
void join( parallel_reduceFibBody &s ) {
sum = sum * s.sum;
}
//! Process multiplications
void operator()( const blocked_range<int> &r ) {
for( int k = r.begin() + split_flag; k < r.end(); ++k )
sum = sum * Matrix1110;
split_flag = 0; // reset flag, because this method can be reused for next range
}
};
//! Root function
value parallel_reduceFib(int n)
{
parallel_reduceFibBody b;
parallel_reduce(blocked_range<int>(2, n, 3), b); // do parallel reduce on range [2, n) for b
return b.sum.v[0][0];
}
int main() {
HRTimer start = HR::now();
uint64_t serialFib = SerialFib(50);
HRTimer end = HR::now();
auto duration = duration_cast<microseconds>(end - start).count();
cout << "Sequential Fibonacci in " << duration << " us\n";
start = HR::now();
uint64_t parFib = parallel_reduceFib(50);
end = HR::now();
assert(serialFib == parFib);
duration = duration_cast<microseconds>(end - start).count();
cout << "Fibonacci-based Fibonacci in " << duration << " us\n";
return EXIT_SUCCESS;
}
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thank you for posting in Intel Forums.
We are moving this case to Intel® oneAPI Threading Building Blocks Forum so that the subject matter experts can help you out.
Regards,
Raeesa
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi!
Could you share more detailed information about the issue: error log, information about the execution environment (tbb version, compiler version)?
I am successfully compiled this example using the online compiler (tbb version: 2020.3, compiler version: gcc 5.5): https://godbolt.org/z/GTYs9E
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to compile the TBB cloud on Intel DevCloud. These are the steps I am following.
1) SSH into DevCloud
2) Compile the program: g++ -std=c++11 fibonacci-blocking.cpp -o fibonacci -ltbb
3) Compilation error
u47641@login-2:~/cs610$ g++ -std=c++11 fibonacci-blocking.cpp -o fibonacci -ltbb
fibonacci-blocking.cpp:23:34: error: expected class-name before '{' token
class FibTask : public tbb::task {
^
fibonacci-blocking.cpp:31:3: error: 'task' does not name a type; did you mean 'tanl'?
task* execute() {
^~~~
tanl
fibonacci-blocking.cpp: In function 'uint64_t ParallelFib(uint64_t)':
fibonacci-blocking.cpp:53:28: error: 'allocate_root' is not a member of 'tbb::v1::task'
FibTask& a = *new (task::allocate_root()) FibTask(n, &sum);
^~~~~~~~~~~~~
fibonacci-blocking.cpp:54:9: error: 'spawn_root_and_wait' is not a member of 'tbb::v1::task'
task::spawn_root_and_wait(a);
^~~~~~~~~~~~~~~~~~~
u47641@login-2:~/cs610$
I tried the following as well, but it does not help.
export ONEAPI_INSTALL=/opt/intel/inteloneapi
source $ONEAPI_INSTALL/setvars.sh --dnnl-configuration=cpu_tbb --force> /dev/null 2>&1
icpc -std=c++11 fibonacci-blocking.cpp -o fibonacci -ltbb
This is on a login node, I face the same problem on compute nodes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel DevCloud systems have the oneAPI bundle which contains a reworked TBB version (called oneTBB).
Some of the origin TBB interfaces were reworked in oneTBB. All changed interfaces are described here.
Regards the tbb::task interface, it was deprecated in TBB 2020 and removed in oneTBB. To find Fibonacci numbers, you can use other still actual oneTBB interfaces (e.g. parallel_reduce).
Example of Fibonacci numbers calculation using the tbb::parallel_reduce algorithm:
#include <cassert>
#include <chrono>
#include <iostream>
#include <tbb/tbb.h>
using std::cout;
using namespace std::chrono;
using namespace tbb;
using HR = high_resolution_clock;
using HRTimer = HR::time_point;
uint64_t CUTOFF = 16;
uint64_t SerialFib(uint64_t n) {
if (n < 2)
return n;
else
return SerialFib(n - 1) + SerialFib(n - 2);
}
typedef long long value;
//! Matrix 2x2 class
struct Matrix2x2
{
//! Array of values
value v[2][2];
Matrix2x2() {}
Matrix2x2(value v00, value v01, value v10, value v11) {
v[0][0] = v00; v[0][1] = v01; v[1][0] = v10; v[1][1] = v11;
}
Matrix2x2 operator * (const Matrix2x2 &to) const;
};
//! Identity matrix
static const Matrix2x2 MatrixIdentity(1, 0, 0, 1);
//! Default matrix to multiply
static const Matrix2x2 Matrix1110(1, 1, 1, 0);
//! Raw arrays matrices multiply
void Matrix2x2Multiply(const value a[2][2], const value b[2][2], value c[2][2])
{
for( int i = 0; i <= 1; i++)
for( int j = 0; j <= 1; j++)
c[i][j] = a[i][0]*b[0][j] + a[i][1]*b[1][j];
}
Matrix2x2 Matrix2x2::operator *(const Matrix2x2 &to) const
{
Matrix2x2 result;
Matrix2x2Multiply(v, to.v, result.v);
return result;
}
//! Functor for parallel_reduce
struct parallel_reduceFibBody {
Matrix2x2 sum;
int split_flag; //< flag to make one less operation for split bodies
//! Constructor fills sum with initial matrix
parallel_reduceFibBody() : sum( Matrix1110 ), split_flag(0) { }
//! Splitting constructor
parallel_reduceFibBody( parallel_reduceFibBody& other, split ) : sum( Matrix1110 ), split_flag(1/*note that it is split*/) {}
//! Join point
void join( parallel_reduceFibBody &s ) {
sum = sum * s.sum;
}
//! Process multiplications
void operator()( const blocked_range<int> &r ) {
for( int k = r.begin() + split_flag; k < r.end(); ++k )
sum = sum * Matrix1110;
split_flag = 0; // reset flag, because this method can be reused for next range
}
};
//! Root function
value parallel_reduceFib(int n)
{
parallel_reduceFibBody b;
parallel_reduce(blocked_range<int>(2, n, 3), b); // do parallel reduce on range [2, n) for b
return b.sum.v[0][0];
}
int main() {
HRTimer start = HR::now();
uint64_t serialFib = SerialFib(50);
HRTimer end = HR::now();
auto duration = duration_cast<microseconds>(end - start).count();
cout << "Sequential Fibonacci in " << duration << " us\n";
start = HR::now();
uint64_t parFib = parallel_reduceFib(50);
end = HR::now();
assert(serialFib == parFib);
duration = duration_cast<microseconds>(end - start).count();
cout << "Fibonacci-based Fibonacci in " << duration << " us\n";
return EXIT_SUCCESS;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, the example works.
The task-based example continues to work on my TBB 2020 desktop installation (Ubuntu 20.04). Do you know when the deprecations will be merged into the Desktop versions? Or will oneTBB and desktop TBBs continue to be separate for now?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know the non-Intel distribution channels plans about switching from the TBB to oneTBB library.
If you want to use the oneTBB library on Ubuntu 20.04, you can download one of the oneAPI toolkits or the oneTBB GitHub package.
Also, I want to note, that the oneTBB is in the Beta stage now, the Gold release will be available later.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page