Coelacanth's Dream

Xe-HPC のサポートが intel-graphics-compiler、oneDNN に追加される

Intel GPU の OpenCLコンパイラ intel-graphics-compiler、oneAPI における深層学習ライブラリ oneDNNXe-HPC のサポートが追加された。

Index

Xe-HPC の L1命令キャッシュサイズ

Xe アーキテクチャ では複数の EU (Vector Engine, Matrix Engine) やロード/ストアユニットをまとめた Xe-Core ごとに L1命令キャッシュを持つ。
Xe-Core は、以前は Sub-Slice(s) と呼ばれており、Intel GPU 向けのオープンソースソフトウェア、ドライバーではそのまま Sub-Slice(s) を使っている。

Tiger/Rocket/Alder LakeDG1 が採用する Xe-LP アーキテクチャ では L1命令キャッシュのサイズは 48 KiB となっていた。
以前には、Xe-HPXe-LP と同じ 48 KiB、Xe-HPG はその倍のサイズとなる 96 KiB を L1命令キャッシュに持つことを示す記述が oneDNN に追加されていた。
Xe-LP/HP より大きな命令キャッシュを持つ Xe-HPG | Coelacanth’s Dream 今回、同様の部分に Xe-HPC の L1命令キャッシュサイズを示す記述が追加され、Xe-LP/HP とも Xe-HPG とも異なる 80 KiB とされている。

 static size_t icache_size(ngen::HW arch) {
     switch (arch) {
         case gpu_gen9: return 48 * 1024;
         case gpu_xe_lp: return 48 * 1024;
         case gpu_xe_hp: return 48 * 1024;
         case gpu_xe_hpg: return 96 * 1024;
         case gpu_xe_hpc: return 80 * 1024;
         default: return 0;
     }
 }

ただ、GPUアーキテクチャにおける命令キャッシュの増減について触れられることは少ないと感じており、単にサイズからどうこう言うことは自分にはできない。
oneDNN では命令キャッシュの情報を、実行するカーネルの生サイズと比較してカーネルが命令キャッシュより大きかった場合にログに警告メッセージを出力する、といった使い方をしている。より大きなカーネルの実行性能を高めるために命令キャッシュを大きくした、という可能性はある。

とはいえ、上記のコードの通りであれば、Xe-LP/HP, Xe-HPG, Xe-HPC でそれぞれ Xe-Core (Sub-Slice) あたりの命令キャッシュサイズは異なることとなり、目的があってサイズを調整していることは窺い知れる。

Xe GPU Xe-LP Xe-HPG Xe-HP Xe-HPC
Vector Engine 256-bit? 256-bit ? 512-bit
VE per SS (Sub-Slice) 16 16 ? 8
L1I$ per SS 48 KB 96 KB? 48 KB? 80 KB?
Matrix Engine N/A 1024-bit ? 4096-bit
Load/Store per cycle (SLM) 128 B?
(per Dataport)
? ? 512 B
L1D$/SLM per SS 128 KB ? ? 512 KB
Native FP64 N/A N/A Y Y

Xe-HPC では GRF (General Register File) のサイズが 64 Bytes (512-bit) に拡張されており、従来のアーキテクチャでは 32 Bytes (256-bit, 8x 32-bit) だった。
恐らく FP64演算性能の最適化のため、8x 64-bit の構成を採っていると思われる。
同様のアーキテクチャ拡張は AMD Aldebaran/MI200 GPU でも施されており、FullRateFP64、PackedFP32 への対応と同時に行われている。
LLVM に GFX90A のサポートが追加される ―― CDNA 2/MI200 か | Coelacanth’s Dream

     const int REG_SIZE_BITS = p >= Platform::XE_HPC ? 512 : 256;
     const int GRF_BYTES = platform() >= Platform::XE_HPC ? 64 : 32;
     const int DEFAULT_SIMD = GRF_BYTES / 2;

EU あたりの最大スレッド数が 8スレッドとなり、また半分の 4スレッドに設定することでスレッドあたりのレジスタファイルを 256エントリに増やす Large GRFモードをサポートする点は Xe-HP/HPG/HPC で共通する。

     // Assume 7 threads by default
     int32_t threads_per_eu[2] = {7, 7};
     switch (gpu_arch_) {
         case gpu::compute::gpu_arch_t::gen9:
         case gpu::compute::gpu_arch_t::xe_lp:
             threads_per_eu[0] = 7;
             threads_per_eu[1] = 7;
             break;
         case gpu::compute::gpu_arch_t::xe_hp:
         case gpu::compute::gpu_arch_t::xe_hpg:
         case gpu::compute::gpu_arch_t::xe_hpc:
             threads_per_eu[0] = 8; // 128 regs/thread
             threads_per_eu[1] = 4; // 256 regs/thread
             break;
         default: break;
     }

Xe-HPC ではデータタイプに、QF, BF8, TF32 を新しくサポートする。
TF32 (Tensor Float32) は 19-bit長のデータフォーマットで、NVIDIA A100 GPU がサポートしているデータタイプだが、QF,BF8 については詳細不明。
QF は Quadword Float、BF8 は BF16 (BFloat16) からダイナミックレンジと精度を減らしたフォーマットとは考えられるが。

     GED_DATA_TYPE_qf,      ///< XE.HPC.A
     GED_DATA_TYPE_bf8,     ///< XE.HPC
     GED_DATA_TYPE_tf32,    ///< XE.HPC

Xe-HPC-XT と Xe-HPC-XL

Xe-HPC では XT と XL の 2種類があることがコメントで示されている。
これまで公開されてきた Xe-HPC アーキテクチャ を採用する Ponte Vecchio は Base Tile を 2基持ち、Co-EMIB でそれらを接続する 2-Tile 構成だったが、Raja Koduri 氏は 1-Tile バージョンを提供する予定があることを話している。1
AMD風の命名法則に従えば、Xe-HPC-XL が 1-Tile、Xe-HPC-XT が 2-Tile 構成の Ponte Vecchio となるのかもしれない。

     XE_HPC      = IGA_XE_VER_ORDINAL(1, 4), // XeHPC-XT, preserved (1, 3) for XeHPC-XL

参考リンク