Repository navigation
fix: handle negative exponents in integer powi - #2043
Merged
Merged
Conversation
`powi_int` read its `i32` exponent as `u32`, so `3^-1` wrapped to -1431655765 (the inverse of 3 mod 2^32) instead of truncating to 0. A negative exponent now gives `1 / base^|exp|` truncated toward zero: 1 for a base of 1, 1 or -1 by parity for a base of -1, and 0 otherwise, including for a base of 0. Non-negative exponents are unchanged. The wrapping calculation moves to a public `powi_unsigned`, which takes a `u32` exponent, so callers whose exponent is unsigned (such as Burn's unsigned integer tensors) keep powers above `i32::MAX`. Co-Authored-By: Claude Opus 5.5 <[email protected]>
laggui
approved these changes
Nov 4, 2026
laggui
left a comment
Member
There was a problem hiding this comment.
LGTM, just consolidated some of the tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to tracel-ai/burn#6355, where @laggui asked to fix signed exponent handling in
powi_intand keep the wrapping calculation in apowi_unsignedhelper, so Burn can pick the right one per dtype.Changes
powi_intread itsi32exponent asu32, so3^-1gave -1431655765 (the inverse of 3 mod 2^32). A negative exponent now gives1 / base^|exp|truncated toward zero: 1 for a base of 1, 1 or -1 by parity for a base of -1, and 0 otherwise, including a base of 0. That matches Burn's Flex backend andtorch.powon integer tensors. Non-negative exponents are unchanged.powi_unsigned(base, exp: Vector<u32, N>). Callers with an unsigned exponent keep powers abovei32::MAX.This changes integer
powion every backend that lowers throughpowi_int(WGSL, SPIR-V, C++, LLVM): a negative exponent used to act like a large unsigned one.Testing
test_powi_int_negative_exponentfails on main (Values differ: actual=-1431655765, expected=0, index=0) and passes with the fix.test_powi_intnow expects truncated results for its negative-exponent cases; on main it fails at(3i64, i32::MIN).test_powi_unsignedcovers exponents abovei32::MAXfor 8- to 64-bit bases.cargo test -p cubecl-wgpu --lib(WGSL, 699 passed) and the same with--features spirv(949 passed) both pass. I couldn't run CUDA, HIP, Metal or the CPU runtime.cargo fmt --checkandcargo clippy -p cubecl-core --all-targets --features export_tests -- -D warningsare clean. I didn't run the fullcargo xtask validate.powitests pass on the Vulkan backend after switchingPowiOptopowi_unsignedfor unsigned dtypes andpowi_intfor signed ones. Without that switch, au32exponent abovei32::MAXgives 0, so the Burn change has to land together with the rev bump.Validate your PR with burn.
I used Claude Code to write this change.