[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