SU(
Some of the features of SU(
- maximally efficient storage strategy for standard Young tableaux (SYTs)
- fast indexing of SYTs
- NUMA-aware first-touch allocation of large arrays
- on-node parallelization with OpenMP
- distributed-memory multi-node parallelization with MPI
The figure below shows the strong scaling of the matrix-vector multiplication (MVM) runtime obtained on four different systems (Hamiltonian matrix of dimension 1.26 billion and 13.67 billions, with and without next-nearest neighbor (NNN) interaction), versus number of compute nodes. Each node has 192 cores.
Details: This plot shows the MVM runtime for the SU(4) Heisenberg model on a triangular lattice with 24 sites with simulation torus
Following the topology of the AMD Epyc 9654 socket, we bind each die of a node to a MPI process, thus 8 cores per MPI process, 24 processes per node. All cores on a die work in parallel on their section of the Hilbert space, which is memory-distributed among all processes.
| Number of sites | Model | Irrep | Dimension | Number of bonds | Number of operators | Line color | |
|---|---|---|---|---|---|---|---|
| 4 | 24 | Plain Heisenberg (nearest neighbor only) | Adjoint | 1.26 billion | 72 | 616 | red |
| 4 | 24 | Heisenberg + next-nearest neighbor | Adjoint | 1.26 billion | 144 | 1688 | blue |
| 4 | 28 | Plain Heisenberg (nearest neighbor only) | Singlet | 13.67 billions | 84 | 884 | green |
| 4 | 28 | Heisenberg + next-nearest neighbor | Singlet | 13.67 billions | 168 | 2368 | magenta |
- CMake (minimum version 3.21)
- C++ compiler with standard 20
- OpenBLAS
- OpenMP
- (optional but recommended) MPI
SU(src/nlohmann/.
SU(
Start by cloning the repository:
git clone git@github.com:sgozel/SUNED.git
cd ./SUNED
You can then simply invoke the Makefile at the root of the directory:
make
This will build the MPI executables for energy eigenvalues, eigenpairs and correlations with some predefined configuration (see below). Alternatively, you can configure you own specific build using the usual CMake commands:
cmake -S . -B build/release_special_build/ -DCMAKE_BUILD_TYPE=Release <SUNED OPTIONS>
cmake --build build/release_special_build/
where the <SUNED OPTIONS> are described in the next section.
The following options can be provided to the cmake command at configure time to customize the build:
| Option | Description | Default value |
|---|---|---|
SUNED_EIGVALS |
Build eigenvalue extraction only (no eigenvector) | ON |
SUNED_EIGVECS |
Build eigenvector extraction | OFF |
SUNED_CORRELATIONS |
Build correlations extraction | OFF |
SUNED_USE_MPI |
Build MPI implementation for multi-node distributed-memory version | ON |
SUNED_LANCZOS_TWO_VECTORS |
Build Lanczos with two vectors | OFF |
SUNED_USE_NUMA |
Use NUMA-aware memory allocation of Lanczos vectors | OFF |
SUNED_STORE_COLUMNS |
Store column-SYTs instead of rows-SYTs | OFF |
SUNED_USE_VSYT |
Build with basic storage strategy for SYTs | OFF |
SUNED_BSYT_NBITS |
Number of bits per box for bSYT |
2 |
SUNED_BSYT_CONTAINER_SIZE |
Number of bytes per SYT for bSYT |
8 |
SUNED_USE_VSYT=ON leads to a larger memory usage and a less efficient (slower) search across SYTs. It is also slower when applying transpositions on SYTs. It is thus not recommended for production runs. See this page for more details.
Before executing the code, set the OMP variables:
export OMP_NUM_THREADS=...
export OMP_PROC_BIND=close
export OMP_PLACES=cores
The following table describes all possible input parameters to the SUNED executables, with their eventual default values. These parameters can be fed to the executables in two different compatible ways:
- as a flat
.jsonfile, such as the one provided at the root of theSUNEDdirectory; - as command line
--key valuepairs on the call of the executable.
The rule is that any --key value pair provided on the command line will override the associated pair in the input .json file, if provided. We provide below a few illustrative examples.
| Input | Description | Default value if optional |
|---|---|---|
N |
SU( |
|
Ns |
Number of sites | |
alpha |
Target sector (irrep) | |
latticefile |
Path to lattice file | |
seed |
Seed for Lanczos initialization vector | 42 |
max_iter |
Maximum number of Lanczos iterations | 1000 |
tol_ritz |
Tolerance on Ritz value stabilization in Lanczos | 1e-12 |
tol_residual |
Tolerance on residual in Lanczos | 1e-12 |
convergence_check_frequency |
Frequency of convergence check in Lanczos | 1 |
dump_eigvec |
Write eigenvector to file | true |
eigvec_folder_path |
Folder path for eigenvector | . |
logging |
Log convergence data during Lanczos | true |
logging_full |
Log full spectrum during Lanczos | false |
logging_folder_path |
Folder path for logging data | . |
logging_frequency |
Logging frequency | 1 |
checkpointing |
Checkpoint Lanczos iterations for restarting | false |
checkpoint_folder_path |
Folder path for checkpoints | . |
checkpoint_frequency |
Checkpointing frequency | 5 |
keep_checkpoint |
Keep checkpoint on disk after convergence | false |
dump_matrices |
Write matrices |
false |
matrix_dump_folder_path |
Folder path for |
. |
dump_counts |
Write counts of local and remote pairs of SYTs in each |
false |
counts_dump_folder_path |
Folder path for counts | . |
dump_runtime |
Write runtimes to files | false |
n_mvm_runtime |
Number of MVMs for which runtime is written to file | 10 |
runtime_dump_folder_path |
Folder path for runtimes | . |
correlation_refsite |
Reference site |
0 |
/path/to/main data.json
/path/to/main --N 4 --Ns 10 --alpha '[3,3,2,2]' --latticefile /path/to/latticefiles/HB_chain_10_OBC.lattice --J 1.0
This is the simplest minimal example for running a job with SUNED.
/path/to/main data.json --checkpointing true --checkpoint_folder_path /scratch/jobid2026/
This is the most useful when executing jobs on a cluster, in particular for job arrays.
SU(.json file, with key latticefile). A lattice file is a very generic description of the geometric lattice, and of the underlying interactions. It must have the following structure:
[sites]=<number of sites>
0 x0 y0 z0
1 x1 y1 z1
2 x2 y2 z2
...
[interactions]=<number of interactions (bonds)>
couplingName0 (siteA0, siteB0)
couplingName1 (siteA1, siteB1)
...
where x0, y0, z0 are the <number of sites> rows with this format after the [sites]=<number of sites> instruction. Each line after the [interactions]=<number of interactions (bonds)> instruction begins with the name of a coupling constant, which is then followed by a cycle (in the permutation sense) which describes the sites involved in the interaction.
Below are two examples of lattices.
Chain lattice with 5 sites and open boundary conditions, with isotropic nearest neighbor coupling
[sites]=5
0 0 0 0
1 1 0 0
2 2 0 0
3 3 0 0
4 4 0 0
[interactions]=4
J (0, 1)
J (1, 2)
J (2, 3)
J (3, 4)
Chain lattice with 5 sites and periodic boundary conditions, with isotropic nearest neighbor coupling
[sites]=5
0 0 0 0
1 1 0 0
2 4 0 0
3 2 0 0
4 3 0 0
[interactions]=10
J (0, 1)
J (1, 3)
J (3, 4)
J (2, 4)
J (0, 2)
K (0, 3)
K (1, 4)
K (2, 3)
K (0, 4)
K (1, 2)
The coupling name(s) must then be provided in the .json file with their numerical value(s). For instance, for the 5-sites chain with coupling constants
"N": 3,
"Ns": 5,
"alpha": [2, 2, 1],
"latticefile": "/path/to/latticefile.lattice",
"J": 1.0,
"K": -0.5,
...
Note that in the case of the 5-sites periodic chain above, we did not number the sites in a sequential way when turning around the ring. This is a general optimization. Indeed, the algorithmic complexity of this ED algorithm is linear in the total number of elementary operators
lattice_optimizer also provides a convenient Python script for plotting a lattice.
To compile tests:
make build_tests_mpi
The three following repositories, written by the same author, are closely related to SU(
- lattice_optimizer: reduce the computational cost of ED by performing a graph optimization based on the specified Hamiltonian.
-
suned_analysis: a set of Python scripts to plot data obtained with SU(
$N$ )ED, in particular ED spectra. -
SUN4Py: an extended Python library to perform ED and DMRG calculations on SU(
$N$ ) models.
If you use any of the codes of this repository in your work, you are invited to cite it as explained in the CITATION.cff file. Your are also invited to cite the two following articles:
@misc{gozel_spectral_2026,
title = {Spectral Mapping Theorem between SU(N) and SU(Ns/N) Heisenberg Models and Exact Diagonalization of SU(4) and SU(7) Long-Range Ordered Phases on the Triangular Lattice},
author = {Samuel Gozel and Pierre Nataf},
year = {2026},
eprint = {2610.15162},
archivePrefix = {arXiv},
primaryClass = {cond-mat.str-el},
url = {https://arxiv.org/abs/2610.15162}
}
@article{nataf_exact_2014,
title = {Exact Diagonalization of Heisenberg $\mathrm{SU}(N)$ Models},
author = {Nataf, Pierre and Mila, Fr\'ed\'eric},
journal = {Phys. Rev. Lett.},
volume = {113},
issue = {12},
pages = {127204},
numpages = {5},
year = {2014},
month = {Sep},
publisher = {American Physical Society},
doi = {10.1103/PhysRevLett.113.127204},
url = {https://link.aps.org/doi/10.1103/PhysRevLett.113.127204}
}
The code is licensed under GNU GPL-v3.0 as given in the file LICENSE.
Samuel Gozel
