Skip to content

test(rocfft): stable, position-aware hash for bitwise repro buffers - #12752

Merged
Abuudiii merged 7 commits into
developfrom
users/Abdullah/rocfft-bitwise-repro-stable-hash
Oct 12, 2026
Merged

Abuudiii merged 7 commits into
developfrom
users/Abdullah/rocfft-bitwise-repro-stable-hash

Conversation

@Abuudiii

@Abuudiii Abuudiii commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

JIRA ID : AIFFT-517

The bitwise reproducibility tests store a fingerprint (hash) of each FFT result and compare it on later runs. The hash had three problems:

  • It used std::hash, which can give different results on different compilers or runs, so stored fingerprints could stop matching even when the output was identical.
  • Each value was multiplied by a weight and rounded before hashing, so a change in the last bit could be lost.
  • Each element's position was computed as row + column, so a transposed output produced the same hash.

Technical Details

  • shared/fft_hash.h: each element is hashed from its exact bits together with its real position (batch, then row-major index), using a fixed hash function. Results are still added together, so the thread count doesn't affect the hash.
  • projects/hipfft/shared/fft_hash.h: kept identical to the rocFFT copy.
  • clients/tests/buffer_hash_test.cpp: new tests check that a transpose, a 1-bit change and a batch swap all change the hash, and that padding doesn't. Fixed expected hashes cover half, single and double precision.
  • testing.md: updated to describe the new hash.

SHA-256 (shared/sha256.h) isn't used because its result depends on the order of the data, so it would change with the number of threads.

Existing stored fingerprints must be regenerated.

Test Plan

On MI300X (gfx942), ROCm 7.2.4:

  • Ran the new tests against the old hash and the new one.
  • Ran the bitwise repro test twice in separate processes with --repro-db, for 5 FFT cases.

Test Result

  • The old hash fails the transpose, 1-bit and padding tests. The new hash passes all hash tests.
  • Repro-db: the first run stored all 5 fingerprints, and the second run matched all 5.

Submission Checklist

@therock-pr-bot

therock-pr-bot Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

@Abuudiii Abuudiii self-assigned this Sep 29, 2026
@codecov

codecov Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 38 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
projects/rocfft/shared/fft_hash.h 0.00% 38 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #12752      +/-   ##
===========================================
- Coverage    71.86%   70.66%   -1.20%     
===========================================
  Files         2876     2939      +63     
  Lines       475315   483978    +8663     
  Branches     70237    69789     -448     
===========================================
+ Hits        341569   341963     +394     
- Misses      109960   118257    +8297     
+ Partials     23786    23758      -28     
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 48.82% <ø> (-0.85%) ⬇️ Carriedforward from ec7d018
TensileLite-Unit 82.58% <ø> (-0.86%) ⬇️ Carriedforward from ec7d018
hipBLAS 90.62% <ø> (ø) Carriedforward from ec7d018
hipBLASLt 35.59% <ø> (-7.13%) ⬇️ Carriedforward from ec7d018
hipCUB 82.68% <ø> (ø) Carriedforward from ec7d018
hipDNN 86.71% <ø> (+0.05%) ⬆️ Carriedforward from ec7d018
hipFFT 42.33% <ø> (-0.25%) ⬇️
hipRAND 76.12% <ø> (ø) Carriedforward from ec7d018
hipSOLVER 68.96% <ø> (ø) Carriedforward from ec7d018
hipSPARSE 86.99% <ø> (ø) Carriedforward from ec7d018
rocBLAS 48.25% <ø> (+0.08%) ⬆️ Carriedforward from ec7d018
rocFFT 48.95% <0.00%> (+2.43%) ⬆️
rocRAND 57.42% <ø> (+0.03%) ⬆️ Carriedforward from ec7d018
rocSOLVER 76.83% <ø> (+<0.01%) ⬆️ Carriedforward from ec7d018
rocSPARSE 74.75% <ø> (+0.68%) ⬆️ Carriedforward from ec7d018
rocThrust 78.45% <ø> (-14.70%) ⬇️ Carriedforward from ec7d018

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
projects/rocfft/shared/fft_hash.h 0.00% <0.00%> (ø)

... and 636 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@eng-flavio-teixeira

Copy link
Copy Markdown
Contributor

Any reason to use yet another hashing algorithm (splitmix64 finalizer) instead of the already available SHA-256 reference from shared/sha256.h ?

@Abuudiii

Abuudiii commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor Author

Any reason to use yet another hashing algorithm (splitmix64 finalizer) instead of the already available SHA-256 reference from shared/sha256.h ?

@eng-flavio-teixeira SHA-256 reads data in order, so hashing each partition with it changes the fingerprint when the thread count changes. Hashing each element with it is ~186× slower, and hashing the whole buffer would mean redesigning the layout handling and the repro-db format.

@Abuudiii
Abuudiii requested a review from a team as a code owner October 5, 2026 18:10
@eng-flavio-teixeira

Copy link
Copy Markdown
Contributor

Any reason to use yet another hashing algorithm (splitmix64 finalizer) instead of the already available SHA-256 reference from shared/sha256.h ?

@eng-flavio-teixeira SHA-256 reads data in order, so hashing each partition with it changes the fingerprint when the thread count changes. Hashing each element with it is ~186× slower, and hashing the whole buffer would mean redesigning the layout handling and the repro-db format.

Thanks for the explanation.

