Repository navigation
Resolve spaces diamonds (AbelianLegPipe + ElementarySpace) - #323
Open
jhauschild wants to merge 12 commits into
Open
jhauschild wants to merge 12 commits into
jhauschild wants to merge 12 commits into
Conversation
…resent so it works when rebuilding
…utes of Site instead of subclassing
Remove spaces diamond MI for nanobind readiness (#254). AbelianLegPipe is ElementarySpace-only with composed pipe fields; drop LegOrSpace and make Leg a value handle over ES|LegPipe. Python Leg is an ABC; use is_leg_pipe() instead of isinstance(..., LegPipe) for ALP.
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
#254 listed three MI uses; #310 and #317 already removed Tensor-labels and Site-DOF diamonds. Remaining item 3 is two related diamonds that both block nanobind (#255):
Intentional product tension:
ElementarySpace.LegPipe.Nanobind binds only one C++ base and assumes address-preserving non-virtual inheritance. Both diamonds must go.
Why we do not keep
LegOrSpaceToday
LegOrSpaceexists for one reason: a sharedenable_shared_from_thissoElementarySpace : Space, Leghas a single control block. That reason disappears once ES no longer multiply-inherits.A common root would only still be useful as a polymorphic factor type (
vector<shared_ptr<Base>>holding both ES and LegPipe). That is a bad fit here:Spacesits under that root,TensorProductis also under it — then factors need runtimeis_leg()filters to exclude TP.ES : Space, Axis) or making ES not aSpace.Decision: delete
LegOrSpace. Use two separate trees, each with its ownenable_shared_from_this. Represent “tensor axis = ES | LegPipe” as an explicit closed sum, not a shared base.Target hierarchy
Two independent trees. No virtual inheritance. No shared root.
ElementarySpace/ DSSAbelianLegPipeTensorProductLegPipeAxis handle (replaces
Leg::Ptr)Prefer a thin
Leghandle (value type wrapping the variant) so call sites keepleg->is_dual/leg.dual()sugar without an inheritance base. Python still sees concreteElementarySpace/LegPipeinstances; the handle is a C++ ergonomics layer (bindings continue to pass the concrete object).Shared axis operations that today are virtual on
Legbecome:visitthe variantTensorProduct::factorsbecomesvector<AxisPtr>(orvector<Leg>handle). Construction asserts the variant alternatives only — TP cannot sneak in by inheritance.Delete abstract C++ base
LegToday's abstract
Leggoes away as a polymorphic base:is_dual,basis_perm,ascii_arrow, …)LegPipekeeps its own copies of axis fields (symmetry,dim,is_dual, …)Space::symmetry/dimandLeg::symmetry/dimPart 1 — AbelianLegPipe composition
Make
AbelianLegPipe : public ElementarySpaceonly, composing formerLegPipefields:legs,num_legs,combine_cstyle,sector_strides,fusion_outcomes_sort,block_ind_map_slices,block_ind_mapAbelianLegPipeAbelianBackend::make_pipe→ ALP (still ES → nested pipes +Site.legOK)make_pipe→ plainLegPipeisinstance(alp, LegPipe)becomes False. Useis_pipe/lasy.is_leg_pipe.Part 2 — Linearize ElementarySpace / drop LegOrSpace
C++ shape
LegOrSpaceand abstract baseLeg.Space : enable_shared_from_this<Space>— sector API; ownssymmetry/dim.ElementarySpace : public Spaceonly — axis fields from former Leg; singledual()/operator==.LegPipe : enable_shared_from_this<LegPipe>— independent tree; nested legs asvector<AxisPtr>;as_space()→TensorProduct.TensorProduct : public Space—factors: vector<AxisPtr>; not an axis alternative.DirectSumSpace/AbelianLegPipe— ES subclasses as today / Part 1.Python
LegABCKeeps
isinstance(es, Leg)forasserting.py.isinstance(x, Space)remains real C++ inheritance.Bindings
class_<Space>/class_<ElementarySpace, Space>/class_<AbelianLegPipe, ElementarySpace>/ …class_<LegPipe>as its own top (no Space/LegOrSpace base)Trampolines
dual_leg/dual_space), dualoperator==,as_space_objrename,init_leg.Pipe protocol
On concrete types + axis handle helpers:
is_pipe()— true for plainLegPipeandAbelianLegPipeis_plain_leg_pipe:= pipe and not ES / not abelianis_abelian_leg_pipe()— ALPPython:
lasy.is_leg_pipe(x)covers both pipe kinds.Mandatory dispatch updates
ops_legs.cppis_pipe; ALP strips to plain ES when flatteningmask.cpp,diagonal_tensor.cpp, ops_legsLegPipecastspaces.cppfusion_tree_backend.cppLegPipeonlydegrees_of_freedom.cppspaces.h,tensor.hAxisPtr/ Leg handlehdf5_export.cppasserting.pyis_pipenotisinstance(LegPipe)isinstance guarantees after
isinstance(es/dss/alp, Space)isinstance(es/dss/alp/pipe, Leg)isinstance(tp, Space)isinstance(tp, Leg)isinstance(pipe, Space)isinstance(alp, LegPipe)is_pipe)isinstance(alp, ElementarySpace)Sequencing
is_pipeprotocol.Leg::Ptrcall sites; Python Leg ABC.Call-site map (docs)
LegOrSpaceshared rootAbelianLegPipeMRO includesLegPipeAbelianLegPipe → ElementarySpace → SpaceElementarySpaceMRO includes C++LegElementarySpace → Space;isinstance(..., Leg)via ABCLeg::PtrfactorsAxisPtr/ thin Leg handle (ES | LegPipe)isinstance(x, LegPipe)for abelian combinesis_pipe/isinstance(x, AbelianLegPipe)dynamic_pointer_cast<Leg>(…)dual_leg/dual_spacehooksdual()per concrete type