“Integrals first” — public integral primitives, by implementation

Mike’s directive on 2026-05-29 — “always integrals and these low- level things first, otherwise how shall the method ever work?” — is the meta-fix for the four-cycle GDF release defer (v0.8.0 → v0.9.0 → v0.10.0 → v0.11.0). The pattern under the slips: a method chat lands a Python-level driver that exercises an integral primitive at production scale before that primitive has a C++ backend; the run OOMs or slows to a crawl; the release misses; an integrals chat is spawned to backfill C++. The fix that breaks the pattern is bookkeeping — keep a live catalogue of every public Python integral primitive vibe-qc exposes, what its implementation is (C++ / Python / hybrid), and whether production workloads hit it.

This page is that catalogue. It is the source of truth for the “does my driver have C++ underneath it?” question every method chat should ask before landing scale-sensitive code. Owners: release chat owns refreshing it per tag (see release_process.md); the integrals chat owns the C++-vs-Python column.

How to read the table

  • Primitive — the name a Python caller sees. Most are re-exported from vibeqc/_vibeqc_core (the pybind11 module) via python/vibeqc/__init__.py; some are pure-Python wrappers around lower-level primitives.

  • ImplC++ if the kernel work is C++ (with pybind11 glue); Python if the kernel work is NumPy / Python; hybrid if the Python side performs non-trivial assembly on top of C++ kernels (typical for the density-fitting builders).

  • Hot in production? — whether typical user workloads exercise this at scale (i.e. with n_orb × n_aux × n_G or n_cells large enough that a Python loop on top would dominate wall-clock or memory). A yes here paired with Python in Impl is the “land a C++ port before the next method chat lands a driver on top” warning the catalogue exists to surface.

  • Status / SHA — references the commit that landed the listed implementation, or the open follow-up task if Python-only-and-hot.

Molecular integrals

Primitive

Impl

Hot in production?

Status / SHA

compute_overlap(basis)

C++

yes — every SCF

shipped; libint Operator::overlap

compute_kinetic(basis)

C++

yes — every SCF

shipped; libint Operator::kinetic

compute_nuclear(basis, molecule)

C++

yes — every SCF

shipped; libint Operator::nuclear

compute_nuclear_with_charges(basis, positions, charges)

C++

yes — solvation, ECP

shipped — commit 39bf8629 (ECP+CPCM)

compute_dipole(basis, origin)

C++

yes — dipole moments, property analysis

shipped; libint Operator::emultipole1

compute_eri(basis)

C++

yes — direct-SCF backends

shipped; dense 4-index tensor builder

compute_2c_eri(aux)

C++

yes — DF builders

shipped; libint BraKet::xs_xs

compute_3c_eri(orbital, aux)

C++

yes — DF builders

shipped; libint BraKet::xs_xx

compute_ecp_matrix(basis, ecp_centers, ...)

C++

yes — ECP-aware SCF

shipped; libecpint wrapper

Periodic integrals — real-space lattice sums

Primitive

Impl

Hot in production?

Status / SHA

compute_overlap_lattice(basis, system, opts)

C++

yes — every periodic SCF

shipped

compute_kinetic_lattice(basis, system, opts)

C++

yes — every periodic SCF

shipped

compute_nuclear_lattice(basis, system, opts)

C++

yes — every periodic SCF

shipped

compute_nuclear_lattice_ewald(basis, system, opts, ...)

C++

yes — Ewald V_ne

shipped

compute_nuclear_erfc_lattice(basis, system, opts, omega)

C++

yes — Ewald V_ne short-range half

shipped

compute_2c_eri_lattice(aux, system, opts)

C++

yes — periodic DF

shipped (see cpp/include/vibeqc/aux_eri.hpp)

compute_2c_eri_lattice_blocks(aux, system, opts)

C++

yes — multi-k DF storage

shipped

compute_3c_eri_lattice(orbital, aux, system, opts)

C++

yes — periodic DF

shipped

compute_3c_eri_lattice_blocks(orbital, aux, system, opts)

C++

yes — multi-k DF storage

shipped

compute_2c_eri_lattice_sr(aux, system, opts, omega)

C++

yes — RSGDF SR half

shipped (Ye & Berkelbach 2021)

