HEFFSO Build And Usage#
HEFFSO builds and diagonalizes the spin-orbit effective Hamiltonian after DIAGPT. Determinants, effective Hamiltonian matrices, orbital metadata, and spin-orbit integrals are read from an explicit shared HDF5 dump and one DIAGPT HEFFSO handoff file.
Interpret degeneracies with the MPPT symmetry and convergence rules. Reconstructing MPPT need not preserve non-Kramers multiplets. S and applicable L/J completeness, selection and retained states affect the result; larger spaces need not reduce splittings monotonically. Passive covariance of fixed matrices and conditional time-reversal protection remain separate requirements.
Complete the environment-manager setup and
MPPT installation before using the build sections below.
Miniforge is the recommended bootstrap on Linux, including glibc 2.17 servers;
Micromamba is the lightweight fallback when a full base environment is
undesirable. The setup guide lists the distinct conda, mamba, and
micromamba commands.
After activating mppt in a new shell, repeat the GNU compiler exports from the
installation guide before configuring any build profile on this page.
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. When the variable is unset, HEFFSO openspyscf_dump.h5.The fixed
<prefix>heffso.h5handoff from DIAGPT, for examplePr_heffso.h5.A HEFFSO input file with
&sofil, a title line,&sort, and&ic.
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.
Properties#
Properties are enabled by default. Set properties=.false. in &sort, or set
mppt.heffso.properties: false in the unified YAML input, only when the
properties result is not needed. The enabled route requires full-space intdip
and intang datasets in the PySCF HDF5 file.
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. The total angular-momentum matrices satisfy
J = L + S component by component. The oscillator strength from state 1 is
(2/3) * (E_f - E_1) * sum_c |D_c(f,1)|^2; state 1 has oscillator strength zero.
The Cartesian sum is also stored as the state-indexed E1 line strength.
For Q in L, S, and J, HEFFSO stores
Q2(n) = sum_(c,m) |Q_c(n,m)|^2 and the nonnegative effective value q
defined by q(q+1)=Q2. These values describe the retained HEFFSO state basis;
they do not assign term symbols or certify complete multiplets.
The run writes <prefix>heffso_properties.h5 with schema
mppt_heffso_properties_v4. For n HEFFSO states, its required root
attributes are:
Attribute |
Value or meaning |
|---|---|
|
|
|
one-based state IDs, |
|
|
|
vacuum energy added to the HEFFSO eigenvalues |
|
|
|
|
|
|
|
|
|
Cartesian state-1 dipole norm, |
|
retained-state Cartesian norm and |
|
|
|
scalar consistency residuals |
Required datasets are:
Dataset |
Shape |
Meaning |
|---|---|---|
|
|
contiguous one-based state IDs |
|
|
absolute electronic energies in Hartree |
|
|
dimensionless oscillator strength from state 1 |
|
|
Cartesian state-1 E1 line strength |
|
|
squared angular values from retained-state matrices |
|
|
real diagonal of |
|
|
effective angular values from |
|
|
normalized |
|
|
normalized |
|
|
split-complex Cartesian |
|
|
split-complex Cartesian |
|
|
split-complex Cartesian |
|
|
split-complex Cartesian dipole matrices |
Schema v4 also requires complete /solver, /determinant_identity and
/magnetic groups. The root write_complete=1 marker is written only after all groups and root
datasets are complete.
Magnetic controls#
Magnetic output inherits enabled properties. The YAML subsection is
mppt.heffso.magnetic_properties; the manual &sort equivalents are:
magnetic_properties=.true.,
magnetic_spin_g=2.00231930436092,
magnetic_degeneracy_tolerance=1.d-8,
magnetic_nfields=2, magnetic_ntemperatures=2,
magnetic_fields(:,1)=0.d0,0.d0,0.d0,
magnetic_fields(:,2)=0.d0,0.d0,1.d0,
magnetic_temperatures(1)=2.d0, magnetic_temperatures(2)=300.d0,
magnetic_susceptibility=.true., magnetic_store_field_matrices=.false.,
Fields are in tesla and temperatures in kelvin; both counts default to zero
and are bounded by 256. The magnetic-moment operator at zeroth order in the
MPPT perturbation is -(L + spin_g*S) in μB, projected into retained SOC states.
The MPPT2 Hamiltonian does not add first- or second-order corrections to this
operator. The Zeeman interaction is linear in the external field.
HEFFSO preserves zero-field gaps, reports principal g only for eligible
isolated Kramers pairs, and computes optional M and differential χB natively.
See Magnetic Properties for the model, formulas
and interpretation, the YAML controls for defaults
and dependencies, and Outputs for
the magnetic-v1 datasets and applicability codes.
/solver uses schema mppt_heffso_solver_diagnostics_v1. It records the
PRIMME backend and method, matrix dimension, requested and converged root counts,
return status, iteration/restart/matvec/preconditioner counters, eps, a_norm,
inv_b_norm, the resulting convergence limit, bounded orthogonality metrics,
and solver timings. Its root_residual_norm_hartree dataset has shape (n,).
The matrix dimension must equal the number of determinant rows, every requested
root must converge, and every residual must satisfy the stored convergence
limit.
/determinant_identity uses schema
mppt_heffso_determinant_identity_v1. It stores contiguous one-based
determinant_id with shape (ndet,) and signed-int64
determinant_alpha_bits and determinant_beta_bits with shape
(ndet,nword). Bits are least-significant-bit first. The stored spatial-orbital
window is the smallest interval in which any final determinant differs from the
closed-shell vacuum; orbitals outside it are defined by that vacuum. An
all-vacuum catalog uses determinant_orbital_start=0, count and word count zero,
and bit-matrix shape (ndet,0). The
determinant_content_hash_fnv1a64 attribute binds dimensions, row IDs, and both
determinant-major bit matrices using signed-int64 little-endian FNV-1a.
An explicit properties=.false., invalid-input, or failed run removes any
existing current properties artifact, so stale enabled-run output is not
exposed as current. 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_properties
result = read_heffso_properties("Pr_heffso_properties.h5")
print(result.state_energy_hartree)
print(result.oscillator_strength)
print(result.line_strength)
print(result.state_j)
print(result.j_matrix.shape) # (3, n, n)
print(result.solver.root_residual_norm_hartree)
print(result.determinant_identity.alpha_bits.shape) # (ndet, nword)
The returned arrays own their data and are read-only; the source HDF5 handle is
closed before the reader returns. The reader validates the v4 metadata, shapes,
finiteness, Hermiticity, J = L + S, derived angular values, line strengths,
oscillator strengths, persisted residuals, solver evidence, determinant minimality, and
the determinant hash.
Human Report#
The bounded primary console report contains:
SOLVER DIAGNOSTICS, a fixed-size PRIMME summary; complete per-root residuals remain in HDF5;SPIN-ORBIT STATES, withstate, absoluteEh,dE / eV,dE / cm-1,S^2,J^2, andoscillator strengthwhen properties are enabled;ANGULAR PROPERTIES;PROPERTIES VALIDATION;PROPERTIES SUMMARY.
HEFFSO writes active-orbital occupations to
<prefix>heffso_occupancy_analysis.log and dominant configuration weights to
<prefix>heffso_configuration_analysis.log. Both files are required for every
successful run, including properties=.false.. The primary report then contains
only SOLVER DIAGNOSTICS and SPIN-ORBIT STATES in disabled mode.
Property matrices and complete state-1 line strengths are HDF5-only. The primary
state table already prints every relative energy and oscillator strength, so no separate
E1 transition table duplicates those rows. Oscillator strengths in the state table and
strongest-transition summary use scientific notation; every other HEFFSO report
and solver value uses fixed decimal notation. Hermiticity, J = L + S, and the
oscillator-strength formula use strict PASS/FAIL status. Angular commutators use
PASS/OPEN, because algebra closure is not guaranteed in an incomplete
retained state span.
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 |
The automatic block is bounded by the resolved basis, including a small explicit
primme_max_basis. This leaves room for PRIMME’s retained vectors and restart
space: a 14-dimensional full-spectrum problem with eight threads now selects
block 3 instead of block 8. The requested root count and tolerance are unchanged.
Explicit nonzero block sizes are not automatically reduced.
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 on Linux x86-64 is CPU oneMKL:
PRIMME for the final eigensolver.
oneMKL BLAS/LAPACK for dense projected operations.
oneMKL Sparse BLAS for HEFFSO sparse Hamiltonian matrix-vector products.
On first successful sparse-handle creation, HEFFSO writes
HEFFSO oneMKL sparse backend active to its primary log. Production acceptance
uses this marker and rejects any subsequent oneMKL fallback diagnostic.
Activate mppt with the environment manager used during installation. Install
oneMKL into that same environment with one matching command below.
With conda from Miniforge, Miniconda, or Anaconda Distribution:
conda install -c https://software.repos.intel.com/python/conda \
mkl mkl-devel mkl-include intel-openmp
With mamba from Miniforge:
mamba install -c https://software.repos.intel.com/python/conda \
mkl mkl-devel mkl-include intel-openmp
With Micromamba:
micromamba install -c https://software.repos.intel.com/python/conda \
mkl mkl-devel mkl-include intel-openmp
Configure and build:
export MKL_THREADING_LAYER=GNU
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" \
-DMPPT_COPY_TO_HOME_BIN=OFF \
-DINSTALL_PYSCF2MPPT=OFF \
-DWITH_LIBGRPP=OFF \
-DWITH_MKL=ON \
-DWITH_MKL_SPARSE=ON \
-DWITH_CUDA_SPARSE=OFF
cmake --build build_heffso_mkl --target heffso
Recommended run environment:
export MKL_THREADING_LAYER=GNU
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
MKL_THREADING_LAYER=GNU keeps oneMKL on the same GNU OpenMP runtime as the
Fortran build. Do not select Intel’s OpenMP threading layer in the same process.
When built with WITH_MKL_SPARSE=ON, oneMKL Sparse BLAS is the production
default. To validate the portable Fortran/OpenMP path through the unified
workflow, use:
mppt:
heffso:
sparse_backend: fortran
direct_sparse: false
The workflow maps these settings to the backend environment and
primme_direct_sparse=.false.. For a manual namelist run, set
primme_direct_sparse=.false. directly. The oneMKL and portable paths preserve
the same numerical invariants; compare eigenvalues, converged subspaces for
degenerate roots, residuals, and observables rather than byte-identical
eigenvectors.
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" \
-DMPPT_COPY_TO_HOME_BIN=OFF \
-DINSTALL_PYSCF2MPPT=OFF \
-DWITH_LIBGRPP=OFF \
-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, provide the host’s actual library paths. This example uses Debian/Ubuntu Linux x86-64:
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 Hamiltonian 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" \
-DMPPT_COPY_TO_HOME_BIN=OFF \
-DINSTALL_PYSCF2MPPT=OFF \
-DWITH_LIBGRPP=OFF \
-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:
For oneMKL or CUDA profiles, set MKL_THREADING_LAYER=GNU in the test shell.
cmake --build <build_dir> --target heffso mppt_heffso_unit_tests \
mppt_heffso_properties_writer_probe
ctest --test-dir <build_dir> -L HEFFSO --output-on-failure
Smoke-test the Python/MPPT path:
ctest --test-dir <build_dir> -R '^workflows_yaml_hf_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
logs/heffso.log. Raw &sort input accepts
the complete primme_* contract listed above. Workflow YAML PRIMME controls
are authoritative at launch.
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:
<prefix>sovec(for YAML prefixPr, this isPr_sovec)<prefix>heffso_occupancy_analysis.log<prefix>heffso_configuration_analysis.log<prefix>heffso_properties.h5whenproperties=.true.the console table headed
state Eh dE / eV dE / cm-1 S^2 J^2 oscillator strengthwhen properties are enabled
Internal unformatted sequential and stream work units are anonymous compiler-managed scratch. They have no stable filenames and are neither durable outputs nor workflow cleanup targets.
Successful logs end with:
fin heffso
Performance Notes#
MKL Sparse BLAS is the default performance target on CPU.
Property calculation 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.