Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

[SOLVED] TBB and floating point exceptions

Kristensen__Anders_W
889 Views

Hi,

I'm having some trouble using floating point exceptions (FPE) with TBB in release mode. Basically when an FPE happens I want my program to show the windows crash dialog with the option to attach a debugger.  This works fine for programs compiled in debug mode for FPE both inside and outside TBB algorithms. For release mode builds FPE outside TBB algorithms also produce the desired crash, but for FPE inside TBB the error is translated into a C++ exception, which seems inconsistent.

So:

debug mode + outside parallel_for: crash dialog

debug mode + inside parallel_for: crash dialog

release mode + outside parallel_for: crash dialog

release mode + inside parallel_for: unknown exception thrown!

How do I avoid TBB translating my FPE to a C++ exception?

Kind regards

Anders

[cpp]

extern float bar = -1.f;

int main(int argc, char* argv[])
{

_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK()

& ~(_MM_MASK_INVALID|
_MM_MASK_OVERFLOW |
_MM_MASK_DIV_ZERO));


tbb::task_scheduler_init tsi;

std::vector<float> foo(16);

//make FPE outside TBB

//foo[0] = std::sqrt(bar);

try {
tbb::parallel_for(
tbb::blocked_range<size_t>(0, foo.size()),
[&](const tbb::blocked_range<size_t>& range) {

std::printf("before\n");
for (auto i=range.begin(); i!=range.end(); ++i)
{
std::printf("%i\n", int(i));
foo = std::sqrt(float(i));

//make FPE inside TBB algorithm

if (i==15)
foo = std::sqrt(bar);
}
std::printf("after\n");
}, tbb::auto_partitioner());

}catch (std::exception& e)
{
std::printf("exception: %s\n", e.what());
}

return 0;

}

[/cpp]

0 Kudos
4 Replies
RafSchietekat
Valued Contributor III
889 Views

Is this for a Microsoft compiler on x86? Then aren't those settings only for SSE instructions, with FPU instructions still masked by default? But even if the compiler decides on SSE by default and only uses the FPU to optimise that particular case, it shouldn't generate a C++ exception, I suppose.

I've experienced that this environment will catch(...) a bus error (when dereferencing a dangling pointer or so), which is also rather strange (compared to Linux). What happens if you surround the freestanding offending instruction with a try/catch(...)? If it is caught that way, perhaps that might hint at an explanation after inspecting the source code for TBB, but it's a long shot, and others with more FP experience in this environment (or access to it for reproduction purposes) might be better able to assist.

BTW, you don't need a task_scheduler_init anymore (except for specific purposes).

0 Kudos
Kristensen__Anders_W
889 Views

Thanks for replying.  I'm using vs2012 and 64bit mode, so no FPU.

I figured out the cause..  When I ran the program from inside VS (both with and without debugging) my program used the correct tbb.dll from the distribution of tbb that I was linking against.  But when I ran from command prompt it used whatever tbb.dll it found in the path, which happened to be and old version of tbb.  This is what was causing the exception in release mode.

0 Kudos
RafSchietekat
Valued Contributor III
889 Views

Thanks for letting us know (I'll assume you only just found out, yourself).

0 Kudos
Vladimir_P_1234567890
889 Views

Anders,

Could you put [SOLVED] to the subject that people can google the answer later?

thanks,
--Vladimir 

0 Kudos
Reply