compute_3c_eri_lattice_sr(orbital, aux, system, opts, omega)

C++

yes — RSGDF SR half

shipped

direct_lattice_cells(system, cutoff_bohr)

C++

yes — every lattice sum

shipped

ewald_nuclear_potential(...), ewald_nuclear_repulsion(...)

C++

yes — every periodic SCF

shipped

multipole_moments_lattice(...)

C++

yes — periodic multipoles

shipped

Periodic integrals — reciprocal-space (G-mesh) primitives

This is the column that was Python-only-and-hot at the start of the v0.11.0 cycle — the OOM problem that motivated this catalogue.

Primitive

Impl

Hot in production?

Status / SHA

ao_pair_fourier_transform(basis, G)

hybrid

yes — RSGDF dense-mesh 3c

Python loop (_aopair_ft.py) calls C++ Bloch wrapper at k = 0 and squeezes; for L > 0 walks the MD recursion in Python only when basis is Cartesian / L > 6

ao_pair_fourier_transform_at_cells(basis, G, R_g_list)

Python

no longer hot — bypassed by the C++ Bloch wrapper

retained as the reference path for parity testing

ao_pair_fourier_transform_shifted_ket(basis, G, R_g)

Python

low

reference / debug path

ao_pair_fourier_transform_bloch(basis, G, R_g_list, k_cart)

C++ (since 74f3eb4a + 590d022d)

yes — RSGDF dense-mesh 3c, every k-point

C++ s-only fast path + general-L MD kernel; streams Bloch sum over R_g so the per-cell intermediate never materialises. This was the OOM driver pre-v0.11.0.

rsgdf_aux_fourier_transform(aux, G)

Python

yes — RSGDF 2c metric assembly

single-AO FT (one shell axis); the loop is over n_aux × n_G — modest, currently fits inside SCF budgets. Track for promotion if larger aux bases land

rsgdf_dense_g_mesh(system, ke_cutoff)

C++ (via FFTW3 grid + filter)

yes

shipped

Density-fitting assembly — hybrids that compose the above

These are not “integrals” per se, but they exercise the integral primitives and decide whether a Python loop sits between the C++ kernels and the user driver. Worth tracking because the loop is where scaling problems live.

Primitive

Impl

Hot in production?

Status / SHA

aux_basis.build_lpq_native_fft(system, ao_basis, aux_basis, ...)

hybrid

yes — RSGDF dense-mesh path

dispatches to the C++ pair-FT kernel via _aopair_ft.ao_pair_fourier_transform_bloch; the remaining work is small (auxiliary FT contraction + eigendecompose-threshold)

aux_basis.build_lpq_native(system, ao_basis, aux_basis, ...)

hybrid

yes — compcell GDF path

C++ compute_2c_eri_lattice + compute_3c_eri_lattice + Python fitting / threshold

aux_basis.build_lpq_bloch_native(system, ...)

hybrid

yes — multi-k GDF

C++ cell-resolved 2c/3c blocks + Python Bloch phase assembly

aux_basis.rsgdf_lr_2c_metric(...) / rsgdf_lr_3c_tensor(...)

hybrid

yes — RSGDF LR halves

analytic FTs in Python; modest scale today

Functional / DFT primitives

Out of scope for the integrals catalogue — covered by libxc.

How to use this catalogue

  1. Before landing a periodic driver, find the primitives it calls. If any are Python-only and the driver pushes them at production scale (large n_orb, dense G-meshes, many k-points, large cell lists), pause and open an integrals task to port the primitive before shipping the driver.

  2. Per-release sweep — the release chat re-validates this table at every tag. Add rows for any new primitive landed in the cycle; update implementation status where it changed; flag anything newly hot-in-production.

  3. CI-side guard — see tests/test_binding_sanity.py for the mechanical check that the .so actually exposes everything python/vibeqc/__init__.py claims it imports.

Footnote — v0.11.0 cycle close

The Python ao_pair_fourier_transform_bloch row was Python-only and hot at the start of the v0.11.0 cycle; the C++ port landed in commits 74f3eb4a (s-shell tier) and 590d022d (general-L). The table flip from Python to C++ in the corresponding row is the canonical “fix the catalogue before the next defer cycle starts” example. The catalogue itself lands in this cycle to make the pattern repeatable.