Fix #342, #343: index sequences are part of node identity - #399
Merged
Conversation
This was referenced Jul 24, 2026
petlenz
force-pushed
the
fix-344-pow-division-rules
branch
from
July 25, 2026 12:06
951d0e8 to
8f5ef67
Compare
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
from
July 25, 2026 12:09
150c225 to
3e626cc
Compare
petlenz
added a commit
that referenced
this pull request
Jul 25, 2026
The tensor_inner_product_to_scalar evaluator always computed the plain
tmech::dcontract(l, r): dot_product(A,{1,2},B,{2,1}) (= A_ij B_ji)
silently evaluated as A : B, and rank-1 full contractions threw
'requires rank 2' even though the node is a legal dot product (which
also broke evaluating derivatives of dot() on rank-1 arguments).
tensor_data_dcontract_wrapper now receives both sequences: matching
rank-2 sequences contract plain ({2,1}/{2,1} sums the same pairs),
mismatched ones contract against the transpose, and rank-1 uses
tmech::dot. Rank>2 general contraction stays a clear
not-implemented error (tracked by the #383 evaluation-ceilings epic)
instead of a silently wrong value.
The identity half of this node (hash/== ignoring the sequences) landed
in #399.
Signed-off-by: petlenz <peterlenz89.pl@gmail.com>
petlenz
force-pushed
the
fix-344-pow-division-rules
branch
from
July 25, 2026 13:25
8f5ef67 to
9af5448
Compare
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
from
July 25, 2026 13:25
3e626cc to
9af5448
Compare
petlenz
added a commit
that referenced
this pull request
Jul 25, 2026
The tensor_inner_product_to_scalar evaluator always computed the plain
tmech::dcontract(l, r): dot_product(A,{1,2},B,{2,1}) (= A_ij B_ji)
silently evaluated as A : B, and rank-1 full contractions threw
'requires rank 2' even though the node is a legal dot product (which
also broke evaluating derivatives of dot() on rank-1 arguments).
tensor_data_dcontract_wrapper now receives both sequences: matching
rank-2 sequences contract plain ({2,1}/{2,1} sums the same pairs),
mismatched ones contract against the transpose, and rank-1 uses
tmech::dot. Rank>2 general contraction stays a clear
not-implemented error (tracked by the #383 evaluation-ceilings epic)
instead of a silently wrong value.
The identity half of this node (hash/== ignoring the sequences) landed
in #399.
Signed-off-by: petlenz <peterlenz89.pl@gmail.com>
petlenz
added a commit
that referenced
this pull request
Jul 25, 2026
The tensor_inner_product_to_scalar evaluator always computed the plain
tmech::dcontract(l, r): dot_product(A,{1,2},B,{2,1}) (= A_ij B_ji)
silently evaluated as A : B, and rank-1 full contractions threw
'requires rank 2' even though the node is a legal dot product (which
also broke evaluating derivatives of dot() on rank-1 arguments).
tensor_data_dcontract_wrapper now receives both sequences: matching
rank-2 sequences contract plain ({2,1}/{2,1} sums the same pairs),
mismatched ones contract against the transpose, and rank-1 uses
tmech::dot. Rank>2 general contraction stays a clear
not-implemented error (tracked by the #383 evaluation-ceilings epic)
instead of a silently wrong value.
The identity half of this node (hash/== ignoring the sequences) landed
in #399.
Signed-off-by: petlenz <peterlenz89.pl@gmail.com>
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
from
July 25, 2026 22:30
42da614 to
9121a68
Compare
petlenz
added a commit
that referenced
this pull request
Jul 25, 2026
The tensor_inner_product_to_scalar evaluator always computed the plain
tmech::dcontract(l, r): dot_product(A,{1,2},B,{2,1}) (= A_ij B_ji)
silently evaluated as A : B, and rank-1 full contractions threw
'requires rank 2' even though the node is a legal dot product (which
also broke evaluating derivatives of dot() on rank-1 arguments).
tensor_data_dcontract_wrapper now receives both sequences: matching
rank-2 sequences contract plain ({2,1}/{2,1} sums the same pairs),
mismatched ones contract against the transpose, and rank-1 uses
tmech::dot. Rank>2 general contraction stays a clear
not-implemented error (tracked by the #383 evaluation-ceilings epic)
instead of a silently wrong value.
The identity half of this node (hash/== ignoring the sequences) landed
in #399.
Signed-off-by: petlenz <peterlenz89.pl@gmail.com>
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
from
July 26, 2026 12:14
9121a68 to
a4eff94
Compare
petlenz
force-pushed
the
fix-344-pow-division-rules
branch
from
July 26, 2026 12:14
9af5448 to
54ae610
Compare
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
2 times, most recently
from
July 26, 2026 17:18
b731e94 to
8e05846
Compare
petlenz
force-pushed
the
fix-344-pow-division-rules
branch
from
July 26, 2026 17:18
90ead43 to
60f222f
Compare
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
from
July 26, 2026 17:42
8e05846 to
352c37e
Compare
petlenz
force-pushed
the
fix-344-pow-division-rules
branch
2 times, most recently
from
July 26, 2026 18:16
32b1fd9 to
cb35152
Compare
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
2 times, most recently
from
July 26, 2026 18:40
b20178b to
517baa9
Compare
petlenz
force-pushed
the
fix-344-pow-division-rules
branch
from
July 26, 2026 18:40
cb35152 to
444bca1
Compare
permute_indices_wrapper and tensor_inner_product_to_scalar stored
their index sequences but inherited unary_op/binary_op hashing and
equality, which see only the children. Two different permutations of
the same tensor compared equal (permute(T,{2,1,3}) == permute(T,{1,3,2}),
their difference folded to 0{3}), and A:B compared equal to A:B^T
(dot_product with sequences {1,2}/{1,2} vs {1,2}/{2,1}), so sums and
differences of distinct contractions silently mis-merged.
Both nodes now override update_hash_value (folding in the sequences,
mirroring inner_product_wrapper's #266 fix, with the m_hash_value
reset the #266 version lacks) and provide operator== / operator<
comparing the sequences before delegating to the base comparison.
Lock-in tests: distinct permutations/sequences neither hash- nor
compare-equal and no longer cancel; identical ones still fold to
zero.
Signed-off-by: petlenz <peterlenz89.pl@gmail.com>
petlenz
force-pushed
the
fix-342-343-index-sequence-identity
branch
from
July 26, 2026 19:03
517baa9 to
df50715
Compare
petlenz
force-pushed
the
fix-344-pow-division-rules
branch
from
July 26, 2026 19:03
444bca1 to
44b9918
Compare
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.
Summary
Fixes #342, fixes #343. Stacked on #388.
Two nodes stored index sequences but inherited base-class hash/equality that ignore them — the same bug class #266 fixed for
inner_product_wrapper:permute_indices(T,{2,1,3}) == permute_indices(T,{1,3,2})→ true; difference →0{3}dot_product(A,{1,2},B,{1,2}) == dot_product(A,{1,2},B,{2,1})→ true (A:B ≡ A:Bᵀ); sum →2*dot(...), difference →0Design
update_hash_valueoverrides fold the sequence(s) into the hash (the inner_product_wrapper hash excludes contraction indices #266 pattern, plus them_hash_value = 0reset that inner/outer_product_wrapper update_hash_value never resets m_hash_value — recompute yields a different hash #372 notes the inner_product_wrapper hash excludes contraction indices #266 version lacks — the new overrides don't inherit that latent bug).operator==/operator<friends compare sequences before delegating to the base comparison (win overload resolution over the base templates used byequals_same_type/less_than_same_type).Tests
2 new
IndexSequenceIdentitylock-in tests (hash + equality + no-false-cancel + exact-match-still-cancels, both nodes). Full suite: 2428/2428 pass. gcc-14-Werrorsyntax check clean.