Matrix Square

top Top: 10 lines / v

par Par: 160 lines

Problem Statement

LM0上の \(3\) 次元 Float 配列 \(X\) に対して、\(2\) 次元目と \(3\) 次元目に対する \(2\) 次元行列積の転置 \(Y[i] = (X[i] \times X[i])^T\) を計算してLM1に出力してください。

Explanation

各 MAB に \(16 \times 16\) 行列が、((4_PE:1, 2:1, 2_W:1), (16:2)) のレイアウトで格納されています。

この行列の \(2\) 乗を計算し、転置を行った結果を同様のレイアウトで出力する問題です。

いよいよ最後のチュートリアルです。MN-Core の大きな特色の一つである行列演算の問題です。

行列演算は大まかに、各行列のブロックフロート化と行列レジスタへの書き込み、m(mul|fma)命令の呼び出しが必要になります。

また行列演算では、半精度と単精度の中間の精度である疑似単精度も使用することができます。

チュートリアルの内容が長いため、別ページに分けています。以下のリンクから進んでください。

行列積の注意点要点

・行列レジスタ($lx, $ly) の読み書きをする命令は、mwritemread であり、読み出しの方は転置で読み込みをします。

・行列演算を行う際、乗算を行う値は、内積を行う組単位で指数を合わせる「ブロックフロート」化を行う必要があります。

・行列積和演算 mfma の場合、加算項はブロックフロート化を行う必要はありません。

・疑似単精度は指数部は単精度と同じ\(8\) bit、仮数部長は \(18\) bit で、MSB側に有効値が配置されています。つまり単精度から、 LSB 側 \(5\) bit が無視されるものです。

・LM, GRF は単語 (\(32\) bit) 基準のアドレッシングですが、行列レジスタは長語 (\(64\) bit) 基準のアドレッシングですのでお気をつけください。

練習用入出力

いきなり \(16\times16\) 行列の行列積を実装するのは難しいかもしれませんので練習用の小さい入出力を用意しました。必要であれば練習にご使用ください。

