Coelacanth's Dream

AMD GPU の GPU ID は何を意味するか

AMD GPU を話題にすると時々出てくる gfx908 だとか gfx1012 といった文字列。
これが何を意味するかと言うと、AMD GPUのマシンタイプ、アーキテクチャであり、そのアーキテクチャが対応する命令や機能、つまりは命令セット、ISA であり、
また存在するバグを示すために使われる。

ちなみに gfx908Arcturusgfx1012Navi14 に採用されているアーキテクチャを示す。

Index

Machine Type / GPU ID / GFX ID

そして gfx から始まる文字列は Machine Type / GPU ID / GFX ID といった名で使われる。
どれも同じ意味であるため、名前で特に使い分けはされておらず、コードを書く人次第なのではないかと思う。
この記事では GPU ID とする。

そして gfx より後ろの数字にはそれぞれ意味があり、
最初がその GPU の主要なバージョン、世代を、(pGfxIpMajorVer)
その次が補助的なバージョンを、(pGfxIpMinorVer)
最後がステッピングとなる。(pGfxIpStepping)1

Navi からは世代が GFX10 と二桁になったが、LLVM 等では _ で区切りを付けて記述されているため、問題はない。2
GFX1世代とされる AMD GPU はないため、間違うこともそう無いと思うが。

また、GFX10 までは補助的なバージョンを示す数字が使われることはあまり無く、gfx810 である Stoney APU くらいで、ほとんど 0 となっていた。
GFX10 からは RDNA /Navi1x であることを示すためには 1 (gfx101x) 、RDNA 2/Navi2x には 3 (gfx103x) が充てられている。
2 (gfx102x) が飛ばされているが、存在はしており、Navi21_Lite/nv21_litegfx1020 とされている。3gfx1000Navi10_Lite/nv10_lite もあり、そちらは Ariel というコードネームが付けられている。4
自分が知っているのはそれだけで、詳しくは知らない。知りたいなら探偵様にでも聞いてくれ。

GPU ID から読み取れること

その GPU IDllvm-project/AMDGPU.td と照らし合わせることで、その AMD GPUアーキテクチャが対応している命令、機能、存在するバグについて知ることができる。

これまでに登場してきた AMD GPU の GPU ID記事下部の表にて。

読み方としては例えば、gfx1011 (Navi12)gfx1012 (Navi14) には FeatureDot1InstsFeatureDot2InstsFeatureDot5InstsFeatureDot6Insts があるけど5gfx1010 (Navi10) には無い6
gfx1012 (Navi14) にはバグに FeatureLdsMisalignedBug があるけど7gfx1011 (Navi12) には無い (修正されている?)7、という風に比較することが基本となる。

規模は読み取れない

下の表を見るとわかるが、GPU ID は普通に被る。
規模の異なる Fiji /Polaris10 /Polaris11 /Polaris12 が一緒の gfx803 になってたり、
最近の AMD GPU でも、Raven2 /Renoir が一緒の gfx909 だった。
だから、GPU ID と llvm-project/AMDGPU.td と組み合わせで、ある AMD GPU の規模を知ることは不可能と言っていい。
GPU ID だけとなるともっと無理。

倍精度(FP64)演算を、単精度(FP32)演算の半分のレートで実行できることを示す HalfRate64Ops があれば、その AMD GPUアーキテクチャはサーバやデータセンター向けで、それを採用する GPUもそういった製品に使われる、といったことは推測できるが、あくまで規模が読み取れる訳ではない。

対応している命令、機能、存在するバグといった情報は、GPUの中で低い階層に位置するため、それだけで全体を見渡すことはできない。

また GPU ID がアーキテクチャを示すと言っても、llvm-project/AMDGPU.td を見るに、
GFX10世代が対応する命令、機能をまとめた FeatureGFX10 に、Wave内のスレッド数が 32スレッドである FeatureWavefrontSize32 が無く、gfx1010 /gfx1011 /gfx1012 /gfx1030 それぞれに記述されていることから、
gfx10xx としても、厳密に言えば RDNA系列でない可能性がある、というのが自分の考えだ。
gfx10xx すべてが RDNA系列となるなら FeatureGFX10 に記述すれば楽に済む。

メジャーバージョン、世代で Wavefront のサイズを判定するコードもどっかにあるだろうから、わざわざややこしく、わかりにくいことをするとも考えにくいが、可能性としてはわずかに存在する。

HBCC / XNACK について

HBCC は CPU側の一部 DRAM も追加で VRAM として扱う Vega の目玉機能だが、これを有効にすると GPU ID が変更されていた。8
Vega10 (HBCC無効)gfx900Vega10 (HBCC有効)gfx901 となる。

何で変更する必要があるのかは、
まず HBCC機能の中身としては、メモリのデマンドページングやページ移行に使用される XNACK という機能を有効にしている。910 LLVM から gfx901 等は消されているが、消された時の内容から gfx901FeatureXNACK がある。11

XNACK を有効にした場合に生成したコードを、無効にされている GPU で実行すると、正しく実行されない、またはパフォーマンスが低下するといったことが発生するため、GPU ID で判別する必要があるのだと思われる。

しかし HBCC/XNACK はもう dGPU で有効にすることは想定されておらず、dGPU には FeatureDoesNotSupportXNACK が記述され、また Vega20 (gfx906) 以降は判別するための GPU ID も確保されていない。
元々 XNACK はメモリを CPU と GPU で共有する APU 向けの機能だったらしく、元の位置に収まったとも言える。

AMD GPU Code Name / GPU ID

Code Name Tahiti Pitcairn / Capeverde / Oland / Hainan
GPU ID gfx600 gfx601
Code Name Spectre / Spooky HawaiiPro Hawaii Kalindi / Godavari Banaire
GPU ID gfx700 gfx701 gfx702 gfx703 gfx704
Code Name Carrizo / Bristol Iceland / Tonga Fiji / Polaris10 / Polaris11 / Polaris12 Stoney
GPU ID gfx801 gfx802 gfx803 gfx810
Code Name Vega10 Vega10 (HBCC) Raven / Picasso Vega12 Vega20 Arcturus Raven2 / Renoir
GPU ID gfx900 gfx901 gfx902 gfx904 gfx906 gfx908 gfx909
Code Name Navi10 Navi12 Navi14 Navi21
GPU ID gfx1010 gfx1011 gfx1012 gfx1030

(参考: https://github.com/GPUOpen-Drivers/pal/blob/e1b2dde021a2efd34da6593994f87317a803b065/src/core/os/nullDevice/ndDevice.cpp#L106)