Skip to content

Commit 6f2abf0

Browse files
committed
test: add regression test for large tensors exceeding INT32_MAX
1 parent b0dd31f commit 6f2abf0

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

emlx/test/emlx_test.exs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,33 @@ defmodule EMLXTest do
170170
end
171171
end
172172
end
173+
174+
describe "large tensors (element count > INT32_MAX)" do
175+
# Regression: elem_count used std::accumulate with an `int` initial value,
176+
# so products > INT32_MAX overflowed to a huge uint64 and the binary-size
177+
# guard rejected valid binaries with "Binary size is too small".
178+
# Real-world trigger: Gemma-4's embed_tokens_per_layer {262144, 8960}
179+
# = 2_348_810_240 elements > INT32_MAX (2_147_483_647).
180+
@tag :large_tensor
181+
test "from_binary accepts shape whose element count exceeds INT32_MAX" do
182+
# 2 × 1_073_741_824 = 2_147_483_648 > INT32_MAX.
183+
# :u8 (1 byte/element) keeps total allocation at ~2 GB.
184+
#
185+
# We reshape on BinaryBackend first (pure Elixir, no NIF) because
186+
# Nx.from_binary always creates a 1D tensor — and a single dimension of
187+
# 2_147_483_648 also exceeds INT32_MAX, which breaks SHAPE_PARAM before
188+
# even reaching elem_count. The 2D shape {2, 1_073_741_824} has both
189+
# dims within int32 range; only their product overflows.
190+
n = 2_147_483_648
191+
binary = :binary.copy(<<7>>, n)
192+
193+
t =
194+
Nx.from_binary(binary, :u8, backend: Nx.BinaryBackend)
195+
|> Nx.reshape({2, 1_073_741_824})
196+
|> Nx.backend_transfer(EMLX.Backend)
197+
198+
assert Nx.shape(t) == {2, 1_073_741_824}
199+
assert Nx.to_number(t[0][0]) == 7
200+
end
201+
end
173202
end

0 commit comments

Comments
 (0)