⚡ Thunderbolt: softmax_v6 — 8x unrolled AVX2 single-FMA exp256#73
⚡ Thunderbolt: softmax_v6 — 8x unrolled AVX2 single-FMA exp256#73bugparty wants to merge 1 commit into
Conversation
Co-authored-by: bugparty <1510776+bugparty@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
📝 WalkthroughWalkthroughThis PR adds an AVX2 exp approximation helper ChangesAVX2 softmax_v6 kernel addition
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
ml_kernels/src/test_naive_ops.cpp (1)
217-218: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider adding
test_softmax_v6()at the end ofmain()for consistency.It's called first, before all existing tests. Not a bug, but placing it after
test_softmax_v5()would be more consistent with the version-ordered progression of the other test calls.♻️ Suggested ordering
int main() { - test_softmax_v6(); test_relu_naive(); test_max_naive(); test_softmax_v3(); test_softmax_v4(); test_softmax_v5(); + test_softmax_v6(); std::cout << "All tests passed successfully!" << std::endl; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ml_kernels/src/test_naive_ops.cpp` around lines 217 - 218, Move the test_softmax_v6() call in main() to the end of the existing softmax test sequence so the versioned test calls stay in order. Keep the change localized in main() in test_naive_ops.cpp, placing test_softmax_v6() after test_softmax_v5() and before any later cleanup/return logic if present.ml_kernels/include/ml_kernels/softmax.h (1)
505-505: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueBrace placement violates the repo style rule.
Function-body opening braces sit on the signature line for both
exp256_ps_v3(Line 505) andsoftmax_v6(Line 539). The rest of the file shares this pattern, but the guideline calls for braces on their own line.As per coding guidelines: "Keep braces on their own lines for function bodies".
Also applies to: 539-539
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ml_kernels/include/ml_kernels/softmax.h` at line 505, Move the function-body opening braces for exp256_ps_v3 and softmax_v6 onto their own lines to match the repo’s brace style. Update the function declarations so the opening brace is separated from the signature for each of these functions, and keep the rest of the body unchanged.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@ml_kernels/include/ml_kernels/softmax.h`:
- Line 505: Move the function-body opening braces for exp256_ps_v3 and
softmax_v6 onto their own lines to match the repo’s brace style. Update the
function declarations so the opening brace is separated from the signature for
each of these functions, and keep the rest of the body unchanged.
In `@ml_kernels/src/test_naive_ops.cpp`:
- Around line 217-218: Move the test_softmax_v6() call in main() to the end of
the existing softmax test sequence so the versioned test calls stay in order.
Keep the change localized in main() in test_naive_ops.cpp, placing
test_softmax_v6() after test_softmax_v5() and before any later cleanup/return
logic if present.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4d6a629c-81a5-495e-85ad-eff90567b4a4
📒 Files selected for processing (4)
.jules/thunderbolt.mdml_kernels/include/ml_kernels/softmax.hml_kernels/src/kernel_bench.cppml_kernels/src/test_naive_ops.cpp
💡 What: Added
softmax_v6andexp256_ps_v3toml_kernels/include/ml_kernels/softmax.h.softmax_v6unrolls the softmax loops 8x (64 elements per iteration).exp256_ps_v3utilizes a single FMA for ther = x - n * ln(2)operation rather than splittingln(2).🎯 Why: To shift the bottleneck away from execution port contention/instruction latency and directly towards L1/L2 cache bandwidth limits by fully utilizing all 16 YMM registers.
🏗️ How:
softmax_v5unrolled 4x.softmax_v6aggressively unrolls 8x and merges the precision-split subtraction in range reduction into a single_mm256_fnmadd_ps. The single FMA sacrifices ~1e-7 precision (still well within the 1e-4 tolerance of softmax ML kernels) to eliminate an instruction dependency.📊 Impact:
softmax_v5) to ~4.91 GFLOP/s (softmax_v6), a ~12% speedup.softmax_v5) to ~3.03 GFLOP/s (softmax_v6), a ~12% speedup.🖥️ Tested on: Target: AVX2 (Haswell+). Environment: GCC 13.3.0.
🔬 How to reproduce:
DISABLE_CPU_BINDING=1 ./build/ml_kernels/ml_kernel_bench --filter "softmax_v[56]" --sizes 262144 --iters 200PR created automatically by Jules for task 7534808963543397349 started by @bugparty
Summary by CodeRabbit
New Features
Documentation
Tests