Intel® Embree Ray Tracing Kernels
Discussion forum on the open source ray tracing kernels for fast photo-realistic rendering on Intel® CPUs.
This community is designed for sharing of public information. Please do not share Intel or third-party confidential information here.

Floating point exceptions



We are building an Embree-based rendering module within a larger application. For various reasons, floating point exceptions (FPE) handlers are installed in that application which can result in undetermined behavior when FPEs are thrown from within Embree.

While running initial tests with Embree , we discovered that many FPEs were originating from within the embree library code (for instance in the BVH code). While we can manage most of these by disabling FPE trapping before calls to Embree functions, there are a few which are pretty hard to avoid. 

For instance, the code in bezier_curve.cpp reads:

PrecomputedBezierBasis::PrecomputedBezierBasis(int dj)
    for (size_t i=0; i<=N; i++) 
      for (size_t j=0; j<=N; j++) 
        const float u = float(j+dj)/float(i);

As can easily be seen, this code is certain to perform divide-by-zeros. (similarly for the code in bspline_curve.cpp).

The tricky part about this code is that it is used to initialize static variables (bezier_basis0 and bezier_basis1)  and as a result runs as the Embree library is loaded by the system (rather than at the opportunity of a call in our program). This gives us very little chance to surround that code execution with FPE disabling and re-enabling statements. 

Our current solution is to modify the Embree code itself to disable FPEs at the beginning of such functions using:

int state = fedisableexcept(FE_ALL_EXCEPT);

And re-enabling them at the end of the function with:


Here are our questions:

1) Specifically for the case of the FPE-throwing code which runs at library load time, can you think of any solution which would save us from having local modifications to the Embree code? Would you be open to incorporating code like the one above to the official source to solve that problem for us and others who have to live with FPEs enabled?

2) Is there a good reason why this code should perform divide-by-zeros? Can it be fixed to not throw FPEs?

3) Do you have any recommendation regarding how to best deal with floating point exceptions when running Embree kernels inside an application?


0 Kudos
4 Replies

We will fix this issue with floating point exceptions in Bezier/bspline_curve.cpp in Embree 3.2, which will get released soon.


Great to know. Thanks!


Stephane - if you know of any _more_ instances of this happening at load time, please let us know ASAP, so we can include it into the release. Agree these should be fixed (and should be easy to fix, too); so want to avoid that we're fixing them all in one go.



Hi Ingo, 

Outside of the code in bezier_curve in bspline_curve, I also disabled FPEs in catmullclark_coefficients.cpp but that was more to be on the safe-side, I didn't verify that exceptions were actually thrown from there.

Otherwise, unfortunately, for now all I can offer regarding the other SIGFPE occurrences we ran into with Embree is the top row of a stack trace:

embree::sse2::HeuristicArrayBinningSAH<embree::PrimRef, 32ul>::find(embree::sse2::PrimInfoRange const&, unsigned long)

(next in the stack is:

embree::sse2::GeneralBVHBuilder::BuilderT<embree::sse2::GeneralBVHBuilder::BuildRecordT<embree::sse2::PrimInfoRange, embree::sse2::BinSplit<32ul> >, embree::sse2::HeuristicArrayBinningSAH<embree::PrimRef, 32ul>, embree::sse2::PrimInfoRange, embree::PrimRef, embree::BVHN<4>::NodeRef, embree::FastAllocator::CachedAllocator, embree::FastAllocator::Create, embree::BVHN<4>::AlignedNode::Create2, embree::BVHN<4>::AlignedNode::Set3, embree::sse2::BVHNBuilderVirtual<4>::BVHNBuilderV::build(embree::FastAllocator*, embree::BuildProgressMonitor&, embree::PrimRef*, embree::sse2::PrimInfoT<embree::BBox<embree::Vec3fa> > const&, embree::sse2::GeneralBVHBuilder::Settings)::{lambda(embree::PrimRef const*, embree::range<unsigned long> const&, embree::FastAllocator::CachedAllocator const&)#1}, embree::BuildProgressMonitor>::recurse(embree::sse2::GeneralBVHBuilder::BuildRecordT<embree::sse2::PrimInfoRange, embree::sse2::BinSplit<32ul> >&, embree::FastAllocator::CachedAllocator, bool) ()

I'll update the thread with more precise data if I can get around to running more tests but sadly I won't be able to do so in the next few days.