|
Uni20
Asynchronous tensor and runtime library.
|
Status: implemented finite-chain ground-state run for immediate host or single-device packed CUDA MPS and environment storage.
In the resident CUDA path, MPS sites, cached environments, two-site centers, Krylov vectors, R/A/B/C intermediates, charge-sector SVD matrices, and selected U/Vh factors remain in CUDA storage across bonds and sweeps. MPO coefficient blocks remain immediately host-readable and are compiled into the sparse effective-Hamiltonian plan. The compact singular-value spectrum is copied to the host for global truncation selection and for the returned diagonal bond diagnostic; it is not used as a host mirror of the active MPS state.
The first sweep API combines the existing finite-chain components without introducing a new tensor representation:
Every Krylov vector, effective-Hamiltonian operand, SVD factor, and installed site remains a symmetry-aware BlockTensor; its boundary spaces and stored block keys determine the contraction and decomposition worklists.
For repeated alternating sweeps:
One run-level sweep is one complete directional traversal. Directions alternate from initial_direction, which defaults to left-to-right.
The optional final storage-policy tag selects the representation and block execution policy of the transient two-site center and all Krylov vectors:
This does not change the persistent MPS or MPO storage. With an active TbbScheduler, independent center-output blocks execute through synchronous lightweight task batches, while every contribution to one output block remains serial within its batch item. The environment cache has its own storage-policy template parameter and may select the same execution policy independently. ParallelPackedCompleteBlockStorage<CudaStorage> selects a packed CUDA center and CUDA Krylov vectors. A CUDA-resident run also uses packed CUDA policies for the persistent MPS and environment cache; storage domains are never changed implicitly by the center policy.
Performance instrumentation is opt-in and separate from the mathematical run result. The coarse collector records inclusive host wall durations for the run, each sweep and bond update, center construction, the local eigensolver, block SVD, state selection, selected-factor materialization, environment update, and each effective-Hamiltonian application within the local eigensolver:
DetailedTwoSiteDmrgPerformanceMeasurements additionally times Krylov vector allocation, update, and reduction calls and retains item timing for every per-charge block-SVD batch. Ordinary overloads instantiate performance::NoMeasurements; optimized builds contain no profiling branch, clock read, counter, or measurement state on that path.
Parent and child phase durations are inclusive and must not be added together. Host wall timing around future asynchronous CUDA work would measure submission, not device execution; provider-domain timings require their own event mechanism. The fine Krylov events intentionally perform clock reads around individual vector primitives and therefore belong only to detailed attribution runs. The generic measurement levels, batch fields, and overhead contract are in Performance Measurements.
optimize_two_site_dmrg_bond() applies this sequence to adjacent sites i and i+1:
left[i] and right[i+2] from the attached MpoEnvironmentCache. If their leaf memory domain differs from the center, materialize owned packed sparse copies in the center domain.TwoSiteEffectiveHamiltonian from those environments and the two MPO sites. This also prepares the R/A/B/C grouping, output order, and reusable intermediate workspace. Same-domain environments remain zero-copy identity views. Transferred environments are owned by the effective-Hamiltonian object for the complete local solve.FiniteMps::replace_pair().The default is four effective-Hamiltonian applications per bond. The local solver does not test Ritz convergence, perform a restart, or fully reorthogonalize the basis. It exits early only for an exact numerical invariant-subspace breakdown or when the local vector-space dimension is less than four. The resulting approximate Ritz vector is installed and the sweep continues so that the environments, rather than one stale local problem, are converged. Invalid solver or truncation options and failed SVD materialization leave the MPS unchanged.
The complete local key structure is essential for optimization. A sparse MPS may omit a numerically zero site block even though the Hamiltonian couples its current center into the corresponding legal two-site block. Restricting Krylov to the contraction's initially stored keys would reject that valid coupling or solve the wrong local problem.
The cache must be attached to the exact MPS and MPO objects passed to the step, not merely owners of the same types. This prevents a compound operation from solving with environments belonging to another chain instance.
For a left-to-right step, singular values are absorbed into site i+1. Site i is left as the selected isometry, and the step rebuilds left[i+1] from the still-valid left[i]:
For a right-to-left step, singular values are absorbed into site i. Site i+1 is the selected isometry, and the step rebuilds right[i+1] from the still-valid right[i+2]:
The revision cache invalidates the other entries affected by pair replacement. They remain absent until a later step requires them.
Each TwoSiteDmrgStepResult records:
local_energy is deliberately not called the installed-state energy. SVD truncation changes the optimized center and can raise its expectation value. The run controller does not perform a second effective-Hamiltonian apply to measure that post-truncation value.
sweep_two_site_dmrg() visits every bond exactly once:
It returns step results in visitation order. Environments are built lazily; the caller does not need to call build_all() before a sweep. Repeated sweeps reuse the two chain-boundary entries and the directional entries retained or refreshed by preceding steps.
run_two_site_dmrg() repeatedly calls the directional traversal and retains a compact TwoSiteDmrgSweepSummary rather than all installed bond spectra. Each summary records:
At the terminal pair, the active bond lies next to a one-dimensional chain boundary. If its SVD has zero discarded weight, factorization does not change the optimized center. Under the mixed-canonical sweep invariant, the terminal local Ritz value is therefore also the installed whole-chain expectation value. Only such energies participate in convergence. A nonzero terminal discarded weight clears the preceding comparison state, so even a large energy tolerance cannot report convergence from provisional local values.
Convergence compares consecutive valid terminal energies with
A zero configured tolerance selects 100 * numeric_limits<Real>::epsilon(). At least two valid terminal energies are therefore required. Reaching maximum_sweeps without satisfying the criterion returns normally with converged == false.
The input MPS must be canonical for initial_direction. A normalized rank-one product MPS is canonical from both directions; in particular, models::make_neel_product_mps() satisfies this precondition. Each directional split preserves the mixed-canonical state needed by the next update.
The registered spin_half_heisenberg_dmrg_example exercises this path on the length-four open chain. Without truncation it reaches the exact energy -(3 + 2 sqrt(3))/4 while preserving U(1) block structure. MPLAPACK-enabled builds also register real and complex uni20::float128 runs through the same BlockTensor contraction, fixed-step Lanczos, block-SVD, and materialization path. Their analytic energy check uses a decimal reference and tolerance beyond double precision, so this is execution coverage rather than only a template-instantiation probe.
The first larger CPU scaling measurements, the exact block-level parallel boundary, and cross-library orientation points are recorded in DMRG Performance Baselines. The current effective-Hamiltonian plan schedules estimated-expensive output groups first. Per-charge SVDs now run as estimated-cost-ordered lightweight batch items. Selected-factor construction remains serial and is the next parallel checkpoint.
This checkpoint is synchronous and supports immediate host or single-device packed CUDA MPS and environment blocks. It requires BlockSpace MPS bonds, LocalSpace MPO auxiliaries, bosonic Abelian symmetry, real float or double for the CUDA SVD path, and the current sparse MPO effective-Hamiltonian planner.
It does not yet provide energy or variance measurement after truncation, generic canonicalization of an arbitrary initial MPS, adaptive local-work schedules, noise or subspace expansion, excited-state projection, per-bond truncation policies, async block solves, multi-device CUDA, MPI, or checkpoint/restart. Those are separate layers over the verified directional state transition. Legal center keys are initially found by scanning the Cartesian product of key-bearing factors; a charge-indexed planner can replace that structural setup when large sector counts make it material.