- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have an application where I want to use the TBB Task Scheduler. I
need to be able to handle exceptions in the following way:
a). Exceptions that occur within the tasks need to propagate through and
cancel the tasks within the algorithm.
b). Exceptions need to be able to be caught at the top most invocation
of the Task Scheduler for the set of tasks (i.e. at the
site of tbb::task::spawn_root_and_wait method call).
In order to factor out my application code, I modified the Fibonacci
example found both in the book "Intel Threading Build Blocks" and the
Intel TBB Developer Guide.
Here is the code:
////////////Start of Code
// Parallel example of Fibonacci Number Calculation
// Used to understand exception handling with
// the TBB custom scheduler.
#include "tbb/tbb.h"
#include <system_error>
#include <exception>
#include <iostream>
long SerialFib (long n)
{
// Simulated exception - we throw a "Resource temporarily unavailable"
// After some parallel processing is occurring.
if (n == 14)
throw std::system_error (EAGAIN, std::system_category());
if (n < 2)
return n;
else
return SerialFib(n - 1) + SerialFib (n - 2);
}
const int cutoff = 16;
class FibTask: public tbb::task
{
public:
const long d_n;
long * const d_sum;
FibTask(long n, long * sum): d_n(n), d_sum(sum){}
virtual ~FibTask(){}
tbb::task * execute()
{
if (d_n < cutoff)
{
std::cout << "SERIAL..." << std::endl;
*d_sum = SerialFib(d_n);
}
else
{
std::cout << "PARALLEL..." << std::endl;
long x, y;
FibTask & a = *new(allocate_child()) FibTask(d_n - 1, &x);
FibTask & b = *new(allocate_child()) FibTask(d_n - 2, &y);
set_ref_count(3);
spawn(b);
spawn_and_wait_for_all(a);
*d_sum = x+y;
}
return nullptr;
}
};
long ParallelFib(long n)
{
long sum;
try
{
FibTask & a = * new(tbb::task::allocate_root()) FibTask(n, &sum);
tbb::task::spawn_root_and_wait(a);
return sum;
}
catch(std::exception & e)
{
std::cout << "EXCEPTION PARALLEL CALL POINT: " << e.what() << std::endl;
throw;
}
catch(...)
{
std::cout << "EXCEPTION: PARALLEL CALL POINT..." << std::endl;
throw;
}
}
const int from_range = 20;
const int to_range = 22;
main()
{
std::cout << "In Main..." << std::endl;
try
{
for(int x = from_range; x < to_range;++x)
{
std::cout << ParallelFib(x) << std::endl;
}
}
catch(std::exception & e)
{
std::cout << "MAIN EXCEPTION: " << e.what() << std::endl;
}
catch(...)
{
std::cout << "MAIN EXCEPTION..." << std::endl;
}
}
//////// End of Code
Here's the issue: in roughly 3 out of 5 runs of the program, the
following occurs:
Assertion !is_worker() || !CancellationInfoPresent(*my_dummy_task) failed on
line 663 of file ../../src/tbb/custom_scheduler.h
Detailed description: Worker's dummy task context modified
I have not be able to find any additional information on this assertion in
the TBB code.
My questions are:
1). Is it possible to get the exception behavior I'm looking for from the
Task Scheduler?
2). What is the cause of the assertion?
Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
The exception handling is done automatically when parallel algorithms are used, e.g. tbb::parallel_for, tbb::task_group or tbb::flow::graph. If you want use tasks directly, you need to use tbb::task_group_context. In the example you just need to replace a line in ParallelFib:
FibTask & a = * new(tbb::task::allocate_root()) FibTask(n, &sum);
With
tbb::task_group_context ctx; FibTask & a = * new(tbb::task::allocate_root(ctx)) FibTask(n, &sum);
As for a reason why you observe the assert. Each task is bind to a context. The child tasks are usually bound to a context of the parent tasks. However, the root task does not have parent and bound to a default context that is used by master and all worker threads for some purpose. So when an exception raised, it is caught into the default context and all worker threads see the exception in default context; however, it is a logic error in TBB.
Regards, Alex
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks! That did it.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page