HEFFSO Build And Usage#
HEFFSO builds and diagonalizes the spin-orbit effective Hamiltonian after DIAGPT. The current implementation is HDF5-first: previous-stage determinants, effective Hamiltonian matrices, orbital metadata, and spin-orbit integrals are read from an explicit shared HDF5 dump and one DIAGPT HEFFSO handoff file.
Runtime Model#
The recommended route is the unified cipsixx workflow, which validates all inputs, generates the runtime namelist, and checkpoints completion. For a manual run, provide:
An HDF5 dump from
pyscf2mppt; it must contain orbital metadata andintso. Select it withMPPT_HDF5_FILE=/path/to/calculation.h5. The historical fallback name ispyscf_dump.h5.The fixed
<prefix>heffso.1.h5handoff from DIAGPT, for examplePr_heffso.1.h5. The.1suffix is retained for file compatibility.A HEFFSO input file with
&sofil, a title line,&sort, and&ic.
The legacy previous-stage scalar integral and determinant files are not used by the current HEFFSO route.
Minimal input:
&sofil prefix='Pr_', &end
Pr
&sort
nvectw=228, primme_guess_space=-1,
primme_max_basis=0, primme_max_block=0, primme_max_matvecs=0,
primme_eps=1.d-6, primme_initial_vector_tolerance=1.d-7,
primme_print_level=1, primme_progress_interval_seconds=60,
primme_allow_constrained_basis=.false.,
primme_preconditioner=.true., primme_direct_sparse=.true.,
&end
&ic iorder=2, &end
iorder=2 reads the h2 matrix from the HDF5 handoff. Use iorder=1 for
h1.
Bare Projected Effective Operators#
Set effective_operators=.true. in &sort, or set
mppt.heffso.effective_operators: true in the unified YAML input, to write the
bare projected effective-operator artifact. This route requires full-space
intdip and intang datasets in the PySCF HDF5 file. It does not require scalar
root vectors or energies in the DIAGPT handoff.
For each Cartesian one-body operator
Q in L, S, J, and the length-gauge dipole r, HEFFSO stores
V^dagger Q V in the HEFFSO eigenstate basis, where the columns of V are the
computed HEFFSO eigenvectors in the finite determinant catalog. The total
angular-momentum matrices satisfy J = L + S component by component.
Before projection, HEFFSO converts the legacy excitation-record phases of those
eigenvectors to the canonical alpha-then-beta occupation convention used by the
catalog operator kernel.
The determinant catalog is also the model-space projector: an operator-generated daughter determinant contributes only when that daughter is present in the finite catalog. External daughters outside the catalog are omitted. The stored matrices are therefore bare model-space operators. They do not include wave-operator dressing or an external-space correction, and they do not provide exact Casimir values, multiplet or parentage assignments, certification, or exact E1 spectroscopy claims.
The run writes <prefix>heffso_effective_operators.h5 with schema
mppt_heffso_effective_operators_v1. For n HEFFSO states, its required
attributes are:
Attribute |
Value or meaning |
|---|---|
|
|
|
one-based state IDs, |
|
|
|
vacuum energy added to the HEFFSO eigenvalues |
|
|
|
|
|
|
Required datasets are:
Dataset |
Shape |
Meaning |
|---|---|---|
|
|
contiguous one-based state IDs |
|
|
absolute electronic energies in Hartree |
|
|
split-complex Cartesian |
|
|
split-complex Cartesian |
|
|
split-complex Cartesian |
|
|
split-complex Cartesian bare dipole matrices |
An effective-operators-disabled run removes any existing artifact with that
prefix before continuing, so a stale enabled-run file is not exposed as current
output. MPPT_HDF5_FILE must not name or alias that prefix-owned artifact;
native HEFFSO checks file identity before cleanup and rejects the run instead of
deleting its input.
Caspy provides a typed eager reader:
from caspy import read_heffso_effective_operators
result = read_heffso_effective_operators(
"Pr_heffso_effective_operators.h5"
)
print(result.state_energy_hartree)
print(result.j_matrix.shape) # (3, n, n)
The returned arrays own their data and are read-only; the source HDF5 handle is
closed before the reader returns. The reader validates the v1 metadata, shapes,
finiteness, Hermiticity, and J = L + S relation.
Human Report#
The bounded console report is independent of the effective-operator switch. It contains only:
SPIN-ORBIT STATES, withstate, absoluteEh,dE / eV, anddE / cm-1;ACTIVE-ORBITAL OCCUPATIONS;DOMINANT CONFIGURATION WEIGHTS.
Operator matrices are HDF5-only. Caspy’s text parser reads these bounded energy,
occupation, and configuration sections; use
read_heffso_effective_operators for L, S, J, and dipole matrices.
Runtime Controls#
Raw &sort controls and defaults are:
Setting |
Default |
Role |
|---|---|---|
|
|
p-space size; negative selects |
|
|
search basis; zero selects |
|
|
block size; zero selects |
|
|
matrix-vector budget; zero selects |
|
|
relative residual convergence tolerance |
|
|
minimum norm accepted for an initial vector |
|
|
compact progress reporting |
|
|
maximum progress interval at outer-iteration boundaries |
|
|
permit an explicit basis smaller than |
|
|
diagonal preconditioner policy |
|
|
direct complex sparse callback policy |
|
|
strict ` |
|
|
minimum configurations per state |
PRIMME tolerances are finite and positive. Explicit PRIMME limits are rejected
instead of clamped. A basis below
2*nev requires primme_allow_constrained_basis=.true., and any basis below
the recommended 4*nev emits a performance warning. Before allocating solver
storage, HEFFSO reports the complex n * max_basis basis lower bound and the
returned n * nev vectors in GiB. PRIMME working memory is higher than this
portable lower bound. configuration_weight_percent must be finite and in
[0,100]; configuration_top_n must be positive.
HEFFSO always uses the repository-pinned PRIMME 3.2.3 eigensolver. CMake fetches and builds this mandatory dependency; configuration or compilation fails rather than producing a binary with a different eigensolver.
Recommended CPU Build#
The primary production path is CPU oneMKL:
PRIMME for the final eigensolver.
oneMKL BLAS/LAPACK for dense projected operations.
oneMKL Sparse BLAS for HEFFSO HMAT matrix-vector products.
Install oneMKL in the same conda environment used for MPPT:
conda activate mppt
conda install -c https://software.repos.intel.com/python/conda \
mkl mkl-devel mkl-include intel-openmp
Configure and build:
MPPT_PREFIX="$CONDA_PREFIX"
cmake -S . -B build_heffso_mkl \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$MPPT_PREFIX" \
-DHDF5_ROOT="$MPPT_PREFIX" \
-DOpenMP_gomp_LIBRARY="$MPPT_PREFIX/lib/libgomp.so.1" \
-DWITH_MKL=ON \
-DWITH_MKL_SPARSE=ON \
-DWITH_CUDA_SPARSE=OFF
cmake --build build_heffso_mkl --target heffso
Recommended run environment:
export OMP_NUM_THREADS=8
export MKL_NUM_THREADS=8
export OMP_DYNAMIC=FALSE
export MKL_DYNAMIC=FALSE
export OMP_PROC_BIND=close
export OMP_PLACES=threads
export MPPT_HDF5_FILE=/path/to/calculation.h5
unset HEFFSO_SPMM
build_heffso_mkl/bin/heffso < Pr_heffso.inp > heffso.log 2> heffso.stderr
When built with WITH_MKL_SPARSE=ON, oneMKL Sparse BLAS is selected by default.
Set HEFFSO_SPMM=fortran only for comparisons against the portable OpenMP HMAT
kernel.
Plain BLAS/LAPACK Build#
This path is useful for portability checks and systems without oneMKL. It is not the preferred performance path.
MPPT_PREFIX="$CONDA_PREFIX"
cmake -S . -B build_heffso_blas \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$MPPT_PREFIX" \
-DHDF5_ROOT="$MPPT_PREFIX" \
-DOpenMP_gomp_LIBRARY="$MPPT_PREFIX/lib/libgomp.so.1" \
-DWITH_MKL=OFF \
-DWITH_MKL_SPARSE=OFF \
-DWITH_CUDA_SPARSE=OFF
cmake --build build_heffso_blas --target heffso
To force system BLAS/LAPACK instead of whatever CMake finds first:
cmake -S . -B build_heffso_blas \
-DBLAS_LIBRARIES=/usr/lib/x86_64-linux-gnu/libblas.so.3 \
-DLAPACK_LIBRARIES=/usr/lib/x86_64-linux-gnu/liblapack.so.3 \
...
With no sparse backend compiled, PRIMME falls back to the split real/imaginary Fortran/OpenMP HMAT callback.
Optional CUDA Build#
CUDA/cuSPARSE is an experimental acceleration backend for the PRIMME sparse matrix products. It is not selected implicitly at runtime.
Build CUDA together with MKL:
MPPT_PREFIX="$CONDA_PREFIX"
cmake -S . -B build_heffso_cuda \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$MPPT_PREFIX" \
-DHDF5_ROOT="$MPPT_PREFIX" \
-DOpenMP_gomp_LIBRARY="$MPPT_PREFIX/lib/libgomp.so.1" \
-DWITH_MKL=ON \
-DWITH_MKL_SPARSE=ON \
-DWITH_CUDA_SPARSE=ON \
-DCUDAToolkit_ROOT="$CUDA_HOME" \
-DCMAKE_CUDA_COMPILER="$CUDA_HOME/bin/nvcc" \
-DCMAKE_CUDA_ARCHITECTURES=86
cmake --build build_heffso_cuda --target heffso
Runtime:
export HEFFSO_SPMM=cuda
build_heffso_cuda/bin/heffso < Pr_heffso.inp > heffso.log 2> heffso.stderr
CUDA controls:
HEFFSO_CUDA_SPMM_ALG=csr_alg3is the tuned default.HEFFSO_CUDA_SPMM_ALG=csr_alg1,csr_alg2, ordefaultcan be used for comparisons.HEFFSO_CUDA_TIMING=1prints aggregate CUDA setup, transfer, and SpMM times.
The Python workflow requires direct_sparse: true for the CUDA backend and
includes both CUDA controls in HEFFSO checkpoint identity.
Use CUDA only after the MKL path is working and validated on the same input.
Validation#
For every build profile:
cmake --build <build_dir> --target heffso mppt_heffso_unit_tests \
mppt_heffso_effective_operators_writer_probe
ctest --test-dir <build_dir> -L HEFFSO --output-on-failure
Smoke-test the Python/MPPT path:
conda run -n mppt ctest --test-dir <build_dir> -R '^hf_based_mppt_H2O_no_symm$' \
--output-on-failure
For CUDA builds add HEFFSO_SPMM=cuda to the smoke-test environment.
mppt.heffso.print_level and raw primme_print_level use these levels:
0: final completion or failure summary only.1: compact progress after another 5% of roots converge or after 60 seconds.2: PRIMME per-root convergence output.3and above: increasingly detailed iteration diagnostics.
The compact lines start with HEFFSO PRIMME, so the Python workflow mirrors
only those lines live while retaining the complete output in
.mppt-workflow/logs/heffso.log. Raw &sort input accepts
the complete primme_* contract listed above. Workflow runs remove historical
HEFFSO_PRIMME_* and HEFFSO_GUESS_SPACE variables so ambient shell settings
cannot override fingerprinted YAML controls.
With PRIMME hard locking, compact progress counts locked roots, matching
PRIMME’s monotonic completed-root contract. An exact zero Hamiltonian is also a
valid converged case when both its scaled residual limit and residual are zero.
Debug builds suspend IEEE exception halting only while inside zprimme and
restore the caller’s modes before HEFFSO post-processing.
The repository test-light target injects exact paths to the current CMake
targets. See the installation guide for the supported test
command.
Outputs#
HEFFSO writes:
HEFF.TMPHMAT<prefix>sovec(for YAML prefixPr, this isPr_sovec)<prefix>heffso_effective_operators.h5wheneffective_operators=.true.the console table headed
state Eh dE / eV dE / cm-1
Successful logs end with:
fin heffso
Performance Notes#
MKL Sparse BLAS is the default performance target on CPU.
Bare operator projection traverses the finite determinant catalog and skips every generated daughter that is not in that catalog. Cost scales with the catalog, operator connectivity, and requested state count; no external determinant image map is built.
CUDA can improve large sparse PRIMME matvecs on the local RTX 3090, but profiling shows the remaining wall time is mostly CPU-side PRIMME and projected-vector work, not host-device transfer.
Automatic guess space uses
min(n, max(512, 2*nev)). Setguess_spaceexplicitly only for a controlled comparison or memory-constrained run.