Skip to content

permute_indices_wrapper hash/equality ignore the permutation — permute(T,{2,1,3}) == permute(T,{1,3,2}) #342

Description

@petlenz

Summary

permute_indices_wrapper (include/numsim_cas/tensor/wrappers/permute_indices_wrapper.h:20-57) stores its permutation in m_indices but inherits unary_op::update_hash_value (core/unary_op.h:52) and unary_op::operator== (core/unary_op.h:85), neither of which sees the sequence. Two different permutations of the same tensor hash equal and compare equal:

// rank-3 T
auto p1 = permute_indices(T, sequence{2,1,3});
auto p2 = permute_indices(T, sequence{1,3,2});
*p1 == *p2;          // true — WRONG
to_string(p1 - p2);  // "0{3}" — WRONG (different tensors)
to_string(p1 + p2);  // "2*permute_indices(T,{1,3,2})" — WRONG

Reproduced at 0f6c0b9. Also poisons substitute (matches the wrong permutation) and n-ary map keying. This is exactly the bug class fixed for inner_product_wrapper in #266; this node was missed.

Severity: critical for rank≥3 users; rank-2 mostly shielded (only {2,1} builds a wrapper).

Fix

Override update_hash_value() in permute_indices_wrapper to hash_combine each entry of m_indices (copy the #266 pattern from inner_product_wrapper.h:59-67), and add operator==/operator< that compare m_indices before delegating to the child comparison.

Tests (lock-in)

TEST(PermuteIdentity, DifferentPermutationsDistinct) {
  auto [T] = make_tensor_variable(std::tuple{"T", 3, 3});
  auto p1 = permute_indices(T, sequence{2, 1, 3});
  auto p2 = permute_indices(T, sequence{1, 3, 2});
  EXPECT_FALSE(*p1 == *p2);
  EXPECT_NE(p1.get().hash_value(), p2.get().hash_value());
  EXPECT_NE(to_string(p1 - p2), "0{3}");
  // same permutation still folds
  auto q = permute_indices(T, sequence{2, 1, 3});
  EXPECT_EQ(to_string(p1 - q), "0{3}");
}

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