You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PyDP silently truncates and converts np.float32 into int64, leading to sensitivity underestimation #499
In the code that registers the bindings with the C++ building blocks library, the int64 binding is defined before the double binding. This has a surprising consequence: pybind11, after doing a pass that sees if the input type matches the declared type, it then tries overloads in order with an implicit conversion path. The int caster apparently accepts a np.float32 and silently truncates its input, so values of this type automatically use the int64 binding.
Silent truncation predictably negative consequences on the sensitivity analysis: 0.95 becomes 0 and 1.05 becomes 1, so sensitivity increases unexpectedly. This is observable in PyDP:
and also affects PipelineDP via add_dp_noise, or VECTOR_SUM with float32 values. This happens even though the value is multiplied by 1.0, maybe to try and cast it to float? Sadly this doesn't work, since 1.0 * np.float32(1.7) still has type np.float32.
other PipelineDP aggregations (sum, mean, variance) convert to float64 and so aren't vulnerable to this.
This issue doesn't happen with np.float64, because np.float64 is a subclass of Python's native floats (while np.float32 is not). Therefore, the right binding is selected by pybind11 during the first pass.
Registering the double binding first would fix it.
Activity