[Bf-blender-cvs] [a293e5b] soc-2016-cycles_denoising: Cycles: Add Debug build option that enables floating point exceptions
Lukas Stockner
noreply at git.blender.org
Sat Aug 6 05:40:58 CEST 2016
Commit: a293e5b7e1a36c68baff579962c75937664bd4da
Author: Lukas Stockner
Date: Mon Jul 25 15:55:42 2016 +0200
Branches: soc-2016-cycles_denoising
https://developer.blender.org/rBa293e5b7e1a36c68baff579962c75937664bd4da
Cycles: Add Debug build option that enables floating point exceptions
By enabling the new WITH_CYCLES_DEBUG_FPE, floating point exceptions are enabled in the CPU kernels.
That way, the debugger stops as soon as an invalid calculation is performed, which makes it a lot easier to track these issues.
Note that the option may cause problems in combination with the --debug-fpe runtime option.
===================================================================
M CMakeLists.txt
M intern/cycles/CMakeLists.txt
M intern/cycles/device/device_cpu.cpp
M intern/cycles/kernel/bvh/bvh.h
M intern/cycles/kernel/kernel_compat_cpu.h
M intern/cycles/util/util_system.cpp
M intern/cycles/util/util_system.h
===================================================================
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d26fe71..88ddeba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -401,10 +401,12 @@ option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
option(WITH_CYCLES_DEBUG "Build Cycles with extra debug capabilities" OFF)
option(WITH_CYCLES_DEBUG_FILTER "Build Cycles with extra debug capabilities in the denoising filter" OFF)
option(WITH_CYCLES_NATIVE_ONLY "Build Cycles with native kernel only (which fits current CPU, use for development only)" OFF)
+option(WITH_CYCLES_DEBUG_FPE "Build Cycles with floating point exceptions enabled for easier debugging of numerical issues (only for CPU rendering)" OFF)
mark_as_advanced(WITH_CYCLES_LOGGING)
mark_as_advanced(WITH_CYCLES_DEBUG)
mark_as_advanced(WITH_CYCLES_DEBUG_FILTER)
mark_as_advanced(WITH_CYCLES_NATIVE_ONLY)
+mark_as_advanced(WITH_CYCLES_DEBUG_FPE)
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime" ON)
mark_as_advanced(WITH_CUDA_DYNLOAD)
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index d609511..c874633 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -109,6 +109,10 @@ if(CXX_HAS_AVX2)
add_definitions(-DWITH_KERNEL_AVX2)
endif()
+if(WITH_CYCLES_DEBUG_FPE)
+ add_definitions(-DWITH_CYCLES_DEBUG_FPE)
+endif()
+
if(WITH_CYCLES_OSL)
if(WIN32 AND MSVC)
set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 47e977c..67b4df8 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -411,6 +411,9 @@ public:
}
while(task.acquire_tile(this, tile)) {
+#ifdef WITH_CYCLES_DEBUG_FPE
+ scoped_fpe fpe(FPE_ENABLED);
+#endif
float *render_buffer = (float*)tile.buffer;
if(tile.task == RenderTile::PATH_TRACE) {
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index 5988173..43c7c56 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -213,6 +213,10 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
float difl,
float extmax)
{
+#ifdef WITH_CYCLES_DEBUG_FPE
+ scoped_fpe fpe(FPE_DISABLED);
+#endif
+
#ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
# ifdef __HAIR__
@@ -256,6 +260,10 @@ ccl_device_intersect void scene_intersect_subsurface(KernelGlobals *kg,
uint *lcg_state,
int max_hits)
{
+#ifdef WITH_CYCLES_DEBUG_FPE
+ scoped_fpe fpe(FPE_DISABLED);
+#endif
+
#ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
return bvh_intersect_subsurface_motion(kg,
@@ -278,6 +286,10 @@ ccl_device_intersect void scene_intersect_subsurface(KernelGlobals *kg,
#ifdef __SHADOW_RECORD_ALL__
ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, const Ray *ray, Intersection *isect, uint max_hits, uint *num_hits)
{
+#ifdef WITH_CYCLES_DEBUG_FPE
+ scoped_fpe fpe(FPE_DISABLED);
+#endif
+
# ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
# ifdef __HAIR__
@@ -309,6 +321,10 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg,
Intersection *isect,
const uint visibility)
{
+#ifdef WITH_CYCLES_DEBUG_FPE
+ scoped_fpe fpe(FPE_DISABLED);
+#endif
+
# ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
return bvh_intersect_volume_motion(kg, ray, isect, visibility);
@@ -337,6 +353,10 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
const uint max_hits,
const uint visibility)
{
+#ifdef WITH_CYCLES_DEBUG_FPE
+ scoped_fpe fpe(FPE_DISABLED);
+#endif
+
# ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility);
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index c882b47..f7fdee1 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -38,6 +38,7 @@
#include "util_debug.h"
#include "util_math.h"
#include "util_simd.h"
+#include "util_system.h"
#include "util_half.h"
#include "util_types.h"
#include "util_texture.h"
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index d5fac9a..e52a953 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -33,6 +33,12 @@
# include <unistd.h>
#endif
+#ifdef __GNUC__
+# include <fenv.h>
+#elif defined(_MSC_VER)
+# include <float.h>
+#endif
+
CCL_NAMESPACE_BEGIN
int system_cpu_group_count()
@@ -276,5 +282,53 @@ bool system_cpu_support_avx2()
#endif
+static void system_enable_fpe()
+{
+#ifdef __GNUC__
+ feenableexcept(FE_INVALID | FE_OVERFLOW | FE_DIVBYZERO);
+#elif defined(_MSC_VER)
+ _controlfp(0, _EM_INVALID | _EM_OVERFLOW | _EM_ZERODIVIDE);
+#endif
+}
+
+static void system_disable_fpe()
+{
+#ifdef __GNUC__
+ fedisableexcept(FE_INVALID | FE_OVERFLOW | FE_DIVBYZERO);
+#elif defined(_MSC_VER)
+ _controlfp(0xffffffff, _EM_INVALID | _EM_OVERFLOW | _EM_ZERODIVIDE);
+#endif
+}
+
+static bool system_check_fpe()
+{
+#ifdef __GNUC__
+ return fegetexcept() & FE_INVALID;
+#elif
+ return !(_controlfp(0, 0) & _EM_INVALID);
+#endif
+}
+
+scoped_fpe::scoped_fpe(FPEState state)
+{
+ was_enabled = system_check_fpe();
+ if(state == FPE_ENABLED) {
+ system_enable_fpe();
+ }
+ else {
+ system_disable_fpe();
+ }
+}
+
+scoped_fpe::~scoped_fpe()
+{
+ if(was_enabled) {
+ system_enable_fpe();
+ }
+ else {
+ system_disable_fpe();
+ }
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h
index 557aab6..83cee1b 100644
--- a/intern/cycles/util/util_system.h
+++ b/intern/cycles/util/util_system.h
@@ -38,6 +38,21 @@ bool system_cpu_support_sse41();
bool system_cpu_support_avx();
bool system_cpu_support_avx2();
+typedef enum FPEState
+{
+ FPE_ENABLED,
+ FPE_DISABLED,
+} FPEState;
+
+class scoped_fpe
+{
+public:
+ explicit scoped_fpe(FPEState state);
+ ~scoped_fpe();
+private:
+ bool was_enabled;
+};
+
CCL_NAMESPACE_END
#endif /* __UTIL_SYSTEM_H__ */
More information about the Bf-blender-cvs
mailing list