Skip to content

[RFC][SM120] Strategy for Implementing Backward Pass for sm120 #30

Description

@minatoyukinaa

It is time to realize it.

1. Motivation

As we move towards supporting the backward pass for Blackwell (SM120), we face a strict 99KB shared memory limit per thread block. This proposal strictly targets the optimization of the fused_bwd.py kernel for single-GPU execution.

For the target configuration of block_S = 32, DK = DV = 128, and fp16 precision, the current naive allocation in fused_bwd.py exceeds this limit by approximately 37KB. This issue outlines a two-step optimization strategy to fit the kernel within the hardware constraints while maintaining correctness.

Note: Context Parallelism (CP) is out of scope for this initial implementation and will be considered in subsequent phases.

2. Current Shared Memory Budget Analysis

Below is the breakdown of the current shared memory consumption for the target configuration: block_S = 32, DK = DV = 128, fp16.

Buffer Group Components Calculation / Dimensions Current Size After Opt 1 After Opt 2
tmp_shared_1_x 1_1, 1_2, 1_3 $3 \times 32 \times 32 \times 2\text{B}$ 6 KB 6 KB 6 KB
tmp_shared_2_x 2_1, 2_2, 2_3 $3 \times 32 \times 128 \times 2\text{B}$ 24 KB 24 KB 24 KB
tmp_shared_4_1 4_1 (Staging) $128 \times 128 \times 2\text{B}$ 32 KB 32 KB 0 KB
I/O Buffers do, q, k, v $4 \times 32 \times 128 \times 2\text{B}$ 32 KB 24 KB 24 KB
State Buffers h, a $32\text{KB} + 2\text{KB}$ 34 KB 34 KB 34 KB
Scalars/Misc g, dg, db, etc. $6 \times 32 \times 4\text{B}$ 0.75 KB 0.75 KB 0.75 KB
dqkv_shared Output staging - 8 KB 8 KB 8 KB
Total Usage ~136.75 KB ~128.75 KB ~96.75 KB
Hardware Limit SM120 (Blackwell) 99 KB ❌ Overflow Fit

Deficit Analysis:

  • Current Deficit: ~37.75 KB over the 99KB limit.
  • After Opt 1 (Reuse q_shared): Saves ~8 KB. Deficit reduces to ~29 KB.
  • After Opt 2 (Merge Warps): Saves ~32 KB (tmp_shared_4_1). Final usage fits within the limit with ~2.25 KB margin.

3. Proposed Optimization Plan

To bridge this gap, I propose the following two optimizations:

Opt 1: Reuse q_shared with tmp_shared_2_1 (Save ~8 KB)
  • Mechanism: By moving T.copy(q_shared, odot_fragment_2) (currently line 662) to occur before the write of dV' into tmp_shared_2_1, we can alias tmp_shared_2_1 to occupy the memory region previously reserved for q_shared.
  • Validation: This pattern has been validated on H20 (SM90). It eliminates the standalone q_shared allocation without breaking the producer-consumer pipeline.
  • Result: Deficit reduces to ~29 KB.
  • Reference: Briefly discussed in #PR 21.
Opt 2: Merge Consumer S & Consumer K Warps (Save ~32 KB)
  • Mechanism:
    • Currently, tmp_shared_4_1 (32 KB) is used to stage dh_fragment for GEMM operations.
    • By merging the Consumer S (tx < 128) and Consumer K (tx < 256) warp groups, we can perform T.gemm directly between Shared Memory and Register Fragments (dh_fragment).
    • TileLang supports T.gemm(shared_memory, fragment) operations (verified on RTX 5090/SM120 simulators).
  • Impact: This allows dh_fragment to remain resident in registers throughout the iteration, eliminating the need for the large tmp_shared_4_1 buffer entirely.
  • Trade-off: While this saves significant SMEM, it increases register pressure. However, since tmp_shared_4_1 is only involved in two specific GEMM calls, keeping dh in registers is likely more efficient than spilling or using SMEM staging.

4. Discussion Points

Opt 1: Reuse q_shared with tmp_shared_2_1 (~8 KB savings)
Status: ✅ Validated on SM90 (H20/H800), but encountered precision issues in some test cases after dtype modification. Investigation ongoing.
Impact: Reduces deficit from ~37KB to ~29KB (still over limit).
Opt 2: Merge Consumer S & Consumer K Warps (~32 KB savings)
Status: ❌ Blocked due to fundamental conflicts:
Dual layout requirements: tmp_shared_4_1 needs both transpose-B and row-major layouts for different GEMMs, which register fragments cannot simultaneously satisfy.
Type conversion barrier: Cannot copy between fragments with different layouts in TileLang, forcing fallback to shared memory staging.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions