萌えハッカーニュースリーダー

2025/10/02 15:43 Writing high-performance matrix multiplication kernels for Blackwell

出典: https://docs.jax.dev/en/latest/pallas/gpu/blackwell_matmul.html
hakase
博士

やっほー、ロボ子!Blackwell向けの高性能行列積カーネルの開発に関する記事、読んだかのじゃ?

roboko
ロボ子

はい、博士。cuBLASやCUTLASSに匹敵するカーネルを開発する過程が解説されていましたね。入力データの分布を指定する必要があるという点が興味深かったです。

hakase
博士

そうそう!入力データの分布はベンチマーク結果に影響するから、そこを考慮する必要があるのは当然なのじゃ。で、実装は基本的なカーネルから始めて、段階的に最適化を進めるみたいじゃな。

roboko
ロボ子

各段階でTensorCoreの利用率とcuBLASに対する割合が示されていて、最終的なカーネルはcuBLASと同等の性能を達成するんですね。

hakase
博士

ふむふむ。基本的なカーネルは、単一のCTAと単一のワーピングループを使うシンプルな実装らしいぞ。`tile_m`, `tile_n`, `tile_k`パラメータでmatmulのサイズを指定するのじゃ。

roboko
ロボ子

`max_concurrent_steps`でメモリプリフェッチの深さを指定したり、SMEMのデータ形式をMMA命令に合わせるための変換を設定したりするんですね。

hakase
博士

`plgpu.emit_pipeline`を使ってcompute/memoryパイプラインを設定するのは、効率的じゃな。TMEMからSMEMへのコピーと、SMEMからGMEMへのコピーをTMAを使って行うのもポイントじゃ。

roboko
ロボ子

Blackwellでは、PallasのスレッドがCUDAレーンのワーピンググループに対応するんですね。ワーピングの特殊化も行われているようですが…。

hakase
博士

そう!ワーピンググループを4つに分割して、それぞれを特殊化するのじゃ。`pl.core_map`と`plgpu.WarpMesh`を使うらしいぞ。スレッド0は非同期コピーを発行して、スレッド1はMMA演算を実行するってわけ。

roboko
ロボ子

`load_barriers`と`consumed_barriers`でGMEM->SMEMコピーの進行状況を追跡し、`plgpu.tcgen05_commit_arrive(mma_done_barrier)`でTensorCoreにMMA完了を要求するんですね。同期処理が重要そうです。

hakase
博士

タイル化されたエピローグも重要じゃぞ!TMEMからSMEMへのコピーと、SMEMからGMEMへの転送をパイプライン化するのじゃ。`scratch_shapes`を変更して、より小さなバッファを割り当てるのもミソじゃな。

roboko
ロボ子

出力カラムを`epilogue_tile_n`のチャンクに分割してGMEMに送信するんですね。集団(2CTA)MMAも使われているようですが…。

hakase
博士

2つのブロックのクラスタを使って、単一のmatmulを計算するのじゃ!各ブロックはオペランドの半分だけをロードして、MMA演算は各ブロックのSMEMからデータを交換するのじゃ。

roboko
ロボ子

`cluster`パラメータを`plgpu.kernel`に追加して、`collective=True`を指定するんですね。TMEM割り当てに`cluster_tile_n`を追加して、カラム数を2倍にするのもポイントですね。

hakase
博士

`collective_axes="cluster"`を使って、クラスタ間で分割されたコピーを要求するのじゃ。リーダーブロックだけがMMA命令を発行するのも面白いな。

roboko
ロボ子

`collective_axis=`引数を`tcgen05`呼び出しに追加して、MMAの完了がクラスタ内の両方のブロックでバリアを完了することを示すんですね。永続カーネルについても解説されていますね。

hakase
博士

GPU上で同時に実行できるクラスタ数だけを起動して、各クラスタは固定数の出力タイルをループするのじゃ。`plgpu.nd_loop`ヘルパーを使って、反復空間を指定するらしいぞ。

roboko
ロボ子

`collective_axes=`引数を使って、クラスタグリッド全体で分割されることを要求するんですね。専用のエピローグワーピンググループも使われているんですね。

hakase
博士

2つのPallasスレッド(ワーピンググループ)を使って、1つ目はMMAオペランドのフェッチとMMA演算の発行に集中、2つ目はエピローグだけを実行するのじゃ!

roboko
ロボ子

アキュムレータに使用されるTMEMをダブルバッファリングして、追加のバリアで同期するんですね。`acc_tmem`を`acc_tmem_slots`にリネームして、出力タイルをループするときにその半分を切り替えるのも効率的ですね。

hakase
博士

`wg_idx==0`に基づいて、compute部分をさらに述語化するのじゃ。TMEM割り当てをMMAに再利用する場合は、再利用するTMEMの半分の`store_done_barrier`を待機する必要があるらしいぞ。

roboko
ロボ子

グリッドタイリングも重要な戦略のようですね。L2をより有効に活用するために、出力ブロックを生成する順序を変更するんですね。

hakase
博士

`grid_minor_dim`で高速に変化する次元を選択して、`grid_tile_width`でその次元に沿ったタイルサイズを選択するのじゃ。`plgpu.planar_snake`ヘルパーを使うらしいぞ。この戦略は非常に効果的で、最先端のパフォーマンスを達成するために重要らしい。

roboko
ロボ子

なるほど。色々な最適化手法が組み合わさって、高性能な行列積カーネルが実現されているんですね。勉強になりました!

hakase
博士

そうじゃろ、そうじゃろ!しかし、ロボ子よ、これだけ高性能なカーネルを作っても、結局は電源コードが抜けたら意味ないのじゃ!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search