Skip to content

Use linear scans instead of hashing for contraction labels#190

Merged
mtfishman merged 1 commit into
mainfrom
mf/linear-label-setops
Jun 29, 2026
Merged

Use linear scans instead of hashing for contraction labels#190
mtfishman merged 1 commit into
mainfrom
mf/linear-label-setops

Conversation

@mtfishman

@mtfishman mtfishman commented Jun 29, 2026

Copy link
Copy Markdown
Member

Summary

Does the dimname/label bookkeeping in the out-of-place contraction path with linear scans instead of the Set- and Dict-based Base.setdiff/intersect/indexin. For the handful of labels a tensor carries the hashing those build dominates, and on a small contraction it costs more than the matrix multiply itself. biperms and contract_labels use order-preserving Vector comprehensions for the output and contracted labels, and tuple_indexin finds label positions with findfirst rather than Base.indexin. The old check that every label appears exactly twice is replaced by a check that the destination carries exactly the uncontracted labels: the contracted and output groups partition the operands by construction, so that is the only consistency left to verify. These all assume the labels within each group are unique, which holds for a contraction.

On a 4x4 contraction sharing one index, a1 * a2 drops from 4.6 μs / 124 allocations to 1.9 μs / 60.

@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.62%. Comparing base (546fa59) to head (687f8c7).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #190      +/-   ##
==========================================
- Coverage   82.71%   82.62%   -0.09%     
==========================================
  Files          22       22              
  Lines         619      616       -3     
==========================================
- Hits          512      509       -3     
  Misses        107      107              
Flag Coverage Δ
docs 29.00% <77.77%> (-0.24%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

## Summary

Does the dimname/label bookkeeping in the out-of-place contraction path with linear scans instead of the `Set`- and `Dict`-based `Base.setdiff`/`intersect`/`indexin`. For the handful of labels a tensor carries the hashing those build dominates, and on a small contraction it costs more than the matrix multiply itself. `biperms` and `contract_labels` use order-preserving `Vector` comprehensions for the output and contracted labels, and `tuple_indexin` finds label positions with `findfirst` rather than `Base.indexin`. The old check that every label appears exactly twice is replaced by a check that the destination carries exactly the uncontracted labels: the contracted and output groups partition the operands by construction, so that is the only consistency left to verify. These all assume the labels within each group are unique, which holds for a contraction.

On a 4x4 contraction sharing one index, `a1 * a2` drops from 4.6 μs / 124 allocations to 1.9 μs / 60.
@mtfishman mtfishman force-pushed the mf/linear-label-setops branch from ba983f1 to 687f8c7 Compare June 29, 2026 23:02
@mtfishman mtfishman changed the title Use linear set operations for contraction labels Use linear scans instead of hashing for contraction labels Jun 29, 2026
@mtfishman mtfishman enabled auto-merge (squash) June 29, 2026 23:14
@mtfishman mtfishman merged commit c3b0232 into main Jun 29, 2026
21 checks passed
@mtfishman mtfishman deleted the mf/linear-label-setops branch June 29, 2026 23:23
mtfishman added a commit that referenced this pull request Jun 30, 2026
## Summary

Derives the bipartitioned permutations for `contract` as
concretely-typed tuples behind a single `Val` function-barrier on the
contracted count, rather than building them by converting runtime-length
`Vector`s into abstract-typed tuples. The abstract tuples defeated the
type stability of the downstream `matricize` pipeline, which is built
around statically-sized tuples and `Val` barriers, so the per-call
bookkeeping for a small contraction boxed heavily.

This is a second pass on the label-derivation layer, after
#190 removed the `Set`
and `Dict` hashing from the same path. For a 4x4 matrix multiply the
per-call cost drops from 51 allocations to 17 and is several times
faster, landing just above the floor set by the lower-level entry point
that takes the permutations directly. The remaining allocations are the
output array temporaries and the destination-label `Vector`.

The public `biperms` and `biperm` signatures are unchanged. The
type-stable core is a new `Val`-parameterized method of `biperms`, and
the two label entry points cross into `Val`-specialized helpers so the
contraction itself runs type-stably.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant