Skip to content

einsum: Fallback to multiply-and-reduce for integer contractions - #4466

Closed
somuai wants to merge 1 commit into
ml-explore:mainfrom
somuai:fix-einsum-integer-contractions
Closed

einsum: Fallback to multiply-and-reduce for integer contractions#4466
somuai wants to merge 1 commit into
ml-explore:mainfrom
somuai:fix-einsum-integer-contractions

Conversation

@somuai

@somuai somuai commented Sep 4, 2026

Copy link
Copy Markdown

[x] I understand it is strictly prohibited to use AI to write PR description

  • AI usage disclosure: None

Fixes #4463

Problem

mx.einsum lowers contractions using can_dot, which selects batch_tensordot (and subsequently matmul). Because matmul rejects non-floating point types, valid integer contractions (such as mx.einsum("ij,jk->ik", x, x)) fail with:
ValueError: [matmul] Only inexact types are supported but int32 and int32 were provided...

Solution

Update can_dot in mlx/einsum.cpp to verify that the promoted operand dtype is an inexact type before selecting the batch_tensordot fast path. When contracting integer or boolean arrays, can_dot evaluates to false, routing the operation to einsum_naive. einsum_naive uses general multiply-and-reduce, which natively supports all integer, unsigned integer, and boolean dtypes with exact mathematical precision.

Verification

  • Added C++ test case in tests/einsum_tests.cpp validating integer matrix contraction ("ij,jk->ik") with array_equal.
  • Added Python test case test_integer_contractions in python/tests/test_einsum.py testing contractions across int8, int16, int32, int64, uint8, uint16, uint32, uint64 with NumPy parity.
  • Passed pre-commit hooks: clang-format, black, isort.

Comment thread mlx/einsum.cpp Outdated
return false;
}

// Matmul only supports inexact types

@JasonHonKL JasonHonKL Sep 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why we don't place this check before the can_dot call in the einsum function? Because right now, you add two extra parameters to the can_dot function while the purpose is just for checking (?).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point @JasonHonKL! You are completely right—can_dot should remain purely a subscript topology check without requiring tensor instances.

I have updated the implementation so that can_dot keeps its original signature (const std::vector<Subscript>& inputs, const Subscript& output), and the issubdtype(promote_types(...), inexact) check is performed directly at the call site in einsum alongside can_dot. Pushed in commit f4090e0.

Fixes ml-explore#4463

Einsum lowered all contractions with can_dot to batch_tensordot,
which invokes matmul. Because matmul requires inexact (floating or
complex) dtypes, integer contractions like 'ij,jk->ik' failed with
a ValueError.

Check operand dtypes before invoking batch_tensordot and route non-inexact
contractions to einsum_naive, which performs general multiply-and-reduce
across all integer and boolean dtypes.
@somuai
somuai force-pushed the fix-einsum-integer-contractions branch from d44fc34 to f4090e0 Compare September 5, 2026 06:35
@zcbenz

zcbenz commented Sep 5, 2026

Copy link
Copy Markdown
Member

Closing per #4463 (comment). @somuai Please do not lie about AI usage.

@zcbenz zcbenz closed this Sep 5, 2026
@simeetnayan81

simeetnayan81 commented Sep 5, 2026

Copy link
Copy Markdown

@zcbenz Just a suggestion, I don't know how feasible would that be.
Let's just promote habit of discussing solutions in the issue before raising a PR. Maybe we can ignore such PRs which don't follow solution discussion.

Recently I have been seeing, whenever I see an open unassigned issue, by the time I start even digging down or do some analysis, I see someone already raising a PR with code changes.

I am in no way saying that we shouldn't use AI for coding. It's just that whoever is working should have full idea about what impact their changes might bring or the whole project would be a big chunk which noone understands.

This might make things slow, but keeps things transparent for contributors, maintainers, as well as someone who wants to learn why we did what we did.

PS: I have very little idea about project management and I'm very junior so if this doesn't sound logical/feasible, please ignore me 🥲

@zcbenz

zcbenz commented Sep 5, 2026

Copy link
Copy Markdown
Member

Strictly speaking we require fully understanding of the problem and code when sending a PR, and for a lot of cases reasonable people should discuss first before asking their agent to send a fix, but we don't really have a good way to enforce that without adding more burdens on management.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Einsum selects unsupported matmul for integer contractions

4 participants