Skip to content

pto-isa version of spmd_paged_attention_highperf#1266

Draft
MirkoDeVita98 wants to merge 3 commits into
hw-native-sys:mainfrom
MirkoDeVita98:paged_attention_isa
Draft

pto-isa version of spmd_paged_attention_highperf#1266
MirkoDeVita98 wants to merge 3 commits into
hw-native-sys:mainfrom
MirkoDeVita98:paged_attention_isa

Conversation

@MirkoDeVita98

@MirkoDeVita98 MirkoDeVita98 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor
python test_spmd_paged_attention_highperf.py -p a2a3sim


=== Runtime: tensormap_and_ringbuffer  Level: 2 ===
  TestSpmdPagedAttentionHighPerf::b1_h32_kv8_s128_bs128_fp16 ...
[2026-07-03 09:49:11.740157][T0xfe037b595b60][INFO_V9] ~StraceScope: [strace.h:129] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=2 name=simpler_run.bind.args ts=6028243865711371 dur=132139639 
[2026-07-03 09:49:11.765796][T0xfe037b595b60][INFO_V9] ~StraceScope: [strace.h:129] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=2 name=simpler_run.bind.prebuilt ts=6028243997921061 dur=25569374 
[2026-07-03 09:49:11.765841][T0xfe037b595b60][INFO_V9] ~StraceScope: [strace.h:129] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=1 name=simpler_run.bind ts=6028243865661851 dur=157883125 
[2026-07-03 09:49:12.393458][T0xfe037b595b60][INFO_V9] ~StraceScope: [strace.h:129] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=1 name=simpler_run.runner_run ts=6028244023557046 dur=627595138 
[2026-07-03 09:49:12.393517][T0xfe037b595b60][INFO_V9] ~StraceScope: [strace.h:129] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=1 name=simpler_run.validate ts=6028244651213454 dur=7970 
[2026-07-03 09:49:12.393534][T0xfe037b595b60][INFO_V9] emit_span_at: [strace.h:182] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=2 name=simpler_run.runner_run.device_wall ts=0 dur=586223136 clk=dev
[2026-07-03 09:49:12.393546][T0xfe037b595b60][INFO_V9] emit_span_at: [strace.h:182] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=3 name=simpler_run.runner_run.device_wall.config_validate ts=0 dur=1480 clk=dev
[2026-07-03 09:49:12.393557][T0xfe037b595b60][INFO_V9] emit_span_at: [strace.h:182] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=3 name=simpler_run.runner_run.device_wall.arena_wire ts=1540 dur=2340 clk=dev
[2026-07-03 09:49:12.393568][T0xfe037b595b60][INFO_V9] emit_span_at: [strace.h:182] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=3 name=simpler_run.runner_run.device_wall.sm_reset ts=3920 dur=3180 clk=dev
[2026-07-03 09:49:12.393578][T0xfe037b595b60][INFO_V9] emit_span_at: [strace.h:182] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=3 name=simpler_run.runner_run.device_wall.post_orch ts=574218580 dur=2640 clk=dev
[2026-07-03 09:49:12.393589][T0xfe037b595b60][INFO_V9] emit_span_at: [strace.h:182] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=3 name=simpler_run.runner_run.device_wall.orch ts=7340 dur=59500 clk=dev
[2026-07-03 09:49:12.393602][T0xfe037b595b60][INFO_V9] emit_span_at: [strace.h:182] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=3 name=simpler_run.runner_run.device_wall.sched ts=14460 dur=573150940 clk=dev
[2026-07-03 09:49:12.393614][T0xfe037b595b60][INFO_V9] ~StraceScope: [strace.h:129] [STRACE] v=1 pid=17600 tid=17600 inv=1 hid=0 depth=0 name=simpler_run ts=6028243865659150 dur=785658996 
  TestSpmdPagedAttentionHighPerf::b1_h32_kv8_s128_bs128_fp16 PASSED

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d300a453-f165-4383-af53-e4164696c11a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces high-performance paged attention kernels for Ascend/CANN, including split-KV pipelines. The code review identifies several critical issues: the entry point paged_attention_mask_body completely bypasses the high-performance non-split pipelines, and there are multiple cross-pipe synchronization race conditions in RunPtoPagedAttentionDecodeSplitKV where vector operations (such as TROWSUM, manual exponentiation, and manual logarithm) are read on the scalar side without proper synchronization flags. The reviewer recommends calling the high-performance pipelines when supported and utilizing robust helpers like PtoExpScalar and PtoLogScalar to ensure correct cross-pipe synchronization.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +67 to +88
#ifdef __DAV_C220_CUBE__
const int64_t workerIdx = static_cast<int64_t>(ptoBlockIdx);
const int64_t workerNum = static_cast<int64_t>(ptoBlockNum);
if (SupportsPtoPagedAttentionRawSplitKV(tilingParaGm)) {
RunPtoPagedAttentionCubePipelineSplitKV(qGm, kGm, vGm, blockTablesGm, sGm, pGm, oTmpGm, tilingParaGm,
workerIdx, workerNum);
} else {
pipe_barrier(PIPE_ALL);
}
#elif defined(__DAV_C220_VEC__)
const int64_t workerIdx = static_cast<int64_t>(ptoBlockIdx) * 2 + static_cast<int64_t>(ptoSubBlockId);
const int64_t workerNum = static_cast<int64_t>(ptoBlockNum) * 2;
const PaTilingContext ctx = LoadPaTilingContext(tilingParaGm);
if (SupportsPtoPagedAttentionRawSplitKV(tilingParaGm)) {
RunPtoPagedAttentionVecPipelineSplitKV(oGm, sGm, pGm, oTmpGm, oCoreTmpGm, lGm, tilingParaGm,
static_cast<int64_t>(ptoBlockIdx), static_cast<int64_t>(ptoBlockNum), ptoSubBlockId);
} else if (ctx.kvSplitCoreNum > 1) {
RunPtoPagedAttentionDecodeSplitKV(qGm, kGm, vGm, blockTablesGm, oGm, oCoreTmpGm, lGm, tilingParaGm,
static_cast<int64_t>(ptoBlockIdx), static_cast<int64_t>(ptoBlockNum), ptoSubBlockId);
} else {
RunPtoPagedAttentionDecode(qGm, kGm, vGm, blockTablesGm, oGm, tilingParaGm, workerIdx, workerNum);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The high-performance non-split pipeline (RunPtoPagedAttentionCubePipeline and RunPtoPagedAttentionVecPipeline) is implemented in pa_kernel_impl.hpp but is completely bypassed and never called in the entry point paged_attention_mask_body. When SupportsPtoPagedAttentionHighPerf is true, we should run these pipelined implementations. Note that when calling RunPtoPagedAttentionVecPipeline, we must pass static_cast<int64_t>(ptoBlockIdx) and static_cast<int64_t>(ptoBlockNum) (not the multiplied workerIdx and workerNum) to ensure the Vector sub-blocks coordinate correctly with the Cube core over the shared FIFO pipes.

#ifdef __DAV_C220_CUBE__
    const int64_t workerIdx = static_cast<int64_t>(ptoBlockIdx);
    const int64_t workerNum = static_cast<int64_t>(ptoBlockNum);
    if (SupportsPtoPagedAttentionRawSplitKV(tilingParaGm)) {
        RunPtoPagedAttentionCubePipelineSplitKV(qGm, kGm, vGm, blockTablesGm, sGm, pGm, oTmpGm, tilingParaGm,
            workerIdx, workerNum);
    } else if (SupportsPtoPagedAttentionHighPerf(tilingParaGm)) {
        RunPtoPagedAttentionCubePipeline(qGm, kGm, vGm, blockTablesGm, sGm, pGm, oTmpGm, tilingParaGm,
            workerIdx, workerNum);
    } else {
        pipe_barrier(PIPE_ALL);
    }
#elif defined(__DAV_C220_VEC__)
    const int64_t workerIdx = static_cast<int64_t>(ptoBlockIdx) * 2 + static_cast<int64_t>(ptoSubBlockId);
    const int64_t workerNum = static_cast<int64_t>(ptoBlockNum) * 2;
    const PaTilingContext ctx = LoadPaTilingContext(tilingParaGm);
    if (SupportsPtoPagedAttentionRawSplitKV(tilingParaGm)) {
        RunPtoPagedAttentionVecPipelineSplitKV(oGm, sGm, pGm, oTmpGm, oCoreTmpGm, lGm, tilingParaGm,
            static_cast<int64_t>(ptoBlockIdx), static_cast<int64_t>(ptoBlockNum), ptoSubBlockId);
    } else if (SupportsPtoPagedAttentionHighPerf(tilingParaGm)) {
        RunPtoPagedAttentionVecPipeline(oGm, sGm, pGm, oTmpGm, tilingParaGm,
            static_cast<int64_t>(ptoBlockIdx), static_cast<int64_t>(ptoBlockNum), ptoSubBlockId);
    } else if (ctx.kvSplitCoreNum > 1) {
        RunPtoPagedAttentionDecodeSplitKV(qGm, kGm, vGm, blockTablesGm, oGm, oCoreTmpGm, lGm, tilingParaGm,
            static_cast<int64_t>(ptoBlockIdx), static_cast<int64_t>(ptoBlockNum), ptoSubBlockId);
    } else {
        RunPtoPagedAttentionDecode(qGm, kGm, vGm, blockTablesGm, oGm, tilingParaGm, workerIdx, workerNum);
    }

Comment on lines +1494 to +1496
TROWSUM(scoreTile, qkProductTile, reduceTmpTile);
pipe_barrier(PIPE_V);
const float score = scoreTile.data()[0] * ctx.scale;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

There is a critical synchronization race condition here. TROWSUM is a vector instruction executed asynchronously by the Vector pipe (PIPE_V), but score is read immediately on the scalar side (PIPE_S). pipe_barrier(PIPE_V) only blocks the Vector pipe itself; it does not prevent the Scalar pipe from reading the value before TROWSUM completes. We must use cross-pipe flags (set_flag / wait_flag) to synchronize the Vector and Scalar pipes before reading scoreTile.data()[0].

                TROWSUM(scoreTile, qkProductTile, reduceTmpTile);
                pipe_barrier(PIPE_V);
                set_flag(PIPE_V, PIPE_S, EVENT_ID3);
                wait_flag(PIPE_V, PIPE_S, EVENT_ID3);
                const float score = scoreTile.data()[0] * ctx.scale;

Comment on lines +1498 to +1504
float oldScale = 0.0f;
if (relPos != 0) {
scalarMathTile.data()[0] = maxScore - newMax;
TEXP(scalarMathTile, scalarMathTile);
pipe_barrier(PIPE_V);
oldScale = scalarMathTile.data()[0];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This manual exponentiation block lacks proper synchronization between the Scalar and Vector pipes, which can lead to pipeline hazards and incorrect values for oldScale. Since the robust helper PtoExpScalar is already implemented with correct synchronization guards, we should use it here instead.

                float oldScale = 0.0f;
                if (relPos != 0) {
                    oldScale = PtoExpScalar(scalarMathTile, maxScore - newMax);
                }

Comment on lines +1505 to +1508
scalarMathTile.data()[0] = score - newMax;
TEXP(scalarMathTile, scalarMathTile);
pipe_barrier(PIPE_V);
const float probUnnorm = scalarMathTile.data()[0];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the previous block, this manual exponentiation lacks proper cross-pipe synchronization. We should use the robust PtoExpScalar helper to ensure correctness.

                const float probUnnorm = PtoExpScalar(scalarMathTile, score - newMax);

Comment on lines +1528 to +1534
float logSumExp = -3.4028234663852886e38f;
if (sumExp > 0.0f) {
scalarMathTile.data()[0] = sumExp;
TLOG(scalarMathTile, scalarMathTile);
pipe_barrier(PIPE_V);
logSumExp = scalarMathTile.data()[0];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This manual logarithm block lacks proper cross-pipe synchronization. We should use the robust PtoLogScalar helper to ensure correctness.

            const float logSumExp = PtoLogScalar(scalarMathTile, sumExp);

Comment on lines +1573 to +1581
for (int32_t split = 0; split < kvLoop; ++split) {
const float lValue = partialL[lBase + static_cast<uint64_t>(head) * ctx.kvSplitCoreNum + split];
scalarMathTile.data()[0] = lValue - lMax;
TEXP(scalarMathTile, scalarMathTile);
pipe_barrier(PIPE_V);
const float scale = scalarMathTile.data()[0];
splitScale[split] = scale;
denom += scale;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This manual exponentiation block in the split-reduction loop lacks proper cross-pipe synchronization. We should use the robust PtoExpScalar helper to ensure correctness.

        for (int32_t split = 0; split < kvLoop; ++split) {
            const float lValue = partialL[lBase + static_cast<uint64_t>(head) * ctx.kvSplitCoreNum + split];
            const float scale = PtoExpScalar(scalarMathTile, lValue - lMax);
            splitScale[split] = scale;
            denom += scale;
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant