Conversation
bernalde
left a comment
There was a problem hiding this comment.
GitHub rejected REQUEST_CHANGES because the authenticated account owns this pull request. The findings below are blocking from a maintainer review perspective. I would not merge this until the blocking issues above are addressed.
f4a3769 to
009bcd1
Compare
cb9598f to
ca890fc
Compare
|
Pushed commit Main changes:
Tests run:
Notes on tests not cleanly runnable:
Comments intentionally not addressed:
Remaining risks/follow-up:
|
bernalde
left a comment
There was a problem hiding this comment.
Fresh review of the current net diff: I did not find blocking issues. The PEPS scaffold is now kept out of exports/public API docs, and the restored Val backend dispatch preserves the extension hook. I left two nonblocking comments on test coverage and documentation wording.
|
Pushed commit Main changes:
Tests run:
Comments intentionally not addressed:
Remaining risks/follow-up:
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feature/issue-37-backend-interface #44 +/- ##
=====================================================================
Coverage ? 72.84%
=====================================================================
Files ? 6
Lines ? 475
Branches ? 0
=====================================================================
Hits ? 346
Misses ? 129
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
bernalde
left a comment
There was a problem hiding this comment.
Reviewed the current net diff against feature/issue-37-backend-interface. No blocking or nonblocking inline issues found. The PEPS scaffolding remains internal, solve_ising is covered as public API, and the updated tests cover the newly public behavior and internal boundary sufficiently for this PR.
GitHub would not let me submit APPROVE because this account is the PR author: "Review Can not approve your own pull request".
Tests run locally:
- git diff --check origin/feature/issue-37-backend-interface...HEAD
- julia --project=. -e "using Pkg; Pkg.test()"
- julia --project=. -e "using Test, Random, LinearAlgebra, TenSolver; include("test/utils.jl"); include("test/backend.jl"); include("test/peps_backend.jl")"
- julia +1.12 --project=. -e "using Test, Random, LinearAlgebra, TenSolver; include("test/utils.jl"); include("test/backend.jl"); include("test/peps_backend.jl")"
- julia --project=. targeted solve_ising exact-energy probe
- julia --project=docs/ -e "using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()"
- julia --project=docs/ docs/make.jl local
The optional SpinGlassPEPS extension path still cannot be exercised locally because SpinGlassNetworks/SpinGlassEngine/SpinGlassTensors cannot currently resolve with this package dependency stack; the PR documents that limitation and keeps the PEPS backend internal.
Merge recommendation: merge-ready from this review pass.
bernalde
left a comment
There was a problem hiding this comment.
Senior maintainer review. Note: I am the PR author, so GitHub only permits a COMMENT event from me; a formal approval or change-request must come from another maintainer. No blocking issues; one substantive Question for the reviewer below.
Diff verification: confirmed against the stacked base feature/issue-37-backend-interface (not main). merge-base 009bcd1; git diff <merge-base>..HEAD --stat = 10 files, +646 / -5, matching the PR's reported totals.
Issue intent (#38): add an optional SpinGlassPEPS-backed path without making SpinGlassPEPS a hard dependency; reuse the #42 conversions; decode back to Boolean and report the objective in TenSolver's convention; keep DMRG default; guard tests so absence of the heavy dep / Julia 1.10 does not break core CI. The PR satisfies all of these.
Optionality — PASS: the three SpinGlass packages are in [weakdeps] + [extensions] (TenSolverSpinGlassPEPSExt), not in [deps]. julia = "1.10" is left unchanged (no silent breaking bump); the extension mechanism is valid on 1.10.
Julia-compat reality (Question, not a blocker): I confirmed empirically on Julia 1.10.11 that SpinGlassNetworks@1.4/SpinGlassTensors@1.3 are unresolvable (resolver: "restricted by julia compatibility ... no versions left"). So on the only CI-able Julia (1.10) the weakdeps can never install, the extension never loads, and ordinary users are unaffected — but the entire SpinGlassPEPS bridge is therefore dead/untested-on-CI until TenSolver raises compat to 1.11. The PR is honest about this and keeps the PEPS types internal/unexported. For the reviewer to decide: merge now as the "experimental scaffolding" #38 explicitly permits (option 3), or defer activation until compat is raised to 1.11. Not blocking under #38's stated acceptance.
Bridge correctness (static; heavy dep not runnable here) — looks correct: _minimize(::PEPSBackend, ...) reuses qubo_to_ising; the reported objective is recomputed independently in TenSolver's convention via _decoded_records (decode Potts -> spins -> spin_to_bool -> ising_energy), not trusting SpinGlassPEPS's raw_energy (kept as metadata) — this sidesteps any sign/offset mismatch between the libraries. _ising_instance maps diagonal=biases, off-diag=couplings, consistent with the upper-triangular canonical J. The DMRG solve_ising round trip is verified by the new passing test.
Default unchanged — PASS. Tests guarded — PASS: test/peps_backend.jl gates the extension test on Base.find_package for all three components and uses @test_skip (observed as "Broken 1", i.e. skipped, on 1.10); the always-run "PEPS backend core" tests only the available types/validation.
Nonblocking
src/solution.jlnarrowsBase.in(bs, psi)toBase.in(bs::AbstractVector, psi). All in-repo callers pass vectors and tests pass, but this is a subtle public-API signature narrowing — confirm intended.src/TenSolver.jladdsexport Solution(previously unexported). Purely additive/non-breaking;PEPSSolution/PEPSBackend/SquareGrid/KingGridare intentionally not exported.ext/...Ext.jl_metadatareads SpinGlassEngineSolutionfields (energies/probabilities/largest_discarded_probability); plausible but unverifiable without the dep — confirm against SpinGlassEngine 1.6 when the path is first exercised.
Tests run (Julia 1.10.11):
julia --project=. -e 'using Pkg; Pkg.instantiate(); Pkg.test()'— passed (Testing TenSolver tests passed): Backend interface 25/25, PEPS backend core 34/34, Optional SpinGlassPEPS extension = 1 Broken (skipped as expected), QUBODrivers 128/128, Aqua 11/11, VRP/HDF5/Doctests pass.- Adversarial install:
Pkg.add(SpinGlassNetworks@1.4)on fresh 1.10 -> resolve failed with explicit julia-compat exclusion (confirms uninstallable on 1.10; expected, not a PR failure).
Merge readiness: No blocking issues. The PR honors #38: optionality via package extension (not [deps]), DMRG default preserved, conversions reused, objective decoded into TenSolver's Boolean convention, tests properly guarded, core suite green on 1.10. The substantive caveat is the Question above: the bridge is uninstallable/untested on CI Julia and remains so until compat is raised to 1.11; merge as documented scaffolding or defer, and track a follow-up to exercise it under 1.11. Stacked on #43 and must merge after it. The formal verdict must come from another maintainer.
| SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" | ||
|
|
||
| [weakdeps] | ||
| SpinGlassEngine = "0563570f-ea1b-4080-8a64-041ac6565a4e" |
There was a problem hiding this comment.
Question for the reviewer: these weakdeps require Julia 1.11, but TenSolver declares julia = "1.10". I confirmed SpinGlassNetworks@1.4 / SpinGlassTensors@1.3 are unresolvable on 1.10, so the extension can never load on the only CI-able Julia — the whole bridge is dead/untested on CI until compat is raised to 1.11. Optionality is correct (weakdeps, not deps), so not a blocker; decide whether to merge as experimental scaffolding (allowed by #38) or defer activation, and track a follow-up to exercise it under 1.11.
There was a problem hiding this comment.
Not changed in this pass. I am keeping this as experimental scaffolding rather than raising TenSolver's Julia compat or adding an activation path here. Follow-up remains to exercise the extension under Julia 1.11 or once the SpinGlass compat stack resolves.
There was a problem hiding this comment.
Status update: the resolvability blocker is now precisely diagnosed and filed upstream. On Julia 1.10 (our LTS CI) the stack can never load because SpinGlassEngine 1.6 requires julia = "1.11". On Julia 1.11 the minimal failing pair is SpinGlassNetworks@1.4 + ITensors: NDTensors hard-depends on InlineStrings (Parsers 2.x) while SpinGlassNetworks pins CSV = "0.8" (Parsers ≤ 1.1.2). Filed as euro-hpc-pl/SpinGlassNetworks.jl#23 with a suggested compat widening. The scaffolding stance here is unchanged; activation is tracked on #38.
There was a problem hiding this comment.
The extension remains experimental scaffolding on the current head. I did not raise TenSolver's Julia compatibility or make the SpinGlass packages hard dependencies; the PR still uses Refs #38, and the real optional-stack CPU exercise remains follow-up work for #38.
There was a problem hiding this comment.
Status unchanged at current head 33764cb: the extension remains experimental scaffolding; TenSolver compatibility and weak-dependency status are unchanged, and the real optional-stack CPU exercise remains follow-up work under #38.
bernalde
left a comment
There was a problem hiding this comment.
Senior maintainer review of PR #44 ("Add optional SpinGlassPEPS backend"), diffed against the merge-base of origin/feature/issue-37-backend-interface and the PR head (009bcd1). Reproduced totals: 10 files, +646/-5. Only issues introduced by #44 itself are flagged; the #41-#43 base chain is treated as inherited.
Process note: I am the PR author, so GitHub only permits an event = COMMENT from this account. A formal approve/request-changes must come from another maintainer.
Test execution: the review sandbox denied julia and git (including with sandbox disabled), so I could not run the suite locally. Findings are from static review of the head sources plus CI. CI is green at the head SHA across all 12 check-runs (Julia 1/lts/pre x ubuntu/macOS/windows, build, docs, codecov). Caveat: CI ran with the stack cut from old main, and the optional SpinGlassPEPS path is @test_skip-ped because the component packages are not installed in CI, so the real PEPS solve and decode path is NOT exercised by any automated test.
Optionality mechanism (verified correct): the SpinGlass components are declared under [weakdeps] + [extensions] (TenSolverSpinGlassPEPSExt), not hard [deps]. Compat bounds are set (SpinGlassEngine 1.6, SpinGlassNetworks 1.4, SpinGlassTensors 1.3; QUBOTools widened to "0.10, 0.11"). When the extension is not loaded, PEPSBackend solves throw a clear ArgumentError naming the three packages and pointing to backend = :dmrg (covered by test/peps_backend.jl). This satisfies issue #38's "do not add SpinGlassPEPS as mandatory deps" requirement and the packaging-option-1 (extension) preference. Ordinary installs keep the existing dependency footprint.
Mapping correctness (static): _ising_instance builds the SpinGlassNetworks dict from model.h (diagonal) and the upper-triangle of model.J, which matches IsingModel's objective offset + sum(h_i s_i) + sum_{i<j} J_ij s_i s_j. The constant offset is intentionally dropped from the instance and reintroduced by recomputing the final energy via ising_energy(model, spins), so returned energies are in TenSolver's original convention. Decode uses decode_potts_hamiltonian_state then spin_to_bool. Square/king super_square_lattice clustering and the SquareSingleNode/KingSingleNode{GaugesEnergy} networks follow the issue's implementation sketch. Multi-spin-per-site is handled in _check_layout_edges by skipping intra-cell couplings (ci == cj). I did not find a correctness bug in the mapping by inspection, but see the no-coverage caveat below.
- Blocking
None introduced by this PR. The mapping/decoding code is plausible but completely unexercised by CI (the only test that would run it is skipped). I am not raising this to Blocking because issue #38 explicitly anticipates this as packaging-option-3 ("clearly experimental branch-only prototype if dependency/version constraints block an extension") and the PR keeps the PEPS types unexported and out of the public API docs. But it is the single largest risk: 244 lines of extension logic ship with zero executed-path coverage. See Questions.
- Nonblocking
Nonblocking: sample/prob/in on PEPSSolution operate on the deduplicated retained states, and _deduplicated_records keeps only the first record per Boolean state. Duplicate states' probability mass is therefore dropped rather than summed, and sample's cumulative-weight draw uses the un-renormalized retained probabilities. This is acceptable for "retained states" semantics but is a latent fidelity gap if two PEPS records decode to the same Boolean vector; a one-line comment or summing duplicates in prob would make the intent explicit.
Nonblocking: in TenSolver._solve_ising the per-transformation loop uses try ... finally clear_memoize_cache() with no catch. If any single transformation in transformations = :all throws inside SpinGlassEngine, the whole solve aborts even when other transformations would have succeeded. Issue #38 frames transformations as a set "to try"; consider catching and recording per-transform failures so one bad transform does not fail the solve. Not blocking since the default-path correctness is unaffected.
Nonblocking: the cutoff keyword (always injected by minimize(...; cutoff = 1e-8)) is silently absorbed by the extension's _solve_ising(...; cutoff = nothing, ...) and ignored. That is the right behavior for a DMRG-specific knob, but the extension's strict "Unsupported PEPS backend keyword(s)" guard relies on cutoff (and verbosity) being explicitly captured. A short comment noting that cutoff is intentionally accepted-and-ignored would prevent a future refactor from accidentally routing it into the kwargs guard and breaking minimize(Q; backend = PEPSBackend(...)).
- Questions
Question: Closes #38. Issue #38's acceptance criteria require "A PEPS-backed direct API works for at least one small structured grid case on CPU" and "Exact small tests prove objective consistency." Because the SpinGlass stack does not resolve in the TenSolver environment (documented in the PR body and in docs/src/spinglasspeps_integration.md), that acceptance test is skipped, not passing. The core scaffolding, error handling, and DMRG-path solve_ising tests do pass. Given the real PEPS solve was never executed end-to-end, should this be Refs #38 (keeping #38 open until the component stack resolves and the gated test actually runs) rather than Closes #38? As written, merging would auto-close #38 while its primary acceptance criterion remains unverified.
Question: export Solution is added to src/TenSolver.jl. Solution was previously unexported (documented via TenSolver.Solution in api.md). Exporting it is a public-API surface change that is unrelated to the SpinGlassPEPS backend goal of this PR. Is this intentional and in scope for #44, or stack drift that belongs in a separate change?
- Tests run and outcomes
Local execution blocked: julia and git were both denied by the review sandbox (confirmed even with sandbox disabled; not retried). Verified statically from head sources via gh pr diff/gh api contents. CI: all 12 check-runs success at head f3c4db1 (build, docs deploy, codecov patch+project, and the 9 Julia matrix jobs). The optional SpinGlassPEPS test is skipped in CI (Base.find_package returns nothing for the components), so the actual PEPS solve/decode path has no executed coverage anywhere.
- Merge-readiness
Not mergeable yet, primarily due to the stacked-base dependency, not code defects. PR #44's base is feature/issue-37-backend-interface (PR #43, still OPEN), which itself chains through #42 -> #41 -> main. #44 cannot merge until #41, #42, and #43 merge first. Additionally, the whole #41..#46 stack was cut from old main (ca27880); current origin/main is 9a3dd5c (v0.2.0, with #49/#53/#54 merged), so the stack is stale and carries rebase/conflict risk against current main (Project.toml compat and exports are likely touch points). CI green here was computed on the stale base. No code changes are required from a correctness standpoint; the nonblocking items and the Closes #38 vs Refs #38 question above are the substantive follow-ups.
I would not merge this until the stacked base chain (#41-#43) merges and the stack is rebased onto current main; the Closes #38 linkage should also be reconsidered given the PEPS solve path is not exercised by CI.
|
Pushed commits:
Main changes:
Tests run:
Comments intentionally not addressed:
Remaining risks or follow-up:
|
|
Commits pushed:
Main changes made:
Tests run and results:
Comments intentionally not addressed:
Remaining risks or follow-up items:
|
d4c1b35 to
dc92d85
Compare
d5207ae to
673cd63
Compare
iagoleal
left a comment
There was a problem hiding this comment.
General comments:
- we should try to keep the API as unified as possible.
- minimize / maximize or JuMP as only solver entry-points;
- PEPSBackend should be similar to DMRG;
- There should be an abstract
Solutiontype with a clear interface and each backend may then specialize to a subtype of its own. (Or just a generalSolutiontype that is general enough to work for all backends) - Let's keep the file structure organized:
solver.jlfor general solver inteface,backend/*.jlfor the backends properly. - Only export methods that the user should see. Keep internal helpers internal.
- I like that most of the hard word is being done at an extension level.
- For easier autocomplete / style, do not start function names with an underline.
- With the latest rebase, some stuff got duplicated and some other broke. We have to investigate how to properly update this PEPS code to align it with the current main branch.
I still didn't have the time to deep dive into the backend code itself. But these point should already get things running.
There was a problem hiding this comment.
This file must be merged with docs/internal/spinglasspeps_integration.md. During the branch rebasing, we ended up with both of them.
There was a problem hiding this comment.
Merged. The docs/src copy was the newer one (post-#43 content), so its content now lives at docs/internal/spinglasspeps_integration.md and the docs/src duplicate is gone, along with its entries in docs/make.jl and docs/DOCUMENTATION.md — the design note is internal-only again.
There was a problem hiding this comment.
Still addressed on the current head: there is one design note at docs/internal/spinglasspeps_integration.md, and the duplicate docs/src copy remains removed.
There was a problem hiding this comment.
Still addressed at current head 33764cb: the single SpinGlassPEPS design note remains at docs/internal/spinglasspeps_integration.md, with no duplicate under docs/src.
|
|
||
| - **Home** (`docs/src/index.md`): Overview, installation, quick start, and features | ||
| - **Examples** (`docs/src/examples.md`): Practical examples showing how to use TenSolver.jl | ||
| - **SpinGlassPEPS Integration** (`docs/src/spinglasspeps_integration.md`): Planned architecture for the optional structured PEPS backend |
There was a problem hiding this comment.
| - **SpinGlassPEPS Integration** (`docs/src/spinglasspeps_integration.md`): Planned architecture for the optional structured PEPS backend |
Internal
There was a problem hiding this comment.
Applied — removed from the public docs listing; the internal-notes entry below already covers it.
There was a problem hiding this comment.
Still addressed on the current head: the SpinGlassPEPS design note is not listed as public documentation.
There was a problem hiding this comment.
Still addressed at current head 33764cb: the SpinGlassPEPS design note remains absent from the public documentation listing.
| pages = [ | ||
| "Home" => "index.md", | ||
| "Examples" => "examples.md", | ||
| "SpinGlassPEPS Integration" => "spinglasspeps_integration.md", |
There was a problem hiding this comment.
| "SpinGlassPEPS Integration" => "spinglasspeps_integration.md", |
Internal
There was a problem hiding this comment.
Applied — removed from the Documenter pages; the design note is internal-only.
There was a problem hiding this comment.
Still addressed on the current head: the internal design note is absent from the Documenter page navigation.
There was a problem hiding this comment.
Still addressed at current head 33764cb: the internal SpinGlassPEPS design note remains absent from Documenter navigation.
| ising_to_qubo(model::IsingModel) = ising_to_qubo(ising_form(model.J, model.h, model.offset)) | ||
|
|
There was a problem hiding this comment.
| ising_to_qubo(model::IsingModel) = ising_to_qubo(ising_form(model.J, model.h, model.offset)) |
Leftover from rebasing.
There was a problem hiding this comment.
Addressed, though not by deleting this line — the actual rebase leftover was more serious and one level up: the rebase lost the IsingModel struct and its validating constructor entirely (which is why the package stopped precompiling and CI went red), and left src/ising.jl included twice in TenSolver.jl (which duplicated every docstring and broke the Documentation build). This method itself is required — solve_ising(::DMRGBackend, model) and the PEPS extension both convert through ising_to_qubo(model).
Fixed by restoring the struct/constructor (with the diagonal-coupling folding) and dropping the duplicate include (f244b53), plus restoring the IsingModel(::QUBOTools.AbstractForm) form constructor and scaled_form_parts (8459f8d). The solve_ising preserves pair couplings and offsets regression test covers the restored behavior.
There was a problem hiding this comment.
The IsingModel type was deleted as part of the final review in #42, but the changes never reached this branch. I'm ok with either deleting or keeping it, but we should reaccess why that PR chose to not provide this type.
There was a problem hiding this comment.
Reassessed against current main and removed the obsolete IsingModel type and its adapter methods. PEPS now consumes native spin-domain inputs through minimize(...; domain = [-1, 1]).
There was a problem hiding this comment.
Still addressed at current head 33764cb: the obsolete IsingModel type and adapters remain removed, and PEPS consumes native spin-domain inputs through minimize(...; domain = [-1, 1]).
| struct PEPSBackend{T <: AbstractStructuredTopology, S} <: AbstractTenSolverBackend | ||
| topology :: T | ||
| beta :: Float64 | ||
| bond_dim :: Int | ||
| max_states :: Int | ||
| cutoff_prob :: Float64 | ||
| onGPU :: Bool | ||
| contraction :: Symbol | ||
| num_sweeps :: Int | ||
| graduate_truncation :: Bool | ||
| transformations :: S | ||
| local_dimension :: Union{Nothing, Int} | ||
| no_cache :: Bool | ||
| end |
There was a problem hiding this comment.
We should strive for keyword compatibility with the DMRG backend. When a concept applies to both, we should use the same name.
Ex: onGPU vs device, bond_dim vs maxdim, num_sweeps vs iterations, etc.
Also, why is the DMRGBackend "empty" with all keywords being passed to minimize while PEPSBackend has many fields? Let's keep it consistent.
There was a problem hiding this comment.
Done (commit ea75764), both halves:
PEPSBackendis now "empty" likeDMRGBackend— it carries only the topology (structural, not tunable). All solver parameters moved to keywords of the solve call.- Shared concepts reuse the DMRG names:
maxdim(wasbond_dim),iterations(wasnum_sweeps),device(wasonGPU; any non-cpudevice runs the contractor on GPU). The PEPS-specific keywords (beta,max_states,cutoff_prob,contraction,graduate_truncation,transformations,local_dimension,no_cache) are normalized and validated by a newTenSolver.peps_optionshelper, which the extension consumes — so keyword validation is testable without the optional SpinGlass stack.
There was a problem hiding this comment.
Addressed on the current design: PEPSBackend carries only its structural topology, shared concepts use DMRG-compatible names such as maxdim, iterations, and device, and PEPS-only option normalization is internal to the extension.
There was a problem hiding this comment.
Still addressed at current head 33764cb: PEPSBackend stores only structural topology, shared concepts use DMRG-compatible keyword names, and PEPS-only option normalization remains internal to the extension.
| preprocess::Bool=false, | ||
| kwargs..., | ||
| ) where T | ||
| preprocess && throw(ArgumentError("PEPSBackend does not support preprocess=true because the topology fixes the variable order. Use backend = :dmrg for preprocessed QUBO solves.")) |
There was a problem hiding this comment.
| preprocess && throw(ArgumentError("PEPSBackend does not support preprocess=true because the topology fixes the variable order. Use backend = :dmrg for preprocessed QUBO solves.")) | |
| preprocess && throw(ArgumentError("PEPSBackend does not support preprocess=true because the topology fixes the variable order. |
Separation of concerns. What if we add more backends supporting preprocessing?
There was a problem hiding this comment.
Applied (commit b5615ac) — the message now states only this backend's constraint, without steering to a specific alternative backend.
There was a problem hiding this comment.
Still addressed: the preprocessing error describes only PEPSBackend's topology constraint and does not direct users to or couple it with another backend.
There was a problem hiding this comment.
Still addressed at current head 33764cb: the preprocessing error describes only the PEPSBackend topology constraint and does not couple the message to another backend.
| include("solver.jl") | ||
| export minimize, maximize | ||
| export DMRGBackend | ||
| export minimize, maximize, solve_ising |
There was a problem hiding this comment.
| export minimize, maximize, solve_ising | |
| export minimize, maximize |
Let's keep the API simple.
There was a problem hiding this comment.
Applied (commit 17207ec) — solve_ising is no longer exported; minimize/maximize (and JuMP) are the solver entry points. It stays documented under "Internal Functions" in the API reference as the backend boundary that structured backends implement, and the tests now call it as TenSolver.solve_ising.
There was a problem hiding this comment.
Addressed more completely on the current head: solve_ising has been removed rather than merely unexported. minimize/maximize and JuMP remain the solver entry points.
There was a problem hiding this comment.
Still addressed at current head 33764cb: solve_ising remains removed, leaving minimize, maximize, and JuMP as solver entry points.
| include("ising.jl") | ||
| export bool_to_spin, spin_to_bool, qubo_to_ising, ising_to_qubo | ||
|
|
There was a problem hiding this comment.
| include("ising.jl") | |
| export bool_to_spin, spin_to_bool, qubo_to_ising, ising_to_qubo |
Beware to not include this twice.
There was a problem hiding this comment.
Applied (commit f244b53) — the duplicated include("ising.jl") + exports block is gone; the file is included exactly once. This double include was also what broke the Documentation build via duplicate docstrings.
There was a problem hiding this comment.
Still addressed: src/ising.jl is included exactly once.
There was a problem hiding this comment.
Still addressed at current head 33764cb: src/ising.jl remains included exactly once.
| @testset "solve_ising preserves pair couplings and offsets" begin | ||
| J = [0.0 0.5; 1.0 0.0] | ||
| h = [-0.25, 0.75] | ||
| offset = 2.0 | ||
| model = TenSolver.IsingModel(J, h, offset) | ||
| spin_states = [[s1, s2] for s1 in (-1, 1) for s2 in (-1, 1)] | ||
| energies = [TenSolver.ising_energy(model, spin) for spin in spin_states] | ||
| expected_energy, expected_index = findmin(energies) | ||
| expected_spin = spin_states[expected_index] | ||
|
|
||
| for solve_call in ( | ||
| () -> solve_ising(model; backend=:dmrg, verbosity=0), | ||
| () -> solve_ising(J, h, offset; backend=:dmrg, verbosity=0), | ||
| ) | ||
| energy, solution = solve_call() | ||
| sample_bits = TenSolver.sample(solution) | ||
| sample_spin = TenSolver.bool_to_spin(sample_bits) | ||
|
|
||
| @test energy ≈ expected_energy | ||
| @test sample_spin == expected_spin |
There was a problem hiding this comment.
These test are not about the backend infrastructure. They should be moved to the peps_backend tests.
There was a problem hiding this comment.
Done (commit 17207ec) — the solve_ising preserves pair couplings and offsets regression testset moved from test/backend.jl into test/peps_backend.jl, next to the rest of the Ising-boundary coverage; test/backend.jl is back to pure backend-interface tests.
There was a problem hiding this comment.
Addressed on the current test layout: test/backend.jl contains backend-interface coverage, while PEPS-specific behavior is covered in test/peps_backend.jl. The obsolete solve_ising tests were removed with that API.
There was a problem hiding this comment.
Still addressed at current head 33764cb: backend-interface tests remain in test/backend.jl, and PEPS-specific behavior remains in test/peps_backend.jl.
The rebase onto main dropped the IsingModel struct and its validating constructor (with diagonal-coupling folding into the offset) while five call sites still referenced the type, so the package no longer precompiled. It also left src/ising.jl included twice in TenSolver.jl, which duplicated every docstring and broke the Documentation build.
The rebase left the design note in both docs/src and docs/internal. Keep the newer content under docs/internal (it is a developer note, not user documentation) and drop it from the public docs nav.
Collect all PEPS-specific code (topologies, PEPSBackend, PEPSSolution, backend minimize methods) into src/backends/peps.jl, mirroring the DMRG backend layout. Rename the remaining underscore-prefixed helpers in the solver and the SpinGlassPEPS extension per review. Restore the backend_error(::PEPSBackend) method lost in the rebase and trim the preprocess error message to the backend-relevant part.
Solution (DMRG) and PEPSSolution subtype AbstractSolution, which documents the sample/prob interface and provides the generic sample(psi, n) and in(xs, psi; cutoff) methods, removing the per-backend duplicates.
Duplicate decoded states are merged (probabilities summed) by the extension before construction; the inner constructor now enforces that invariant, and prob simplifies to a single lookup.
PEPSBackend now only selects the algorithm and topology, like DMRGBackend; solver parameters move to keywords of the solve call. Shared concepts reuse the DMRG names: maxdim (was bond_dim), iterations (was num_sweeps), and device (was onGPU; any non-cpu device runs the contractor on GPU). PEPS-specific keywords are normalized and validated by the new TenSolver.peps_options helper, which the SpinGlassPEPS extension consumes, so validation is testable without the optional stack.
Per review, minimize/maximize (and JuMP) stay the only exported solver entry points; solve_ising remains the documented internal backend boundary. Reorder the backends docs block, document AbstractSolution and the PEPS solve keywords, and move the solve_ising regression tests from the backend-interface suite to the PEPS backend suite.
scaled_form_parts and IsingModel(::QUBOTools.AbstractForm) were also dropped by the rebase, breaking solve_ising(::DMRGBackend, model) and the PEPS minimize path. Give SquareGrid/KingGrid the docstrings their existing api.md entries expect and document peps_options alongside.
|
Addressed the CHANGES_REQUESTED review. Eight commits pushed (head
Review-body findings: API unification → commits 4, 6, 7; file structure → commit 3; export hygiene → commit 7; no leading underscores → commit 3; rebase duplication/breakage → commits 1, 2, 8. Not changed: Tests: full Docs build: CI on Formal gate: the review decision remains |
|
CI follow-up: the Not caused by these changes: every stable ( Since |
iagoleal
left a comment
There was a problem hiding this comment.
A lot has happened in the repo since this PR's last review, so here go a lot of comments. It is a lot, so we will probably have to do a couple iterations more before merging.
The most important thing is that we cannot merge this with a red CI. Right now, it is just not compatible with our package.
Some minor design comments:
- After merging
main, it is worth passing JuliaFormatter on the newext/TenSolverSpinGlassPEPSExt.jlandsrc/backends/peps.jlfiles; - Now that we natively support ising domains, do we need to keep the elpers in
ising.jl? The user will supposedly pass an Ising model directly tominimize - Keep the
minimize/maximizeAPI as the only solver entry-points. - In terms of syntax and "expected behaviour", align the DMRG and PEPS backends as much as possible. For example, preferably there should be a single solution API for both without the user accessing different fields.
| raw_results = Dict{Any, Any}() | ||
| failures = NamedTuple[] | ||
| for transform in resolve_transformations(opts.transformations) | ||
| try |
There was a problem hiding this comment.
In Julia, having a try-catch block inside a tight loop is terrible for performance.
There was a problem hiding this comment.
Addressed: the loop no longer contains a try/catch. The transformation helper uses only try/finally so the memoization cache is cleared while any failure still propagates.
There was a problem hiding this comment.
try/finally is equally slow, so we should make sure it is not called from a tight loop. Legit question: Why do we assume the code can fail?
There was a problem hiding this comment.
Addressed in 33764cb: removed try/finally from the per-transformation solve path. Construction and spectrum failures now propagate directly; the memoized SpinGlass contraction state is cleared only after a successful low_energy_spectrum call, matching SpinGlassEngine 1.6 benchmark/test usage. The extension is JuliaFormatter-clean, the full package suite and docs build pass locally, and all current-head CI checks are green.
|
Addressed the requested review pass on the current base and updated the branch to current Commits pushed:
Main changes and review verification:
Verification:
Comments intentionally not addressed:
Remaining gates:
|
…glasspeps-backend
Resolves the conflicts against post-#131 main: - src/solution.jl keeps the abstract Solution interface and SolverStatistics; the concrete type lives in the DMRG backend. - DMRGSolution absorbs main's per-variable Domains semantics: the domain field is Domains{T}, sample maps each site through its own domain with the non-mutating sampler, and coeff validates through `in`/searchsortedfirst with the corrected repr interpolation. - minimize_mpo samples the objective in tensor order (main's form) and constructs a DMRGSolution. - The SpinGlassPEPS extension accepts the Domains type: the spin check requires every per-variable domain to equal [-1, 1], and the solve path rejects native constraints explicitly, since the front door now always forwards a constraints vector. - docs/src/api.md carries both the Variable Domains and PEPS Backend sections.
|
Merged current
Verification at c88e2f5: full |
Summary
PEPSBackendwhile keeping DMRG as the default backend.minimizeAPI for spin-domain inputs (domain = [-1, 1]); the separatesolve_isingentry point and the obsoleteIsingModeladapter have been removed.Solutioninterface with backend-specificDMRGSolutionandPEPSSolutionimplementations sharingsample,prob, andis_feasiblebehavior.PEPSSolutioninvariants at construction, stores raw backend results in metadata, and propagates transformation failures.mainand updates the implementation, documentation, and tests to the current TenSolver backend and domain APIs.Tests run
git diff --check origin/main...HEAD— passed.ext/TenSolverSpinGlassPEPSExt.jlandsrc/backends/peps.jl— passed.julia +release --project=. --startup-file=no -e 'using Pkg; Pkg.test(; coverage=false)'— passed.julia +release --project=docs/ --startup-file=no docs/make.jl— passed after dependency precompilation; deployment was skipped outside CI.Notes
Refs #38