Skip to content

fix(tabulate): correct sorted padding two-embed gradients#5904

Open
njzjz wants to merge 1 commit into
deepmodeling:masterfrom
njzjz:codex/code-scan-5891
Open

fix(tabulate): correct sorted padding two-embed gradients#5904
njzjz wants to merge 1 commit into
deepmodeling:masterfrom
njzjz:codex/code-scan-5891

Conversation

@njzjz

@njzjz njzjz commented Jul 25, 2026

Copy link
Copy Markdown
Member

Summary

  • preserve the folded sorted-padding forward contract and make only the first sentinel depend on two_embed
  • scale that sentinel gradient by the padding-tail length while leaving later padding gradients zero on CPU and GPU
  • add finite-difference and nonuniform-cotangent grad-grad regression tests, including a GPU tail longer than the four-warp tile

Validation

  • source/build/lib/tests/runUnitTests_lib --gtest_filter='TestTabulateSeA.*:TestTabulateSeASortedPaddingTwoEmbed.*'
  • CUDA 12.4 build of deepmd_op_cuda and runUnitTests_lib
  • RTX 5090 Slurm run of all 8 existing/new SE-A CPU and GPU tests
  • ruff format .
  • ruff check .
  • clang-format --dry-run --Werror on changed C++/CUDA files

Closes #5891

Note: #5844 modifies the same GPU kernel for the shared-breakpoint fix, so the later-merging branch may need a small conflict resolution; the gradient contract fixed here is independent.

Coding agent: Codex
Codex version: codex-cli 0.144.6
Model: gpt-5.6-sol
Reasoning effort: xhigh

Summary by CodeRabbit

  • Bug Fixes

    • Corrected two-embedding gradients for sorted-padding neighbor data.
    • Fixed repeated padding contributions in CPU and GPU gradient calculations.
    • Ensured unused GPU padding gradients are reset before calculation.
  • Tests

    • Added CPU and GPU coverage validating first- and second-order two-embedding gradients against numerical derivatives.

Coding-Agent: Codex
Codex-Version: codex-cli 0.144.6
Model: gpt-5.6-sol
Reasoning-Effort: xhigh
Copilot AI review requested due to automatic review settings July 25, 2026 02:31
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Sorted-padding gradient corrections

Layer / File(s) Summary
Backend gradient logic
source/lib/src/tabulate.cc, source/lib/src/gpu/tabulate.cu
CPU and GPU dy_dtwo handling now assigns the folded tail’s scaled gradient only to its first padding sentinel.
GPU gradient buffer initialization
source/lib/src/gpu/tabulate.cu
The GPU wrapper clears dy_dtwo before launching the gradient kernel when two_embed is present.
Finite-difference validation
source/lib/tests/test_tabulate_se_a.cc
New CPU and GPU tests compare first- and second-order two-embedding gradients against numerical derivatives for sorted padding.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels: bug

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing sorted-padding two_embed gradients in tabulate.
Linked Issues check ✅ Passed The PR implements the requested coherent forward, backward, and grad-grad fixes for sorted-padding two_embed gradients and adds the required regression tests.
Out of Scope Changes check ✅ Passed The code changes stay focused on the sorted-padding two_embed gradient fix and its tests, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (2)
source/lib/tests/test_tabulate_se_a.cc (2)

881-888: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use an unsigned index and assert matching extents in dot.

ii is int while lhs.size() is size_type, so -Wsign-compare fires here and in the test loops at Lines 1008, 1019, 1031, 1049, 1060, and 1070 (a -Werror test target would fail to build). Indexing rhs with lhs's extent is also unguarded.

