Skip to content

Canonicalization of nested products fails #287

@Krzmbrzl

Description

@Krzmbrzl

When trying to canonicalize the expression

(( A{a1;i2} B{i1;a1} ) E{i2;a3} ) ( C{a2;i4} D{i3;a2} )

the program triggers an assert because the nested product is canonicalized independently of the parent and hence index renaming can lead to conflicts with the parent.

Here is a debug output of what is happening:

TensorNetworkV2::canonicalize(slow): input tensors
tensor 0: {A^{{i_2}}_{{a_1}}}
tensor 1: {B^{{a_1}}_{{i_1}}}
cardinal_tensor_labels = κ γ Γ A S P L λ λ¹ h f f̃ g θ t t¹ R F X μ V Ṽ B U GR C s a ã b b̃ E 
==============
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 0 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_2} attached to tensor 0 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_1} attached to tensor 1 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 1 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::canonicalize_graph: input tensors
tensor 0: {A^{{i_2}}_{{a_1}}}
tensor 1: {B^{{a_1}}_{{i_1}}}

TensorNetworkV2::canonicalize(slow): tensors after initial sort
tensor 0: {A^{{i_2}}_{{a_1}}}
tensor 1: {B^{{a_1}}_{{i_1}}}
==============
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 0 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_2} attached to tensor 0 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_1} attached to tensor 1 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 1 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::canonicalize(slow): input tensors
tensor 0: {C^{{i_4}}_{{a_2}}}
tensor 1: {D^{{a_2}}_{{i_3}}}
cardinal_tensor_labels = κ γ Γ A S P L λ λ¹ h f f̃ g θ t t¹ R F X μ V Ṽ B U GR C s a ã b b̃ E 
==============
TensorNetworkV2::init_edges: idx={a_2} attached to tensor 0 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_4} attached to tensor 0 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_3} attached to tensor 1 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_2} attached to tensor 1 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::canonicalize_graph: input tensors
tensor 0: {C^{{i_4}}_{{a_2}}}
tensor 1: {D^{{a_2}}_{{i_3}}}

TensorNetworkV2::canonicalize(slow): tensors after initial sort
tensor 0: {C^{{i_4}}_{{a_1}}}
tensor 1: {D^{{a_1}}_{{i_3}}}
==============
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 0 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_4} attached to tensor 0 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_3} attached to tensor 1 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 1 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::canonicalize(slow): input tensors
tensor 0: {E^{{a_3}}_{{i_2}}}
tensor 1: {A^{{i_2}}_{{a_1}}}
tensor 2: {B^{{a_1}}_{{i_1}}}
tensor 3: {C^{{i_4}}_{{a_1}}}
tensor 4: {D^{{a_1}}_{{i_3}}}
cardinal_tensor_labels = κ γ Γ A S P L λ λ¹ h f f̃ g θ t t¹ R F X μ V Ṽ B U GR C s a ã b b̃ E 
==============
TensorNetworkV2::init_edges: idx={i_2} attached to tensor 0 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_3} attached to tensor 0 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 1 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_2} attached to tensor 1 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={i_1} attached to tensor 2 (Bra) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 2 (Ket) at position 0 (sym: nonsymmetric)
TensorNetworkV2::init_edges: idx={a_1} attached to tensor 3 (Bra) at position 0 (sym: nonsymmetric)
Boom!
unit_tests-sequant: SeQuant/SeQuant/core/tensor_network_v2.hpp:97: sequant::TensorNetworkV2::Edge& sequant::TensorNetworkV2::Edge::connect_to(sequant::TensorNetworkV2::Vertex): Assertion `!second.has_value()' failed.

As can be seen, first the product A*B is canonicalized, then C*D and finally the product A*B*C*D*E. The problem is that during the canonicalization of C*D, a_2 in D gets renamed to a_1 leading to the situation that during the last canonicalization the index a_1 now appears three times, triggering the assertion.

My guess is that in order to fix this, we need to adapt the way a Product canonicalizes itself. Probably, nested products should canonicalize in a single step rather than canonicalizing through the nesting hierarchy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions