Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

PyDP silently truncates and converts `np.float32` into `int64`, leading to sensitivity underestimation

Aperta Adatta ai principianti
#499 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
83/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
cpp, python
Ambito
backend

Direzione di ricerca

Inizia dalle dichiarazioni dei binding in src/bindings/PyDP/mechanisms/mechanism.cpp, intorno alla riga 52, e verifica come vengono registrati gli overload per integer e double. Riproduci il comportamento con l’esempio fornito np.float32, poi verifica che i valori np.float32 selezionino il binding double e non vengano troncati; riesegui i test pertinenti per i binding di mechanism.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Type: Bug :bug:

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:

import numpy as np
from pydp.algorithms.numerical_mechanisms import LaplaceMechanism

mechanism = LaplaceMechanism(epsilon=1.0, sensitivity=0.1)
print("np.float32, D :", [mechanism.add_noise(np.float32(0.95)) for _ in range(10)])
print("np.float32, D':", [mechanism.add_noise(np.float32(1.05)) for _ in range(10)])

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.

Here's a repro for add_dp_noise:

import numpy as np
import pipeline_dp

for name, value in (("D ", np.float32(0.95)), ("D'", np.float32(1.05))):
    releases = []
    for _ in range(10):
        accountant = pipeline_dp.NaiveBudgetAccountant(total_epsilon=1, total_delta=0)
        engine = pipeline_dp.DPEngine(accountant, pipeline_dp.LocalBackend())
        params = pipeline_dp.aggregate_params.AddDPNoiseParams(noise_kind=pipeline_dp.NoiseKind.LAPLACE, l0_sensitivity=1,
                                                               linf_sensitivity=0.1)
        result = engine.add_dp_noise([("partition", value)], params)
        accountant.compute_budgets()
        releases.append(list(result)[0][1])
    print(name, releases)

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.

Lingua principale
Python
Stelle
550
Fork
142
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di OpenMined/PyDP

Tutte le issue di OpenMined/PyDP

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.