Stack position
4 of 6. This PR should be based on the backend interface PR.
Goal
Add an optional SpinGlassPEPS-backed solver path for structured Ising/Potts problems, without making SpinGlassPEPS a hard dependency for ordinary TenSolver users.
This PR should prove the integration at the direct Julia API level before exposing it through QUBODrivers/JuMP.
Context
SpinGlassPEPS is an umbrella reexport package. For implementation, prefer depending on and importing the component packages actually needed:
SpinGlassNetworks
SpinGlassEngine
SpinGlassTensors
The bridge should construct a SpinGlassNetworks Ising graph, cluster it into a Potts Hamiltonian, construct a SpinGlassEngine PEPS network, run MpsContractor, and call low_energy_spectrum.
This should be optional because SpinGlassPEPS components require Julia 1.11 and bring heavy CUDA/MKL/cuTENSOR-oriented dependencies.
Packaging approach
Preferred options, in order:
- A package extension if TenSolver can raise its Julia compatibility to support extensions cleanly.
- A separate bridge package, e.g.
TenSolverSpinGlassPEPS.jl, if keeping TenSolver's core compatibility and dependency footprint is more important.
- A clearly experimental branch-only prototype if dependency/version constraints block an extension.
Do not add SpinGlassPEPS components as mandatory [deps] in TenSolver's Project.toml.
API sketch
Add an optional backend object such as:
struct PEPSBackend <: AbstractTenSolverBackend
topology
beta
bond_dim
max_states
cutoff_prob
onGPU
contraction
truncation
transformations
end
The exact fields can differ, but the backend must capture:
- layout/topology
- inverse temperature
beta
- boundary MPS bond dimension
- branch-and-bound width
max_states
- probability cutoff
- CPU/GPU choice
- contraction strategy, initially
SVDTruncate for small square/king and Zipper for Pegasus/Zephyr
- optional local dimension reduction settings
- lattice transformations to try
Initial supported direct API should focus on structured inputs, for example:
minimize(Q, l, c; backend = PEPSBackend(SquareGrid(m, n), ...))
or:
solve_ising(J, h; backend = PEPSBackend(...))
The second option may be cleaner for this PR because it avoids pretending arbitrary QUBOs have a valid PEPS geometry.
Implementation details
Minimum useful path:
- Convert QUBO to Ising using the utilities from the prior PR.
- Build the SpinGlassNetworks instance accepted by
ising_graph.
- Build a cluster assignment rule:
super_square_lattice for square/king grids.
- Defer Pegasus/Zephyr until square/king works unless implementation is straightforward.
- Build a Potts Hamiltonian:
potts_h = potts_hamiltonian(
ising_graph(instance),
spectrum = full_spectrum,
cluster_assignment_rule = lattice,
)
- Build a PEPS network:
SquareSingleNode{GaugesEnergy} for square grids.
KingSingleNode{GaugesEnergy} for king grids.
SquareCrossDoubleNode{GaugesEnergy} for Pegasus/Zephyr later.
- Build contractor parameters:
params = MpsParameters{T}(; bond_dim = bond_dim, num_sweeps = num_sweeps)
search_params = SearchParameters(; max_states = max_states, cutoff_prob = cutoff_prob)
- Run:
ctr = MpsContractor(strategy, net, params; onGPU, beta, graduate_truncation)
sol, info = low_energy_spectrum(ctr, search_params, merge_strategy)
- Decode SpinGlassPEPS states back to Ising spins and then to Boolean vectors.
- Return a TenSolver-compatible result.
Result adaptation
Add a PEPS-specific result wrapper if needed, but make sure the public path can provide:
- best objective value in the original Boolean QUBO convention
- one or more Boolean states
- source backend metadata
- raw PEPS metadata under an explicit field or metadata dictionary
Metadata should include:
backend = "SpinGlassPEPS"
- topology/layout
beta
bond_dim
max_states
cutoff_prob
- transformations tried
- selected transformation
- SpinGlassPEPS solution energies/probabilities if available
largest_discarded_probability if available
Tests
Start with small CPU-only tests.
Required tests:
- small square grid Ising/QUBO instance with known exact solution
- compare PEPS backend result to brute force for small sizes
- verify decoded Boolean vector evaluates to the returned TenSolver objective
- verify backend not loaded unless extension/package is available
- verify default DMRG backend remains unaffected
Optional tests:
- king grid with diagonals
- multiple lattice transformations
- deterministic path with
onGPU = false
Avoid requiring CUDA in CI.
Acceptance criteria
- A PEPS-backed direct API works for at least one small structured grid case on CPU.
- SpinGlassPEPS component packages are optional, not mandatory TenSolver dependencies.
- Returned solutions are decoded back to TenSolver Boolean conventions.
- Exact small tests prove objective consistency.
- Existing DMRG and QUBODrivers tests continue to pass.
Out of scope
- QUBODrivers/JuMP user-facing attributes.
- Large Pegasus/Zephyr benchmarks.
- Making PEPS the default backend.
- Reimplementing SpinGlassPEPS internals inside TenSolver.
Stack position
4 of 6. This PR should be based on the backend interface PR.
Goal
Add an optional SpinGlassPEPS-backed solver path for structured Ising/Potts problems, without making SpinGlassPEPS a hard dependency for ordinary TenSolver users.
This PR should prove the integration at the direct Julia API level before exposing it through QUBODrivers/JuMP.
Context
SpinGlassPEPS is an umbrella reexport package. For implementation, prefer depending on and importing the component packages actually needed:
SpinGlassNetworksSpinGlassEngineSpinGlassTensorsThe bridge should construct a SpinGlassNetworks Ising graph, cluster it into a Potts Hamiltonian, construct a SpinGlassEngine PEPS network, run
MpsContractor, and calllow_energy_spectrum.This should be optional because SpinGlassPEPS components require Julia 1.11 and bring heavy CUDA/MKL/cuTENSOR-oriented dependencies.
Packaging approach
Preferred options, in order:
TenSolverSpinGlassPEPS.jl, if keeping TenSolver's core compatibility and dependency footprint is more important.Do not add SpinGlassPEPS components as mandatory
[deps]in TenSolver'sProject.toml.API sketch
Add an optional backend object such as:
The exact fields can differ, but the backend must capture:
betamax_statesSVDTruncatefor small square/king andZipperfor Pegasus/ZephyrInitial supported direct API should focus on structured inputs, for example:
or:
The second option may be cleaner for this PR because it avoids pretending arbitrary QUBOs have a valid PEPS geometry.
Implementation details
Minimum useful path:
ising_graph.super_square_latticefor square/king grids.SquareSingleNode{GaugesEnergy}for square grids.KingSingleNode{GaugesEnergy}for king grids.SquareCrossDoubleNode{GaugesEnergy}for Pegasus/Zephyr later.Result adaptation
Add a PEPS-specific result wrapper if needed, but make sure the public path can provide:
Metadata should include:
backend = "SpinGlassPEPS"betabond_dimmax_statescutoff_problargest_discarded_probabilityif availableTests
Start with small CPU-only tests.
Required tests:
Optional tests:
onGPU = falseAvoid requiring CUDA in CI.
Acceptance criteria
Out of scope