• Stanislav Pidhorskyi's avatar
    Added precise division function to fix rounding issues due to `-use_fast_math` · 85f58cf1
    Stanislav Pidhorskyi authored
    Summary:
    This diff fixes some long standing issue with skinning weights some times been negative.
    
    Since initial value of skinning weights are always non-negative, and blending coefficients are supposed to be in range [0..1], and such blending of skinning weight should be non-negative.
    
    Unfortunately that was not the case in practice, despite various clamps.
    
    The issue was hunted down to this part of the code:
    
      c_a = mass_a / mass_ab;
      c_b = 1.0f - c_a;
    
    Even if `mass_a` matches `mass_ab` bit-perfect, `c_a` might not be equal to `1.0`, but some times to `0.999999940395355224609375` and some times to `1.000000119209289550781250`. The later value causes `c_b` to be negative, which leads to negative skinning weights.
    
    tsimk figured out that this behavior is due to the nvcc flag `-use_fast_math`  which makes all devision operators `x/y` to compile to `__fdividef(x, y)` which it turn somehow does not produce exactly 1.0 when dividing same, bit-perfect numbers. See https://docs.nvidia.com/cuda/cuda-c-programming-guide/#intrinsic-functions .
    D71423305
    
    Reviewed By: phg1024
    
    Differential Revision: D71436810
    
    fbshipit-source-id: 64c4e6368d07368ee75997da088d3952ed0c36d0
    85f58cf1
cuda_math_helper.h 78.8 KB