Skip to content

Fix int32 overflow in elem_count for tensors with >2.1B elements#116

Merged
polvalente merged 4 commits into
elixir-nx:mainfrom
edenamram:fix-int32-overflow-elem-count
Jun 14, 2026
Merged

Fix int32 overflow in elem_count for tensors with >2.1B elements#116
polvalente merged 4 commits into
elixir-nx:mainfrom
edenamram:fix-int32-overflow-elem-count

Conversation

@edenamram

Copy link
Copy Markdown
Contributor

Problem

elem_count uses std::accumulate with an int initial value:

uint64_t elem_count(std::vector<int> shape) {
  return std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<>{});
}

When the initial accumulator value is int, all intermediate multiplications are performed in 32-bit signed arithmetic. For shapes whose element-count product exceeds INT32_MAX (~2.1B), the product overflows to a negative int, which is then cast to a large uint64_t value. The binary-size guard in from_blob then always fires:

** (RuntimeError) Binary size is too small for the requested shape

Reproduction

google/gemma-4-2b-it (and larger Gemma-4 variants) include a weight called embed_tokens_per_layer with shape {262144, 8960}:

262144 × 8960 = 2,348,810,240  >  INT32_MAX (2,147,483,647)

This causes elem_count({262144, 8960}) to return 18,446,744,071,762,394,560 instead of 2,348,810,240, making it impossible to load the model via EMLX.Backend.

Fix

Seed the accumulator with uint64_t{1} and use std::multiplies<uint64_t> so every partial product stays in 64-bit arithmetic:

uint64_t elem_count(std::vector<int> shape) {
  return std::accumulate(shape.begin(), shape.end(), uint64_t{1}, std::multiplies<uint64_t>{});
}

Context

Discovered while implementing Gemma-4 support in Bumblebee: elixir-nx/bumblebee#460.

🤖 Generated with Claude Code

Comment thread emlx/c_src/emlx_nif.cpp
@edenamram edenamram force-pushed the fix-int32-overflow-elem-count branch from 6f2abf0 to bba71c1 Compare June 14, 2026 12:05
@edenamram edenamram requested a review from polvalente June 14, 2026 12:05

@polvalente polvalente left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the quick fix!

@polvalente polvalente merged commit e33e11d into elixir-nx:main Jun 14, 2026
5 of 6 checks passed
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.

2 participants