CTM options#
Every option accepted by the CTM routines is a field of one of three dataclasses. They are the single place each default is defined, and they are what the loose keyword arguments below are normalized into.
Object |
Covers |
|---|---|
one CTM sweep: moves, projector method, truncation, convergence, execution |
|
the subspace-iteration projector mode, nested under |
|
the forward / fixed-point pair plus the Neumann backward controls |
Two ways to pass them#
Loose keyword arguments remain the common case:
env.ctmrg_(opts_svd={'D_total': chi}, max_sweeps=200, corner_tol=1e-8)
Alternatively, build the options once and reuse them. This is what the opts= keyword is for:
from yastn.tn.fpeps.envs import make_ctm_opts
opts = make_ctm_opts(opts_svd={'D_total': chi}, max_sweeps=200, corner_tol=1e-8)
env_a.ctmrg_(opts=opts)
env_b.ctmrg_(opts=opts, max_sweeps=10) # same, but ten sweeps
Explicit keywords win over opts, which in turn wins over env.default_opts if that is set.
Anything left unspecified falls back to the dataclass default. Deriving never mutates the original:
options are frozen, and nested bundles are merged into the base rather than replacing it, so
make_ctm_opts(opts, opts_svd={'policy': 'fullrank'}) keeps the rest of opts.opts_svd.
Unknown options are rejected#
A name that is not an option raises YastnError listing the accepted fields:
>>> env.ctmrg_(opts_svd={'D_total': 8}, max_sweep=10)
YastnError: CTM option 'max_sweep' not recognized. Accepted: checkpoint_move, conv_check, ...
Some older spellings are still accepted and normalized: opts_svd_ctm for opts_svd,
iterator for iterator_step, asvr_iterations for adaptive_spectrum_iterations, and
the refinement acronyms 'cwo', 'asvr', 'rds' for their spelled-out names.
From a configuration file, with command-line overrides#
The options are plain stdlib dataclasses holding config-representable types, so they round-trip through nested dictionaries. No configuration framework is required or assumed:
import yaml
from yastn.tn.fpeps.envs import CTMOpts, from_dict, override, to_dict
opts = from_dict(CTMOpts, yaml.safe_load(open('ctm.yaml'))) # defaults <- file
opts = override(opts, {'opts_svd.D_total': 64, # <- CLI
'max_sweeps': 200,
'opts_si.niter': 3})
env.ctmrg_(opts=opts)
override() addresses fields by dotted path, including keys inside
opts_svd and fields of the nested SIOpts. Each layer is validated the same way, so an
unknown name in the file or on the command line is an error. Unlike the
factories – where None means “not supplied”, so a function signature can forward its defaults
harmlessly – an override of None is an explicit assignment and does clear the field.
argspec() yields (dotted_name, type, default, help, choices) for
every field, so a command-line interface can be generated from the schema rather than restating it:
for name, typ, default, help_, choices in argspec(CTMOpts):
parser.add_argument(f'--{name}', default=default, help=help_,
**({'choices': choices} if choices else {}))
One limit is worth knowing: a callable has no representation in a configuration file. conv_check
and a mask_f inside opts_svd round-trip in memory but not through YAML or JSON, so they must
be set from code. to_dict() emits them as objects.
Reference#
- class yastn.tn.fpeps.envs.CTMOpts(*, moves: str = 'hv', method: str = '2x2 corner', max_sweeps: int = 1, corner_tol: float | None = None, conv_check: Callable | None = None, iterator_step: int = 0, opts_svd: dict[str, ~typing.Any]=<factory>, use_qr: bool = True, cutoff: float = 0.0, opts_si: SIOpts | None = None, checkpoint_move: Literal[False, 'reentrant', 'nonreentrant']=False, devices: tuple[str, ...] | None=None, profiling_mode: str | None = None, verbosity: int = 0)[source]#
Options of a CTM environment sweep.
Construct with
make_ctm_opts(), which accepts the legacy keyword spellings and reports unknown names. Direct construction is fine too; all normalization and validation happens in__post_init__, sodataclasses.replaceandfrom_dict()are equally safe.- Parameters:
moves (str) – Sequence of moves forming a single sweep, drawn from
'l','r','t','b','h','v'(and'd'for the c4v variant). Sensible choices are'hv'and'lrtb'.method (str) – Projector construction. Must contain
'2x2','1x2'or'2x1', or be exactly'1site'/'2site'.max_sweeps (int) – Maximal number of sweeps.
corner_tol (float | None) – Convergence tolerance on the change of corner singular values.
Nonedisables the built-in check.conv_check (Callable | None) – Custom convergence check
f(env, history) -> (converged, history), used instead of thecorner_tolcomparison. Previously this was passed as a callablecorner_tol; splitting the two keepscorner_tolexpressible in a configuration file.iterator_step (int) – Yield an intermediate result every that many sweeps.
0runs all sweeps eagerly and returns a single result.opts_svd (dict) – Options forwarded to
yastn.linalg.svd_with_truncation(), setting the environment bond dimension. Copied on construction; treat the stored dict as read-only and go throughsvd_kwargs().use_qr (bool) – Whether to include an intermediate QR while calculating projectors.
cutoff (float) – Absolute pseudo-inverse cutoff in projector construction.
opts_si (SIOpts | None) – Subspace-iteration options; see
SIOpts. A plain dict is accepted and converted.checkpoint_move (False | str) –
'reentrant'or'nonreentrant'to checkpoint each move on the PyTorch backend;Falsedisables checkpointing.devices (tuple[str, …] | None) – Devices for the distributed CTM paths. A list is accepted and converted.
profiling_mode (str | None) – Profiling instrumentation, e.g.
'NVTX'.verbosity (int) – Diagnostic verbosity.
- property si_enabled: bool#
Whether SI projectors are active for this sweep.
- si_trunc_kwargs() dict[source]#
The subset of
opts_svdthe SI path forwards totruncation_mask.Narrower than
svd_kwargs()by design; seeSI_TRUNCATION_KEYS.
- svd_kwargs(**overrides) dict[source]#
The keyword arguments for
yastn.linalg.svd_with_truncation().This is the single boundary at which options become SVD arguments. Returns a fresh dict every call, so a per-pair prediction such as
svd_kwargs(k_block=...)never leaks into the next projector or the next sweep.
- class yastn.tn.fpeps.envs.SIOpts(*, enabled: bool = False, oversampling: int = 5, niter: int = 5, tol: float = 0.001, warmup: int = 5, redistribute_sectors: bool = False, redistribute_frequency: int = 0, refinement: Literal['per_sector_oversampling', 'adaptive_spectrum', 'sector_dimensions'] = 'per_sector_oversampling', adaptive_spectrum_iterations: int = 5, skip_SI_update: bool = False, rebase: bool = True, recycle_grad: bool = False)[source]#
Options of the recycled subspace-iteration (SI) projectors.
- Parameters:
enabled (bool) – Whether SI projectors are used at all. The default is
False.oversampling (int) – Extra directions carried beyond the requested bond dimension.
niter (int) – Number of subspace iterations when adjusting the range-finders.
tol (float) – Target subspace error of the range-finders, weighted by the singular value of each direction.
warmup (int) – Number of projector updates before the redistribution schedule starts.
redistribute_sectors (bool) – Reallocate the SI rank between charge sectors, on the warmup /
redistribute_frequencyschedule.redistribute_frequency (int) – Redistribute every that many updates once past
warmup.0disables the recurring redistribution.refinement (str) – Sector-refinement algorithm:
'per_sector_oversampling','adaptive_spectrum'or'sector_dimensions'.adaptive_spectrum_iterations (int) – Refinement passes used by
refinement='adaptive_spectrum'. Ignored by the other refinements.skip_SI_update (bool) – Skip the subspace iteration entirely on an update that is past
warmup, outside the redistribution schedule, and whose bases already report an error belowtol. Trades accuracy for speed.rebase (bool) – When changed corner legs invalidate the recycled bases, carry them onto the new row space instead of drawing fresh ones.
recycle_grad (bool) – Keep the recycled bases attached to the autograd graph.
- class yastn.tn.fpeps.envs.FixedPointOpts(*, fwd: CTMOpts = <factory>, fp: CTMOpts = <factory>, neumann_patience: int = 10, devices: tuple[str, ...] | None=None, verbosity: int = 0)[source]#
Options of the fixed-point CTM, see
yastn.tn.fpeps.envs.fixed_pt.fp_ctmrg().FixedPointreverses the CTM, so the forward settings carry over to the backward path by design:fpisfwdwith selective overrides, and the Neumann series in the backward pass takes its iteration budget fromfp.max_sweepsand its gradient tolerance fromfp.corner_tol. The additional configuration specific to fixed point approach is defined here.- Parameters:
fwd (CTMOpts) – Options of the forward CTMRG convergence.
fp (CTMOpts) – Options of the single gauge-fixing CTM step, and – through
max_sweepsandcorner_tol– of the Neumann backward loop. Built fromfwdwith overrides applied.neumann_patience (int) – Iterations without improvement before the Neumann series gives up. Unlike the budget and tolerance, this has no forward counterpart.
devices (tuple[str, …] | None) – Devices for the distributed fixed-point path. Was
fp_devices.verbosity (int) – Diagnostic verbosity.
- classmethod from_legacy_dicts(ctm_opts_fwd=None, ctm_opts_fp=None, devices=None)[source]#
Build from the
ctm_opts_fwd/ctm_opts_fpdicts offp_ctmrg.Reproduces the historical derivation exactly:
fpstarts as a copy offwdand is then overridden selectively, withopts_svdmerged key by key rather than replaced.Keys that are not CTM options (
neumann_patience, and the legacyfp_devices) are lifted out before the rest is handed tomake_ctm_opts(), which would otherwise reject them.
- property neumann_max_iter: int#
Neumann iteration budget, carried over from the FP step’s sweep budget.
- property neumann_tol: float#
Neumann gradient tolerance, carried over from the FP step’s corner tolerance.
- yastn.tn.fpeps.envs.make_ctm_opts(base: CTMOpts | None = None, **kwargs) CTMOpts[source]#
Build
CTMOptsfrom loose keyword arguments.This is the single entry point through which every calling convention funnels – a direct keyword call,
from_dict()for a configuration file, andoverride()for command-line layering – so the unknown-key error cannot be bypassed.basesupplies the starting values; anything passed as a keyword overrides it.iterator=Trueis accepted as the historical spelling ofiterator_step=1, andopts_svd_ctmas that ofopts_svd.- Parameters:
base (CTMOpts | None) – Options to derive from.
Nonestarts from the defaults.
Example
opts = make_ctm_opts(opts_svd={'D_total': 64}, max_sweeps=200, corner_tol=1e-8, use_qr=False) tighter = make_ctm_opts(opts, corner_tol=1e-10)
- yastn.tn.fpeps.envs.make_si_opts(base: SIOpts | None = None, **kwargs) SIOpts[source]#
Build
SIOpts, accepting the legacy key spellings.Unknown keys raise
YastnErrorrather than being silently dropped.
- yastn.tn.fpeps.envs.make_fixed_point_opts(base: FixedPointOpts | None = None, **kwargs) FixedPointOpts[source]#
Build
FixedPointOpts.fwdandfpaccept plain dicts.
- yastn.tn.fpeps.envs.to_dict(opts) dict[source]#
Nested plain-dict representation, ready for YAML/JSON.
Note that a callable option has no serializable form:
conv_check, andmask_finsideopts_svd, come out as the objects themselves. They round-trip in memory but not through a file, andfrom_dict()cannot set them – code must.
- yastn.tn.fpeps.envs.from_dict(cls, d: dict)[source]#
Build an options object of type
clsfrom a nested plain dict.The inverse of
to_dict(), and the entry point for a configuration file. Validates through the same factory as every other path, so an unknown key in the file is an error rather than a silent no-op.
- yastn.tn.fpeps.envs.override(opts, overrides: dict)[source]#
Layer dotted-path overrides on top of
opts, returning a new object.The command-line half of the configuration story: a config file builds the base with
from_dict(), then flags layered on top override individual leaves.opts = override(opts, {'max_sweeps': 200, 'opts_svd.D_total': 64, 'opts_si.niter': 3})
A path may address a dataclass field, a nested dataclass field, or a key inside
opts_svd. Each layer is validated.
- yastn.tn.fpeps.envs.argspec(cls, prefix: str = '')[source]#
Yield
(dotted_name, type, default, help, choices)for every option.Lets a downstream application generate its command-line flags from the schema, so adding a CTM option never means editing that CLI.
choicesis derived from theLiteralannotations, andhelpfrom each field’smetadata['help'].for name, typ, default, help_, choices in argspec(CTMOpts): parser.add_argument(f'--{name}', default=default, help=help_, **({'choices': choices} if choices else {}))
See also
Environment CTM for the CTMRG iteration and its SI mode, and Fixed-point CTMRG with implicit differentiation for the differentiable fixed point.