Fix N-D input handling in default backend int8 ops - #2062
Open
2sumtech wants to merge 1 commit into
Open
Conversation
The default backend implementations of int8_mm_dequant, int8_vectorwise_quant and int8_vectorwise_dequant assumed a 2-D input. int8_mm_dequant flattened the leading dimensions and returned the flattened result, and the two vectorwise kernels broadcast against the wrong dimension and raised a RuntimeError. The registered fake kernels and the CUDA implementations all treat the leading dimensions as rows and preserve the shape of A, so this was a shape contract violation that torch.library.opcheck catches on any non-CUDA device. Flatten the leading dimensions for the computation and restore the original shape on the way out. Output for 2-D inputs is bit for bit unchanged.
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.
Summary
The default backend implementations of
int8_mm_dequant,int8_vectorwise_quantandint8_vectorwise_dequantassume a 2-D input. This makes them disagree with their own registered fake kernels on any input with more than two dimensions.int8_mm_dequantflattens the leading dimensions and returns the flattened result, so a 3-D input silently comes back 2-Dint8_vectorwise_quantreduces overdim=1instead of the last dimension and raises a RuntimeErrorint8_vectorwise_dequantbroadcasts the row scales against the wrong dimension and raises a RuntimeErrorRoot cause
All three fake kernels treat the leading dimensions as rows and preserve the shape of
A. The CUDA kernels for the first two do the same, allocating withtorch.empty_like(A)/torch.empty(A.shape)and passingA.numel() // A.shape[-1]as the row count. Only the default implementations flatten, so the disagreement shows up on CPU, MPS and XPU but not on CUDA.torch.library.opcheckfails its FakeTensor comparison for a 3-D input.int8_scaled_mminherits the problem throughint8_mm_dequant, returning a 2-D result where the contract promises 3-D.Fix
Flatten the leading dimensions for the computation and restore the original shape on the way out.
int8_mm_dequantalso switchesviewtoreshapeso a non-contiguous input does not throw.Impact
Output for 2-D inputs is bit for bit unchanged, verified by hashing all three ops over several shapes on CPU and MPS against main. 1-D, 3-D and 4-D inputs now match the fake kernel,
opcheckpasses, andtorch.compilewithfullgraph=Trueworks over a 3-Dint8_mm_dequant.No new tests added. The existing
test_int8_mm_dequantalready asserts shape and runsopcheck, and the current suites cover the change. Happy to parametrize a 3-D shape into it if you want the case pinned.Tests
pytest tests/test_ops.py -k int8(325 passed, 21 skipped)pytest tests/test_functional.py -k "int8 or igemmlt or coo"(49 passed, 5 skipped)pytest tests/test_linear8bitlt.py tests/test_autograd.py(1640 passed)pre-commitruff and ruff-format clean on both changed filesTested on Apple Silicon, so CPU and MPS both exercise the default kernels. I do not have CUDA hardware, and the CUDA paths are untouched.
Drafted with AI assistance. All analysis, the fix and the test runs were verified locally by me.