Can you run the bitwise repro tests twice, passing the repro-db option (if you haven't done it already) to make sure the tests pass without issues with your changes? I don't think a regular CI pass exercise this.

@regan-amd regan-amd left a comment

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.

Please make sure hipfft/shared and rocfft/shared contents are aligned before merging.

Comment thread projects/rocfft/shared/fft_hash.h Resolved
@Abuudiii

Abuudiii commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

@regan-amd Done in 3e957fb, both points as you suggested:

  • Raw bits, no weights. Each element now contributes stable_hash(raw_bits(v) ^ stable_hash(position)). raw_bits is the value's own IEEE-754 pattern: 16-bit for fp16 (no longer widened to float), 32-bit for single, 64-bit for double. The weight * value product is gone, so a 1-ULP change can't round away.
  • True position. position = batch * elements_per_batch + row-major index, computed from the logical lengths. The old counter used all-ones strides (row + col). It no longer uses idist or strides, so padding doesn't change the hash, but a batch swap still does. Per-element results are still summed, so OpenMP partitioning doesn't matter.
  • hipFFT. projects/hipfft/shared/fft_hash.h is now byte-identical to the rocFFT copy.

New tests in buffer_hash_test.cpp. I ran them against the previous hash first (MI300X, ROCm 7.2.4):

Test Old hash New hash
buffer_hash_detects_transpose (4x4 real float/double, complex interleaved) FAIL: the transposed buffer gives the same hash for real and imag pass
buffer_hash_detects_one_ulp (1.7f vs nextafter(1.7f, 2.0f) at weight 3/4) FAIL: same hash pass
buffer_hash_ignores_padding (2D batch 2, contiguous vs padded stride/dist, -999 in the padding) FAIL pass
buffer_hash_detects_batch_swap pass pass (fails if the batch term is set to 0)
buffer_hash_golden_values (now covers half too) FAIL (expected: new values) pass

All buffer_hash* tests pass with OMP_NUM_THREADS=1 and 16. testing.md is updated to match.

@Abuudiii

Abuudiii commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

@eng-flavio-teixeira Two-process --repro-db results on the new head 3e957fb (MI300X gfx942, ROCm 7.2.4). Each line is a separate rocfft-test --gtest_filter=manual.bitwise_reproducibility --repro-db $DB process, all using one DB:

Case Run 1 Run 2 Run 2, OMP_NUM_THREADS=1
--length 1024 -t 0 --precision single added to repro-db (skipped) OK OK
--length 4096 -t 0 --precision double added to repro-db (skipped) OK OK
--length 1000 -t 2 -b 3 --precision single added to repro-db (skipped) OK OK
--length 64 64 -t 1 --precision half added to repro-db (skipped) OK OK
--length 64 64 64 -t 0 --precision double -o added to repro-db (skipped) OK OK

Run 1 printed FFT result entry added to the repro-db file. Previously stored reference entry not found., and every later run printed [ OK ] manual.bitwise_reproducibility. So the stored fingerprints match across processes and across thread counts.

@Abuudiii Abuudiii changed the title test(rocfft): use a stable hash for bitwise repro buffer hashing test(rocfft): stable, position-aware hash for bitwise repro buffers Oct 7, 2026
@Abuudiii
Abuudiii requested a review from regan-amd October 7, 2026 19:33
@Abuudiii
Abuudiii requested a review from regan-amd October 7, 2026 20:33

@anisha-amd anisha-amd left a comment

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.

Looks good!

@Abuudiii
Abuudiii merged commit 2ea93b3 into develop Oct 12, 2026
98 of 101 checks passed
@Abuudiii
Abuudiii deleted the users/Abdullah/rocfft-bitwise-repro-stable-hash branch October 12, 2026 05:03
assistant-librarian Bot pushed a commit to ROCm/hipFFT that referenced this pull request Oct 12, 2026
test(rocfft): stable, position-aware hash for bitwise repro
 buffers (#12752)

## Motivation

JIRA ID : AIFFT-517

The bitwise reproducibility tests store a fingerprint (hash) of each FFT
result and compare it on later runs. The hash had three problems:
- It used `std::hash`, which can give different results on different
compilers or runs, so stored fingerprints could stop matching even when
the output was identical.
- Each value was multiplied by a weight and rounded before hashing, so a
change in the last bit could be lost.
- Each element's position was computed as `row + column`, so a
transposed output produced the same hash.

## Technical Details

- `shared/fft_hash.h`: each element is hashed from its exact bits
together with its real position (batch, then row-major index), using a
fixed hash function. Results are still added together, so the thread
count doesn't affect the hash.
- `projects/hipfft/shared/fft_hash.h`: kept identical to the rocFFT
copy.
- `clients/tests/buffer_hash_test.cpp`: new tests check that a
transpose, a 1-bit change and a batch swap all change the hash, and that
padding doesn't. Fixed expected hashes cover half, single and double
precision.
- `testing.md`: updated to describe the new hash.

SHA-256 (`shared/sha256.h`) isn't used because its result depends on the
order of the data, so it would change with the number of threads.

Existing stored fingerprints must be regenerated.

## Test Plan

On MI300X (gfx942), ROCm 7.2.4:
- Ran the new tests against the old hash and the new one.
- Ran the bitwise repro test twice in separate processes with
`--repro-db`, for 5 FFT cases.

## Test Result

- The old hash fails the transpose, 1-bit and padding tests. The new
hash passes all hash tests.
- Repro-db: the first run stored all 5 fingerprints, and the second run
matched all 5.

## Submission Checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

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.

5 participants