_bind() materializes a Python list[float] on every evaluation, including inside the functionals

Aperta
#197 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
57/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
cpp, numpy, python

Direzione di ricerca

Read src/monoprop/monomial_propagator.py:602-612 and trace how _bind feeds the functional closures; then check the evaluation signatures in src/monoprop/bindings/binder.h to confirm the proposed sequence remains compatible. Run just bench serial and compare benches/results/REPORT.md, especially functional-driven benchmarks, then run just test to verify lists, tuples, and Circuit inputs still work.

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

Descrizione

performance

🤖 AI text below 🤖

What

MonomialPropagator._bind builds a new Python list[float] on every call.

src/monoprop/monomial_propagator.py:602-612

def _bind(self, parameters: ParameterValues) -> list[float]:
    if isinstance(parameters, Circuit):
        parameters = parameters.parameters
    if parameters is None:
        return []
    return [float(v) for v in parameters]

Why this is a problem

_bind is on every evaluation entry point — expectation_value, expectation_value_and_gradient,
gradient, contract_partially, evolved_operator, and, most importantly, inside the closures
returned by expectation_value_functional and expectation_value_and_gradient_functional:

fn = self._simulator.expectation_value_functional(pare_threshold)
return lambda parameters=None: fn(self._bind(parameters))

Those functionals exist precisely to be called in an optimizer loop. So each iteration allocates N
PyFloat objects plus a list, then throws them away — for a parameter vector that the caller almost
always already holds as a contiguous float64 ndarray.

Suggested fix

Pass a contiguous float64 ndarray straight through when the caller supplied one, and widen the
return annotation from list[float] to Sequence[float] | np.ndarray:

if isinstance(parameters, np.ndarray):
    return np.ascontiguousarray(parameters, dtype=np.float64)
return [float(v) for v in parameters]

nanobind's stl/vector.h caster accepts any Python sequence, so the C++ signature
(const VecD &) is unchanged. To be clear about the size of the win: this removes the intermediate
Python objects, not the element-by-element conversion on the C++ side — list_caster still
iterates.

If the measured gain is small and the path matters, the larger version is to add an
nb::ndarray<const double, nb::ndim<1>, nb::c_contig> overload for the evaluation entry points in
src/monoprop/bindings/binder.h, which removes the per-element conversion too. That is a bigger
change to the binding surface and probably wants its own issue.

Verification

  • just bench serial before/after, comparing benches/results/REPORT.md; the functional-driven
    benchmarks are the ones to watch.
  • just test — in particular the paths that pass lists, tuples and Circuit objects rather than
    arrays, which must keep working unchanged.

Found by a code-reading review of the repository at 29a8050. No build tree was available, so the
analysis is from source inspection and should be confirmed by measurement.

Lingua principale
C++
Stelle
52
Fork
2
Merge medio
2g 2h
PR unite (30g)
39

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

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 Algorithmiq/monoprop

Tutte le issue di Algorithmiq/monoprop

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.