Double \(4\times4\) 行列 testcase.vsm
# ======= In(0): ((4_PE:1), (4:1))@LM0 / Double ======= d set $lm0p0 1 4008000000000000 # values=[3.0] / Double @[0,0] d set $lm2p0 1 4022000000000000 # values=[9.0] / Double @[0,1] d set $lm4p0 1 401C000000000000 # values=[7.0] / Double @[0,2] d set $lm6p0 1 4014000000000000 # values=[5.0] / Double @[0,3] d set $lm0p1 1 3FF0000000000000 # values=[1.0] / Double @[1,0] d set $lm2p1 1 3FF0000000000000 # values=[1.0] / Double @[1,1] d set $lm4p1 1 0000000000000000 # values=[0.0] / Double @[1,2] d set $lm6p1 1 4020000000000000 # values=[8.0] / Double @[1,3] d set $lm0p2 1 4018000000000000 # values=[6.0] / Double @[2,0] d set $lm2p2 1 401C000000000000 # values=[7.0] / Double @[2,1] d set $lm4p2 1 0000000000000000 # values=[0.0] / Double @[2,2] d set $lm6p2 1 4022000000000000 # values=[9.0] / Double @[2,3] d set $lm0p3 1 4020000000000000 # values=[8.0] / Double @[3,0] d set $lm2p3 1 4000000000000000 # values=[2.0] / Double @[3,1] d set $lm4p3 1 3FF0000000000000 # values=[1.0] / Double @[3,2] d set $lm6p3 1 3FF0000000000000 # values=[1.0] / Double @[3,3] # ======= YOUR VSM WILL BE INSERTED HERE ======= # ======= Out(0): ((4_PE:1), (4:1))@LM1 / Double ======= d getd $ln0n0c0b0m0p0 1 # expect=[100.0] / Double @[0,0] atol=1e-05 d getd $ln2n0c0b0m0p0 1 # expect=[68.0] / Double @[0,1] atol=1e-05 d getd $ln4n0c0b0m0p0 1 # expect=[97.0] / Double @[0,2] atol=1e-05 d getd $ln6n0c0b0m0p0 1 # expect=[40.0] / Double @[0,3] atol=1e-05 d getd $ln0n0c0b0m0p1 1 # expect=[95.0] / Double @[1,0] atol=1e-05 d getd $ln2n0c0b0m0p1 1 # expect=[26.0] / Double @[1,1] atol=1e-05 d getd $ln4n0c0b0m0p1 1 # expect=[79.0] / Double @[1,2] atol=1e-05 d getd $ln6n0c0b0m0p1 1 # expect=[83.0] / Double @[1,3] atol=1e-05 d getd $ln0n0c0b0m0p2 1 # expect=[26.0] / Double @[2,0] atol=1e-05 d getd $ln2n0c0b0m0p2 1 # expect=[15.0] / Double @[2,1] atol=1e-05 d getd $ln4n0c0b0m0p2 1 # expect=[51.0] / Double @[2,2] atol=1e-05 d getd $ln6n0c0b0m0p2 1 # expect=[57.0] / Double @[2,3] atol=1e-05 d getd $ln0n0c0b0m0p3 1 # expect=[155.0] / Double @[3,0] atol=1e-05 d getd $ln2n0c0b0m0p3 1 # expect=[21.0] / Double @[3,1] atol=1e-05 d getd $ln4n0c0b0m0p3 1 # expect=[95.0] / Double @[3,2] atol=1e-05 d getd $ln6n0c0b0m0p3 1 # expect=[66.0] / Double @[3,3] atol=1e-05
Float \(8\times8\) 行列 testcase.vsm
# ======= In(0): ((4_PE:1, 2_W:1), (8:1))@LM0 / Float ======= d set $lm0p0 1 4040000040C00000 # values=[3.0, 6.0] / Float @[0,0],[1,0] d set $lm2p0 1 4110000040E00000 # values=[9.0, 7.0] / Float @[0,1],[1,1] d set $lm4p0 1 40E0000000000000 # values=[7.0, 0.0] / Float @[0,2],[1,2] d set $lm6p0 1 40A0000041100000 # values=[5.0, 9.0] / Float @[0,3],[1,3] d set $lm8p0 1 3F80000041000000 # values=[1.0, 8.0] / Float @[0,4],[1,4] d set $lm10p0 1 3F80000040000000 # values=[1.0, 2.0] / Float @[0,5],[1,5] d set $lm12p0 1 000000003F800000 # values=[0.0, 1.0] / Float @[0,6],[1,6] d set $lm14p0 1 410000003F800000 # values=[8.0, 1.0] / Float @[0,7],[1,7] d set $lm0p1 1 4040000040800000 # values=[3.0, 4.0] / Float @[2,0],[3,0] d set $lm2p1 1 40A0000040E00000 # values=[5.0, 7.0] / Float @[2,1],[3,1] d set $lm4p1 1 408000003F800000 # values=[4.0, 1.0] / Float @[2,2],[3,2] d set $lm6p1 1 4000000040A00000 # values=[2.0, 5.0] / Float @[2,3],[3,3] d set $lm8p1 1 40C0000040A00000 # values=[6.0, 5.0] / Float @[2,4],[3,4] d set $lm10p1 1 3F80000000000000 # values=[1.0, 0.0] / Float @[2,5],[3,5] d set $lm12p1 1 4000000040C00000 # values=[2.0, 6.0] / Float @[2,6],[3,6] d set $lm14p1 1 404000003F800000 # values=[3.0, 1.0] / Float @[2,7],[3,7] d set $lm0p2 1 000000003F800000 # values=[0.0, 1.0] / Float @[4,0],[5,0] d set $lm2p2 1 4110000040800000 # values=[9.0, 4.0] / Float @[4,1],[5,1] d set $lm4p2 1 4110000000000000 # values=[9.0, 0.0] / Float @[4,2],[5,2] d set $lm6p2 1 4100000041100000 # values=[8.0, 9.0] / Float @[4,3],[5,3] d set $lm8p2 1 4040000040000000 # values=[3.0, 2.0] / Float @[4,4],[5,4] d set $lm10p2 1 0000000040C00000 # values=[0.0, 6.0] / Float @[4,5],[5,5] d set $lm12p2 1 40C0000040400000 # values=[6.0, 3.0] / Float @[4,6],[5,6] d set $lm14p2 1 4080000040A00000 # values=[4.0, 5.0] / Float @[4,7],[5,7] d set $lm0p3 1 40A0000000000000 # values=[5.0, 0.0] / Float @[6,0],[7,0] d set $lm2p3 1 3F8000003F800000 # values=[1.0, 1.0] / Float @[6,1],[7,1] d set $lm4p3 1 4110000000000000 # values=[9.0, 0.0] / Float @[6,2],[7,2] d set $lm6p3 1 40E0000040400000 # values=[7.0, 3.0] / Float @[6,3],[7,3] d set $lm8p3 1 4110000040400000 # values=[9.0, 3.0] / Float @[6,4],[7,4] d set $lm10p3 1 4100000040000000 # values=[8.0, 2.0] / Float @[6,5],[7,5] d set $lm12p3 1 40A0000041000000 # values=[5.0, 8.0] / Float @[6,6],[7,6] d set $lm14p3 1 4110000040400000 # values=[9.0, 3.0] / Float @[6,7],[7,7] # ======= YOUR VSM WILL BE INSERTED HERE ======= # ======= Out(0): ((4_PE:1, 2_W:1), (8:1))@LM1 / Float ======= d getd $ln0n0c0b0m0p0 1 # expect=[105.0, 181.0] / Float @[0,0],[1,0] atol=1e-05 d getd $ln2n0c0b0m0p0 1 # expect=[103.0, 248.0] / Float @[0,1],[1,1] atol=1e-05 d getd $ln4n0c0b0m0p0 1 # expect=[70.0, 159.0] / Float @[0,2],[1,2] atol=1e-05 d getd $ln6n0c0b0m0p0 1 # expect=[107.0, 177.0] / Float @[0,3],[1,3] atol=1e-05 d getd $ln8n0c0b0m0p0 1 # expect=[143.0, 201.0] / Float @[0,4],[1,4] atol=1e-05 d getd $ln10n0c0b0m0p0 1 # expect=[84.0, 150.0] / Float @[0,5],[1,5] atol=1e-05 d getd $ln12n0c0b0m0p0 1 # expect=[109.0, 273.0] / Float @[0,6],[1,6] atol=1e-05 d getd $ln14n0c0b0m0p0 1 # expect=[60.0, 74.0] / Float @[0,7],[1,7] atol=1e-05 d getd $ln0n0c0b0m0p1 1 # expect=[63.0, 176.0] / Float @[2,0],[3,0] atol=1e-05 d getd $ln2n0c0b0m0p1 1 # expect=[132.0, 230.0] / Float @[2,1],[3,1] atol=1e-05 d getd $ln4n0c0b0m0p1 1 # expect=[111.0, 158.0] / Float @[2,2],[3,2] atol=1e-05 d getd $ln6n0c0b0m0p1 1 # expect=[136.0, 195.0] / Float @[2,3],[3,3] atol=1e-05 d getd $ln8n0c0b0m0p1 1 # expect=[125.0, 217.0] / Float @[2,4],[3,4] atol=1e-05 d getd $ln10n0c0b0m0p1 1 # expect=[61.0, 192.0] / Float @[2,5],[3,5] atol=1e-05 d getd $ln12n0c0b0m0p1 1 # expect=[204.0, 293.0] / Float @[2,6],[3,6] atol=1e-05 d getd $ln14n0c0b0m0p1 1 # expect=[102.0, 131.0] / Float @[2,7],[3,7] atol=1e-05 d getd $ln0n0c0b0m0p2 1 # expect=[171.0, 50.0] / Float @[4,0],[5,0] atol=1e-05 d getd $ln2n0c0b0m0p2 1 # expect=[147.0, 42.0] / Float @[4,1],[5,1] atol=1e-05 d getd $ln4n0c0b0m0p2 1 # expect=[124.0, 45.0] / Float @[4,2],[5,2] atol=1e-05 d getd $ln6n0c0b0m0p2 1 # expect=[163.0, 69.0] / Float @[4,3],[5,3] atol=1e-05 d getd $ln8n0c0b0m0p2 1 # expect=[241.0, 83.0] / Float @[4,4],[5,4] atol=1e-05 d getd $ln10n0c0b0m0p2 1 # expect=[138.0, 79.0] / Float @[4,5],[5,5] atol=1e-05 d getd $ln12n0c0b0m0p2 1 # expect=[217.0, 122.0] / Float @[4,6],[5,6] atol=1e-05 d getd $ln14n0c0b0m0p2 1 # expect=[117.0, 84.0] / Float @[4,7],[5,7] atol=1e-05 d getd $ln0n0c0b0m0p3 1 # expect=[126.0, 92.0] / Float @[6,0],[7,0] atol=1e-05 d getd $ln2n0c0b0m0p3 1 # expect=[128.0, 118.0] / Float @[6,1],[7,1] atol=1e-05 d getd $ln4n0c0b0m0p3 1 # expect=[98.0, 99.0] / Float @[6,2],[7,2] atol=1e-05 d getd $ln6n0c0b0m0p3 1 # expect=[107.0, 124.0] / Float @[6,3],[7,3] atol=1e-05 d getd $ln8n0c0b0m0p3 1 # expect=[155.0, 122.0] / Float @[6,4],[7,4] atol=1e-05 d getd $ln10n0c0b0m0p3 1 # expect=[143.0, 101.0] / Float @[6,5],[7,5] atol=1e-05 d getd $ln12n0c0b0m0p3 1 # expect=[236.0, 223.0] / Float @[6,6],[7,6] atol=1e-05 d getd $ln14n0c0b0m0p3 1 # expect=[107.0, 107.0] / Float @[6,7],[7,7] atol=1e-05
Float \(8\times8\) 行列 テキスト形式
[[3,9,7,5,1,1,0,8], [6,7,0,9,8,2,1,1], [3,5,4,2,6,1,2,3], [4,7,1,5,5,0,6,1], [0,9,9,8,3,0,6,4], [1,4,0,9,2,6,3,5], [5,1,9,7,9,8,5,9], [0,1,0,3,3,2,8,3]]
入力の $l2bid = 0 の \(16\times16\) 行列 テキスト形式
[[43, 95, 75, 63, 24, 24, 15, 87, 64, 73, 11, 97, 84, 29, 26, 26], [37, 57, 48, 36, 65, 22, 36, 42, 51, 80, 27, 56, 63, 14, 64, 25], [15, 95, 96, 82, 37, 18, 71, 49, 20, 54, 13, 91, 33, 69, 38, 56], [59, 26, 97, 79, 94, 90, 63, 92, 17, 27, 14, 39, 44, 34, 84, 42], [35, 58, 22, 82, 16, 98, 79, 27, 10, 83, 73, 75, 79, 16, 42, 20], [87, 66, 39, 15, 37, 39, 75, 67, 89, 52, 20, 74, 78, 60, 79, 54], [57, 48, 12, 19, 12, 67, 38, 55, 91, 32, 46, 77, 30, 16, 36, 24], [93, 82, 67, 88, 82, 26, 90, 58, 82, 90, 38, 19, 30, 48, 83, 87], [10, 55, 47, 29, 20, 40, 94, 39, 56, 73, 42, 97, 96, 32, 54, 37], [35, 13, 64, 55, 14, 35, 91, 31, 23, 54, 98, 31, 70, 78, 31, 75], [43, 66, 67, 58, 18, 85, 38, 26, 13, 63, 70, 11, 56, 30, 68, 25], [72, 44, 94, 22, 40, 20, 93, 88, 33, 69, 83, 59, 57, 31, 18, 90], [91, 66, 40, 41, 75, 90, 89, 80, 67, 17, 24, 90, 64, 10, 19, 69], [10, 24, 59, 72, 68, 30, 74, 31, 39, 77, 68, 86, 69, 61, 18, 43], [33, 31, 97, 45, 90, 66, 81, 55, 61, 54, 27, 75, 35, 12, 68, 25], [94, 95, 92, 43, 11, 93, 48, 96, 96, 86, 36, 44, 86, 38, 25, 60]]

Additional Constraints

Inputs

Outputs

Testcases

testcase.vsm

Submission

ログイン / 新規登録