♻️ Proposed fix
   static double dot(const std::vector<double>& lhs,
                     const std::vector<double>& rhs) {
+    EXPECT_EQ(lhs.size(), rhs.size());
     double result = 0.0;
-    for (int ii = 0; ii < lhs.size(); ++ii) {
+    for (std::size_t ii = 0; ii < lhs.size(); ++ii) {
       result += lhs[ii] * rhs[ii];
     }
     return result;
   }

The test loops can likewise use std::size_t ii.

🤖 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 `@source/lib/tests/test_tabulate_se_a.cc` around lines 881 - 888, Update dot to
use std::size_t for its loop index and assert that lhs and rhs have matching
extents before indexing. Apply the same unsigned index type to the test loops
identified at lines 1008, 1019, 1031, 1049, 1060, and 1070, preserving their
existing loop behavior.

1045-1058: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add GPU forward parity to this fixture.

two_embed_gradient_matches_forward_gpu reads GPU gradients while the finite-difference reference comes from forward_projection_cpu, so a CPU/GPU forward mismatch reports as a backward failure. Add an assertion comparing tabulate_fusion_se_a_gpu output with the CPU forward for this last_layer_size == 1 configuration before using the GPU gradient in other wrapper coverage.

🤖 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 `@source/lib/tests/test_tabulate_se_a.cc` around lines 1045 - 1058, Add a
CPU/GPU forward-output parity assertion in
TestTabulateSeASortedPaddingTwoEmbed’s two_embed_gradient_matches_forward_gpu
test, comparing tabulate_fusion_se_a_gpu with forward_projection_cpu for the
last_layer_size == 1 configuration before validating gradients. Keep the
existing finite-difference gradient checks unchanged.
🤖 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 `@source/lib/tests/test_tabulate_se_a.cc`:
- Around line 881-888: Update dot to use std::size_t for its loop index and
assert that lhs and rhs have matching extents before indexing. Apply the same
unsigned index type to the test loops identified at lines 1008, 1019, 1031,
1049, 1060, and 1070, preserving their existing loop behavior.
- Around line 1045-1058: Add a CPU/GPU forward-output parity assertion in
TestTabulateSeASortedPaddingTwoEmbed’s two_embed_gradient_matches_forward_gpu
test, comparing tabulate_fusion_se_a_gpu with forward_projection_cpu for the
last_layer_size == 1 configuration before validating gradients. Keep the
existing finite-difference gradient checks unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4544f118-1fa2-4780-8a29-b5c4895c7753

📥 Commits

Reviewing files that changed from the base of the PR and between e5fdff0 and 20f0839.

📒 Files selected for processing (3)
  • source/lib/src/gpu/tabulate.cu
  • source/lib/src/tabulate.cc
  • source/lib/tests/test_tabulate_se_a.cc

Copilot AI 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.

Pull request overview

Fixes the SE-A tabulation attention (two_embed) gradient contract for sorted padding tails so that only the first padding sentinel contributes to the folded forward output, with its gradient scaled by the tail length, and ensures the GPU path clears unused tail gradients. Adds targeted CPU/GPU finite-difference and grad-grad regression tests for the corrected behavior.

Changes:

  • Update CPU backward to write a repeat-scaled two_embed gradient only at the first sorted-padding sentinel (tail entries remain zero).
  • Update GPU backward to mirror the same folded-tail gradient ownership and explicitly zero dy_dtwo outputs to avoid leaving uninitialized tail values.
  • Add CPU/GPU finite-difference and double-backward regression tests for nonuniform tail cotangents and a tail longer than the 4-warp tile.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
source/lib/tests/test_tabulate_se_a.cc Adds CPU/GPU finite-difference + grad-grad regression tests for sorted-padding two_embed gradients.
source/lib/src/tabulate.cc Fixes CPU two_embed backward to match folded sorted-padding forward contract (only first sentinel gets scaled grad).
source/lib/src/gpu/tabulate.cu Fixes GPU two_embed backward for sorted padding and clears dy_dtwo to keep unused tail gradients at zero.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1049 to +1057
for (int ii = 0; ii < two_embed.size(); ++ii) {
std::vector<double> plus = two_embed;
std::vector<double> minus = two_embed;
plus[ii] += step;
minus[ii] -= step;
const double expected =
(forward_projection_cpu(plus) - forward_projection_cpu(minus)) /
(2.0 * step);
EXPECT_NEAR(actual[ii], expected, 1e-9);
Comment on lines +1091 to +1096
if (two_embed != nullptr) {
// The sorted-padding fast path writes only the first sentinel. Explicitly
// clear the unused tail because framework output buffers are uninitialized.
DPErrcheck(
gpuMemset(dy_dtwo, 0, sizeof(FPTYPE) * nloc * nnei * last_layer_size));
}
@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.64%. Comparing base (e5fdff0) to head (20f0839).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5904      +/-   ##
==========================================
- Coverage   78.89%   78.64%   -0.25%     
==========================================
  Files        1054     1054              
  Lines      121774   121820      +46     
  Branches     4408     4412       +4     
==========================================
- Hits        96076    95810     -266     
- Misses      24121    24429     +308     
- Partials     1577     1581       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 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.

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.

[Code scan] Sorted SE-Attention padding has inconsistent two_embed gradients and double backward

3 participants