compressonator icon indicating copy to clipboard operation
compressonator copied to clipboard

Use of isnan in CMP_Core BC7 encode

Open baldurk opened this issue 3 years ago • 3 comments

isnan and isinf are functions seem to cause headaches in my experience since their definition seems to be unreliable across compilers. When compiling BC7_Encode_Kernel.cpp with GCC 5 you get an undefined error:

BC7_Encode_Kernel.cpp: In function ‘void GetProjectedIndex(CGV_INDEX*, CGV_IMAGE*, CGV_INT, CGV_ENTRIES)’:
BC7_Encode_Kernel.cpp:1001:23: error: ‘isnan’ was not declared in this scope
     if (isnan(img_diff)) return;
                       ^
BC7_Encode_Kernel.cpp:1001:23: note: suggested alternative:
In file included from Common_Def.h:73:0,
                 from BC7_Encode_Kernel.h:32,
                 from BC7_Encode_Kernel.cpp:43:
/usr/include/c++/5/cmath:648:5: note:   ‘std::isnan’
     isnan(_Tp __x)

How exactly isnan should be accessed is problematic because it depends on the compiler version and on whether you include <cmath> or <math.h> or both, and in what order, including other system headers that might include one or the other. In CMP_Core it seems both are included - cmp_math_vec4.h includes <math.h> but other headers like cmd_math_func.h and Common_Def.h include <cmath>.

I believe adding a using std::isnan to the top of BC7_Encode_Kernel.cpp when building for CPU might work around this issue in a cross-compiler way. The other alternative is to either re-implement isnan (some projects do that, either with manual bit-inspection or forwarding to different standard functions depending on compiler detection).

If GCC 5 is below the minspec considered for this repository then please feel free to close this as that seems to be the only compiler I found that breaks, and I believe the headers were fixed deliberately to avoid this kind of problem in GCC 6 and up.

baldurk avatar Jul 14 '20 10:07 baldurk

@baldurk replacing isnan() with this definition

#define cmp_isnan(x) ((x) != (x))

NPCompress avatar Nov 08 '20 17:11 NPCompress

AFAIK that can be quite dangerous since depending on compiler settings it will be optimised out entirely. If you're implementing it by hand I believe it's likely better to check bit patterns with a union or memcpy.

baldurk avatar Nov 08 '20 18:11 baldurk

@baldurk changing to std definition for cpu as suggested

#ifdef ASPM_GPU #define cmp_isnan(x) isnan(x) #else #define cmp_isnan(x) std::isnan(x) #endif

NPCompress avatar Nov 08 '20 19:11 NPCompress

The issue has been resolved in current release v4.4

NPCompress avatar Jul 19 '23 19:07 NPCompress