SQD-compatible solver (sbd.sbd_solver)

SBD solver wrapper compatible with qiskit-addon-sqd interface.

This module provides functions that wrap the SBD (Selected Basis Diagonalization) library to be compatible with the qiskit-addon-sqd diagonalize_fermionic_hamiltonian interface, similar to how qiskit-addon-dice-solver works.

assemble_rdms(results, norb)[source]

Build spin-summed (rdm1, rdm2) from SBD’s raw one_p_rdm/two_p_rdm.

Returns (None, None) when do_rdm was 0 (SBD leaves these keys as empty lists in that case – see sbdiag.h’s do_rdm == 0 branch, which only computes the diagonal density, not the correlation functions), matching SCIResult’s own rdm1/rdm2 default.

The reshape/transpose below is not a guess: it was verified against PySCF’s make_rdm1/make_rdm2 on a fixed subspace, on all three SBD backends (cpu, gpu-thrust, gpu-omp-offload) – both element-wise on the full tensors and via the energy identity E = einsum("pr,pr->",rdm1,hcore) + 0.5*einsum("prqs,prqs->",rdm2,eri) that SCIResult.rdm1/rdm2 are contracted with everywhere else in qiskit-addon-sqd (e.g. fermion.py’s own solve_fermion).

SBD’s documented layout (sbd-ext docs/user-guide.md, matching the C++ reference in apps/chemistry_tpb_selected_basis_diagonalization/main.cc):

one_p_rdm[s][i + L*j]                 = <c+_{i,s} c_{j,s}>
two_p_rdm[s+2t][i + L*j + L^2*k + L^3*l] = <c+_{i,s} c+_{j,t} c_{l,t} c_{k,s}>

A Fortran-order reshape implements those flat-index formulas directly (arr_F[i, j] / arr_F[i, j, k, l]); rdm1 needs no further transpose (it is symmetric here regardless), and rdm2’s spin-summed block sum needs axes (0, 2, 1, 3) to land in the “prqs” slot order SCIResult’s contract expects.

Parameters:
Return type:

tuple[ndarray | None, ndarray | None]

create_sbd_solver(mpi_comm=None, sbd_config=None, temp_dir=None, clean_temp_dir=True, device_config=None)[source]

Create a configured SBD solver function for use with diagonalize_fermionic_hamiltonian.

Example

>>> from functools import partial
>>> sbd_solver = create_sbd_solver(sbd_config={"method": 0, "eps": 1e-10})
>>> result = diagonalize_fermionic_hamiltonian(
...     hcore, eri, bit_array, sci_solver=sbd_solver, ...
... )
Parameters:
  • mpi_comm (Comm | None)

  • sbd_config (dict | None)

  • temp_dir (str | Path | None)

  • clean_temp_dir (bool)

Return type:

Callable

solve_sci(ci_strings, one_body_tensor, two_body_tensor, norb, nelec, *, spin_sq=None, mpi_comm=None, sbd_config=None, temp_dir=None, clean_temp_dir=True, device_config=None, fcidump_path=None)[source]

Diagonalize Hamiltonian in subspace defined by CI strings using SBD.

Parameters:
  • ci_strings (tuple[ndarray, ndarray]) – Pair (strings_a, strings_b) of CI string arrays.

  • one_body_tensor (ndarray) – The one-body tensor of the Hamiltonian.

  • two_body_tensor (ndarray) – The two-body tensor of the Hamiltonian.

  • norb (int) – The number of spatial orbitals.

  • nelec (tuple[int, int]) – The numbers of alpha and beta electrons.

  • spin_sq (float | None) – Target value for total spin squared (unused by SBD).

  • mpi_comm (Comm | None) – MPI communicator. If None, uses MPI.COMM_WORLD.

  • sbd_config (dict | None) – Dictionary of SBD configuration parameters.

  • temp_dir (str | Path | None) – Directory for temporary files.

  • clean_temp_dir (bool) – Whether to delete intermediate files.

  • device_config – DeviceConfig object to select CPU/GPU backend.

  • fcidump_path (str | Path | None) – If set, load the FCIDUMP directly from this path on every rank and skip the tensor->file round-trip. MUST be on a filesystem visible to every rank (shared on multi-node runs). When None (default), rank 0 writes a regenerated FCIDUMP into temp_dir and every rank opens that file, which requires temp_dir to be shared for multi-node runs.

Returns:

The diagonalization result as SCIResult.

Return type:

SCIResult

solve_sci_batch(ci_strings, one_body_tensor, two_body_tensor, norb, nelec, *, spin_sq=None, mpi_comm=None, sbd_config=None, temp_dir=None, clean_temp_dir=True, device_config=None, fcidump_path=None)[source]

Diagonalize Hamiltonian in multiple subspaces using SBD.

The FCIDUMP file is loaded once and reused across all batches.

Parameters:
  • ci_strings (list[tuple[ndarray, ndarray]]) – List of (strings_a, strings_b) pairs.

  • one_body_tensor (ndarray) – The one-body tensor of the Hamiltonian.

  • two_body_tensor (ndarray) – The two-body tensor of the Hamiltonian.

  • norb (int) – The number of spatial orbitals.

  • nelec (tuple[int, int]) – The numbers of alpha and beta electrons.

  • spin_sq (float | None) – Target value for total spin squared (unused by SBD).

  • mpi_comm (Comm | None) – MPI communicator. If None, uses MPI.COMM_WORLD.

  • sbd_config (dict | None) – Dictionary of SBD configuration parameters.

  • temp_dir (str | Path | None) – Directory for temporary files.

  • clean_temp_dir (bool) – Whether to delete intermediate files.

  • device_config – DeviceConfig object to select CPU/GPU backend.

  • fcidump_path (str | Path | None) – If set, load the FCIDUMP directly from this path on every rank and skip the tensor->file round-trip. MUST be on a filesystem visible to every rank (shared on multi-node runs). When None (default), rank 0 writes a regenerated FCIDUMP into temp_dir and every rank opens that file, which requires temp_dir to be shared for multi-node runs.

Returns:

List of SCIResult for each batch.

Return type:

list[SCIResult]