-
Notifications
You must be signed in to change notification settings - Fork 8
Description
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.