消えたCUDA関連の旧ブログ記事を復元するひとり Advent Calendar 2024の記事です。

なんの話か?

cvt.rna.tf32.f32PTX命令によりRNA (Round to Nearest; ties to Away)を用いFP32からTF32への丸め付き変換が行える訳ですが、FP16変換などではRN (Round to Nearest; ties to even)が使える中、何故TF32はRNAなのか?という話。
タイトルの答えとしては、Noです。

cvt.rna.tf32.f32はAmpereのSASSとして何になるか?

適当にFP32->TF32の変換だけを行うカーネルを書き、sm_86用にコンパイルし、cuobjdumpで見てみと以下のようなビット演算(抜粋)に落とされていました。

        /*0050*/                   MOV R5, 0x1000 ;                              /* 0x0000100000057802 */
                                                                                 /* 0x000fe40000000f00 */
        /*0060*/                   FSETP.GEU.AND P0, PT, |R0|, +INF , PT ;       /* 0x7f8000000000780b */
                                                                                 /* 0x004fda0003f0e200 */
        /*0070*/              @!P0 IMAD.IADD.U32 R0, R0, 0x1, R5 ;               /* 0x0000000100008824 */
                                                                                 /* 0x000fca00078e0005 */
        /*0080*/                   LOP3.LUT R5, R0, 0xffffe000, RZ, 0xc0, !PT ;  /* 0xffffe00000057812 */
                                                                                 /* 0x000fca00078ec0ff */
入力はR0です。 2命令目でINF判定をし、INFでなければ次の繰り上げ処理を行います。 3命令目はIMADによるADDのエミュレートです。
FP32入力R0レジスタに0x1000が整数加算されます。
これはちょうどLSBから13 bit目であり、切り捨てられる仮数部の最上位ビット(=RNAで繰り上がりを判定するビット)となります。
この加算により繰り上がりが完成します。
浮動小数点数は仮数部指数部が別れているにも拘らず、仮数部への単純な整数加算によって指数部の繰り上がりまで勝手になされるというのは便利な性質です。

4命令目のLOP3.LUTというのは、3入力の任意の論理演算を行う命令で、LUTからどの組み合わせの演算を行うかを取り出し実行します [1]
3入力中1入力はRZなので、今回は実質的に2入力の論理演算です。
ドキュメントはないので妄想ですが、0xffffe000という上位19bitが1のマスクを見るに、R0とANDが取られているのでしょう。
これにより上位19 bitが取り出され、RNAの完成です。

おわりに

というわけで、FP32->TF32変換のPTX命令はSASSの時点でビット演算となっていました。
RNの場合はtie時の偶数方向繰り上げ判定がビット演算では複雑になるため、RNAを採用したのですかね、きっと。
それにしては零レジスタ(RZ)とRound toward Zero(RZ)は被っていて紛らわしい。

関連

参考