Sorry, you must verify to complete this action. Please click the verification link in your email. You may re-send via your
profile
.
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?
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;
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;
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.
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;
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;
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.
Community support is provided Monday to Friday. Other contact methods are available here.
Intel does not verify all solutions, including but not limited to any file transfers that may appear in this community. Accordingly, Intel disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade.
For more complete information about compiler optimizations, see our Optimization Notice.